diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 17:24:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 17:24:30 -0400 |
| commit | aaeb2554337217dfa4eac2fcc90da7be540b9a73 (patch) | |
| tree | e453668c8e4253c1a86c8fbc3f92090e93f8336f | |
| parent | d27050641e9bc056446deb0814e7ba1aa7911f5a (diff) | |
| parent | a2668e10d7246e782f7708dc47c00f035da23a81 (diff) | |
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
...
263 files changed, 9256 insertions, 5792 deletions
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index 97a69bf6f3eb..a086a5db7a18 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml | |||
| @@ -125,7 +125,7 @@ location of the buffers in device memory can be determined with the | |||
| 125 | <structfield>m.offset</structfield> and <structfield>length</structfield> | 125 | <structfield>m.offset</structfield> and <structfield>length</structfield> |
| 126 | returned in a &v4l2-buffer; are passed as sixth and second parameter to the | 126 | returned in a &v4l2-buffer; are passed as sixth and second parameter to the |
| 127 | <function>mmap()</function> function. When using the multi-planar API, | 127 | <function>mmap()</function> function. When using the multi-planar API, |
| 128 | struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each | 128 | &v4l2-buffer; contains an array of &v4l2-plane; structures, each |
| 129 | containing its own <structfield>m.offset</structfield> and | 129 | containing its own <structfield>m.offset</structfield> and |
| 130 | <structfield>length</structfield>. When using the multi-planar API, every | 130 | <structfield>length</structfield>. When using the multi-planar API, every |
| 131 | plane of every buffer has to be mapped separately, so the number of | 131 | plane of every buffer has to be mapped separately, so the number of |
| @@ -699,7 +699,12 @@ linkend="v4l2-buf-type" /></entry> | |||
| 699 | buffer. It depends on the negotiated data format and may change with | 699 | buffer. It depends on the negotiated data format and may change with |
| 700 | each buffer for compressed variable size data like JPEG images. | 700 | each buffer for compressed variable size data like JPEG images. |
| 701 | Drivers must set this field when <structfield>type</structfield> | 701 | Drivers must set this field when <structfield>type</structfield> |
| 702 | refers to an input stream, applications when it refers to an output stream.</entry> | 702 | refers to an input stream, applications when it refers to an output stream. |
| 703 | If the application sets this to 0 for an output stream, then | ||
| 704 | <structfield>bytesused</structfield> will be set to the size of the | ||
| 705 | buffer (see the <structfield>length</structfield> field of this struct) by | ||
| 706 | the driver. For multiplanar formats this field is ignored and the | ||
| 707 | <structfield>planes</structfield> pointer is used instead.</entry> | ||
| 703 | </row> | 708 | </row> |
| 704 | <row> | 709 | <row> |
| 705 | <entry>__u32</entry> | 710 | <entry>__u32</entry> |
| @@ -861,7 +866,11 @@ should set this to 0.</entry> | |||
| 861 | <entry></entry> | 866 | <entry></entry> |
| 862 | <entry>The number of bytes occupied by data in the plane | 867 | <entry>The number of bytes occupied by data in the plane |
| 863 | (its payload). Drivers must set this field when <structfield>type</structfield> | 868 | (its payload). Drivers must set this field when <structfield>type</structfield> |
| 864 | refers to an input stream, applications when it refers to an output stream.</entry> | 869 | refers to an input stream, applications when it refers to an output stream. |
| 870 | If the application sets this to 0 for an output stream, then | ||
| 871 | <structfield>bytesused</structfield> will be set to the size of the | ||
| 872 | plane (see the <structfield>length</structfield> field of this struct) | ||
| 873 | by the driver.</entry> | ||
| 865 | </row> | 874 | </row> |
| 866 | <row> | 875 | <row> |
| 867 | <entry>__u32</entry> | 876 | <entry>__u32</entry> |
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml index cf8548556c7d..74fb394ec667 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-links.xml | |||
| @@ -79,13 +79,13 @@ | |||
| 79 | <entry>Entity id, set by the application.</entry> | 79 | <entry>Entity id, set by the application.</entry> |
| 80 | </row> | 80 | </row> |
| 81 | <row> | 81 | <row> |
| 82 | <entry>struct &media-pad-desc;</entry> | 82 | <entry>&media-pad-desc;</entry> |
| 83 | <entry>*<structfield>pads</structfield></entry> | 83 | <entry>*<structfield>pads</structfield></entry> |
| 84 | <entry>Pointer to a pads array allocated by the application. Ignored | 84 | <entry>Pointer to a pads array allocated by the application. Ignored |
| 85 | if NULL.</entry> | 85 | if NULL.</entry> |
| 86 | </row> | 86 | </row> |
| 87 | <row> | 87 | <row> |
| 88 | <entry>struct &media-link-desc;</entry> | 88 | <entry>&media-link-desc;</entry> |
| 89 | <entry>*<structfield>links</structfield></entry> | 89 | <entry>*<structfield>links</structfield></entry> |
| 90 | <entry>Pointer to a links array allocated by the application. Ignored | 90 | <entry>Pointer to a links array allocated by the application. Ignored |
| 91 | if NULL.</entry> | 91 | if NULL.</entry> |
| @@ -153,12 +153,12 @@ | |||
| 153 | &cs-str; | 153 | &cs-str; |
| 154 | <tbody valign="top"> | 154 | <tbody valign="top"> |
| 155 | <row> | 155 | <row> |
| 156 | <entry>struct &media-pad-desc;</entry> | 156 | <entry>&media-pad-desc;</entry> |
| 157 | <entry><structfield>source</structfield></entry> | 157 | <entry><structfield>source</structfield></entry> |
| 158 | <entry>Pad at the origin of this link.</entry> | 158 | <entry>Pad at the origin of this link.</entry> |
| 159 | </row> | 159 | </row> |
| 160 | <row> | 160 | <row> |
| 161 | <entry>struct &media-pad-desc;</entry> | 161 | <entry>&media-pad-desc;</entry> |
| 162 | <entry><structfield>sink</structfield></entry> | 162 | <entry><structfield>sink</structfield></entry> |
| 163 | <entry>Pad at the target of this link.</entry> | 163 | <entry>Pad at the target of this link.</entry> |
| 164 | </row> | 164 | </row> |
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml index ea514d6075c5..91dcbc84f3f8 100644 --- a/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt.xml | |||
| @@ -772,7 +772,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see | |||
| 772 | </row> | 772 | </row> |
| 773 | <row id="V4L2-PIX-FMT-H264-MVC"> | 773 | <row id="V4L2-PIX-FMT-H264-MVC"> |
| 774 | <entry><constant>V4L2_PIX_FMT_H264_MVC</constant></entry> | 774 | <entry><constant>V4L2_PIX_FMT_H264_MVC</constant></entry> |
| 775 | <entry>'MVC'</entry> | 775 | <entry>'M264'</entry> |
| 776 | <entry>H264 MVC video elementary stream.</entry> | 776 | <entry>H264 MVC video elementary stream.</entry> |
| 777 | </row> | 777 | </row> |
| 778 | <row id="V4L2-PIX-FMT-H263"> | 778 | <row id="V4L2-PIX-FMT-H263"> |
| @@ -812,7 +812,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see | |||
| 812 | </row> | 812 | </row> |
| 813 | <row id="V4L2-PIX-FMT-VP8"> | 813 | <row id="V4L2-PIX-FMT-VP8"> |
| 814 | <entry><constant>V4L2_PIX_FMT_VP8</constant></entry> | 814 | <entry><constant>V4L2_PIX_FMT_VP8</constant></entry> |
| 815 | <entry>'VP8'</entry> | 815 | <entry>'VP80'</entry> |
| 816 | <entry>VP8 video elementary stream.</entry> | 816 | <entry>VP8 video elementary stream.</entry> |
| 817 | </row> | 817 | </row> |
| 818 | </tbody> | 818 | </tbody> |
diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml index 7331ce116f4c..b2d5a0363cba 100644 --- a/Documentation/DocBook/media/v4l/subdev-formats.xml +++ b/Documentation/DocBook/media/v4l/subdev-formats.xml | |||
| @@ -1898,6 +1898,134 @@ | |||
| 1898 | <entry>y<subscript>1</subscript></entry> | 1898 | <entry>y<subscript>1</subscript></entry> |
| 1899 | <entry>y<subscript>0</subscript></entry> | 1899 | <entry>y<subscript>0</subscript></entry> |
| 1900 | </row> | 1900 | </row> |
| 1901 | <row id="V4L2-MBUS-FMT-UYVY10-2X10"> | ||
| 1902 | <entry>V4L2_MBUS_FMT_UYVY10_2X10</entry> | ||
| 1903 | <entry>0x2018</entry> | ||
| 1904 | <entry></entry> | ||
| 1905 | &dash-ent-22; | ||
| 1906 | <entry>u<subscript>9</subscript></entry> | ||
| 1907 | <entry>u<subscript>8</subscript></entry> | ||
| 1908 | <entry>u<subscript>7</subscript></entry> | ||
| 1909 | <entry>u<subscript>6</subscript></entry> | ||
| 1910 | <entry>u<subscript>5</subscript></entry> | ||
| 1911 | <entry>u<subscript>4</subscript></entry> | ||
| 1912 | <entry>u<subscript>3</subscript></entry> | ||
| 1913 | <entry>u<subscript>2</subscript></entry> | ||
| 1914 | <entry>u<subscript>1</subscript></entry> | ||
| 1915 | <entry>u<subscript>0</subscript></entry> | ||
| 1916 | </row> | ||
| 1917 | <row> | ||
| 1918 | <entry></entry> | ||
| 1919 | <entry></entry> | ||
| 1920 | <entry></entry> | ||
| 1921 | &dash-ent-22; | ||
| 1922 | <entry>y<subscript>9</subscript></entry> | ||
| 1923 | <entry>y<subscript>8</subscript></entry> | ||
| 1924 | <entry>y<subscript>7</subscript></entry> | ||
| 1925 | <entry>y<subscript>6</subscript></entry> | ||
| 1926 | <entry>y<subscript>5</subscript></entry> | ||
| 1927 | <entry>y<subscript>4</subscript></entry> | ||
| 1928 | <entry>y<subscript>3</subscript></entry> | ||
| 1929 | <entry>y<subscript>2</subscript></entry> | ||
| 1930 | <entry>y<subscript>1</subscript></entry> | ||
| 1931 | <entry>y<subscript>0</subscript></entry> | ||
| 1932 | </row> | ||
| 1933 | <row> | ||
| 1934 | <entry></entry> | ||
| 1935 | <entry></entry> | ||
| 1936 | <entry></entry> | ||
| 1937 | &dash-ent-22; | ||
| 1938 | <entry>v<subscript>9</subscript></entry> | ||
| 1939 | <entry>v<subscript>8</subscript></entry> | ||
| 1940 | <entry>v<subscript>7</subscript></entry> | ||
| 1941 | <entry>v<subscript>6</subscript></entry> | ||
| 1942 | <entry>v<subscript>5</subscript></entry> | ||
| 1943 | <entry>v<subscript>4</subscript></entry> | ||
| 1944 | <entry>v<subscript>3</subscript></entry> | ||
| 1945 | <entry>v<subscript>2</subscript></entry> | ||
| 1946 | <entry>v<subscript>1</subscript></entry> | ||
| 1947 | <entry>v<subscript>0</subscript></entry> | ||
| 1948 | </row> | ||
| 1949 | <row> | ||
| 1950 | <entry></entry> | ||
| 1951 | <entry></entry> | ||
| 1952 | <entry></entry> | ||
| 1953 | &dash-ent-22; | ||
| 1954 | <entry>y<subscript>9</subscript></entry> | ||
| 1955 | <entry>y<subscript>8</subscript></entry> | ||
| 1956 | <entry>y<subscript>7</subscript></entry> | ||
| 1957 | <entry>y<subscript>6</subscript></entry> | ||
| 1958 | <entry>y<subscript>5</subscript></entry> | ||
| 1959 | <entry>y<subscript>4</subscript></entry> | ||
| 1960 | <entry>y<subscript>3</subscript></entry> | ||
| 1961 | <entry>y<subscript>2</subscript></entry> | ||
| 1962 | <entry>y<subscript>1</subscript></entry> | ||
| 1963 | <entry>y<subscript>0</subscript></entry> | ||
| 1964 | </row> | ||
| 1965 | <row id="V4L2-MBUS-FMT-VYUY10-2X10"> | ||
| 1966 | <entry>V4L2_MBUS_FMT_VYUY10_2X10</entry> | ||
| 1967 | <entry>0x2019</entry> | ||
| 1968 | <entry></entry> | ||
| 1969 | &dash-ent-22; | ||
| 1970 | <entry>v<subscript>9</subscript></entry> | ||
| 1971 | <entry>v<subscript>8</subscript></entry> | ||
| 1972 | <entry>v<subscript>7</subscript></entry> | ||
| 1973 | <entry>v<subscript>6</subscript></entry> | ||
| 1974 | <entry>v<subscript>5</subscript></entry> | ||
| 1975 | <entry>v<subscript>4</subscript></entry> | ||
| 1976 | <entry>v<subscript>3</subscript></entry> | ||
| 1977 | <entry>v<subscript>2</subscript></entry> | ||
| 1978 | <entry>v<subscript>1</subscript></entry> | ||
| 1979 | <entry>v<subscript>0</subscript></entry> | ||
| 1980 | </row> | ||
| 1981 | <row> | ||
| 1982 | <entry></entry> | ||
| 1983 | <entry></entry> | ||
| 1984 | <entry></entry> | ||
| 1985 | &dash-ent-22; | ||
| 1986 | <entry>y<subscript>9</subscript></entry> | ||
| 1987 | <entry>y<subscript>8</subscript></entry> | ||
| 1988 | <entry>y<subscript>7</subscript></entry> | ||
| 1989 | <entry>y<subscript>6</subscript></entry> | ||
| 1990 | <entry>y<subscript>5</subscript></entry> | ||
| 1991 | <entry>y<subscript>4</subscript></entry> | ||
| 1992 | <entry>y<subscript>3</subscript></entry> | ||
| 1993 | <entry>y<subscript>2</subscript></entry> | ||
| 1994 | <entry>y<subscript>1</subscript></entry> | ||
| 1995 | <entry>y<subscript>0</subscript></entry> | ||
| 1996 | </row> | ||
| 1997 | <row> | ||
| 1998 | <entry></entry> | ||
| 1999 | <entry></entry> | ||
| 2000 | <entry></entry> | ||
| 2001 | &dash-ent-22; | ||
| 2002 | <entry>u<subscript>9</subscript></entry> | ||
| 2003 | <entry>u<subscript>8</subscript></entry> | ||
| 2004 | <entry>u<subscript>7</subscript></entry> | ||
| 2005 | <entry>u<subscript>6</subscript></entry> | ||
| 2006 | <entry>u<subscript>5</subscript></entry> | ||
| 2007 | <entry>u<subscript>4</subscript></entry> | ||
| 2008 | <entry>u<subscript>3</subscript></entry> | ||
| 2009 | <entry>u<subscript>2</subscript></entry> | ||
| 2010 | <entry>u<subscript>1</subscript></entry> | ||
| 2011 | <entry>u<subscript>0</subscript></entry> | ||
| 2012 | </row> | ||
| 2013 | <row> | ||
| 2014 | <entry></entry> | ||
| 2015 | <entry></entry> | ||
| 2016 | <entry></entry> | ||
| 2017 | &dash-ent-22; | ||
| 2018 | <entry>y<subscript>9</subscript></entry> | ||
| 2019 | <entry>y<subscript>8</subscript></entry> | ||
| 2020 | <entry>y<subscript>7</subscript></entry> | ||
| 2021 | <entry>y<subscript>6</subscript></entry> | ||
| 2022 | <entry>y<subscript>5</subscript></entry> | ||
| 2023 | <entry>y<subscript>4</subscript></entry> | ||
| 2024 | <entry>y<subscript>3</subscript></entry> | ||
| 2025 | <entry>y<subscript>2</subscript></entry> | ||
| 2026 | <entry>y<subscript>1</subscript></entry> | ||
| 2027 | <entry>y<subscript>0</subscript></entry> | ||
| 2028 | </row> | ||
| 1901 | <row id="V4L2-MBUS-FMT-YUYV10-2X10"> | 2029 | <row id="V4L2-MBUS-FMT-YUYV10-2X10"> |
| 1902 | <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry> | 2030 | <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry> |
| 1903 | <entry>0x200b</entry> | 2031 | <entry>0x200b</entry> |
| @@ -2308,6 +2436,110 @@ | |||
| 2308 | <entry>v<subscript>1</subscript></entry> | 2436 | <entry>v<subscript>1</subscript></entry> |
| 2309 | <entry>v<subscript>0</subscript></entry> | 2437 | <entry>v<subscript>0</subscript></entry> |
| 2310 | </row> | 2438 | </row> |
| 2439 | <row id="V4L2-MBUS-FMT-UYVY10-1X20"> | ||
| 2440 | <entry>V4L2_MBUS_FMT_UYVY10_1X20</entry> | ||
| 2441 | <entry>0x201a</entry> | ||
| 2442 | <entry></entry> | ||
| 2443 | &dash-ent-12; | ||
| 2444 | <entry>u<subscript>9</subscript></entry> | ||
| 2445 | <entry>u<subscript>8</subscript></entry> | ||
| 2446 | <entry>u<subscript>7</subscript></entry> | ||
| 2447 | <entry>u<subscript>6</subscript></entry> | ||
| 2448 | <entry>u<subscript>5</subscript></entry> | ||
| 2449 | <entry>u<subscript>4</subscript></entry> | ||
| 2450 | <entry>u<subscript>3</subscript></entry> | ||
| 2451 | <entry>u<subscript>2</subscript></entry> | ||
| 2452 | <entry>u<subscript>1</subscript></entry> | ||
| 2453 | <entry>u<subscript>0</subscript></entry> | ||
| 2454 | <entry>y<subscript>9</subscript></entry> | ||
| 2455 | <entry>y<subscript>8</subscript></entry> | ||
| 2456 | <entry>y<subscript>7</subscript></entry> | ||
| 2457 | <entry>y<subscript>6</subscript></entry> | ||
| 2458 | <entry>y<subscript>5</subscript></entry> | ||
| 2459 | <entry>y<subscript>4</subscript></entry> | ||
| 2460 | <entry>y<subscript>3</subscript></entry> | ||
| 2461 | <entry>y<subscript>2</subscript></entry> | ||
| 2462 | <entry>y<subscript>1</subscript></entry> | ||
| 2463 | <entry>y<subscript>0</subscript></entry> | ||
| 2464 | </row> | ||
| 2465 | <row> | ||
| 2466 | <entry></entry> | ||
| 2467 | <entry></entry> | ||
| 2468 | <entry></entry> | ||
| 2469 | &dash-ent-12; | ||
| 2470 | <entry>v<subscript>9</subscript></entry> | ||
| 2471 | <entry>v<subscript>8</subscript></entry> | ||
| 2472 | <entry>v<subscript>7</subscript></entry> | ||
| 2473 | <entry>v<subscript>6</subscript></entry> | ||
| 2474 | <entry>v<subscript>5</subscript></entry> | ||
| 2475 | <entry>v<subscript>4</subscript></entry> | ||
| 2476 | <entry>v<subscript>3</subscript></entry> | ||
| 2477 | <entry>v<subscript>2</subscript></entry> | ||
| 2478 | <entry>v<subscript>1</subscript></entry> | ||
| 2479 | <entry>v<subscript>0</subscript></entry> | ||
| 2480 | <entry>y<subscript>9</subscript></entry> | ||
| 2481 | <entry>y<subscript>8</subscript></entry> | ||
| 2482 | <entry>y<subscript>7</subscript></entry> | ||
| 2483 | <entry>y<subscript>6</subscript></entry> | ||
| 2484 | <entry>y<subscript>5</subscript></entry> | ||
| 2485 | <entry>y<subscript>4</subscript></entry> | ||
| 2486 | <entry>y<subscript>3</subscript></entry> | ||
| 2487 | <entry>y<subscript>2</subscript></entry> | ||
| 2488 | <entry>y<subscript>1</subscript></entry> | ||
| 2489 | <entry>y<subscript>0</subscript></entry> | ||
| 2490 | </row> | ||
| 2491 | <row id="V4L2-MBUS-FMT-VYUY10-1X20"> | ||
| 2492 | <entry>V4L2_MBUS_FMT_VYUY10_1X20</entry> | ||
| 2493 | <entry>0x201b</entry> | ||
| 2494 | <entry></entry> | ||
| 2495 | &dash-ent-12; | ||
| 2496 | <entry>v<subscript>9</subscript></entry> | ||
| 2497 | <entry>v<subscript>8</subscript></entry> | ||
| 2498 | <entry>v<subscript>7</subscript></entry> | ||
| 2499 | <entry>v<subscript>6</subscript></entry> | ||
| 2500 | <entry>v<subscript>5</subscript></entry> | ||
| 2501 | <entry>v<subscript>4</subscript></entry> | ||
| 2502 | <entry>v<subscript>3</subscript></entry> | ||
| 2503 | <entry>v<subscript>2</subscript></entry> | ||
| 2504 | <entry>v<subscript>1</subscript></entry> | ||
| 2505 | <entry>v<subscript>0</subscript></entry> | ||
| 2506 | <entry>y<subscript>9</subscript></entry> | ||
| 2507 | <entry>y<subscript>8</subscript></entry> | ||
| 2508 | <entry>y<subscript>7</subscript></entry> | ||
| 2509 | <entry>y<subscript>6</subscript></entry> | ||
| 2510 | <entry>y<subscript>5</subscript></entry> | ||
| 2511 | <entry>y<subscript>4</subscript></entry> | ||
| 2512 | <entry>y<subscript>3</subscript></entry> | ||
| 2513 | <entry>y<subscript>2</subscript></entry> | ||
| 2514 | <entry>y<subscript>1</subscript></entry> | ||
| 2515 | <entry>y<subscript>0</subscript></entry> | ||
| 2516 | </row> | ||
| 2517 | <row> | ||
| 2518 | <entry></entry> | ||
| 2519 | <entry></entry> | ||
| 2520 | <entry></entry> | ||
| 2521 | &dash-ent-12; | ||
| 2522 | <entry>u<subscript>9</subscript></entry> | ||
| 2523 | <entry>u<subscript>8</subscript></entry> | ||
| 2524 | <entry>u<subscript>7</subscript></entry> | ||
| 2525 | <entry>u<subscript>6</subscript></entry> | ||
| 2526 | <entry>u<subscript>5</subscript></entry> | ||
| 2527 | <entry>u<subscript>4</subscript></entry> | ||
| 2528 | <entry>u<subscript>3</subscript></entry> | ||
| 2529 | <entry>u<subscript>2</subscript></entry> | ||
| 2530 | <entry>u<subscript>1</subscript></entry> | ||
| 2531 | <entry>u<subscript>0</subscript></entry> | ||
| 2532 | <entry>y<subscript>9</subscript></entry> | ||
| 2533 | <entry>y<subscript>8</subscript></entry> | ||
| 2534 | <entry>y<subscript>7</subscript></entry> | ||
| 2535 | <entry>y<subscript>6</subscript></entry> | ||
| 2536 | <entry>y<subscript>5</subscript></entry> | ||
| 2537 | <entry>y<subscript>4</subscript></entry> | ||
| 2538 | <entry>y<subscript>3</subscript></entry> | ||
| 2539 | <entry>y<subscript>2</subscript></entry> | ||
| 2540 | <entry>y<subscript>1</subscript></entry> | ||
| 2541 | <entry>y<subscript>0</subscript></entry> | ||
| 2542 | </row> | ||
| 2311 | <row id="V4L2-MBUS-FMT-YUYV10-1X20"> | 2543 | <row id="V4L2-MBUS-FMT-YUYV10-1X20"> |
| 2312 | <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry> | 2544 | <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry> |
| 2313 | <entry>0x200d</entry> | 2545 | <entry>0x200d</entry> |
| @@ -2486,6 +2718,534 @@ | |||
| 2486 | <entry>v<subscript>1</subscript></entry> | 2718 | <entry>v<subscript>1</subscript></entry> |
| 2487 | <entry>v<subscript>0</subscript></entry> | 2719 | <entry>v<subscript>0</subscript></entry> |
| 2488 | </row> | 2720 | </row> |
| 2721 | <row id="V4L2-MBUS-FMT-UYVY12-2X12"> | ||
| 2722 | <entry>V4L2_MBUS_FMT_UYVY12_2X12</entry> | ||
| 2723 | <entry>0x201c</entry> | ||
| 2724 | <entry></entry> | ||
| 2725 | &dash-ent-20; | ||
| 2726 | <entry>u<subscript>11</subscript></entry> | ||
| 2727 | <entry>u<subscript>10</subscript></entry> | ||
| 2728 | <entry>u<subscript>9</subscript></entry> | ||
| 2729 | <entry>u<subscript>8</subscript></entry> | ||
| 2730 | <entry>u<subscript>7</subscript></entry> | ||
| 2731 | <entry>u<subscript>6</subscript></entry> | ||
| 2732 | <entry>u<subscript>5</subscript></entry> | ||
| 2733 | <entry>u<subscript>4</subscript></entry> | ||
| 2734 | <entry>u<subscript>3</subscript></entry> | ||
| 2735 | <entry>u<subscript>2</subscript></entry> | ||
| 2736 | <entry>u<subscript>1</subscript></entry> | ||
| 2737 | <entry>u<subscript>0</subscript></entry> | ||
| 2738 | </row> | ||
| 2739 | <row> | ||
| 2740 | <entry></entry> | ||
| 2741 | <entry></entry> | ||
| 2742 | <entry></entry> | ||
| 2743 | &dash-ent-20; | ||
| 2744 | <entry>y<subscript>11</subscript></entry> | ||
| 2745 | <entry>y<subscript>10</subscript></entry> | ||
| 2746 | <entry>y<subscript>9</subscript></entry> | ||
| 2747 | <entry>y<subscript>8</subscript></entry> | ||
| 2748 | <entry>y<subscript>7</subscript></entry> | ||
| 2749 | <entry>y<subscript>6</subscript></entry> | ||
| 2750 | <entry>y<subscript>5</subscript></entry> | ||
| 2751 | <entry>y<subscript>4</subscript></entry> | ||
| 2752 | <entry>y<subscript>3</subscript></entry> | ||
| 2753 | <entry>y<subscript>2</subscript></entry> | ||
| 2754 | <entry>y<subscript>1</subscript></entry> | ||
| 2755 | <entry>y<subscript>0</subscript></entry> | ||
| 2756 | </row> | ||
| 2757 | <row> | ||
| 2758 | <entry></entry> | ||
| 2759 | <entry></entry> | ||
| 2760 | <entry></entry> | ||
| 2761 | &dash-ent-20; | ||
| 2762 | <entry>v<subscript>11</subscript></entry> | ||
| 2763 | <entry>v<subscript>10</subscript></entry> | ||
| 2764 | <entry>v<subscript>9</subscript></entry> | ||
| 2765 | <entry>v<subscript>8</subscript></entry> | ||
| 2766 | <entry>v<subscript>7</subscript></entry> | ||
| 2767 | <entry>v<subscript>6</subscript></entry> | ||
| 2768 | <entry>v<subscript>5</subscript></entry> | ||
| 2769 | <entry>v<subscript>4</subscript></entry> | ||
| 2770 | <entry>v<subscript>3</subscript></entry> | ||
| 2771 | <entry>v<subscript>2</subscript></entry> | ||
| 2772 | <entry>v<subscript>1</subscript></entry> | ||
| 2773 | <entry>v<subscript>0</subscript></entry> | ||
| 2774 | </row> | ||
| 2775 | <row> | ||
| 2776 | <entry></entry> | ||
| 2777 | <entry></entry> | ||
| 2778 | <entry></entry> | ||
| 2779 | &dash-ent-20; | ||
| 2780 | <entry>y<subscript>11</subscript></entry> | ||
| 2781 | <entry>y<subscript>10</subscript></entry> | ||
| 2782 | <entry>y<subscript>9</subscript></entry> | ||
| 2783 | <entry>y<subscript>8</subscript></entry> | ||
| 2784 | <entry>y<subscript>7</subscript></entry> | ||
| 2785 | <entry>y<subscript>6</subscript></entry> | ||
| 2786 | <entry>y<subscript>5</subscript></entry> | ||
| 2787 | <entry>y<subscript>4</subscript></entry> | ||
| 2788 | <entry>y<subscript>3</subscript></entry> | ||
| 2789 | <entry>y<subscript>2</subscript></entry> | ||
| 2790 | <entry>y<subscript>1</subscript></entry> | ||
| 2791 | <entry>y<subscript>0</subscript></entry> | ||
| 2792 | </row> | ||
| 2793 | <row id="V4L2-MBUS-FMT-VYUY12-2X12"> | ||
| 2794 | <entry>V4L2_MBUS_FMT_VYUY12_2X12</entry> | ||
| 2795 | <entry>0x201d</entry> | ||
| 2796 | <entry></entry> | ||
| 2797 | &dash-ent-20; | ||
| 2798 | <entry>v<subscript>11</subscript></entry> | ||
| 2799 | <entry>v<subscript>10</subscript></entry> | ||
| 2800 | <entry>v<subscript>9</subscript></entry> | ||
| 2801 | <entry>v<subscript>8</subscript></entry> | ||
| 2802 | <entry>v<subscript>7</subscript></entry> | ||
| 2803 | <entry>v<subscript>6</subscript></entry> | ||
| 2804 | <entry>v<subscript>5</subscript></entry> | ||
| 2805 | <entry>v<subscript>4</subscript></entry> | ||
| 2806 | <entry>v<subscript>3</subscript></entry> | ||
| 2807 | <entry>v<subscript>2</subscript></entry> | ||
| 2808 | <entry>v<subscript>1</subscript></entry> | ||
| 2809 | <entry>v<subscript>0</subscript></entry> | ||
| 2810 | </row> | ||
| 2811 | <row> | ||
| 2812 | <entry></entry> | ||
| 2813 | <entry></entry> | ||
| 2814 | <entry></entry> | ||
| 2815 | &dash-ent-20; | ||
| 2816 | <entry>y<subscript>11</subscript></entry> | ||
| 2817 | <entry>y<subscript>10</subscript></entry> | ||
| 2818 | <entry>y<subscript>9</subscript></entry> | ||
| 2819 | <entry>y<subscript>8</subscript></entry> | ||
| 2820 | <entry>y<subscript>7</subscript></entry> | ||
| 2821 | <entry>y<subscript>6</subscript></entry> | ||
| 2822 | <entry>y<subscript>5</subscript></entry> | ||
| 2823 | <entry>y<subscript>4</subscript></entry> | ||
| 2824 | <entry>y<subscript>3</subscript></entry> | ||
| 2825 | <entry>y<subscript>2</subscript></entry> | ||
| 2826 | <entry>y<subscript>1</subscript></entry> | ||
| 2827 | <entry>y<subscript>0</subscript></entry> | ||
| 2828 | </row> | ||
| 2829 | <row> | ||
| 2830 | <entry></entry> | ||
| 2831 | <entry></entry> | ||
| 2832 | <entry></entry> | ||
| 2833 | &dash-ent-20; | ||
| 2834 | <entry>u<subscript>11</subscript></entry> | ||
| 2835 | <entry>u<subscript>10</subscript></entry> | ||
| 2836 | <entry>u<subscript>9</subscript></entry> | ||
| 2837 | <entry>u<subscript>8</subscript></entry> | ||
| 2838 | <entry>u<subscript>7</subscript></entry> | ||
| 2839 | <entry>u<subscript>6</subscript></entry> | ||
| 2840 | <entry>u<subscript>5</subscript></entry> | ||
| 2841 | <entry>u<subscript>4</subscript></entry> | ||
| 2842 | <entry>u<subscript>3</subscript></entry> | ||
| 2843 | <entry>u<subscript>2</subscript></entry> | ||
| 2844 | <entry>u<subscript>1</subscript></entry> | ||
| 2845 | <entry>u<subscript>0</subscript></entry> | ||
| 2846 | </row> | ||
| 2847 | <row> | ||
| 2848 | <entry></entry> | ||
| 2849 | <entry></entry> | ||
| 2850 | <entry></entry> | ||
| 2851 | &dash-ent-20; | ||
| 2852 | <entry>y<subscript>11</subscript></entry> | ||
| 2853 | <entry>y<subscript>10</subscript></entry> | ||
| 2854 | <entry>y<subscript>9</subscript></entry> | ||
| 2855 | <entry>y<subscript>8</subscript></entry> | ||
| 2856 | <entry>y<subscript>7</subscript></entry> | ||
| 2857 | <entry>y<subscript>6</subscript></entry> | ||
| 2858 | <entry>y<subscript>5</subscript></entry> | ||
| 2859 | <entry>y<subscript>4</subscript></entry> | ||
| 2860 | <entry>y<subscript>3</subscript></entry> | ||
| 2861 | <entry>y<subscript>2</subscript></entry> | ||
| 2862 | <entry>y<subscript>1</subscript></entry> | ||
| 2863 | <entry>y<subscript>0</subscript></entry> | ||
| 2864 | </row> | ||
| 2865 | <row id="V4L2-MBUS-FMT-YUYV12-2X12"> | ||
| 2866 | <entry>V4L2_MBUS_FMT_YUYV12_2X12</entry> | ||
| 2867 | <entry>0x201e</entry> | ||
| 2868 | <entry></entry> | ||
| 2869 | &dash-ent-20; | ||
| 2870 | <entry>y<subscript>11</subscript></entry> | ||
| 2871 | <entry>y<subscript>10</subscript></entry> | ||
| 2872 | <entry>y<subscript>9</subscript></entry> | ||
| 2873 | <entry>y<subscript>8</subscript></entry> | ||
| 2874 | <entry>y<subscript>7</subscript></entry> | ||
| 2875 | <entry>y<subscript>6</subscript></entry> | ||
| 2876 | <entry>y<subscript>5</subscript></entry> | ||
| 2877 | <entry>y<subscript>4</subscript></entry> | ||
| 2878 | <entry>y<subscript>3</subscript></entry> | ||
| 2879 | <entry>y<subscript>2</subscript></entry> | ||
| 2880 | <entry>y<subscript>1</subscript></entry> | ||
| 2881 | <entry>y<subscript>0</subscript></entry> | ||
| 2882 | </row> | ||
| 2883 | <row> | ||
| 2884 | <entry></entry> | ||
| 2885 | <entry></entry> | ||
| 2886 | <entry></entry> | ||
| 2887 | &dash-ent-20; | ||
| 2888 | <entry>u<subscript>11</subscript></entry> | ||
| 2889 | <entry>u<subscript>10</subscript></entry> | ||
| 2890 | <entry>u<subscript>9</subscript></entry> | ||
| 2891 | <entry>u<subscript>8</subscript></entry> | ||
| 2892 | <entry>u<subscript>7</subscript></entry> | ||
| 2893 | <entry>u<subscript>6</subscript></entry> | ||
| 2894 | <entry>u<subscript>5</subscript></entry> | ||
| 2895 | <entry>u<subscript>4</subscript></entry> | ||
| 2896 | <entry>u<subscript>3</subscript></entry> | ||
| 2897 | <entry>u<subscript>2</subscript></entry> | ||
| 2898 | <entry>u<subscript>1</subscript></entry> | ||
| 2899 | <entry>u<subscript>0</subscript></entry> | ||
| 2900 | </row> | ||
| 2901 | <row> | ||
| 2902 | <entry></entry> | ||
| 2903 | <entry></entry> | ||
| 2904 | <entry></entry> | ||
| 2905 | &dash-ent-20; | ||
| 2906 | <entry>y<subscript>11</subscript></entry> | ||
| 2907 | <entry>y<subscript>10</subscript></entry> | ||
| 2908 | <entry>y<subscript>9</subscript></entry> | ||
| 2909 | <entry>y<subscript>8</subscript></entry> | ||
| 2910 | <entry>y<subscript>7</subscript></entry> | ||
| 2911 | <entry>y<subscript>6</subscript></entry> | ||
| 2912 | <entry>y<subscript>5</subscript></entry> | ||
| 2913 | <entry>y<subscript>4</subscript></entry> | ||
| 2914 | <entry>y<subscript>3</subscript></entry> | ||
| 2915 | <entry>y<subscript>2</subscript></entry> | ||
| 2916 | <entry>y<subscript>1</subscript></entry> | ||
| 2917 | <entry>y<subscript>0</subscript></entry> | ||
| 2918 | </row> | ||
| 2919 | <row> | ||
| 2920 | <entry></entry> | ||
| 2921 | <entry></entry> | ||
| 2922 | <entry></entry> | ||
| 2923 | &dash-ent-20; | ||
| 2924 | <entry>v<subscript>11</subscript></entry> | ||
| 2925 | <entry>v<subscript>10</subscript></entry> | ||
| 2926 | <entry>v<subscript>9</subscript></entry> | ||
| 2927 | <entry>v<subscript>8</subscript></entry> | ||
| 2928 | <entry>v<subscript>7</subscript></entry> | ||
| 2929 | <entry>v<subscript>6</subscript></entry> | ||
| 2930 | <entry>v<subscript>5</subscript></entry> | ||
| 2931 | <entry>v<subscript>4</subscript></entry> | ||
| 2932 | <entry>v<subscript>3</subscript></entry> | ||
| 2933 | <entry>v<subscript>2</subscript></entry> | ||
| 2934 | <entry>v<subscript>1</subscript></entry> | ||
| 2935 | <entry>v<subscript>0</subscript></entry> | ||
| 2936 | </row> | ||
| 2937 | <row id="V4L2-MBUS-FMT-YVYU12-2X12"> | ||
| 2938 | <entry>V4L2_MBUS_FMT_YVYU12_2X12</entry> | ||
| 2939 | <entry>0x201f</entry> | ||
| 2940 | <entry></entry> | ||
| 2941 | &dash-ent-20; | ||
| 2942 | <entry>y<subscript>11</subscript></entry> | ||
| 2943 | <entry>y<subscript>10</subscript></entry> | ||
| 2944 | <entry>y<subscript>9</subscript></entry> | ||
| 2945 | <entry>y<subscript>8</subscript></entry> | ||
| 2946 | <entry>y<subscript>7</subscript></entry> | ||
| 2947 | <entry>y<subscript>6</subscript></entry> | ||
| 2948 | <entry>y<subscript>5</subscript></entry> | ||
| 2949 | <entry>y<subscript>4</subscript></entry> | ||
| 2950 | <entry>y<subscript>3</subscript></entry> | ||
| 2951 | <entry>y<subscript>2</subscript></entry> | ||
| 2952 | <entry>y<subscript>1</subscript></entry> | ||
| 2953 | <entry>y<subscript>0</subscript></entry> | ||
| 2954 | </row> | ||
| 2955 | <row> | ||
| 2956 | <entry></entry> | ||
| 2957 | <entry></entry> | ||
| 2958 | <entry></entry> | ||
| 2959 | &dash-ent-20; | ||
| 2960 | <entry>v<subscript>11</subscript></entry> | ||
| 2961 | <entry>v<subscript>10</subscript></entry> | ||
| 2962 | <entry>v<subscript>9</subscript></entry> | ||
| 2963 | <entry>v<subscript>8</subscript></entry> | ||
| 2964 | <entry>v<subscript>7</subscript></entry> | ||
| 2965 | <entry>v<subscript>6</subscript></entry> | ||
| 2966 | <entry>v<subscript>5</subscript></entry> | ||
| 2967 | <entry>v<subscript>4</subscript></entry> | ||
| 2968 | <entry>v<subscript>3</subscript></entry> | ||
| 2969 | <entry>v<subscript>2</subscript></entry> | ||
| 2970 | <entry>v<subscript>1</subscript></entry> | ||
| 2971 | <entry>v<subscript>0</subscript></entry> | ||
| 2972 | </row> | ||
| 2973 | <row> | ||
| 2974 | <entry></entry> | ||
| 2975 | <entry></entry> | ||
| 2976 | <entry></entry> | ||
| 2977 | &dash-ent-20; | ||
| 2978 | <entry>y<subscript>11</subscript></entry> | ||
| 2979 | <entry>y<subscript>10</subscript></entry> | ||
| 2980 | <entry>y<subscript>9</subscript></entry> | ||
| 2981 | <entry>y<subscript>8</subscript></entry> | ||
| 2982 | <entry>y<subscript>7</subscript></entry> | ||
| 2983 | <entry>y<subscript>6</subscript></entry> | ||
| 2984 | <entry>y<subscript>5</subscript></entry> | ||
| 2985 | <entry>y<subscript>4</subscript></entry> | ||
| 2986 | <entry>y<subscript>3</subscript></entry> | ||
| 2987 | <entry>y<subscript>2</subscript></entry> | ||
| 2988 | <entry>y<subscript>1</subscript></entry> | ||
| 2989 | <entry>y<subscript>0</subscript></entry> | ||
| 2990 | </row> | ||
| 2991 | <row> | ||
| 2992 | <entry></entry> | ||
| 2993 | <entry></entry> | ||
| 2994 | <entry></entry> | ||
| 2995 | &dash-ent-20; | ||
| 2996 | <entry>u<subscript>11</subscript></entry> | ||
| 2997 | <entry>u<subscript>10</subscript></entry> | ||
| 2998 | <entry>u<subscript>9</subscript></entry> | ||
| 2999 | <entry>u<subscript>8</subscript></entry> | ||
| 3000 | <entry>u<subscript>7</subscript></entry> | ||
| 3001 | <entry>u<subscript>6</subscript></entry> | ||
| 3002 | <entry>u<subscript>5</subscript></entry> | ||
| 3003 | <entry>u<subscript>4</subscript></entry> | ||
| 3004 | <entry>u<subscript>3</subscript></entry> | ||
| 3005 | <entry>u<subscript>2</subscript></entry> | ||
| 3006 | <entry>u<subscript>1</subscript></entry> | ||
| 3007 | <entry>u<subscript>0</subscript></entry> | ||
| 3008 | </row> | ||
| 3009 | <row id="V4L2-MBUS-FMT-UYVY12-1X24"> | ||
| 3010 | <entry>V4L2_MBUS_FMT_UYVY12_1X24</entry> | ||
| 3011 | <entry>0x2020</entry> | ||
| 3012 | <entry></entry> | ||
| 3013 | &dash-ent-8; | ||
| 3014 | <entry>u<subscript>11</subscript></entry> | ||
| 3015 | <entry>u<subscript>10</subscript></entry> | ||
| 3016 | <entry>u<subscript>9</subscript></entry> | ||
| 3017 | <entry>u<subscript>8</subscript></entry> | ||
| 3018 | <entry>u<subscript>7</subscript></entry> | ||
| 3019 | <entry>u<subscript>6</subscript></entry> | ||
| 3020 | <entry>u<subscript>5</subscript></entry> | ||
| 3021 | <entry>u<subscript>4</subscript></entry> | ||
| 3022 | <entry>u<subscript>3</subscript></entry> | ||
| 3023 | <entry>u<subscript>2</subscript></entry> | ||
| 3024 | <entry>u<subscript>1</subscript></entry> | ||
| 3025 | <entry>u<subscript>0</subscript></entry> | ||
| 3026 | <entry>y<subscript>11</subscript></entry> | ||
| 3027 | <entry>y<subscript>10</subscript></entry> | ||
| 3028 | <entry>y<subscript>9</subscript></entry> | ||
| 3029 | <entry>y<subscript>8</subscript></entry> | ||
| 3030 | <entry>y<subscript>7</subscript></entry> | ||
| 3031 | <entry>y<subscript>6</subscript></entry> | ||
| 3032 | <entry>y<subscript>5</subscript></entry> | ||
| 3033 | <entry>y<subscript>4</subscript></entry> | ||
| 3034 | <entry>y<subscript>3</subscript></entry> | ||
| 3035 | <entry>y<subscript>2</subscript></entry> | ||
| 3036 | <entry>y<subscript>1</subscript></entry> | ||
| 3037 | <entry>y<subscript>0</subscript></entry> | ||
| 3038 | </row> | ||
| 3039 | <row> | ||
| 3040 | <entry></entry> | ||
| 3041 | <entry></entry> | ||
| 3042 | <entry></entry> | ||
| 3043 | &dash-ent-8; | ||
| 3044 | <entry>v<subscript>11</subscript></entry> | ||
| 3045 | <entry>v<subscript>10</subscript></entry> | ||
| 3046 | <entry>v<subscript>9</subscript></entry> | ||
| 3047 | <entry>v<subscript>8</subscript></entry> | ||
| 3048 | <entry>v<subscript>7</subscript></entry> | ||
| 3049 | <entry>v<subscript>6</subscript></entry> | ||
| 3050 | <entry>v<subscript>5</subscript></entry> | ||
| 3051 | <entry>v<subscript>4</subscript></entry> | ||
| 3052 | <entry>v<subscript>3</subscript></entry> | ||
| 3053 | <entry>v<subscript>2</subscript></entry> | ||
| 3054 | <entry>v<subscript>1</subscript></entry> | ||
| 3055 | <entry>v<subscript>0</subscript></entry> | ||
| 3056 | <entry>y<subscript>11</subscript></entry> | ||
| 3057 | <entry>y<subscript>10</subscript></entry> | ||
| 3058 | <entry>y<subscript>9</subscript></entry> | ||
| 3059 | <entry>y<subscript>8</subscript></entry> | ||
| 3060 | <entry>y<subscript>7</subscript></entry> | ||
| 3061 | <entry>y<subscript>6</subscript></entry> | ||
| 3062 | <entry>y<subscript>5</subscript></entry> | ||
| 3063 | <entry>y<subscript>4</subscript></entry> | ||
| 3064 | <entry>y<subscript>3</subscript></entry> | ||
| 3065 | <entry>y<subscript>2</subscript></entry> | ||
| 3066 | <entry>y<subscript>1</subscript></entry> | ||
| 3067 | <entry>y<subscript>0</subscript></entry> | ||
| 3068 | </row> | ||
| 3069 | <row id="V4L2-MBUS-FMT-VYUY12-1X24"> | ||
| 3070 | <entry>V4L2_MBUS_FMT_VYUY12_1X24</entry> | ||
| 3071 | <entry>0x2021</entry> | ||
| 3072 | <entry></entry> | ||
| 3073 | &dash-ent-8; | ||
| 3074 | <entry>v<subscript>11</subscript></entry> | ||
| 3075 | <entry>v<subscript>10</subscript></entry> | ||
| 3076 | <entry>v<subscript>9</subscript></entry> | ||
| 3077 | <entry>v<subscript>8</subscript></entry> | ||
| 3078 | <entry>v<subscript>7</subscript></entry> | ||
| 3079 | <entry>v<subscript>6</subscript></entry> | ||
| 3080 | <entry>v<subscript>5</subscript></entry> | ||
| 3081 | <entry>v<subscript>4</subscript></entry> | ||
| 3082 | <entry>v<subscript>3</subscript></entry> | ||
| 3083 | <entry>v<subscript>2</subscript></entry> | ||
| 3084 | <entry>v<subscript>1</subscript></entry> | ||
| 3085 | <entry>v<subscript>0</subscript></entry> | ||
| 3086 | <entry>y<subscript>11</subscript></entry> | ||
| 3087 | <entry>y<subscript>10</subscript></entry> | ||
| 3088 | <entry>y<subscript>9</subscript></entry> | ||
| 3089 | <entry>y<subscript>8</subscript></entry> | ||
| 3090 | <entry>y<subscript>7</subscript></entry> | ||
| 3091 | <entry>y<subscript>6</subscript></entry> | ||
| 3092 | <entry>y<subscript>5</subscript></entry> | ||
| 3093 | <entry>y<subscript>4</subscript></entry> | ||
| 3094 | <entry>y<subscript>3</subscript></entry> | ||
| 3095 | <entry>y<subscript>2</subscript></entry> | ||
| 3096 | <entry>y<subscript>1</subscript></entry> | ||
| 3097 | <entry>y<subscript>0</subscript></entry> | ||
| 3098 | </row> | ||
| 3099 | <row> | ||
| 3100 | <entry></entry> | ||
| 3101 | <entry></entry> | ||
| 3102 | <entry></entry> | ||
| 3103 | &dash-ent-8; | ||
| 3104 | <entry>u<subscript>11</subscript></entry> | ||
| 3105 | <entry>u<subscript>10</subscript></entry> | ||
| 3106 | <entry>u<subscript>9</subscript></entry> | ||
| 3107 | <entry>u<subscript>8</subscript></entry> | ||
| 3108 | <entry>u<subscript>7</subscript></entry> | ||
| 3109 | <entry>u<subscript>6</subscript></entry> | ||
| 3110 | <entry>u<subscript>5</subscript></entry> | ||
| 3111 | <entry>u<subscript>4</subscript></entry> | ||
| 3112 | <entry>u<subscript>3</subscript></entry> | ||
| 3113 | <entry>u<subscript>2</subscript></entry> | ||
| 3114 | <entry>u<subscript>1</subscript></entry> | ||
| 3115 | <entry>u<subscript>0</subscript></entry> | ||
| 3116 | <entry>y<subscript>11</subscript></entry> | ||
| 3117 | <entry>y<subscript>10</subscript></entry> | ||
| 3118 | <entry>y<subscript>9</subscript></entry> | ||
| 3119 | <entry>y<subscript>8</subscript></entry> | ||
| 3120 | <entry>y<subscript>7</subscript></entry> | ||
| 3121 | <entry>y<subscript>6</subscript></entry> | ||
| 3122 | <entry>y<subscript>5</subscript></entry> | ||
| 3123 | <entry>y<subscript>4</subscript></entry> | ||
| 3124 | <entry>y<subscript>3</subscript></entry> | ||
| 3125 | <entry>y<subscript>2</subscript></entry> | ||
| 3126 | <entry>y<subscript>1</subscript></entry> | ||
| 3127 | <entry>y<subscript>0</subscript></entry> | ||
| 3128 | </row> | ||
| 3129 | <row id="V4L2-MBUS-FMT-YUYV12-1X24"> | ||
| 3130 | <entry>V4L2_MBUS_FMT_YUYV12_1X24</entry> | ||
| 3131 | <entry>0x2022</entry> | ||
| 3132 | <entry></entry> | ||
| 3133 | &dash-ent-8; | ||
| 3134 | <entry>y<subscript>11</subscript></entry> | ||
| 3135 | <entry>y<subscript>10</subscript></entry> | ||
| 3136 | <entry>y<subscript>9</subscript></entry> | ||
| 3137 | <entry>y<subscript>8</subscript></entry> | ||
| 3138 | <entry>y<subscript>7</subscript></entry> | ||
| 3139 | <entry>y<subscript>6</subscript></entry> | ||
| 3140 | <entry>y<subscript>5</subscript></entry> | ||
| 3141 | <entry>y<subscript>4</subscript></entry> | ||
| 3142 | <entry>y<subscript>3</subscript></entry> | ||
| 3143 | <entry>y<subscript>2</subscript></entry> | ||
| 3144 | <entry>y<subscript>1</subscript></entry> | ||
| 3145 | <entry>y<subscript>0</subscript></entry> | ||
| 3146 | <entry>u<subscript>11</subscript></entry> | ||
| 3147 | <entry>u<subscript>10</subscript></entry> | ||
| 3148 | <entry>u<subscript>9</subscript></entry> | ||
| 3149 | <entry>u<subscript>8</subscript></entry> | ||
| 3150 | <entry>u<subscript>7</subscript></entry> | ||
| 3151 | <entry>u<subscript>6</subscript></entry> | ||
| 3152 | <entry>u<subscript>5</subscript></entry> | ||
| 3153 | <entry>u<subscript>4</subscript></entry> | ||
| 3154 | <entry>u<subscript>3</subscript></entry> | ||
| 3155 | <entry>u<subscript>2</subscript></entry> | ||
| 3156 | <entry>u<subscript>1</subscript></entry> | ||
| 3157 | <entry>u<subscript>0</subscript></entry> | ||
| 3158 | </row> | ||
| 3159 | <row> | ||
| 3160 | <entry></entry> | ||
| 3161 | <entry></entry> | ||
| 3162 | <entry></entry> | ||
| 3163 | &dash-ent-8; | ||
| 3164 | <entry>y<subscript>11</subscript></entry> | ||
| 3165 | <entry>y<subscript>10</subscript></entry> | ||
| 3166 | <entry>y<subscript>9</subscript></entry> | ||
| 3167 | <entry>y<subscript>8</subscript></entry> | ||
| 3168 | <entry>y<subscript>7</subscript></entry> | ||
| 3169 | <entry>y<subscript>6</subscript></entry> | ||
| 3170 | <entry>y<subscript>5</subscript></entry> | ||
| 3171 | <entry>y<subscript>4</subscript></entry> | ||
| 3172 | <entry>y<subscript>3</subscript></entry> | ||
| 3173 | <entry>y<subscript>2</subscript></entry> | ||
| 3174 | <entry>y<subscript>1</subscript></entry> | ||
| 3175 | <entry>y<subscript>0</subscript></entry> | ||
| 3176 | <entry>v<subscript>11</subscript></entry> | ||
| 3177 | <entry>v<subscript>10</subscript></entry> | ||
| 3178 | <entry>v<subscript>9</subscript></entry> | ||
| 3179 | <entry>v<subscript>8</subscript></entry> | ||
| 3180 | <entry>v<subscript>7</subscript></entry> | ||
| 3181 | <entry>v<subscript>6</subscript></entry> | ||
| 3182 | <entry>v<subscript>5</subscript></entry> | ||
| 3183 | <entry>v<subscript>4</subscript></entry> | ||
| 3184 | <entry>v<subscript>3</subscript></entry> | ||
| 3185 | <entry>v<subscript>2</subscript></entry> | ||
| 3186 | <entry>v<subscript>1</subscript></entry> | ||
| 3187 | <entry>v<subscript>0</subscript></entry> | ||
| 3188 | </row> | ||
| 3189 | <row id="V4L2-MBUS-FMT-YVYU12-1X24"> | ||
| 3190 | <entry>V4L2_MBUS_FMT_YVYU12_1X24</entry> | ||
| 3191 | <entry>0x2023</entry> | ||
| 3192 | <entry></entry> | ||
| 3193 | &dash-ent-8; | ||
| 3194 | <entry>y<subscript>11</subscript></entry> | ||
| 3195 | <entry>y<subscript>10</subscript></entry> | ||
| 3196 | <entry>y<subscript>9</subscript></entry> | ||
| 3197 | <entry>y<subscript>8</subscript></entry> | ||
| 3198 | <entry>y<subscript>7</subscript></entry> | ||
| 3199 | <entry>y<subscript>6</subscript></entry> | ||
| 3200 | <entry>y<subscript>5</subscript></entry> | ||
| 3201 | <entry>y<subscript>4</subscript></entry> | ||
| 3202 | <entry>y<subscript>3</subscript></entry> | ||
| 3203 | <entry>y<subscript>2</subscript></entry> | ||
| 3204 | <entry>y<subscript>1</subscript></entry> | ||
| 3205 | <entry>y<subscript>0</subscript></entry> | ||
| 3206 | <entry>v<subscript>11</subscript></entry> | ||
| 3207 | <entry>v<subscript>10</subscript></entry> | ||
| 3208 | <entry>v<subscript>9</subscript></entry> | ||
| 3209 | <entry>v<subscript>8</subscript></entry> | ||
| 3210 | <entry>v<subscript>7</subscript></entry> | ||
| 3211 | <entry>v<subscript>6</subscript></entry> | ||
| 3212 | <entry>v<subscript>5</subscript></entry> | ||
| 3213 | <entry>v<subscript>4</subscript></entry> | ||
| 3214 | <entry>v<subscript>3</subscript></entry> | ||
| 3215 | <entry>v<subscript>2</subscript></entry> | ||
| 3216 | <entry>v<subscript>1</subscript></entry> | ||
| 3217 | <entry>v<subscript>0</subscript></entry> | ||
| 3218 | </row> | ||
| 3219 | <row> | ||
| 3220 | <entry></entry> | ||
| 3221 | <entry></entry> | ||
| 3222 | <entry></entry> | ||
| 3223 | &dash-ent-8; | ||
| 3224 | <entry>y<subscript>11</subscript></entry> | ||
| 3225 | <entry>y<subscript>10</subscript></entry> | ||
| 3226 | <entry>y<subscript>9</subscript></entry> | ||
| 3227 | <entry>y<subscript>8</subscript></entry> | ||
| 3228 | <entry>y<subscript>7</subscript></entry> | ||
| 3229 | <entry>y<subscript>6</subscript></entry> | ||
| 3230 | <entry>y<subscript>5</subscript></entry> | ||
| 3231 | <entry>y<subscript>4</subscript></entry> | ||
| 3232 | <entry>y<subscript>3</subscript></entry> | ||
| 3233 | <entry>y<subscript>2</subscript></entry> | ||
| 3234 | <entry>y<subscript>1</subscript></entry> | ||
| 3235 | <entry>y<subscript>0</subscript></entry> | ||
| 3236 | <entry>u<subscript>11</subscript></entry> | ||
| 3237 | <entry>u<subscript>10</subscript></entry> | ||
| 3238 | <entry>u<subscript>9</subscript></entry> | ||
| 3239 | <entry>u<subscript>8</subscript></entry> | ||
| 3240 | <entry>u<subscript>7</subscript></entry> | ||
| 3241 | <entry>u<subscript>6</subscript></entry> | ||
| 3242 | <entry>u<subscript>5</subscript></entry> | ||
| 3243 | <entry>u<subscript>4</subscript></entry> | ||
| 3244 | <entry>u<subscript>3</subscript></entry> | ||
| 3245 | <entry>u<subscript>2</subscript></entry> | ||
| 3246 | <entry>u<subscript>1</subscript></entry> | ||
| 3247 | <entry>u<subscript>0</subscript></entry> | ||
| 3248 | </row> | ||
| 2489 | </tbody> | 3249 | </tbody> |
| 2490 | </tgroup> | 3250 | </tgroup> |
| 2491 | </table> | 3251 | </table> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml index 89891adb928a..820f86e8744b 100644 --- a/Documentation/DocBook/media/v4l/vidioc-dqevent.xml +++ b/Documentation/DocBook/media/v4l/vidioc-dqevent.xml | |||
| @@ -242,6 +242,22 @@ | |||
| 242 | </tgroup> | 242 | </tgroup> |
| 243 | </table> | 243 | </table> |
| 244 | 244 | ||
| 245 | <table frame="none" pgwide="1" id="v4l2-event-src-change"> | ||
| 246 | <title>struct <structname>v4l2_event_src_change</structname></title> | ||
| 247 | <tgroup cols="3"> | ||
| 248 | &cs-str; | ||
| 249 | <tbody valign="top"> | ||
| 250 | <row> | ||
| 251 | <entry>__u32</entry> | ||
| 252 | <entry><structfield>changes</structfield></entry> | ||
| 253 | <entry> | ||
| 254 | A bitmask that tells what has changed. See <xref linkend="src-changes-flags" />. | ||
| 255 | </entry> | ||
| 256 | </row> | ||
| 257 | </tbody> | ||
| 258 | </tgroup> | ||
| 259 | </table> | ||
| 260 | |||
| 245 | <table pgwide="1" frame="none" id="changes-flags"> | 261 | <table pgwide="1" frame="none" id="changes-flags"> |
| 246 | <title>Changes</title> | 262 | <title>Changes</title> |
| 247 | <tgroup cols="3"> | 263 | <tgroup cols="3"> |
| @@ -270,6 +286,23 @@ | |||
| 270 | </tbody> | 286 | </tbody> |
| 271 | </tgroup> | 287 | </tgroup> |
| 272 | </table> | 288 | </table> |
| 289 | |||
| 290 | <table pgwide="1" frame="none" id="src-changes-flags"> | ||
| 291 | <title>Source Changes</title> | ||
| 292 | <tgroup cols="3"> | ||
| 293 | &cs-def; | ||
| 294 | <tbody valign="top"> | ||
| 295 | <row> | ||
| 296 | <entry><constant>V4L2_EVENT_SRC_CH_RESOLUTION</constant></entry> | ||
| 297 | <entry>0x0001</entry> | ||
| 298 | <entry>This event gets triggered when a resolution change is | ||
| 299 | detected at an input. This can come from an input connector or | ||
| 300 | from a video decoder. | ||
| 301 | </entry> | ||
| 302 | </row> | ||
| 303 | </tbody> | ||
| 304 | </tgroup> | ||
| 305 | </table> | ||
| 273 | </refsect1> | 306 | </refsect1> |
| 274 | <refsect1> | 307 | <refsect1> |
| 275 | &return-value; | 308 | &return-value; |
diff --git a/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml b/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml index cd7720d404ea..28a8c1e1c705 100644 --- a/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml +++ b/Documentation/DocBook/media/v4l/vidioc-dv-timings-cap.xml | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | <refentry id="vidioc-dv-timings-cap"> | 1 | <refentry id="vidioc-dv-timings-cap"> |
| 2 | <refmeta> | 2 | <refmeta> |
| 3 | <refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP</refentrytitle> | 3 | <refentrytitle>ioctl VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP</refentrytitle> |
| 4 | &manvol; | 4 | &manvol; |
| 5 | </refmeta> | 5 | </refmeta> |
| 6 | 6 | ||
| 7 | <refnamediv> | 7 | <refnamediv> |
| 8 | <refname>VIDIOC_DV_TIMINGS_CAP</refname> | 8 | <refname>VIDIOC_DV_TIMINGS_CAP</refname> |
| 9 | <refname>VIDIOC_SUBDEV_DV_TIMINGS_CAP</refname> | ||
| 9 | <refpurpose>The capabilities of the Digital Video receiver/transmitter</refpurpose> | 10 | <refpurpose>The capabilities of the Digital Video receiver/transmitter</refpurpose> |
| 10 | </refnamediv> | 11 | </refnamediv> |
| 11 | 12 | ||
| @@ -33,7 +34,7 @@ | |||
| 33 | <varlistentry> | 34 | <varlistentry> |
| 34 | <term><parameter>request</parameter></term> | 35 | <term><parameter>request</parameter></term> |
| 35 | <listitem> | 36 | <listitem> |
| 36 | <para>VIDIOC_DV_TIMINGS_CAP</para> | 37 | <para>VIDIOC_DV_TIMINGS_CAP, VIDIOC_SUBDEV_DV_TIMINGS_CAP</para> |
| 37 | </listitem> | 38 | </listitem> |
| 38 | </varlistentry> | 39 | </varlistentry> |
| 39 | <varlistentry> | 40 | <varlistentry> |
| @@ -54,10 +55,19 @@ | |||
| 54 | interface and may change in the future.</para> | 55 | interface and may change in the future.</para> |
| 55 | </note> | 56 | </note> |
| 56 | 57 | ||
| 57 | <para>To query the capabilities of the DV receiver/transmitter applications can call | 58 | <para>To query the capabilities of the DV receiver/transmitter applications |
| 58 | this ioctl and the driver will fill in the structure. Note that drivers may return | 59 | can call the <constant>VIDIOC_DV_TIMINGS_CAP</constant> ioctl on a video node |
| 60 | and the driver will fill in the structure. Note that drivers may return | ||
| 59 | different values after switching the video input or output.</para> | 61 | different values after switching the video input or output.</para> |
| 60 | 62 | ||
| 63 | <para>When implemented by the driver DV capabilities of subdevices can be | ||
| 64 | queried by calling the <constant>VIDIOC_SUBDEV_DV_TIMINGS_CAP</constant> ioctl | ||
| 65 | directly on a subdevice node. The capabilities are specific to inputs (for DV | ||
| 66 | receivers) or outputs (for DV transmitters), applications must specify the | ||
| 67 | desired pad number in the &v4l2-dv-timings-cap; <structfield>pad</structfield> | ||
| 68 | field. Attempts to query capabilities on a pad that doesn't support them will | ||
| 69 | return an &EINVAL;.</para> | ||
| 70 | |||
| 61 | <table pgwide="1" frame="none" id="v4l2-bt-timings-cap"> | 71 | <table pgwide="1" frame="none" id="v4l2-bt-timings-cap"> |
| 62 | <title>struct <structname>v4l2_bt_timings_cap</structname></title> | 72 | <title>struct <structname>v4l2_bt_timings_cap</structname></title> |
| 63 | <tgroup cols="3"> | 73 | <tgroup cols="3"> |
| @@ -127,7 +137,14 @@ different values after switching the video input or output.</para> | |||
| 127 | </row> | 137 | </row> |
| 128 | <row> | 138 | <row> |
| 129 | <entry>__u32</entry> | 139 | <entry>__u32</entry> |
| 130 | <entry><structfield>reserved</structfield>[3]</entry> | 140 | <entry><structfield>pad</structfield></entry> |
| 141 | <entry>Pad number as reported by the media controller API. This field | ||
| 142 | is only used when operating on a subdevice node. When operating on a | ||
| 143 | video node applications must set this field to zero.</entry> | ||
| 144 | </row> | ||
| 145 | <row> | ||
| 146 | <entry>__u32</entry> | ||
| 147 | <entry><structfield>reserved</structfield>[2]</entry> | ||
| 131 | <entry>Reserved for future extensions. Drivers must set the array to zero.</entry> | 148 | <entry>Reserved for future extensions. Drivers must set the array to zero.</entry> |
| 132 | </row> | 149 | </row> |
| 133 | <row> | 150 | <row> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml index b3e17c1dfaf5..b9fdfeacdbcb 100644 --- a/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml +++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-timings.xml | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | <refentry id="vidioc-enum-dv-timings"> | 1 | <refentry id="vidioc-enum-dv-timings"> |
| 2 | <refmeta> | 2 | <refmeta> |
| 3 | <refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS</refentrytitle> | 3 | <refentrytitle>ioctl VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS</refentrytitle> |
| 4 | &manvol; | 4 | &manvol; |
| 5 | </refmeta> | 5 | </refmeta> |
| 6 | 6 | ||
| 7 | <refnamediv> | 7 | <refnamediv> |
| 8 | <refname>VIDIOC_ENUM_DV_TIMINGS</refname> | 8 | <refname>VIDIOC_ENUM_DV_TIMINGS</refname> |
| 9 | <refname>VIDIOC_SUBDEV_ENUM_DV_TIMINGS</refname> | ||
| 9 | <refpurpose>Enumerate supported Digital Video timings</refpurpose> | 10 | <refpurpose>Enumerate supported Digital Video timings</refpurpose> |
| 10 | </refnamediv> | 11 | </refnamediv> |
| 11 | 12 | ||
| @@ -33,7 +34,7 @@ | |||
| 33 | <varlistentry> | 34 | <varlistentry> |
| 34 | <term><parameter>request</parameter></term> | 35 | <term><parameter>request</parameter></term> |
| 35 | <listitem> | 36 | <listitem> |
| 36 | <para>VIDIOC_ENUM_DV_TIMINGS</para> | 37 | <para>VIDIOC_ENUM_DV_TIMINGS, VIDIOC_SUBDEV_ENUM_DV_TIMINGS</para> |
| 37 | </listitem> | 38 | </listitem> |
| 38 | </varlistentry> | 39 | </varlistentry> |
| 39 | <varlistentry> | 40 | <varlistentry> |
| @@ -61,14 +62,21 @@ standards or even custom timings that are not in this list.</para> | |||
| 61 | 62 | ||
| 62 | <para>To query the available timings, applications initialize the | 63 | <para>To query the available timings, applications initialize the |
| 63 | <structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings; | 64 | <structfield>index</structfield> field and zero the reserved array of &v4l2-enum-dv-timings; |
| 64 | and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl with a pointer to this | 65 | and call the <constant>VIDIOC_ENUM_DV_TIMINGS</constant> ioctl on a video node with a |
| 65 | structure. Drivers fill the rest of the structure or return an | 66 | pointer to this structure. Drivers fill the rest of the structure or return an |
| 66 | &EINVAL; when the index is out of bounds. To enumerate all supported DV timings, | 67 | &EINVAL; when the index is out of bounds. To enumerate all supported DV timings, |
| 67 | applications shall begin at index zero, incrementing by one until the | 68 | applications shall begin at index zero, incrementing by one until the |
| 68 | driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a | 69 | driver returns <errorcode>EINVAL</errorcode>. Note that drivers may enumerate a |
| 69 | different set of DV timings after switching the video input or | 70 | different set of DV timings after switching the video input or |
| 70 | output.</para> | 71 | output.</para> |
| 71 | 72 | ||
| 73 | <para>When implemented by the driver DV timings of subdevices can be queried | ||
| 74 | by calling the <constant>VIDIOC_SUBDEV_ENUM_DV_TIMINGS</constant> ioctl directly | ||
| 75 | on a subdevice node. The DV timings are specific to inputs (for DV receivers) or | ||
| 76 | outputs (for DV transmitters), applications must specify the desired pad number | ||
| 77 | in the &v4l2-enum-dv-timings; <structfield>pad</structfield> field. Attempts to | ||
| 78 | enumerate timings on a pad that doesn't support them will return an &EINVAL;.</para> | ||
| 79 | |||
| 72 | <table pgwide="1" frame="none" id="v4l2-enum-dv-timings"> | 80 | <table pgwide="1" frame="none" id="v4l2-enum-dv-timings"> |
| 73 | <title>struct <structname>v4l2_enum_dv_timings</structname></title> | 81 | <title>struct <structname>v4l2_enum_dv_timings</structname></title> |
| 74 | <tgroup cols="3"> | 82 | <tgroup cols="3"> |
| @@ -82,8 +90,16 @@ application.</entry> | |||
| 82 | </row> | 90 | </row> |
| 83 | <row> | 91 | <row> |
| 84 | <entry>__u32</entry> | 92 | <entry>__u32</entry> |
| 85 | <entry><structfield>reserved</structfield>[3]</entry> | 93 | <entry><structfield>pad</structfield></entry> |
| 86 | <entry>Reserved for future extensions. Drivers must set the array to zero.</entry> | 94 | <entry>Pad number as reported by the media controller API. This field |
| 95 | is only used when operating on a subdevice node. When operating on a | ||
| 96 | video node applications must set this field to zero.</entry> | ||
| 97 | </row> | ||
| 98 | <row> | ||
| 99 | <entry>__u32</entry> | ||
| 100 | <entry><structfield>reserved</structfield>[2]</entry> | ||
| 101 | <entry>Reserved for future extensions. Drivers and applications must | ||
| 102 | set the array to zero.</entry> | ||
| 87 | </row> | 103 | </row> |
| 88 | <row> | 104 | <row> |
| 89 | <entry>&v4l2-dv-timings;</entry> | 105 | <entry>&v4l2-dv-timings;</entry> |
| @@ -103,7 +119,7 @@ application.</entry> | |||
| 103 | <term><errorcode>EINVAL</errorcode></term> | 119 | <term><errorcode>EINVAL</errorcode></term> |
| 104 | <listitem> | 120 | <listitem> |
| 105 | <para>The &v4l2-enum-dv-timings; <structfield>index</structfield> | 121 | <para>The &v4l2-enum-dv-timings; <structfield>index</structfield> |
| 106 | is out of bounds.</para> | 122 | is out of bounds or the <structfield>pad</structfield> number is invalid.</para> |
| 107 | </listitem> | 123 | </listitem> |
| 108 | </varlistentry> | 124 | </varlistentry> |
| 109 | <varlistentry> | 125 | <varlistentry> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml b/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml index 5c70b616d818..17efa870d4d2 100644 --- a/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml +++ b/Documentation/DocBook/media/v4l/vidioc-subscribe-event.xml | |||
| @@ -155,6 +155,26 @@ | |||
| 155 | </entry> | 155 | </entry> |
| 156 | </row> | 156 | </row> |
| 157 | <row> | 157 | <row> |
| 158 | <entry><constant>V4L2_EVENT_SOURCE_CHANGE</constant></entry> | ||
| 159 | <entry>5</entry> | ||
| 160 | <entry> | ||
| 161 | <para>This event is triggered when a source parameter change is | ||
| 162 | detected during runtime by the video device. It can be a | ||
| 163 | runtime resolution change triggered by a video decoder or the | ||
| 164 | format change happening on an input connector. | ||
| 165 | This event requires that the <structfield>id</structfield> | ||
| 166 | matches the input index (when used with a video device node) | ||
| 167 | or the pad index (when used with a subdevice node) from which | ||
| 168 | you want to receive events.</para> | ||
| 169 | |||
| 170 | <para>This event has a &v4l2-event-src-change; associated | ||
| 171 | with it. The <structfield>changes</structfield> bitfield denotes | ||
| 172 | what has changed for the subscribed pad. If multiple events | ||
| 173 | occurred before application could dequeue them, then the changes | ||
| 174 | will have the ORed value of all the events generated.</para> | ||
| 175 | </entry> | ||
| 176 | </row> | ||
| 177 | <row> | ||
| 158 | <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry> | 178 | <entry><constant>V4L2_EVENT_PRIVATE_START</constant></entry> |
| 159 | <entry>0x08000000</entry> | 179 | <entry>0x08000000</entry> |
| 160 | <entry>Base event number for driver-private events.</entry> | 180 | <entry>Base event number for driver-private events.</entry> |
diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt index f4181680831b..3e3c5f349570 100644 --- a/Documentation/devicetree/bindings/media/s5p-mfc.txt +++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt | |||
| @@ -10,7 +10,8 @@ Required properties: | |||
| 10 | - compatible : value should be either one among the following | 10 | - compatible : value should be either one among the following |
| 11 | (a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs | 11 | (a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs |
| 12 | (b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs | 12 | (b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs |
| 13 | (b) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC | 13 | (c) "samsung,mfc-v7" for MFC v7 present in Exynos5420 SoC |
| 14 | (d) "samsung,mfc-v8" for MFC v8 present in Exynos5800 SoC | ||
| 14 | 15 | ||
| 15 | - reg : Physical base address of the IP registers and length of memory | 16 | - reg : Physical base address of the IP registers and length of memory |
| 16 | mapped region. | 17 | mapped region. |
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv index 2f6e93597ce0..b092c0a14df2 100644 --- a/Documentation/video4linux/CARDLIST.bttv +++ b/Documentation/video4linux/CARDLIST.bttv | |||
| @@ -164,3 +164,4 @@ | |||
| 164 | 163 -> Bt848 Capture 14MHz | 164 | 163 -> Bt848 Capture 14MHz |
| 165 | 164 -> CyberVision CV06 (SV) | 165 | 164 -> CyberVision CV06 (SV) |
| 166 | 165 -> Kworld V-Stream Xpert TV PVR878 | 166 | 165 -> Kworld V-Stream Xpert TV PVR878 |
| 167 | 166 -> PCI-8604PW | ||
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index e085b1243b45..5a3ddcd340d3 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx | |||
| @@ -92,3 +92,4 @@ | |||
| 92 | 91 -> SpeedLink Vicious And Devine Laplace webcam (em2765) [1ae7:9003,1ae7:9004] | 92 | 91 -> SpeedLink Vicious And Devine Laplace webcam (em2765) [1ae7:9003,1ae7:9004] |
| 93 | 92 -> PCTV DVB-S2 Stick (461e) (em28178) | 93 | 92 -> PCTV DVB-S2 Stick (461e) (em28178) |
| 94 | 93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c] | 94 | 93 -> KWorld USB ATSC TV Stick UB435-Q V3 (em2874) [1b80:e34c] |
| 95 | 94 -> PCTV tripleStick (292e) (em28178) | ||
diff --git a/Documentation/video4linux/fimc.txt b/Documentation/video4linux/fimc.txt index 7d6e160724bd..e0c6b8bc4743 100644 --- a/Documentation/video4linux/fimc.txt +++ b/Documentation/video4linux/fimc.txt | |||
| @@ -140,39 +140,9 @@ You can either grep through the kernel log to find relevant information, i.e. | |||
| 140 | or retrieve the information from /dev/media? with help of the media-ctl tool: | 140 | or retrieve the information from /dev/media? with help of the media-ctl tool: |
| 141 | # media-ctl -p | 141 | # media-ctl -p |
| 142 | 142 | ||
| 143 | 6. Platform support | ||
| 144 | =================== | ||
| 145 | |||
| 146 | The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select | ||
| 147 | following options: | ||
| 148 | |||
| 149 | CONFIG_S5P_DEV_FIMC0 mandatory | ||
| 150 | CONFIG_S5P_DEV_FIMC1 \ | ||
| 151 | CONFIG_S5P_DEV_FIMC2 | optional | ||
| 152 | CONFIG_S5P_DEV_FIMC3 | | ||
| 153 | CONFIG_S5P_SETUP_FIMC / | ||
| 154 | CONFIG_S5P_DEV_CSIS0 \ optional for MIPI-CSI interface | ||
| 155 | CONFIG_S5P_DEV_CSIS1 / | ||
| 156 | |||
| 157 | Except that, relevant s5p_device_fimc? should be registered in the machine code | ||
| 158 | in addition to a "s5p-fimc-md" platform device to which the media device driver | ||
| 159 | is bound. The "s5p-fimc-md" device instance is required even if only mem-to-mem | ||
| 160 | operation is used. | ||
| 161 | |||
| 162 | The description of sensor(s) attached to FIMC/MIPI-CSIS camera inputs should be | ||
| 163 | passed as the "s5p-fimc-md" device platform_data. The platform data structure | ||
| 164 | is defined in file include/media/s5p_fimc.h. | ||
| 165 | |||
| 166 | 7. Build | 143 | 7. Build |
| 167 | ======== | 144 | ======== |
| 168 | 145 | ||
| 169 | This driver depends on following config options: | ||
| 170 | PLAT_S5P, | ||
| 171 | PM_RUNTIME, | ||
| 172 | I2C, | ||
| 173 | REGULATOR, | ||
| 174 | VIDEO_V4L2_SUBDEV_API, | ||
| 175 | |||
| 176 | If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m) | 146 | If the driver is built as a loadable kernel module (CONFIG_VIDEO_SAMSUNG_S5P_FIMC=m) |
| 177 | two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and | 147 | two modules are created (in addition to the core v4l2 modules): s5p-fimc.ko and |
| 178 | optional s5p-csis.ko (MIPI-CSI receiver subdev). | 148 | optional s5p-csis.ko (MIPI-CSI receiver subdev). |
diff --git a/Documentation/video4linux/v4l2-pci-skeleton.c b/Documentation/video4linux/v4l2-pci-skeleton.c index 3a1c0d2dafce..46904fe49609 100644 --- a/Documentation/video4linux/v4l2-pci-skeleton.c +++ b/Documentation/video4linux/v4l2-pci-skeleton.c | |||
| @@ -77,7 +77,8 @@ struct skeleton { | |||
| 77 | 77 | ||
| 78 | spinlock_t qlock; | 78 | spinlock_t qlock; |
| 79 | struct list_head buf_list; | 79 | struct list_head buf_list; |
| 80 | unsigned int sequence; | 80 | unsigned field; |
| 81 | unsigned sequence; | ||
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | struct skel_buffer { | 84 | struct skel_buffer { |
| @@ -124,7 +125,7 @@ static const struct v4l2_dv_timings_cap skel_timings_cap = { | |||
| 124 | * Interrupt handler: typically interrupts happen after a new frame has been | 125 | * Interrupt handler: typically interrupts happen after a new frame has been |
| 125 | * captured. It is the job of the handler to remove the new frame from the | 126 | * captured. It is the job of the handler to remove the new frame from the |
| 126 | * internal list and give it back to the vb2 framework, updating the sequence | 127 | * internal list and give it back to the vb2 framework, updating the sequence |
| 127 | * counter and timestamp at the same time. | 128 | * counter, field and timestamp at the same time. |
| 128 | */ | 129 | */ |
| 129 | static irqreturn_t skeleton_irq(int irq, void *dev_id) | 130 | static irqreturn_t skeleton_irq(int irq, void *dev_id) |
| 130 | { | 131 | { |
| @@ -139,8 +140,15 @@ static irqreturn_t skeleton_irq(int irq, void *dev_id) | |||
| 139 | spin_lock(&skel->qlock); | 140 | spin_lock(&skel->qlock); |
| 140 | list_del(&new_buf->list); | 141 | list_del(&new_buf->list); |
| 141 | spin_unlock(&skel->qlock); | 142 | spin_unlock(&skel->qlock); |
| 142 | new_buf->vb.v4l2_buf.sequence = skel->sequence++; | ||
| 143 | v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp); | 143 | v4l2_get_timestamp(&new_buf->vb.v4l2_buf.timestamp); |
| 144 | new_buf->vb.v4l2_buf.sequence = skel->sequence++; | ||
| 145 | new_buf->vb.v4l2_buf.field = skel->field; | ||
| 146 | if (skel->format.field == V4L2_FIELD_ALTERNATE) { | ||
| 147 | if (skel->field == V4L2_FIELD_BOTTOM) | ||
| 148 | skel->field = V4L2_FIELD_TOP; | ||
| 149 | else if (skel->field == V4L2_FIELD_TOP) | ||
| 150 | skel->field = V4L2_FIELD_BOTTOM; | ||
| 151 | } | ||
| 144 | vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE); | 152 | vb2_buffer_done(&new_buf->vb, VB2_BUF_STATE_DONE); |
| 145 | } | 153 | } |
| 146 | #endif | 154 | #endif |
| @@ -160,6 +168,17 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
| 160 | { | 168 | { |
| 161 | struct skeleton *skel = vb2_get_drv_priv(vq); | 169 | struct skeleton *skel = vb2_get_drv_priv(vq); |
| 162 | 170 | ||
| 171 | skel->field = skel->format.field; | ||
| 172 | if (skel->field == V4L2_FIELD_ALTERNATE) { | ||
| 173 | /* | ||
| 174 | * You cannot use read() with FIELD_ALTERNATE since the field | ||
| 175 | * information (TOP/BOTTOM) cannot be passed back to the user. | ||
| 176 | */ | ||
| 177 | if (vb2_fileio_is_active(vq)) | ||
| 178 | return -EINVAL; | ||
| 179 | skel->field = V4L2_FIELD_TOP; | ||
| 180 | } | ||
| 181 | |||
| 163 | if (vq->num_buffers + *nbuffers < 3) | 182 | if (vq->num_buffers + *nbuffers < 3) |
| 164 | *nbuffers = 3 - vq->num_buffers; | 183 | *nbuffers = 3 - vq->num_buffers; |
| 165 | 184 | ||
| @@ -173,10 +192,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
| 173 | 192 | ||
| 174 | /* | 193 | /* |
| 175 | * Prepare the buffer for queueing to the DMA engine: check and set the | 194 | * Prepare the buffer for queueing to the DMA engine: check and set the |
| 176 | * payload size and fill in the field. Note: if the format's field is | 195 | * payload size. |
| 177 | * V4L2_FIELD_ALTERNATE, then vb->v4l2_buf.field should be set in the | ||
| 178 | * interrupt handler since that's usually where you know if the TOP or | ||
| 179 | * BOTTOM field has been captured. | ||
| 180 | */ | 196 | */ |
| 181 | static int buffer_prepare(struct vb2_buffer *vb) | 197 | static int buffer_prepare(struct vb2_buffer *vb) |
| 182 | { | 198 | { |
| @@ -190,7 +206,6 @@ static int buffer_prepare(struct vb2_buffer *vb) | |||
| 190 | } | 206 | } |
| 191 | 207 | ||
| 192 | vb2_set_plane_payload(vb, 0, size); | 208 | vb2_set_plane_payload(vb, 0, size); |
| 193 | vb->v4l2_buf.field = skel->format.field; | ||
| 194 | return 0; | 209 | return 0; |
| 195 | } | 210 | } |
| 196 | 211 | ||
| @@ -254,7 +269,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 254 | * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued | 269 | * Stop the DMA engine. Any remaining buffers in the DMA queue are dequeued |
| 255 | * and passed on to the vb2 framework marked as STATE_ERROR. | 270 | * and passed on to the vb2 framework marked as STATE_ERROR. |
| 256 | */ | 271 | */ |
| 257 | static int stop_streaming(struct vb2_queue *vq) | 272 | static void stop_streaming(struct vb2_queue *vq) |
| 258 | { | 273 | { |
| 259 | struct skeleton *skel = vb2_get_drv_priv(vq); | 274 | struct skeleton *skel = vb2_get_drv_priv(vq); |
| 260 | 275 | ||
| @@ -262,7 +277,6 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 262 | 277 | ||
| 263 | /* Release all active buffers */ | 278 | /* Release all active buffers */ |
| 264 | return_all_buffers(skel, VB2_BUF_STATE_ERROR); | 279 | return_all_buffers(skel, VB2_BUF_STATE_ERROR); |
| 265 | return 0; | ||
| 266 | } | 280 | } |
| 267 | 281 | ||
| 268 | /* | 282 | /* |
| @@ -319,10 +333,12 @@ static void skeleton_fill_pix_format(struct skeleton *skel, | |||
| 319 | /* HDMI input */ | 333 | /* HDMI input */ |
| 320 | pix->width = skel->timings.bt.width; | 334 | pix->width = skel->timings.bt.width; |
| 321 | pix->height = skel->timings.bt.height; | 335 | pix->height = skel->timings.bt.height; |
| 322 | if (skel->timings.bt.interlaced) | 336 | if (skel->timings.bt.interlaced) { |
| 323 | pix->field = V4L2_FIELD_INTERLACED; | 337 | pix->field = V4L2_FIELD_ALTERNATE; |
| 324 | else | 338 | pix->height /= 2; |
| 339 | } else { | ||
| 325 | pix->field = V4L2_FIELD_NONE; | 340 | pix->field = V4L2_FIELD_NONE; |
| 341 | } | ||
| 326 | pix->colorspace = V4L2_COLORSPACE_REC709; | 342 | pix->colorspace = V4L2_COLORSPACE_REC709; |
| 327 | } | 343 | } |
| 328 | 344 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index abf98f09ff59..e433e45814af 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -7668,7 +7668,6 @@ L: linux-media@vger.kernel.org | |||
| 7668 | Q: https://patchwork.linuxtv.org/project/linux-media/list/ | 7668 | Q: https://patchwork.linuxtv.org/project/linux-media/list/ |
| 7669 | S: Supported | 7669 | S: Supported |
| 7670 | F: drivers/media/platform/exynos4-is/ | 7670 | F: drivers/media/platform/exynos4-is/ |
| 7671 | F: include/media/s5p_fimc.h | ||
| 7672 | 7671 | ||
| 7673 | SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER | 7672 | SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER |
| 7674 | M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com> | 7673 | M: Sylwester Nawrocki <sylvester.nawrocki@gmail.com> |
| @@ -7971,6 +7970,26 @@ M: Robin Holt <robinmholt@gmail.com> | |||
| 7971 | S: Maintained | 7970 | S: Maintained |
| 7972 | F: drivers/misc/sgi-xp/ | 7971 | F: drivers/misc/sgi-xp/ |
| 7973 | 7972 | ||
| 7973 | SI2157 MEDIA DRIVER | ||
| 7974 | M: Antti Palosaari <crope@iki.fi> | ||
| 7975 | L: linux-media@vger.kernel.org | ||
| 7976 | W: http://linuxtv.org/ | ||
| 7977 | W: http://palosaari.fi/linux/ | ||
| 7978 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ | ||
| 7979 | T: git git://linuxtv.org/anttip/media_tree.git | ||
| 7980 | S: Maintained | ||
| 7981 | F: drivers/media/tuners/si2157* | ||
| 7982 | |||
| 7983 | SI2168 MEDIA DRIVER | ||
| 7984 | M: Antti Palosaari <crope@iki.fi> | ||
| 7985 | L: linux-media@vger.kernel.org | ||
| 7986 | W: http://linuxtv.org/ | ||
| 7987 | W: http://palosaari.fi/linux/ | ||
| 7988 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ | ||
| 7989 | T: git git://linuxtv.org/anttip/media_tree.git | ||
| 7990 | S: Maintained | ||
| 7991 | F: drivers/media/dvb-frontends/si2168* | ||
| 7992 | |||
| 7974 | SI470X FM RADIO RECEIVER I2C DRIVER | 7993 | SI470X FM RADIO RECEIVER I2C DRIVER |
| 7975 | M: Hans Verkuil <hverkuil@xs4all.nl> | 7994 | M: Hans Verkuil <hverkuil@xs4all.nl> |
| 7976 | L: linux-media@vger.kernel.org | 7995 | L: linux-media@vger.kernel.org |
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index b41a38a75844..6c719eccb94e 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c | |||
| @@ -49,11 +49,6 @@ | |||
| 49 | #include <plat/clock.h> | 49 | #include <plat/clock.h> |
| 50 | #include <plat/samsung-time.h> | 50 | #include <plat/samsung-time.h> |
| 51 | #include <plat/mfc.h> | 51 | #include <plat/mfc.h> |
| 52 | #include <plat/camport.h> | ||
| 53 | |||
| 54 | #include <media/v4l2-mediabus.h> | ||
| 55 | #include <media/s5p_fimc.h> | ||
| 56 | #include <media/noon010pc30.h> | ||
| 57 | 52 | ||
| 58 | #include "common.h" | 53 | #include "common.h" |
| 59 | 54 | ||
| @@ -285,14 +280,6 @@ static void __init goni_tsp_init(void) | |||
| 285 | /* USB OTG */ | 280 | /* USB OTG */ |
| 286 | static struct s3c_hsotg_plat goni_hsotg_pdata; | 281 | static struct s3c_hsotg_plat goni_hsotg_pdata; |
| 287 | 282 | ||
| 288 | static void goni_camera_init(void) | ||
| 289 | { | ||
| 290 | s5pv210_fimc_setup_gpio(S5P_CAMPORT_A); | ||
| 291 | |||
| 292 | /* Set max driver strength on CAM_A_CLKOUT pin. */ | ||
| 293 | s5p_gpio_set_drvstr(S5PV210_GPE1(3), S5P_GPIO_DRVSTR_LV4); | ||
| 294 | } | ||
| 295 | |||
| 296 | /* MAX8998 regulators */ | 283 | /* MAX8998 regulators */ |
| 297 | #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) | 284 | #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) |
| 298 | 285 | ||
| @@ -825,34 +812,6 @@ static void goni_setup_sdhci(void) | |||
| 825 | s3c_sdhci2_set_platdata(&goni_hsmmc2_data); | 812 | s3c_sdhci2_set_platdata(&goni_hsmmc2_data); |
| 826 | }; | 813 | }; |
| 827 | 814 | ||
| 828 | static struct noon010pc30_platform_data noon010pc30_pldata = { | ||
| 829 | .clk_rate = 16000000UL, | ||
| 830 | .gpio_nreset = S5PV210_GPB(2), /* CAM_CIF_NRST */ | ||
| 831 | .gpio_nstby = S5PV210_GPB(0), /* CAM_CIF_NSTBY */ | ||
| 832 | }; | ||
| 833 | |||
| 834 | static struct i2c_board_info noon010pc30_board_info = { | ||
| 835 | I2C_BOARD_INFO("NOON010PC30", 0x60 >> 1), | ||
| 836 | .platform_data = &noon010pc30_pldata, | ||
| 837 | }; | ||
| 838 | |||
| 839 | static struct fimc_source_info goni_camera_sensors[] = { | ||
| 840 | { | ||
| 841 | .mux_id = 0, | ||
| 842 | .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | | ||
| 843 | V4L2_MBUS_VSYNC_ACTIVE_LOW, | ||
| 844 | .fimc_bus_type = FIMC_BUS_TYPE_ITU_601, | ||
| 845 | .board_info = &noon010pc30_board_info, | ||
| 846 | .i2c_bus_num = 0, | ||
| 847 | .clk_frequency = 16000000UL, | ||
| 848 | }, | ||
| 849 | }; | ||
| 850 | |||
| 851 | static struct s5p_platform_fimc goni_fimc_md_platdata __initdata = { | ||
| 852 | .source_info = goni_camera_sensors, | ||
| 853 | .num_clients = ARRAY_SIZE(goni_camera_sensors), | ||
| 854 | }; | ||
| 855 | |||
| 856 | /* Audio device */ | 815 | /* Audio device */ |
| 857 | static struct platform_device goni_device_audio = { | 816 | static struct platform_device goni_device_audio = { |
| 858 | .name = "smdk-audio", | 817 | .name = "smdk-audio", |
| @@ -874,10 +833,6 @@ static struct platform_device *goni_devices[] __initdata = { | |||
| 874 | &s5p_device_mixer, | 833 | &s5p_device_mixer, |
| 875 | &s5p_device_sdo, | 834 | &s5p_device_sdo, |
| 876 | &s3c_device_i2c0, | 835 | &s3c_device_i2c0, |
| 877 | &s5p_device_fimc0, | ||
| 878 | &s5p_device_fimc1, | ||
| 879 | &s5p_device_fimc2, | ||
| 880 | &s5p_device_fimc_md, | ||
| 881 | &s3c_device_hsmmc0, | 836 | &s3c_device_hsmmc0, |
| 882 | &s3c_device_hsmmc1, | 837 | &s3c_device_hsmmc1, |
| 883 | &s3c_device_hsmmc2, | 838 | &s3c_device_hsmmc2, |
| @@ -946,14 +901,8 @@ static void __init goni_machine_init(void) | |||
| 946 | /* FB */ | 901 | /* FB */ |
| 947 | s3c_fb_set_platdata(&goni_lcd_pdata); | 902 | s3c_fb_set_platdata(&goni_lcd_pdata); |
| 948 | 903 | ||
| 949 | /* FIMC */ | ||
| 950 | s3c_set_platdata(&goni_fimc_md_platdata, sizeof(goni_fimc_md_platdata), | ||
| 951 | &s5p_device_fimc_md); | ||
| 952 | |||
| 953 | s3c_hsotg_set_platdata(&goni_hsotg_pdata); | 904 | s3c_hsotg_set_platdata(&goni_hsotg_pdata); |
| 954 | 905 | ||
| 955 | goni_camera_init(); | ||
| 956 | |||
| 957 | /* SPI */ | 906 | /* SPI */ |
| 958 | spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); | 907 | spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); |
| 959 | 908 | ||
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h index 1bdc0e7e8b79..11d2bea23b02 100644 --- a/drivers/media/dvb-core/dvb-usb-ids.h +++ b/drivers/media/dvb-core/dvb-usb-ids.h | |||
| @@ -356,11 +356,13 @@ | |||
| 356 | #define USB_PID_ELGATO_EYETV_DTT_2 0x003f | 356 | #define USB_PID_ELGATO_EYETV_DTT_2 0x003f |
| 357 | #define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 | 357 | #define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 |
| 358 | #define USB_PID_ELGATO_EYETV_SAT 0x002a | 358 | #define USB_PID_ELGATO_EYETV_SAT 0x002a |
| 359 | #define USB_PID_ELGATO_EYETV_SAT_V2 0x0025 | ||
| 359 | #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 | 360 | #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 |
| 360 | #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 | 361 | #define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 |
| 361 | #define USB_PID_FRIIO_WHITE 0x0001 | 362 | #define USB_PID_FRIIO_WHITE 0x0001 |
| 362 | #define USB_PID_TVWAY_PLUS 0x0002 | 363 | #define USB_PID_TVWAY_PLUS 0x0002 |
| 363 | #define USB_PID_SVEON_STV20 0xe39d | 364 | #define USB_PID_SVEON_STV20 0xe39d |
| 365 | #define USB_PID_SVEON_STV20_RTL2832U 0xd39d | ||
| 364 | #define USB_PID_SVEON_STV22 0xe401 | 366 | #define USB_PID_SVEON_STV22 0xe401 |
| 365 | #define USB_PID_SVEON_STV22_IT9137 0xe411 | 367 | #define USB_PID_SVEON_STV22_IT9137 0xe411 |
| 366 | #define USB_PID_AZUREWAVE_AZ6027 0x3275 | 368 | #define USB_PID_AZUREWAVE_AZ6027 0x3275 |
| @@ -375,4 +377,5 @@ | |||
| 375 | #define USB_PID_CTVDIGDUAL_V2 0xe410 | 377 | #define USB_PID_CTVDIGDUAL_V2 0xe410 |
| 376 | #define USB_PID_PCTV_2002E 0x025c | 378 | #define USB_PID_PCTV_2002E 0x025c |
| 377 | #define USB_PID_PCTV_2002E_SE 0x025d | 379 | #define USB_PID_PCTV_2002E_SE 0x025d |
| 380 | #define USB_PID_SVEON_STV27 0xd3af | ||
| 378 | #endif | 381 | #endif |
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 025fc5496bfc..1469d44acb22 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig | |||
| @@ -446,6 +446,13 @@ config DVB_RTL2832 | |||
| 446 | help | 446 | help |
| 447 | Say Y when you want to support this frontend. | 447 | Say Y when you want to support this frontend. |
| 448 | 448 | ||
| 449 | config DVB_SI2168 | ||
| 450 | tristate "Silicon Labs Si2168" | ||
| 451 | depends on DVB_CORE && I2C && I2C_MUX | ||
| 452 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
| 453 | help | ||
| 454 | Say Y when you want to support this frontend. | ||
| 455 | |||
| 449 | comment "DVB-C (cable) frontends" | 456 | comment "DVB-C (cable) frontends" |
| 450 | depends on DVB_CORE | 457 | depends on DVB_CORE |
| 451 | 458 | ||
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 282aba2fe8db..dda0bee36f29 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile | |||
| @@ -78,6 +78,7 @@ obj-$(CONFIG_DVB_AF9013) += af9013.o | |||
| 78 | obj-$(CONFIG_DVB_CX24116) += cx24116.o | 78 | obj-$(CONFIG_DVB_CX24116) += cx24116.o |
| 79 | obj-$(CONFIG_DVB_CX24117) += cx24117.o | 79 | obj-$(CONFIG_DVB_CX24117) += cx24117.o |
| 80 | obj-$(CONFIG_DVB_SI21XX) += si21xx.o | 80 | obj-$(CONFIG_DVB_SI21XX) += si21xx.o |
| 81 | obj-$(CONFIG_DVB_SI2168) += si2168.o | ||
| 81 | obj-$(CONFIG_DVB_STV0288) += stv0288.o | 82 | obj-$(CONFIG_DVB_STV0288) += stv0288.o |
| 82 | obj-$(CONFIG_DVB_STB6000) += stb6000.o | 83 | obj-$(CONFIG_DVB_STB6000) += stb6000.o |
| 83 | obj-$(CONFIG_DVB_S921) += s921.o | 84 | obj-$(CONFIG_DVB_S921) += s921.o |
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c new file mode 100644 index 000000000000..8637d2ed7623 --- /dev/null +++ b/drivers/media/dvb-frontends/si2168.c | |||
| @@ -0,0 +1,760 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs Si2168 DVB-T/T2/C demodulator driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "si2168_priv.h" | ||
| 18 | |||
| 19 | static const struct dvb_frontend_ops si2168_ops; | ||
| 20 | |||
| 21 | /* execute firmware command */ | ||
| 22 | static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd) | ||
| 23 | { | ||
| 24 | int ret; | ||
| 25 | unsigned long timeout; | ||
| 26 | |||
| 27 | mutex_lock(&s->i2c_mutex); | ||
| 28 | |||
| 29 | if (cmd->wlen) { | ||
| 30 | /* write cmd and args for firmware */ | ||
| 31 | ret = i2c_master_send(s->client, cmd->args, cmd->wlen); | ||
| 32 | if (ret < 0) { | ||
| 33 | goto err_mutex_unlock; | ||
| 34 | } else if (ret != cmd->wlen) { | ||
| 35 | ret = -EREMOTEIO; | ||
| 36 | goto err_mutex_unlock; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | if (cmd->rlen) { | ||
| 41 | /* wait cmd execution terminate */ | ||
| 42 | #define TIMEOUT 50 | ||
| 43 | timeout = jiffies + msecs_to_jiffies(TIMEOUT); | ||
| 44 | while (!time_after(jiffies, timeout)) { | ||
| 45 | ret = i2c_master_recv(s->client, cmd->args, cmd->rlen); | ||
| 46 | if (ret < 0) { | ||
| 47 | goto err_mutex_unlock; | ||
| 48 | } else if (ret != cmd->rlen) { | ||
| 49 | ret = -EREMOTEIO; | ||
| 50 | goto err_mutex_unlock; | ||
| 51 | } | ||
| 52 | |||
| 53 | /* firmware ready? */ | ||
| 54 | if ((cmd->args[0] >> 7) & 0x01) | ||
| 55 | break; | ||
| 56 | } | ||
| 57 | |||
| 58 | dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", | ||
| 59 | __func__, | ||
| 60 | jiffies_to_msecs(jiffies) - | ||
| 61 | (jiffies_to_msecs(timeout) - TIMEOUT)); | ||
| 62 | |||
| 63 | if (!(cmd->args[0] >> 7) & 0x01) { | ||
| 64 | ret = -ETIMEDOUT; | ||
| 65 | goto err_mutex_unlock; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | ret = 0; | ||
| 70 | |||
| 71 | err_mutex_unlock: | ||
| 72 | mutex_unlock(&s->i2c_mutex); | ||
| 73 | if (ret) | ||
| 74 | goto err; | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | err: | ||
| 78 | dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 79 | return ret; | ||
| 80 | } | ||
| 81 | |||
| 82 | static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
| 83 | { | ||
| 84 | struct si2168 *s = fe->demodulator_priv; | ||
| 85 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
| 86 | int ret; | ||
| 87 | struct si2168_cmd cmd; | ||
| 88 | |||
| 89 | *status = 0; | ||
| 90 | |||
| 91 | if (!s->active) { | ||
| 92 | ret = -EAGAIN; | ||
| 93 | goto err; | ||
| 94 | } | ||
| 95 | |||
| 96 | switch (c->delivery_system) { | ||
| 97 | case SYS_DVBT: | ||
| 98 | cmd.args[0] = 0xa0; | ||
| 99 | cmd.args[1] = 0x01; | ||
| 100 | cmd.wlen = 2; | ||
| 101 | cmd.rlen = 13; | ||
| 102 | break; | ||
| 103 | case SYS_DVBC_ANNEX_A: | ||
| 104 | cmd.args[0] = 0x90; | ||
| 105 | cmd.args[1] = 0x01; | ||
| 106 | cmd.wlen = 2; | ||
| 107 | cmd.rlen = 9; | ||
| 108 | break; | ||
| 109 | case SYS_DVBT2: | ||
| 110 | cmd.args[0] = 0x50; | ||
| 111 | cmd.args[1] = 0x01; | ||
| 112 | cmd.wlen = 2; | ||
| 113 | cmd.rlen = 14; | ||
| 114 | break; | ||
| 115 | default: | ||
| 116 | ret = -EINVAL; | ||
| 117 | goto err; | ||
| 118 | } | ||
| 119 | |||
| 120 | ret = si2168_cmd_execute(s, &cmd); | ||
| 121 | if (ret) | ||
| 122 | goto err; | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Possible values seen, in order from strong signal to weak: | ||
| 126 | * 16 0001 0110 full lock | ||
| 127 | * 1e 0001 1110 partial lock | ||
| 128 | * 1a 0001 1010 partial lock | ||
| 129 | * 18 0001 1000 no lock | ||
| 130 | * | ||
| 131 | * [b3:b1] lock bits | ||
| 132 | * [b4] statistics ready? Set in a few secs after lock is gained. | ||
| 133 | */ | ||
| 134 | |||
| 135 | switch ((cmd.args[2] >> 1) & 0x03) { | ||
| 136 | case 0x01: | ||
| 137 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
| 138 | break; | ||
| 139 | case 0x03: | ||
| 140 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | | ||
| 141 | FE_HAS_SYNC | FE_HAS_LOCK; | ||
| 142 | break; | ||
| 143 | } | ||
| 144 | |||
| 145 | s->fe_status = *status; | ||
| 146 | |||
| 147 | dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n", | ||
| 148 | __func__, *status, cmd.rlen, cmd.args); | ||
| 149 | |||
| 150 | return 0; | ||
| 151 | err: | ||
| 152 | dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 153 | return ret; | ||
| 154 | } | ||
| 155 | |||
| 156 | static int si2168_set_frontend(struct dvb_frontend *fe) | ||
| 157 | { | ||
| 158 | struct si2168 *s = fe->demodulator_priv; | ||
| 159 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
| 160 | int ret; | ||
| 161 | struct si2168_cmd cmd; | ||
| 162 | u8 bandwidth, delivery_system; | ||
| 163 | |||
| 164 | dev_dbg(&s->client->dev, | ||
| 165 | "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n", | ||
| 166 | __func__, c->delivery_system, c->modulation, | ||
| 167 | c->frequency, c->bandwidth_hz, c->symbol_rate, | ||
| 168 | c->inversion); | ||
| 169 | |||
| 170 | if (!s->active) { | ||
| 171 | ret = -EAGAIN; | ||
| 172 | goto err; | ||
| 173 | } | ||
| 174 | |||
| 175 | switch (c->delivery_system) { | ||
| 176 | case SYS_DVBT: | ||
| 177 | delivery_system = 0x20; | ||
| 178 | break; | ||
| 179 | case SYS_DVBC_ANNEX_A: | ||
| 180 | delivery_system = 0x30; | ||
| 181 | break; | ||
| 182 | case SYS_DVBT2: | ||
| 183 | delivery_system = 0x70; | ||
| 184 | break; | ||
| 185 | default: | ||
| 186 | ret = -EINVAL; | ||
| 187 | goto err; | ||
| 188 | } | ||
| 189 | |||
| 190 | if (c->bandwidth_hz <= 5000000) | ||
| 191 | bandwidth = 0x05; | ||
| 192 | else if (c->bandwidth_hz <= 6000000) | ||
| 193 | bandwidth = 0x06; | ||
| 194 | else if (c->bandwidth_hz <= 7000000) | ||
| 195 | bandwidth = 0x07; | ||
| 196 | else if (c->bandwidth_hz <= 8000000) | ||
| 197 | bandwidth = 0x08; | ||
| 198 | else if (c->bandwidth_hz <= 9000000) | ||
| 199 | bandwidth = 0x09; | ||
| 200 | else if (c->bandwidth_hz <= 10000000) | ||
| 201 | bandwidth = 0x0a; | ||
| 202 | else | ||
| 203 | bandwidth = 0x0f; | ||
| 204 | |||
| 205 | /* program tuner */ | ||
| 206 | if (fe->ops.tuner_ops.set_params) { | ||
| 207 | ret = fe->ops.tuner_ops.set_params(fe); | ||
| 208 | if (ret) | ||
| 209 | goto err; | ||
| 210 | } | ||
| 211 | |||
| 212 | memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5); | ||
| 213 | cmd.wlen = 5; | ||
| 214 | cmd.rlen = 5; | ||
| 215 | ret = si2168_cmd_execute(s, &cmd); | ||
| 216 | if (ret) | ||
| 217 | goto err; | ||
| 218 | |||
| 219 | /* that has no big effect */ | ||
| 220 | if (c->delivery_system == SYS_DVBT) | ||
| 221 | memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6); | ||
| 222 | else if (c->delivery_system == SYS_DVBC_ANNEX_A) | ||
| 223 | memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6); | ||
| 224 | else if (c->delivery_system == SYS_DVBT2) | ||
| 225 | memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6); | ||
| 226 | cmd.wlen = 6; | ||
| 227 | cmd.rlen = 3; | ||
| 228 | ret = si2168_cmd_execute(s, &cmd); | ||
| 229 | if (ret) | ||
| 230 | goto err; | ||
| 231 | |||
| 232 | memcpy(cmd.args, "\x51\x03", 2); | ||
| 233 | cmd.wlen = 2; | ||
| 234 | cmd.rlen = 12; | ||
| 235 | ret = si2168_cmd_execute(s, &cmd); | ||
| 236 | if (ret) | ||
| 237 | goto err; | ||
| 238 | |||
| 239 | memcpy(cmd.args, "\x12\x08\x04", 3); | ||
| 240 | cmd.wlen = 3; | ||
| 241 | cmd.rlen = 3; | ||
| 242 | ret = si2168_cmd_execute(s, &cmd); | ||
| 243 | if (ret) | ||
| 244 | goto err; | ||
| 245 | |||
| 246 | memcpy(cmd.args, "\x14\x00\x01\x04\x00\x00", 6); | ||
| 247 | cmd.wlen = 6; | ||
| 248 | cmd.rlen = 1; | ||
| 249 | ret = si2168_cmd_execute(s, &cmd); | ||
| 250 | if (ret) | ||
| 251 | goto err; | ||
| 252 | |||
| 253 | memcpy(cmd.args, "\x14\x00\x03\x10\x17\x00", 6); | ||
| 254 | cmd.wlen = 6; | ||
| 255 | cmd.rlen = 1; | ||
| 256 | ret = si2168_cmd_execute(s, &cmd); | ||
| 257 | if (ret) | ||
| 258 | goto err; | ||
| 259 | |||
| 260 | memcpy(cmd.args, "\x14\x00\x02\x10\x15\x00", 6); | ||
| 261 | cmd.wlen = 6; | ||
| 262 | cmd.rlen = 1; | ||
| 263 | ret = si2168_cmd_execute(s, &cmd); | ||
| 264 | if (ret) | ||
| 265 | goto err; | ||
| 266 | |||
| 267 | memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6); | ||
| 268 | cmd.wlen = 6; | ||
| 269 | cmd.rlen = 1; | ||
| 270 | ret = si2168_cmd_execute(s, &cmd); | ||
| 271 | if (ret) | ||
| 272 | goto err; | ||
| 273 | |||
| 274 | memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6); | ||
| 275 | cmd.wlen = 6; | ||
| 276 | cmd.rlen = 1; | ||
| 277 | ret = si2168_cmd_execute(s, &cmd); | ||
| 278 | if (ret) | ||
| 279 | goto err; | ||
| 280 | |||
| 281 | memcpy(cmd.args, "\x14\x00\x0b\x10\x88\x13", 6); | ||
| 282 | cmd.wlen = 6; | ||
| 283 | cmd.rlen = 1; | ||
| 284 | ret = si2168_cmd_execute(s, &cmd); | ||
| 285 | if (ret) | ||
| 286 | goto err; | ||
| 287 | |||
| 288 | memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6); | ||
| 289 | cmd.wlen = 6; | ||
| 290 | cmd.rlen = 1; | ||
| 291 | ret = si2168_cmd_execute(s, &cmd); | ||
| 292 | if (ret) | ||
| 293 | goto err; | ||
| 294 | |||
| 295 | memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6); | ||
| 296 | cmd.args[4] = delivery_system | bandwidth; | ||
| 297 | cmd.wlen = 6; | ||
| 298 | cmd.rlen = 1; | ||
| 299 | ret = si2168_cmd_execute(s, &cmd); | ||
| 300 | if (ret) | ||
| 301 | goto err; | ||
| 302 | |||
| 303 | memcpy(cmd.args, "\x14\x00\x04\x10\x15\x00", 6); | ||
| 304 | cmd.wlen = 6; | ||
| 305 | cmd.rlen = 1; | ||
| 306 | ret = si2168_cmd_execute(s, &cmd); | ||
| 307 | if (ret) | ||
| 308 | goto err; | ||
| 309 | |||
| 310 | memcpy(cmd.args, "\x14\x00\x05\x10\xa1\x00", 6); | ||
| 311 | cmd.wlen = 6; | ||
| 312 | cmd.rlen = 1; | ||
| 313 | ret = si2168_cmd_execute(s, &cmd); | ||
| 314 | if (ret) | ||
| 315 | goto err; | ||
| 316 | |||
| 317 | memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6); | ||
| 318 | cmd.wlen = 6; | ||
| 319 | cmd.rlen = 1; | ||
| 320 | ret = si2168_cmd_execute(s, &cmd); | ||
| 321 | if (ret) | ||
| 322 | goto err; | ||
| 323 | |||
| 324 | memcpy(cmd.args, "\x14\x00\x0d\x10\xd0\x02", 6); | ||
| 325 | cmd.wlen = 6; | ||
| 326 | cmd.rlen = 1; | ||
| 327 | ret = si2168_cmd_execute(s, &cmd); | ||
| 328 | if (ret) | ||
| 329 | goto err; | ||
| 330 | |||
| 331 | memcpy(cmd.args, "\x14\x00\x01\x10\x00\x00", 6); | ||
| 332 | cmd.wlen = 6; | ||
| 333 | cmd.rlen = 1; | ||
| 334 | ret = si2168_cmd_execute(s, &cmd); | ||
| 335 | if (ret) | ||
| 336 | goto err; | ||
| 337 | |||
| 338 | memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6); | ||
| 339 | cmd.wlen = 6; | ||
| 340 | cmd.rlen = 1; | ||
| 341 | ret = si2168_cmd_execute(s, &cmd); | ||
| 342 | if (ret) | ||
| 343 | goto err; | ||
| 344 | |||
| 345 | memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6); | ||
| 346 | cmd.wlen = 6; | ||
| 347 | cmd.rlen = 1; | ||
| 348 | ret = si2168_cmd_execute(s, &cmd); | ||
| 349 | if (ret) | ||
| 350 | goto err; | ||
| 351 | |||
| 352 | memcpy(cmd.args, "\x14\x00\x04\x03\x00\x00", 6); | ||
| 353 | cmd.wlen = 6; | ||
| 354 | cmd.rlen = 1; | ||
| 355 | ret = si2168_cmd_execute(s, &cmd); | ||
| 356 | if (ret) | ||
| 357 | goto err; | ||
| 358 | |||
| 359 | memcpy(cmd.args, "\x14\x00\x03\x03\x00\x00", 6); | ||
| 360 | cmd.wlen = 6; | ||
| 361 | cmd.rlen = 1; | ||
| 362 | ret = si2168_cmd_execute(s, &cmd); | ||
| 363 | if (ret) | ||
| 364 | goto err; | ||
| 365 | |||
| 366 | memcpy(cmd.args, "\x14\x00\x08\x03\x00\x00", 6); | ||
| 367 | cmd.wlen = 6; | ||
| 368 | cmd.rlen = 1; | ||
| 369 | ret = si2168_cmd_execute(s, &cmd); | ||
| 370 | if (ret) | ||
| 371 | goto err; | ||
| 372 | |||
| 373 | memcpy(cmd.args, "\x14\x00\x07\x03\x01\x02", 6); | ||
| 374 | cmd.wlen = 6; | ||
| 375 | cmd.rlen = 1; | ||
| 376 | ret = si2168_cmd_execute(s, &cmd); | ||
| 377 | if (ret) | ||
| 378 | goto err; | ||
| 379 | |||
| 380 | memcpy(cmd.args, "\x14\x00\x06\x03\x00\x00", 6); | ||
| 381 | cmd.wlen = 6; | ||
| 382 | cmd.rlen = 1; | ||
| 383 | ret = si2168_cmd_execute(s, &cmd); | ||
| 384 | if (ret) | ||
| 385 | goto err; | ||
| 386 | |||
| 387 | memcpy(cmd.args, "\x14\x00\x05\x03\x00\x00", 6); | ||
| 388 | cmd.wlen = 6; | ||
| 389 | cmd.rlen = 1; | ||
| 390 | ret = si2168_cmd_execute(s, &cmd); | ||
| 391 | if (ret) | ||
| 392 | goto err; | ||
| 393 | |||
| 394 | memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x40", 6); | ||
| 395 | cmd.wlen = 6; | ||
| 396 | cmd.rlen = 1; | ||
| 397 | ret = si2168_cmd_execute(s, &cmd); | ||
| 398 | if (ret) | ||
| 399 | goto err; | ||
| 400 | |||
| 401 | memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6); | ||
| 402 | cmd.wlen = 6; | ||
| 403 | cmd.rlen = 1; | ||
| 404 | ret = si2168_cmd_execute(s, &cmd); | ||
| 405 | if (ret) | ||
| 406 | goto err; | ||
| 407 | |||
| 408 | memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6); | ||
| 409 | cmd.wlen = 6; | ||
| 410 | cmd.rlen = 1; | ||
| 411 | ret = si2168_cmd_execute(s, &cmd); | ||
| 412 | if (ret) | ||
| 413 | goto err; | ||
| 414 | |||
| 415 | cmd.args[0] = 0x85; | ||
| 416 | cmd.wlen = 1; | ||
| 417 | cmd.rlen = 1; | ||
| 418 | ret = si2168_cmd_execute(s, &cmd); | ||
| 419 | if (ret) | ||
| 420 | goto err; | ||
| 421 | |||
| 422 | s->delivery_system = c->delivery_system; | ||
| 423 | |||
| 424 | return 0; | ||
| 425 | err: | ||
| 426 | dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 427 | return ret; | ||
| 428 | } | ||
| 429 | |||
| 430 | static int si2168_init(struct dvb_frontend *fe) | ||
| 431 | { | ||
| 432 | struct si2168 *s = fe->demodulator_priv; | ||
| 433 | int ret, len, remaining; | ||
| 434 | const struct firmware *fw = NULL; | ||
| 435 | u8 *fw_file = SI2168_FIRMWARE; | ||
| 436 | const unsigned int i2c_wr_max = 8; | ||
| 437 | struct si2168_cmd cmd; | ||
| 438 | |||
| 439 | dev_dbg(&s->client->dev, "%s:\n", __func__); | ||
| 440 | |||
| 441 | cmd.args[0] = 0x13; | ||
| 442 | cmd.wlen = 1; | ||
| 443 | cmd.rlen = 0; | ||
| 444 | ret = si2168_cmd_execute(s, &cmd); | ||
| 445 | if (ret) | ||
| 446 | goto err; | ||
| 447 | |||
| 448 | cmd.args[0] = 0xc0; | ||
| 449 | cmd.args[1] = 0x12; | ||
| 450 | cmd.args[2] = 0x00; | ||
| 451 | cmd.args[3] = 0x0c; | ||
| 452 | cmd.args[4] = 0x00; | ||
| 453 | cmd.args[5] = 0x0d; | ||
| 454 | cmd.args[6] = 0x16; | ||
| 455 | cmd.args[7] = 0x00; | ||
| 456 | cmd.args[8] = 0x00; | ||
| 457 | cmd.args[9] = 0x00; | ||
| 458 | cmd.args[10] = 0x00; | ||
| 459 | cmd.args[11] = 0x00; | ||
| 460 | cmd.args[12] = 0x00; | ||
| 461 | cmd.wlen = 13; | ||
| 462 | cmd.rlen = 0; | ||
| 463 | ret = si2168_cmd_execute(s, &cmd); | ||
| 464 | if (ret) | ||
| 465 | goto err; | ||
| 466 | |||
| 467 | cmd.args[0] = 0xc0; | ||
| 468 | cmd.args[1] = 0x06; | ||
| 469 | cmd.args[2] = 0x01; | ||
| 470 | cmd.args[3] = 0x0f; | ||
| 471 | cmd.args[4] = 0x00; | ||
| 472 | cmd.args[5] = 0x20; | ||
| 473 | cmd.args[6] = 0x20; | ||
| 474 | cmd.args[7] = 0x01; | ||
| 475 | cmd.wlen = 8; | ||
| 476 | cmd.rlen = 1; | ||
| 477 | ret = si2168_cmd_execute(s, &cmd); | ||
| 478 | if (ret) | ||
| 479 | goto err; | ||
| 480 | |||
| 481 | cmd.args[0] = 0x02; | ||
| 482 | cmd.wlen = 1; | ||
| 483 | cmd.rlen = 13; | ||
| 484 | ret = si2168_cmd_execute(s, &cmd); | ||
| 485 | if (ret) | ||
| 486 | goto err; | ||
| 487 | |||
| 488 | cmd.args[0] = 0x05; | ||
| 489 | cmd.args[1] = 0x00; | ||
| 490 | cmd.args[2] = 0xaa; | ||
| 491 | cmd.args[3] = 0x4d; | ||
| 492 | cmd.args[4] = 0x56; | ||
| 493 | cmd.args[5] = 0x40; | ||
| 494 | cmd.args[6] = 0x00; | ||
| 495 | cmd.args[7] = 0x00; | ||
| 496 | cmd.wlen = 8; | ||
| 497 | cmd.rlen = 1; | ||
| 498 | ret = si2168_cmd_execute(s, &cmd); | ||
| 499 | if (ret) | ||
| 500 | goto err; | ||
| 501 | |||
| 502 | /* cold state - try to download firmware */ | ||
| 503 | dev_info(&s->client->dev, "%s: found a '%s' in cold state\n", | ||
| 504 | KBUILD_MODNAME, si2168_ops.info.name); | ||
| 505 | |||
| 506 | /* request the firmware, this will block and timeout */ | ||
| 507 | ret = request_firmware(&fw, fw_file, &s->client->dev); | ||
| 508 | if (ret) { | ||
| 509 | dev_err(&s->client->dev, "%s: firmare file '%s' not found\n", | ||
| 510 | KBUILD_MODNAME, fw_file); | ||
| 511 | goto err; | ||
| 512 | } | ||
| 513 | |||
| 514 | dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n", | ||
| 515 | KBUILD_MODNAME, fw_file); | ||
| 516 | |||
| 517 | for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) { | ||
| 518 | len = remaining; | ||
| 519 | if (len > i2c_wr_max) | ||
| 520 | len = i2c_wr_max; | ||
| 521 | |||
| 522 | memcpy(cmd.args, &fw->data[fw->size - remaining], len); | ||
| 523 | cmd.wlen = len; | ||
| 524 | cmd.rlen = 1; | ||
| 525 | ret = si2168_cmd_execute(s, &cmd); | ||
| 526 | if (ret) { | ||
| 527 | dev_err(&s->client->dev, | ||
| 528 | "%s: firmware download failed=%d\n", | ||
| 529 | KBUILD_MODNAME, ret); | ||
| 530 | goto err; | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 534 | release_firmware(fw); | ||
| 535 | fw = NULL; | ||
| 536 | |||
| 537 | cmd.args[0] = 0x01; | ||
| 538 | cmd.args[1] = 0x01; | ||
| 539 | cmd.wlen = 2; | ||
| 540 | cmd.rlen = 1; | ||
| 541 | ret = si2168_cmd_execute(s, &cmd); | ||
| 542 | if (ret) | ||
| 543 | goto err; | ||
| 544 | |||
| 545 | dev_info(&s->client->dev, "%s: found a '%s' in warm state\n", | ||
| 546 | KBUILD_MODNAME, si2168_ops.info.name); | ||
| 547 | |||
| 548 | s->active = true; | ||
| 549 | |||
| 550 | return 0; | ||
| 551 | err: | ||
| 552 | if (fw) | ||
| 553 | release_firmware(fw); | ||
| 554 | |||
| 555 | dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 556 | return ret; | ||
| 557 | } | ||
| 558 | |||
| 559 | static int si2168_sleep(struct dvb_frontend *fe) | ||
| 560 | { | ||
| 561 | struct si2168 *s = fe->demodulator_priv; | ||
| 562 | |||
| 563 | dev_dbg(&s->client->dev, "%s:\n", __func__); | ||
| 564 | |||
| 565 | s->active = false; | ||
| 566 | |||
| 567 | return 0; | ||
| 568 | } | ||
| 569 | |||
| 570 | static int si2168_get_tune_settings(struct dvb_frontend *fe, | ||
| 571 | struct dvb_frontend_tune_settings *s) | ||
| 572 | { | ||
| 573 | s->min_delay_ms = 900; | ||
| 574 | |||
| 575 | return 0; | ||
| 576 | } | ||
| 577 | |||
| 578 | /* | ||
| 579 | * I2C gate logic | ||
| 580 | * We must use unlocked i2c_transfer() here because I2C lock is already taken | ||
| 581 | * by tuner driver. | ||
| 582 | */ | ||
| 583 | static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) | ||
| 584 | { | ||
| 585 | struct si2168 *s = mux_priv; | ||
| 586 | int ret; | ||
| 587 | struct i2c_msg gate_open_msg = { | ||
| 588 | .addr = s->client->addr, | ||
| 589 | .flags = 0, | ||
| 590 | .len = 3, | ||
| 591 | .buf = "\xc0\x0d\x01", | ||
| 592 | }; | ||
| 593 | |||
| 594 | mutex_lock(&s->i2c_mutex); | ||
| 595 | |||
| 596 | /* open tuner I2C gate */ | ||
| 597 | ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1); | ||
| 598 | if (ret != 1) { | ||
| 599 | dev_warn(&s->client->dev, "%s: i2c write failed=%d\n", | ||
| 600 | KBUILD_MODNAME, ret); | ||
| 601 | if (ret >= 0) | ||
| 602 | ret = -EREMOTEIO; | ||
| 603 | } else { | ||
| 604 | ret = 0; | ||
| 605 | } | ||
| 606 | |||
| 607 | return ret; | ||
| 608 | } | ||
| 609 | |||
| 610 | static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) | ||
| 611 | { | ||
| 612 | struct si2168 *s = mux_priv; | ||
| 613 | int ret; | ||
| 614 | struct i2c_msg gate_close_msg = { | ||
| 615 | .addr = s->client->addr, | ||
| 616 | .flags = 0, | ||
| 617 | .len = 3, | ||
| 618 | .buf = "\xc0\x0d\x00", | ||
| 619 | }; | ||
| 620 | |||
| 621 | /* close tuner I2C gate */ | ||
| 622 | ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1); | ||
| 623 | if (ret != 1) { | ||
| 624 | dev_warn(&s->client->dev, "%s: i2c write failed=%d\n", | ||
| 625 | KBUILD_MODNAME, ret); | ||
| 626 | if (ret >= 0) | ||
| 627 | ret = -EREMOTEIO; | ||
| 628 | } else { | ||
| 629 | ret = 0; | ||
| 630 | } | ||
| 631 | |||
| 632 | mutex_unlock(&s->i2c_mutex); | ||
| 633 | |||
| 634 | return ret; | ||
| 635 | } | ||
| 636 | |||
| 637 | static const struct dvb_frontend_ops si2168_ops = { | ||
| 638 | .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A}, | ||
| 639 | .info = { | ||
| 640 | .name = "Silicon Labs Si2168", | ||
| 641 | .caps = FE_CAN_FEC_1_2 | | ||
| 642 | FE_CAN_FEC_2_3 | | ||
| 643 | FE_CAN_FEC_3_4 | | ||
| 644 | FE_CAN_FEC_5_6 | | ||
| 645 | FE_CAN_FEC_7_8 | | ||
| 646 | FE_CAN_FEC_AUTO | | ||
| 647 | FE_CAN_QPSK | | ||
| 648 | FE_CAN_QAM_16 | | ||
| 649 | FE_CAN_QAM_32 | | ||
| 650 | FE_CAN_QAM_64 | | ||
| 651 | FE_CAN_QAM_128 | | ||
| 652 | FE_CAN_QAM_256 | | ||
| 653 | FE_CAN_QAM_AUTO | | ||
| 654 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
| 655 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
| 656 | FE_CAN_HIERARCHY_AUTO | | ||
| 657 | FE_CAN_MUTE_TS | | ||
| 658 | FE_CAN_2G_MODULATION | ||
| 659 | }, | ||
| 660 | |||
| 661 | .get_tune_settings = si2168_get_tune_settings, | ||
| 662 | |||
| 663 | .init = si2168_init, | ||
| 664 | .sleep = si2168_sleep, | ||
| 665 | |||
| 666 | .set_frontend = si2168_set_frontend, | ||
| 667 | |||
| 668 | .read_status = si2168_read_status, | ||
| 669 | }; | ||
| 670 | |||
| 671 | static int si2168_probe(struct i2c_client *client, | ||
| 672 | const struct i2c_device_id *id) | ||
| 673 | { | ||
| 674 | struct si2168_config *config = client->dev.platform_data; | ||
| 675 | struct si2168 *s; | ||
| 676 | int ret; | ||
| 677 | struct si2168_cmd cmd; | ||
| 678 | |||
| 679 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
| 680 | |||
| 681 | s = kzalloc(sizeof(struct si2168), GFP_KERNEL); | ||
| 682 | if (!s) { | ||
| 683 | ret = -ENOMEM; | ||
| 684 | dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); | ||
| 685 | goto err; | ||
| 686 | } | ||
| 687 | |||
| 688 | s->client = client; | ||
| 689 | mutex_init(&s->i2c_mutex); | ||
| 690 | |||
| 691 | /* check if the demod is there */ | ||
| 692 | cmd.wlen = 0; | ||
| 693 | cmd.rlen = 1; | ||
| 694 | ret = si2168_cmd_execute(s, &cmd); | ||
| 695 | if (ret) | ||
| 696 | goto err; | ||
| 697 | |||
| 698 | /* create mux i2c adapter for tuner */ | ||
| 699 | s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s, | ||
| 700 | 0, 0, 0, si2168_select, si2168_deselect); | ||
| 701 | if (s->adapter == NULL) | ||
| 702 | goto err; | ||
| 703 | |||
| 704 | /* create dvb_frontend */ | ||
| 705 | memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops)); | ||
| 706 | s->fe.demodulator_priv = s; | ||
| 707 | |||
| 708 | *config->i2c_adapter = s->adapter; | ||
| 709 | *config->fe = &s->fe; | ||
| 710 | |||
| 711 | i2c_set_clientdata(client, s); | ||
| 712 | |||
| 713 | dev_info(&s->client->dev, | ||
| 714 | "%s: Silicon Labs Si2168 successfully attached\n", | ||
| 715 | KBUILD_MODNAME); | ||
| 716 | return 0; | ||
| 717 | err: | ||
| 718 | kfree(s); | ||
| 719 | dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 720 | return ret; | ||
| 721 | } | ||
| 722 | |||
| 723 | static int si2168_remove(struct i2c_client *client) | ||
| 724 | { | ||
| 725 | struct si2168 *s = i2c_get_clientdata(client); | ||
| 726 | |||
| 727 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
| 728 | |||
| 729 | i2c_del_mux_adapter(s->adapter); | ||
| 730 | |||
| 731 | s->fe.ops.release = NULL; | ||
| 732 | s->fe.demodulator_priv = NULL; | ||
| 733 | |||
| 734 | kfree(s); | ||
| 735 | |||
| 736 | return 0; | ||
| 737 | } | ||
| 738 | |||
| 739 | static const struct i2c_device_id si2168_id[] = { | ||
| 740 | {"si2168", 0}, | ||
| 741 | {} | ||
| 742 | }; | ||
| 743 | MODULE_DEVICE_TABLE(i2c, si2168_id); | ||
| 744 | |||
| 745 | static struct i2c_driver si2168_driver = { | ||
| 746 | .driver = { | ||
| 747 | .owner = THIS_MODULE, | ||
| 748 | .name = "si2168", | ||
| 749 | }, | ||
| 750 | .probe = si2168_probe, | ||
| 751 | .remove = si2168_remove, | ||
| 752 | .id_table = si2168_id, | ||
| 753 | }; | ||
| 754 | |||
| 755 | module_i2c_driver(si2168_driver); | ||
| 756 | |||
| 757 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
| 758 | MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver"); | ||
| 759 | MODULE_LICENSE("GPL"); | ||
| 760 | MODULE_FIRMWARE(SI2168_FIRMWARE); | ||
diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h new file mode 100644 index 000000000000..3c5b5ab01796 --- /dev/null +++ b/drivers/media/dvb-frontends/si2168.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs Si2168 DVB-T/T2/C demodulator driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef SI2168_H | ||
| 18 | #define SI2168_H | ||
| 19 | |||
| 20 | #include <linux/dvb/frontend.h> | ||
| 21 | /* | ||
| 22 | * I2C address | ||
| 23 | * 0x64 | ||
| 24 | */ | ||
| 25 | struct si2168_config { | ||
| 26 | /* | ||
| 27 | * frontend | ||
| 28 | * returned by driver | ||
| 29 | */ | ||
| 30 | struct dvb_frontend **fe; | ||
| 31 | |||
| 32 | /* | ||
| 33 | * tuner I2C adapter | ||
| 34 | * returned by driver | ||
| 35 | */ | ||
| 36 | struct i2c_adapter **i2c_adapter; | ||
| 37 | }; | ||
| 38 | |||
| 39 | #endif | ||
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h new file mode 100644 index 000000000000..2a343e896f40 --- /dev/null +++ b/drivers/media/dvb-frontends/si2168_priv.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs Si2168 DVB-T/T2/C demodulator driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef SI2168_PRIV_H | ||
| 18 | #define SI2168_PRIV_H | ||
| 19 | |||
| 20 | #include "si2168.h" | ||
| 21 | #include "dvb_frontend.h" | ||
| 22 | #include <linux/firmware.h> | ||
| 23 | #include <linux/i2c-mux.h> | ||
| 24 | |||
| 25 | #define SI2168_FIRMWARE "dvb-demod-si2168-01.fw" | ||
| 26 | |||
| 27 | /* state struct */ | ||
| 28 | struct si2168 { | ||
| 29 | struct i2c_client *client; | ||
| 30 | struct i2c_adapter *adapter; | ||
| 31 | struct mutex i2c_mutex; | ||
| 32 | struct dvb_frontend fe; | ||
| 33 | fe_delivery_system_t delivery_system; | ||
| 34 | fe_status_t fe_status; | ||
| 35 | bool active; | ||
| 36 | }; | ||
| 37 | |||
| 38 | /* firmare command struct */ | ||
| 39 | #define SI2157_ARGLEN 30 | ||
| 40 | struct si2168_cmd { | ||
| 41 | u8 args[SI2157_ARGLEN]; | ||
| 42 | unsigned wlen; | ||
| 43 | unsigned rlen; | ||
| 44 | }; | ||
| 45 | |||
| 46 | #endif | ||
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index 1b7ecfd88673..fada17566205 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c | |||
| @@ -571,35 +571,6 @@ static const struct v4l2_subdev_core_ops ad9389b_core_ops = { | |||
| 571 | .interrupt_service_routine = ad9389b_isr, | 571 | .interrupt_service_routine = ad9389b_isr, |
| 572 | }; | 572 | }; |
| 573 | 573 | ||
| 574 | /* ------------------------------ PAD OPS ------------------------------ */ | ||
| 575 | |||
| 576 | static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | ||
| 577 | { | ||
| 578 | struct ad9389b_state *state = get_ad9389b_state(sd); | ||
| 579 | |||
| 580 | if (edid->pad != 0) | ||
| 581 | return -EINVAL; | ||
| 582 | if (edid->blocks == 0 || edid->blocks > 256) | ||
| 583 | return -EINVAL; | ||
| 584 | if (!edid->edid) | ||
| 585 | return -EINVAL; | ||
| 586 | if (!state->edid.segments) { | ||
| 587 | v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); | ||
| 588 | return -ENODATA; | ||
| 589 | } | ||
| 590 | if (edid->start_block >= state->edid.segments * 2) | ||
| 591 | return -E2BIG; | ||
| 592 | if (edid->blocks + edid->start_block >= state->edid.segments * 2) | ||
| 593 | edid->blocks = state->edid.segments * 2 - edid->start_block; | ||
| 594 | memcpy(edid->edid, &state->edid.data[edid->start_block * 128], | ||
| 595 | 128 * edid->blocks); | ||
| 596 | return 0; | ||
| 597 | } | ||
| 598 | |||
| 599 | static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = { | ||
| 600 | .get_edid = ad9389b_get_edid, | ||
| 601 | }; | ||
| 602 | |||
| 603 | /* ------------------------------ VIDEO OPS ------------------------------ */ | 574 | /* ------------------------------ VIDEO OPS ------------------------------ */ |
| 604 | 575 | ||
| 605 | /* Enable/disable ad9389b output */ | 576 | /* Enable/disable ad9389b output */ |
| @@ -678,6 +649,9 @@ static int ad9389b_g_dv_timings(struct v4l2_subdev *sd, | |||
| 678 | static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd, | 649 | static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd, |
| 679 | struct v4l2_enum_dv_timings *timings) | 650 | struct v4l2_enum_dv_timings *timings) |
| 680 | { | 651 | { |
| 652 | if (timings->pad != 0) | ||
| 653 | return -EINVAL; | ||
| 654 | |||
| 681 | return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap, | 655 | return v4l2_enum_dv_timings_cap(timings, &ad9389b_timings_cap, |
| 682 | NULL, NULL); | 656 | NULL, NULL); |
| 683 | } | 657 | } |
| @@ -685,6 +659,9 @@ static int ad9389b_enum_dv_timings(struct v4l2_subdev *sd, | |||
| 685 | static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd, | 659 | static int ad9389b_dv_timings_cap(struct v4l2_subdev *sd, |
| 686 | struct v4l2_dv_timings_cap *cap) | 660 | struct v4l2_dv_timings_cap *cap) |
| 687 | { | 661 | { |
| 662 | if (cap->pad != 0) | ||
| 663 | return -EINVAL; | ||
| 664 | |||
| 688 | *cap = ad9389b_timings_cap; | 665 | *cap = ad9389b_timings_cap; |
| 689 | return 0; | 666 | return 0; |
| 690 | } | 667 | } |
| @@ -693,10 +670,39 @@ static const struct v4l2_subdev_video_ops ad9389b_video_ops = { | |||
| 693 | .s_stream = ad9389b_s_stream, | 670 | .s_stream = ad9389b_s_stream, |
| 694 | .s_dv_timings = ad9389b_s_dv_timings, | 671 | .s_dv_timings = ad9389b_s_dv_timings, |
| 695 | .g_dv_timings = ad9389b_g_dv_timings, | 672 | .g_dv_timings = ad9389b_g_dv_timings, |
| 673 | }; | ||
| 674 | |||
| 675 | /* ------------------------------ PAD OPS ------------------------------ */ | ||
| 676 | |||
| 677 | static int ad9389b_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | ||
| 678 | { | ||
| 679 | struct ad9389b_state *state = get_ad9389b_state(sd); | ||
| 680 | |||
| 681 | if (edid->pad != 0) | ||
| 682 | return -EINVAL; | ||
| 683 | if (edid->blocks == 0 || edid->blocks > 256) | ||
| 684 | return -EINVAL; | ||
| 685 | if (!state->edid.segments) { | ||
| 686 | v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); | ||
| 687 | return -ENODATA; | ||
| 688 | } | ||
| 689 | if (edid->start_block >= state->edid.segments * 2) | ||
| 690 | return -E2BIG; | ||
| 691 | if (edid->blocks + edid->start_block >= state->edid.segments * 2) | ||
| 692 | edid->blocks = state->edid.segments * 2 - edid->start_block; | ||
| 693 | memcpy(edid->edid, &state->edid.data[edid->start_block * 128], | ||
| 694 | 128 * edid->blocks); | ||
| 695 | return 0; | ||
| 696 | } | ||
| 697 | |||
| 698 | static const struct v4l2_subdev_pad_ops ad9389b_pad_ops = { | ||
| 699 | .get_edid = ad9389b_get_edid, | ||
| 696 | .enum_dv_timings = ad9389b_enum_dv_timings, | 700 | .enum_dv_timings = ad9389b_enum_dv_timings, |
| 697 | .dv_timings_cap = ad9389b_dv_timings_cap, | 701 | .dv_timings_cap = ad9389b_dv_timings_cap, |
| 698 | }; | 702 | }; |
| 699 | 703 | ||
| 704 | /* ------------------------------ AUDIO OPS ------------------------------ */ | ||
| 705 | |||
| 700 | static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable) | 706 | static int ad9389b_s_audio_stream(struct v4l2_subdev *sd, int enable) |
| 701 | { | 707 | { |
| 702 | v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis")); | 708 | v4l2_dbg(1, debug, sd, "%s: %sable\n", __func__, (enable ? "en" : "dis")); |
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 5e638b159452..ac1cdbe251a3 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c | |||
| @@ -461,6 +461,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd, | |||
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | static const struct v4l2_subdev_video_ops adv7180_video_ops = { | 463 | static const struct v4l2_subdev_video_ops adv7180_video_ops = { |
| 464 | .s_std = adv7180_s_std, | ||
| 464 | .querystd = adv7180_querystd, | 465 | .querystd = adv7180_querystd, |
| 465 | .g_input_status = adv7180_g_input_status, | 466 | .g_input_status = adv7180_g_input_status, |
| 466 | .s_routing = adv7180_s_routing, | 467 | .s_routing = adv7180_s_routing, |
| @@ -472,7 +473,6 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { | |||
| 472 | }; | 473 | }; |
| 473 | 474 | ||
| 474 | static const struct v4l2_subdev_core_ops adv7180_core_ops = { | 475 | static const struct v4l2_subdev_core_ops adv7180_core_ops = { |
| 475 | .s_std = adv7180_s_std, | ||
| 476 | .s_power = adv7180_s_power, | 476 | .s_power = adv7180_s_power, |
| 477 | }; | 477 | }; |
| 478 | 478 | ||
diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c index d45e0e3a781d..df461b07b2f7 100644 --- a/drivers/media/i2c/adv7183.c +++ b/drivers/media/i2c/adv7183.c | |||
| @@ -501,8 +501,6 @@ static const struct v4l2_ctrl_ops adv7183_ctrl_ops = { | |||
| 501 | 501 | ||
| 502 | static const struct v4l2_subdev_core_ops adv7183_core_ops = { | 502 | static const struct v4l2_subdev_core_ops adv7183_core_ops = { |
| 503 | .log_status = adv7183_log_status, | 503 | .log_status = adv7183_log_status, |
| 504 | .g_std = adv7183_g_std, | ||
| 505 | .s_std = adv7183_s_std, | ||
| 506 | .reset = adv7183_reset, | 504 | .reset = adv7183_reset, |
| 507 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 505 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 508 | .g_register = adv7183_g_register, | 506 | .g_register = adv7183_g_register, |
| @@ -511,6 +509,8 @@ static const struct v4l2_subdev_core_ops adv7183_core_ops = { | |||
| 511 | }; | 509 | }; |
| 512 | 510 | ||
| 513 | static const struct v4l2_subdev_video_ops adv7183_video_ops = { | 511 | static const struct v4l2_subdev_video_ops adv7183_video_ops = { |
| 512 | .g_std = adv7183_g_std, | ||
| 513 | .s_std = adv7183_s_std, | ||
| 514 | .s_routing = adv7183_s_routing, | 514 | .s_routing = adv7183_s_routing, |
| 515 | .querystd = adv7183_querystd, | 515 | .querystd = adv7183_querystd, |
| 516 | .g_input_status = adv7183_g_input_status, | 516 | .g_input_status = adv7183_g_input_status, |
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 942ca4b99297..f98acf4aafd4 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c | |||
| @@ -597,34 +597,6 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled) | |||
| 597 | return 0; | 597 | return 0; |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | ||
| 601 | { | ||
| 602 | struct adv7511_state *state = get_adv7511_state(sd); | ||
| 603 | |||
| 604 | if (edid->pad != 0) | ||
| 605 | return -EINVAL; | ||
| 606 | if ((edid->blocks == 0) || (edid->blocks > 256)) | ||
| 607 | return -EINVAL; | ||
| 608 | if (!edid->edid) | ||
| 609 | return -EINVAL; | ||
| 610 | if (!state->edid.segments) { | ||
| 611 | v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); | ||
| 612 | return -ENODATA; | ||
| 613 | } | ||
| 614 | if (edid->start_block >= state->edid.segments * 2) | ||
| 615 | return -E2BIG; | ||
| 616 | if ((edid->blocks + edid->start_block) >= state->edid.segments * 2) | ||
| 617 | edid->blocks = state->edid.segments * 2 - edid->start_block; | ||
| 618 | |||
| 619 | memcpy(edid->edid, &state->edid.data[edid->start_block * 128], | ||
| 620 | 128 * edid->blocks); | ||
| 621 | return 0; | ||
| 622 | } | ||
| 623 | |||
| 624 | static const struct v4l2_subdev_pad_ops adv7511_pad_ops = { | ||
| 625 | .get_edid = adv7511_get_edid, | ||
| 626 | }; | ||
| 627 | |||
| 628 | static const struct v4l2_subdev_core_ops adv7511_core_ops = { | 600 | static const struct v4l2_subdev_core_ops adv7511_core_ops = { |
| 629 | .log_status = adv7511_log_status, | 601 | .log_status = adv7511_log_status, |
| 630 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 602 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| @@ -700,12 +672,18 @@ static int adv7511_g_dv_timings(struct v4l2_subdev *sd, | |||
| 700 | static int adv7511_enum_dv_timings(struct v4l2_subdev *sd, | 672 | static int adv7511_enum_dv_timings(struct v4l2_subdev *sd, |
| 701 | struct v4l2_enum_dv_timings *timings) | 673 | struct v4l2_enum_dv_timings *timings) |
| 702 | { | 674 | { |
| 675 | if (timings->pad != 0) | ||
| 676 | return -EINVAL; | ||
| 677 | |||
| 703 | return v4l2_enum_dv_timings_cap(timings, &adv7511_timings_cap, NULL, NULL); | 678 | return v4l2_enum_dv_timings_cap(timings, &adv7511_timings_cap, NULL, NULL); |
| 704 | } | 679 | } |
| 705 | 680 | ||
| 706 | static int adv7511_dv_timings_cap(struct v4l2_subdev *sd, | 681 | static int adv7511_dv_timings_cap(struct v4l2_subdev *sd, |
| 707 | struct v4l2_dv_timings_cap *cap) | 682 | struct v4l2_dv_timings_cap *cap) |
| 708 | { | 683 | { |
| 684 | if (cap->pad != 0) | ||
| 685 | return -EINVAL; | ||
| 686 | |||
| 709 | *cap = adv7511_timings_cap; | 687 | *cap = adv7511_timings_cap; |
| 710 | return 0; | 688 | return 0; |
| 711 | } | 689 | } |
| @@ -714,8 +692,6 @@ static const struct v4l2_subdev_video_ops adv7511_video_ops = { | |||
| 714 | .s_stream = adv7511_s_stream, | 692 | .s_stream = adv7511_s_stream, |
| 715 | .s_dv_timings = adv7511_s_dv_timings, | 693 | .s_dv_timings = adv7511_s_dv_timings, |
| 716 | .g_dv_timings = adv7511_g_dv_timings, | 694 | .g_dv_timings = adv7511_g_dv_timings, |
| 717 | .enum_dv_timings = adv7511_enum_dv_timings, | ||
| 718 | .dv_timings_cap = adv7511_dv_timings_cap, | ||
| 719 | }; | 695 | }; |
| 720 | 696 | ||
| 721 | /* ------------------------------ AUDIO OPS ------------------------------ */ | 697 | /* ------------------------------ AUDIO OPS ------------------------------ */ |
| @@ -797,6 +773,36 @@ static const struct v4l2_subdev_audio_ops adv7511_audio_ops = { | |||
| 797 | .s_routing = adv7511_s_routing, | 773 | .s_routing = adv7511_s_routing, |
| 798 | }; | 774 | }; |
| 799 | 775 | ||
| 776 | /* ---------------------------- PAD OPS ------------------------------------- */ | ||
| 777 | |||
| 778 | static int adv7511_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | ||
| 779 | { | ||
| 780 | struct adv7511_state *state = get_adv7511_state(sd); | ||
| 781 | |||
| 782 | if (edid->pad != 0) | ||
| 783 | return -EINVAL; | ||
| 784 | if ((edid->blocks == 0) || (edid->blocks > 256)) | ||
| 785 | return -EINVAL; | ||
| 786 | if (!state->edid.segments) { | ||
| 787 | v4l2_dbg(1, debug, sd, "EDID segment 0 not found\n"); | ||
| 788 | return -ENODATA; | ||
| 789 | } | ||
| 790 | if (edid->start_block >= state->edid.segments * 2) | ||
| 791 | return -E2BIG; | ||
| 792 | if ((edid->blocks + edid->start_block) >= state->edid.segments * 2) | ||
| 793 | edid->blocks = state->edid.segments * 2 - edid->start_block; | ||
| 794 | |||
| 795 | memcpy(edid->edid, &state->edid.data[edid->start_block * 128], | ||
| 796 | 128 * edid->blocks); | ||
| 797 | return 0; | ||
| 798 | } | ||
| 799 | |||
| 800 | static const struct v4l2_subdev_pad_ops adv7511_pad_ops = { | ||
| 801 | .get_edid = adv7511_get_edid, | ||
| 802 | .enum_dv_timings = adv7511_enum_dv_timings, | ||
| 803 | .dv_timings_cap = adv7511_dv_timings_cap, | ||
| 804 | }; | ||
| 805 | |||
| 800 | /* --------------------- SUBDEV OPS --------------------------------------- */ | 806 | /* --------------------- SUBDEV OPS --------------------------------------- */ |
| 801 | 807 | ||
| 802 | static const struct v4l2_subdev_ops adv7511_ops = { | 808 | static const struct v4l2_subdev_ops adv7511_ops = { |
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 98cc5407f1b1..338baa4c23ef 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c | |||
| @@ -1673,8 +1673,6 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
| 1673 | return -EINVAL; | 1673 | return -EINVAL; |
| 1674 | if (edid->start_block == 1) | 1674 | if (edid->start_block == 1) |
| 1675 | edid->blocks = 1; | 1675 | edid->blocks = 1; |
| 1676 | if (!edid->edid) | ||
| 1677 | return -EINVAL; | ||
| 1678 | 1676 | ||
| 1679 | if (edid->blocks > state->edid.blocks) | 1677 | if (edid->blocks > state->edid.blocks) |
| 1680 | edid->blocks = state->edid.blocks; | 1678 | edid->blocks = state->edid.blocks; |
| @@ -1761,8 +1759,6 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
| 1761 | edid->blocks = 2; | 1759 | edid->blocks = 2; |
| 1762 | return -E2BIG; | 1760 | return -E2BIG; |
| 1763 | } | 1761 | } |
| 1764 | if (!edid->edid) | ||
| 1765 | return -EINVAL; | ||
| 1766 | 1762 | ||
| 1767 | v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n", | 1763 | v4l2_dbg(2, debug, sd, "%s: write EDID pad %d, edid.present = 0x%x\n", |
| 1768 | __func__, edid->pad, state->edid.present); | 1764 | __func__, edid->pad, state->edid.present); |
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 636ac08925f6..0d554919cdd5 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c | |||
| @@ -1399,6 +1399,9 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) | |||
| 1399 | static int adv7842_enum_dv_timings(struct v4l2_subdev *sd, | 1399 | static int adv7842_enum_dv_timings(struct v4l2_subdev *sd, |
| 1400 | struct v4l2_enum_dv_timings *timings) | 1400 | struct v4l2_enum_dv_timings *timings) |
| 1401 | { | 1401 | { |
| 1402 | if (timings->pad != 0) | ||
| 1403 | return -EINVAL; | ||
| 1404 | |||
| 1402 | return v4l2_enum_dv_timings_cap(timings, | 1405 | return v4l2_enum_dv_timings_cap(timings, |
| 1403 | adv7842_get_dv_timings_cap(sd), adv7842_check_dv_timings, NULL); | 1406 | adv7842_get_dv_timings_cap(sd), adv7842_check_dv_timings, NULL); |
| 1404 | } | 1407 | } |
| @@ -1406,6 +1409,9 @@ static int adv7842_enum_dv_timings(struct v4l2_subdev *sd, | |||
| 1406 | static int adv7842_dv_timings_cap(struct v4l2_subdev *sd, | 1409 | static int adv7842_dv_timings_cap(struct v4l2_subdev *sd, |
| 1407 | struct v4l2_dv_timings_cap *cap) | 1410 | struct v4l2_dv_timings_cap *cap) |
| 1408 | { | 1411 | { |
| 1412 | if (cap->pad != 0) | ||
| 1413 | return -EINVAL; | ||
| 1414 | |||
| 1409 | *cap = *adv7842_get_dv_timings_cap(sd); | 1415 | *cap = *adv7842_get_dv_timings_cap(sd); |
| 1410 | return 0; | 1416 | return 0; |
| 1411 | } | 1417 | } |
| @@ -2000,6 +2006,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled) | |||
| 2000 | if (irq_status[5] & 0x08) { | 2006 | if (irq_status[5] & 0x08) { |
| 2001 | v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__, | 2007 | v4l2_dbg(1, debug, sd, "%s: irq %s mode\n", __func__, |
| 2002 | (io_read(sd, 0x65) & 0x08) ? "HDMI" : "DVI"); | 2008 | (io_read(sd, 0x65) & 0x08) ? "HDMI" : "DVI"); |
| 2009 | set_rgb_quantization_range(sd); | ||
| 2003 | if (handled) | 2010 | if (handled) |
| 2004 | *handled = true; | 2011 | *handled = true; |
| 2005 | } | 2012 | } |
| @@ -2029,8 +2036,6 @@ static int adv7842_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | |||
| 2029 | return -EINVAL; | 2036 | return -EINVAL; |
| 2030 | if (edid->start_block == 1) | 2037 | if (edid->start_block == 1) |
| 2031 | edid->blocks = 1; | 2038 | edid->blocks = 1; |
| 2032 | if (!edid->edid) | ||
| 2033 | return -EINVAL; | ||
| 2034 | 2039 | ||
| 2035 | switch (edid->pad) { | 2040 | switch (edid->pad) { |
| 2036 | case ADV7842_EDID_PORT_A: | 2041 | case ADV7842_EDID_PORT_A: |
| @@ -2065,8 +2070,6 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *e) | |||
| 2065 | return -EINVAL; | 2070 | return -EINVAL; |
| 2066 | if (e->blocks > 2) | 2071 | if (e->blocks > 2) |
| 2067 | return -E2BIG; | 2072 | return -E2BIG; |
| 2068 | if (!e->edid) | ||
| 2069 | return -EINVAL; | ||
| 2070 | 2073 | ||
| 2071 | /* todo, per edid */ | 2074 | /* todo, per edid */ |
| 2072 | state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], | 2075 | state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], |
| @@ -2610,6 +2613,12 @@ static int adv7842_core_init(struct v4l2_subdev *sd) | |||
| 2610 | 2613 | ||
| 2611 | disable_input(sd); | 2614 | disable_input(sd); |
| 2612 | 2615 | ||
| 2616 | /* | ||
| 2617 | * Disable I2C access to internal EDID ram from HDMI DDC ports | ||
| 2618 | * Disable auto edid enable when leaving powerdown mode | ||
| 2619 | */ | ||
| 2620 | rep_write_and_or(sd, 0x77, 0xd3, 0x20); | ||
| 2621 | |||
| 2613 | /* power */ | 2622 | /* power */ |
| 2614 | io_write(sd, 0x0c, 0x42); /* Power up part and power down VDP */ | 2623 | io_write(sd, 0x0c, 0x42); /* Power up part and power down VDP */ |
| 2615 | io_write(sd, 0x15, 0x80); /* Power up pads */ | 2624 | io_write(sd, 0x15, 0x80); /* Power up pads */ |
| @@ -2690,9 +2699,6 @@ static int adv7842_core_init(struct v4l2_subdev *sd) | |||
| 2690 | 2699 | ||
| 2691 | enable_input(sd); | 2700 | enable_input(sd); |
| 2692 | 2701 | ||
| 2693 | /* disable I2C access to internal EDID ram from HDMI DDC ports */ | ||
| 2694 | rep_write_and_or(sd, 0x77, 0xf3, 0x00); | ||
| 2695 | |||
| 2696 | if (pdata->hpa_auto) { | 2702 | if (pdata->hpa_auto) { |
| 2697 | /* HPA auto, HPA 0.5s after Edid set and Cable detect */ | 2703 | /* HPA auto, HPA 0.5s after Edid set and Cable detect */ |
| 2698 | hdmi_write(sd, 0x69, 0x5c); | 2704 | hdmi_write(sd, 0x69, 0x5c); |
| @@ -2869,8 +2875,6 @@ static const struct v4l2_ctrl_ops adv7842_ctrl_ops = { | |||
| 2869 | 2875 | ||
| 2870 | static const struct v4l2_subdev_core_ops adv7842_core_ops = { | 2876 | static const struct v4l2_subdev_core_ops adv7842_core_ops = { |
| 2871 | .log_status = adv7842_log_status, | 2877 | .log_status = adv7842_log_status, |
| 2872 | .g_std = adv7842_g_std, | ||
| 2873 | .s_std = adv7842_s_std, | ||
| 2874 | .ioctl = adv7842_ioctl, | 2878 | .ioctl = adv7842_ioctl, |
| 2875 | .interrupt_service_routine = adv7842_isr, | 2879 | .interrupt_service_routine = adv7842_isr, |
| 2876 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2880 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| @@ -2880,14 +2884,14 @@ static const struct v4l2_subdev_core_ops adv7842_core_ops = { | |||
| 2880 | }; | 2884 | }; |
| 2881 | 2885 | ||
| 2882 | static const struct v4l2_subdev_video_ops adv7842_video_ops = { | 2886 | static const struct v4l2_subdev_video_ops adv7842_video_ops = { |
| 2887 | .g_std = adv7842_g_std, | ||
| 2888 | .s_std = adv7842_s_std, | ||
| 2883 | .s_routing = adv7842_s_routing, | 2889 | .s_routing = adv7842_s_routing, |
| 2884 | .querystd = adv7842_querystd, | 2890 | .querystd = adv7842_querystd, |
| 2885 | .g_input_status = adv7842_g_input_status, | 2891 | .g_input_status = adv7842_g_input_status, |
| 2886 | .s_dv_timings = adv7842_s_dv_timings, | 2892 | .s_dv_timings = adv7842_s_dv_timings, |
| 2887 | .g_dv_timings = adv7842_g_dv_timings, | 2893 | .g_dv_timings = adv7842_g_dv_timings, |
| 2888 | .query_dv_timings = adv7842_query_dv_timings, | 2894 | .query_dv_timings = adv7842_query_dv_timings, |
| 2889 | .enum_dv_timings = adv7842_enum_dv_timings, | ||
| 2890 | .dv_timings_cap = adv7842_dv_timings_cap, | ||
| 2891 | .enum_mbus_fmt = adv7842_enum_mbus_fmt, | 2895 | .enum_mbus_fmt = adv7842_enum_mbus_fmt, |
| 2892 | .g_mbus_fmt = adv7842_g_mbus_fmt, | 2896 | .g_mbus_fmt = adv7842_g_mbus_fmt, |
| 2893 | .try_mbus_fmt = adv7842_g_mbus_fmt, | 2897 | .try_mbus_fmt = adv7842_g_mbus_fmt, |
| @@ -2897,6 +2901,8 @@ static const struct v4l2_subdev_video_ops adv7842_video_ops = { | |||
| 2897 | static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { | 2901 | static const struct v4l2_subdev_pad_ops adv7842_pad_ops = { |
| 2898 | .get_edid = adv7842_get_edid, | 2902 | .get_edid = adv7842_get_edid, |
| 2899 | .set_edid = adv7842_set_edid, | 2903 | .set_edid = adv7842_set_edid, |
| 2904 | .enum_dv_timings = adv7842_enum_dv_timings, | ||
| 2905 | .dv_timings_cap = adv7842_dv_timings_cap, | ||
| 2900 | }; | 2906 | }; |
| 2901 | 2907 | ||
| 2902 | static const struct v4l2_subdev_ops adv7842_ops = { | 2908 | static const struct v4l2_subdev_ops adv7842_ops = { |
diff --git a/drivers/media/i2c/bt819.c b/drivers/media/i2c/bt819.c index 369cf6ff88f7..76b334a6a56d 100644 --- a/drivers/media/i2c/bt819.c +++ b/drivers/media/i2c/bt819.c | |||
| @@ -387,10 +387,10 @@ static const struct v4l2_subdev_core_ops bt819_core_ops = { | |||
| 387 | .s_ctrl = v4l2_subdev_s_ctrl, | 387 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 388 | .queryctrl = v4l2_subdev_queryctrl, | 388 | .queryctrl = v4l2_subdev_queryctrl, |
| 389 | .querymenu = v4l2_subdev_querymenu, | 389 | .querymenu = v4l2_subdev_querymenu, |
| 390 | .s_std = bt819_s_std, | ||
| 391 | }; | 390 | }; |
| 392 | 391 | ||
| 393 | static const struct v4l2_subdev_video_ops bt819_video_ops = { | 392 | static const struct v4l2_subdev_video_ops bt819_video_ops = { |
| 393 | .s_std = bt819_s_std, | ||
| 394 | .s_routing = bt819_s_routing, | 394 | .s_routing = bt819_s_routing, |
| 395 | .s_stream = bt819_s_stream, | 395 | .s_stream = bt819_s_stream, |
| 396 | .querystd = bt819_querystd, | 396 | .querystd = bt819_querystd, |
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 2e3771d57354..e453a3ffe7d1 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c | |||
| @@ -5041,8 +5041,6 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = { | |||
| 5041 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, | 5041 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, |
| 5042 | .queryctrl = v4l2_subdev_queryctrl, | 5042 | .queryctrl = v4l2_subdev_queryctrl, |
| 5043 | .querymenu = v4l2_subdev_querymenu, | 5043 | .querymenu = v4l2_subdev_querymenu, |
| 5044 | .s_std = cx25840_s_std, | ||
| 5045 | .g_std = cx25840_g_std, | ||
| 5046 | .reset = cx25840_reset, | 5044 | .reset = cx25840_reset, |
| 5047 | .load_fw = cx25840_load_fw, | 5045 | .load_fw = cx25840_load_fw, |
| 5048 | .s_io_pin_config = common_s_io_pin_config, | 5046 | .s_io_pin_config = common_s_io_pin_config, |
| @@ -5067,6 +5065,8 @@ static const struct v4l2_subdev_audio_ops cx25840_audio_ops = { | |||
| 5067 | }; | 5065 | }; |
| 5068 | 5066 | ||
| 5069 | static const struct v4l2_subdev_video_ops cx25840_video_ops = { | 5067 | static const struct v4l2_subdev_video_ops cx25840_video_ops = { |
| 5068 | .s_std = cx25840_s_std, | ||
| 5069 | .g_std = cx25840_g_std, | ||
| 5070 | .s_routing = cx25840_s_video_routing, | 5070 | .s_routing = cx25840_s_video_routing, |
| 5071 | .s_mbus_fmt = cx25840_s_mbus_fmt, | 5071 | .s_mbus_fmt = cx25840_s_mbus_fmt, |
| 5072 | .s_stream = cx25840_s_stream, | 5072 | .s_stream = cx25840_s_stream, |
diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c index c3e94ae82c03..25b81bc58c81 100644 --- a/drivers/media/i2c/ks0127.c +++ b/drivers/media/i2c/ks0127.c | |||
| @@ -648,11 +648,8 @@ static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status) | |||
| 648 | 648 | ||
| 649 | /* ----------------------------------------------------------------------- */ | 649 | /* ----------------------------------------------------------------------- */ |
| 650 | 650 | ||
| 651 | static const struct v4l2_subdev_core_ops ks0127_core_ops = { | ||
| 652 | .s_std = ks0127_s_std, | ||
| 653 | }; | ||
| 654 | |||
| 655 | static const struct v4l2_subdev_video_ops ks0127_video_ops = { | 651 | static const struct v4l2_subdev_video_ops ks0127_video_ops = { |
| 652 | .s_std = ks0127_s_std, | ||
| 656 | .s_routing = ks0127_s_routing, | 653 | .s_routing = ks0127_s_routing, |
| 657 | .s_stream = ks0127_s_stream, | 654 | .s_stream = ks0127_s_stream, |
| 658 | .querystd = ks0127_querystd, | 655 | .querystd = ks0127_querystd, |
| @@ -660,7 +657,6 @@ static const struct v4l2_subdev_video_ops ks0127_video_ops = { | |||
| 660 | }; | 657 | }; |
| 661 | 658 | ||
| 662 | static const struct v4l2_subdev_ops ks0127_ops = { | 659 | static const struct v4l2_subdev_ops ks0127_ops = { |
| 663 | .core = &ks0127_core_ops, | ||
| 664 | .video = &ks0127_video_ops, | 660 | .video = &ks0127_video_ops, |
| 665 | }; | 661 | }; |
| 666 | 662 | ||
diff --git a/drivers/media/i2c/m5mols/m5mols_capture.c b/drivers/media/i2c/m5mols/m5mols_capture.c index ab34ccedf31e..1a03d02bd4d1 100644 --- a/drivers/media/i2c/m5mols/m5mols_capture.c +++ b/drivers/media/i2c/m5mols/m5mols_capture.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <media/v4l2-device.h> | 26 | #include <media/v4l2-device.h> |
| 27 | #include <media/v4l2-subdev.h> | 27 | #include <media/v4l2-subdev.h> |
| 28 | #include <media/m5mols.h> | 28 | #include <media/m5mols.h> |
| 29 | #include <media/s5p_fimc.h> | 29 | #include <media/exynos-fimc.h> |
| 30 | 30 | ||
| 31 | #include "m5mols.h" | 31 | #include "m5mols.h" |
| 32 | #include "m5mols_reg.h" | 32 | #include "m5mols_reg.h" |
diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c index a9110d8bbbcd..2cace7313a22 100644 --- a/drivers/media/i2c/ml86v7667.c +++ b/drivers/media/i2c/ml86v7667.c | |||
| @@ -276,6 +276,7 @@ static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = { | |||
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| 278 | static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = { | 278 | static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = { |
| 279 | .s_std = ml86v7667_s_std, | ||
| 279 | .querystd = ml86v7667_querystd, | 280 | .querystd = ml86v7667_querystd, |
| 280 | .g_input_status = ml86v7667_g_input_status, | 281 | .g_input_status = ml86v7667_g_input_status, |
| 281 | .enum_mbus_fmt = ml86v7667_enum_mbus_fmt, | 282 | .enum_mbus_fmt = ml86v7667_enum_mbus_fmt, |
| @@ -286,7 +287,6 @@ static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = { | |||
| 286 | }; | 287 | }; |
| 287 | 288 | ||
| 288 | static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { | 289 | static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = { |
| 289 | .s_std = ml86v7667_s_std, | ||
| 290 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 290 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 291 | .g_register = ml86v7667_g_register, | 291 | .g_register = ml86v7667_g_register, |
| 292 | .s_register = ml86v7667_s_register, | 292 | .s_register = ml86v7667_s_register, |
diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index 8190fec68080..4d9c6bc34265 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c | |||
| @@ -649,10 +649,10 @@ static const struct v4l2_subdev_core_ops msp_core_ops = { | |||
| 649 | .s_ctrl = v4l2_subdev_s_ctrl, | 649 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 650 | .queryctrl = v4l2_subdev_queryctrl, | 650 | .queryctrl = v4l2_subdev_queryctrl, |
| 651 | .querymenu = v4l2_subdev_querymenu, | 651 | .querymenu = v4l2_subdev_querymenu, |
| 652 | .s_std = msp_s_std, | ||
| 653 | }; | 652 | }; |
| 654 | 653 | ||
| 655 | static const struct v4l2_subdev_video_ops msp_video_ops = { | 654 | static const struct v4l2_subdev_video_ops msp_video_ops = { |
| 655 | .s_std = msp_s_std, | ||
| 656 | .querystd = msp_querystd, | 656 | .querystd = msp_querystd, |
| 657 | }; | 657 | }; |
| 658 | 658 | ||
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 33daace81297..e18797ff7faf 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c | |||
| @@ -647,6 +647,28 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev, | |||
| 647 | #define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004) | 647 | #define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004) |
| 648 | #define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005) | 648 | #define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005) |
| 649 | 649 | ||
| 650 | static int mt9p031_restore_blc(struct mt9p031 *mt9p031) | ||
| 651 | { | ||
| 652 | struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); | ||
| 653 | int ret; | ||
| 654 | |||
| 655 | if (mt9p031->blc_auto->cur.val != 0) { | ||
| 656 | ret = mt9p031_set_mode2(mt9p031, 0, | ||
| 657 | MT9P031_READ_MODE_2_ROW_BLC); | ||
| 658 | if (ret < 0) | ||
| 659 | return ret; | ||
| 660 | } | ||
| 661 | |||
| 662 | if (mt9p031->blc_offset->cur.val != 0) { | ||
| 663 | ret = mt9p031_write(client, MT9P031_ROW_BLACK_TARGET, | ||
| 664 | mt9p031->blc_offset->cur.val); | ||
| 665 | if (ret < 0) | ||
| 666 | return ret; | ||
| 667 | } | ||
| 668 | |||
| 669 | return 0; | ||
| 670 | } | ||
| 671 | |||
| 650 | static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) | 672 | static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) |
| 651 | { | 673 | { |
| 652 | struct mt9p031 *mt9p031 = | 674 | struct mt9p031 *mt9p031 = |
| @@ -655,6 +677,9 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 655 | u16 data; | 677 | u16 data; |
| 656 | int ret; | 678 | int ret; |
| 657 | 679 | ||
| 680 | if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) | ||
| 681 | return 0; | ||
| 682 | |||
| 658 | switch (ctrl->id) { | 683 | switch (ctrl->id) { |
| 659 | case V4L2_CID_EXPOSURE: | 684 | case V4L2_CID_EXPOSURE: |
| 660 | ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER, | 685 | ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER, |
| @@ -709,18 +734,20 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 709 | MT9P031_READ_MODE_2_ROW_MIR, 0); | 734 | MT9P031_READ_MODE_2_ROW_MIR, 0); |
| 710 | 735 | ||
| 711 | case V4L2_CID_TEST_PATTERN: | 736 | case V4L2_CID_TEST_PATTERN: |
| 737 | /* The digital side of the Black Level Calibration function must | ||
| 738 | * be disabled when generating a test pattern to avoid artifacts | ||
| 739 | * in the image. Activate (deactivate) the BLC-related controls | ||
| 740 | * when the test pattern is enabled (disabled). | ||
| 741 | */ | ||
| 742 | v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0); | ||
| 743 | v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0); | ||
| 744 | |||
| 712 | if (!ctrl->val) { | 745 | if (!ctrl->val) { |
| 713 | /* Restore the black level compensation settings. */ | 746 | /* Restore the BLC settings. */ |
| 714 | if (mt9p031->blc_auto->cur.val != 0) { | 747 | ret = mt9p031_restore_blc(mt9p031); |
| 715 | ret = mt9p031_s_ctrl(mt9p031->blc_auto); | 748 | if (ret < 0) |
| 716 | if (ret < 0) | 749 | return ret; |
| 717 | return ret; | 750 | |
| 718 | } | ||
| 719 | if (mt9p031->blc_offset->cur.val != 0) { | ||
| 720 | ret = mt9p031_s_ctrl(mt9p031->blc_offset); | ||
| 721 | if (ret < 0) | ||
| 722 | return ret; | ||
| 723 | } | ||
| 724 | return mt9p031_write(client, MT9P031_TEST_PATTERN, | 751 | return mt9p031_write(client, MT9P031_TEST_PATTERN, |
| 725 | MT9P031_TEST_PATTERN_DISABLE); | 752 | MT9P031_TEST_PATTERN_DISABLE); |
| 726 | } | 753 | } |
| @@ -735,9 +762,7 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 735 | if (ret < 0) | 762 | if (ret < 0) |
| 736 | return ret; | 763 | return ret; |
| 737 | 764 | ||
| 738 | /* Disable digital black level compensation when using a test | 765 | /* Disable digital BLC when generating a test pattern. */ |
| 739 | * pattern. | ||
| 740 | */ | ||
| 741 | ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC, | 766 | ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC, |
| 742 | 0); | 767 | 0); |
| 743 | if (ret < 0) | 768 | if (ret < 0) |
diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index 8272c0b9c5bf..04e9e55018a5 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c | |||
| @@ -643,10 +643,10 @@ static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = { | |||
| 643 | 643 | ||
| 644 | static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { | 644 | static const struct v4l2_subdev_core_ops saa6752hs_core_ops = { |
| 645 | .init = saa6752hs_init, | 645 | .init = saa6752hs_init, |
| 646 | .s_std = saa6752hs_s_std, | ||
| 647 | }; | 646 | }; |
| 648 | 647 | ||
| 649 | static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { | 648 | static const struct v4l2_subdev_video_ops saa6752hs_video_ops = { |
| 649 | .s_std = saa6752hs_s_std, | ||
| 650 | .s_mbus_fmt = saa6752hs_s_mbus_fmt, | 650 | .s_mbus_fmt = saa6752hs_s_mbus_fmt, |
| 651 | .try_mbus_fmt = saa6752hs_try_mbus_fmt, | 651 | .try_mbus_fmt = saa6752hs_try_mbus_fmt, |
| 652 | .g_mbus_fmt = saa6752hs_g_mbus_fmt, | 652 | .g_mbus_fmt = saa6752hs_g_mbus_fmt, |
diff --git a/drivers/media/i2c/saa7110.c b/drivers/media/i2c/saa7110.c index ac43e929a1d6..99689ee57d7e 100644 --- a/drivers/media/i2c/saa7110.c +++ b/drivers/media/i2c/saa7110.c | |||
| @@ -365,10 +365,10 @@ static const struct v4l2_subdev_core_ops saa7110_core_ops = { | |||
| 365 | .s_ctrl = v4l2_subdev_s_ctrl, | 365 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 366 | .queryctrl = v4l2_subdev_queryctrl, | 366 | .queryctrl = v4l2_subdev_queryctrl, |
| 367 | .querymenu = v4l2_subdev_querymenu, | 367 | .querymenu = v4l2_subdev_querymenu, |
| 368 | .s_std = saa7110_s_std, | ||
| 369 | }; | 368 | }; |
| 370 | 369 | ||
| 371 | static const struct v4l2_subdev_video_ops saa7110_video_ops = { | 370 | static const struct v4l2_subdev_video_ops saa7110_video_ops = { |
| 371 | .s_std = saa7110_s_std, | ||
| 372 | .s_routing = saa7110_s_routing, | 372 | .s_routing = saa7110_s_routing, |
| 373 | .s_stream = saa7110_s_stream, | 373 | .s_stream = saa7110_s_stream, |
| 374 | .querystd = saa7110_querystd, | 374 | .querystd = saa7110_querystd, |
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index afdbcb045cee..35a44648150e 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c | |||
| @@ -1582,7 +1582,6 @@ static const struct v4l2_subdev_core_ops saa711x_core_ops = { | |||
| 1582 | .s_ctrl = v4l2_subdev_s_ctrl, | 1582 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 1583 | .queryctrl = v4l2_subdev_queryctrl, | 1583 | .queryctrl = v4l2_subdev_queryctrl, |
| 1584 | .querymenu = v4l2_subdev_querymenu, | 1584 | .querymenu = v4l2_subdev_querymenu, |
| 1585 | .s_std = saa711x_s_std, | ||
| 1586 | .reset = saa711x_reset, | 1585 | .reset = saa711x_reset, |
| 1587 | .s_gpio = saa711x_s_gpio, | 1586 | .s_gpio = saa711x_s_gpio, |
| 1588 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1587 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| @@ -1601,6 +1600,7 @@ static const struct v4l2_subdev_audio_ops saa711x_audio_ops = { | |||
| 1601 | }; | 1600 | }; |
| 1602 | 1601 | ||
| 1603 | static const struct v4l2_subdev_video_ops saa711x_video_ops = { | 1602 | static const struct v4l2_subdev_video_ops saa711x_video_ops = { |
| 1603 | .s_std = saa711x_s_std, | ||
| 1604 | .s_routing = saa711x_s_routing, | 1604 | .s_routing = saa711x_s_routing, |
| 1605 | .s_crystal_freq = saa711x_s_crystal_freq, | 1605 | .s_crystal_freq = saa711x_s_crystal_freq, |
| 1606 | .s_mbus_fmt = saa711x_s_mbus_fmt, | 1606 | .s_mbus_fmt = saa711x_s_mbus_fmt, |
diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index 401ca114ab99..6922a9f9a5cd 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c | |||
| @@ -1198,7 +1198,6 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = { | |||
| 1198 | .g_register = saa717x_g_register, | 1198 | .g_register = saa717x_g_register, |
| 1199 | .s_register = saa717x_s_register, | 1199 | .s_register = saa717x_s_register, |
| 1200 | #endif | 1200 | #endif |
| 1201 | .s_std = saa717x_s_std, | ||
| 1202 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, | 1201 | .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, |
| 1203 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, | 1202 | .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, |
| 1204 | .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, | 1203 | .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, |
| @@ -1216,6 +1215,7 @@ static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = { | |||
| 1216 | }; | 1215 | }; |
| 1217 | 1216 | ||
| 1218 | static const struct v4l2_subdev_video_ops saa717x_video_ops = { | 1217 | static const struct v4l2_subdev_video_ops saa717x_video_ops = { |
| 1218 | .s_std = saa717x_s_std, | ||
| 1219 | .s_routing = saa717x_s_video_routing, | 1219 | .s_routing = saa717x_s_video_routing, |
| 1220 | .s_mbus_fmt = saa717x_s_mbus_fmt, | 1220 | .s_mbus_fmt = saa717x_s_mbus_fmt, |
| 1221 | .s_stream = saa717x_s_stream, | 1221 | .s_stream = saa717x_s_stream, |
diff --git a/drivers/media/i2c/saa7191.c b/drivers/media/i2c/saa7191.c index 606a4baf944d..8e9699268a63 100644 --- a/drivers/media/i2c/saa7191.c +++ b/drivers/media/i2c/saa7191.c | |||
| @@ -573,10 +573,10 @@ static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status) | |||
| 573 | static const struct v4l2_subdev_core_ops saa7191_core_ops = { | 573 | static const struct v4l2_subdev_core_ops saa7191_core_ops = { |
| 574 | .g_ctrl = saa7191_g_ctrl, | 574 | .g_ctrl = saa7191_g_ctrl, |
| 575 | .s_ctrl = saa7191_s_ctrl, | 575 | .s_ctrl = saa7191_s_ctrl, |
| 576 | .s_std = saa7191_s_std, | ||
| 577 | }; | 576 | }; |
| 578 | 577 | ||
| 579 | static const struct v4l2_subdev_video_ops saa7191_video_ops = { | 578 | static const struct v4l2_subdev_video_ops saa7191_video_ops = { |
| 579 | .s_std = saa7191_s_std, | ||
| 580 | .s_routing = saa7191_s_routing, | 580 | .s_routing = saa7191_s_routing, |
| 581 | .querystd = saa7191_querystd, | 581 | .querystd = saa7191_querystd, |
| 582 | .g_input_status = saa7191_g_input_status, | 582 | .g_input_status = saa7191_g_input_status, |
diff --git a/drivers/media/i2c/smiapp-pll.h b/drivers/media/i2c/smiapp-pll.h index a4a649834a18..5ce2b61da3c5 100644 --- a/drivers/media/i2c/smiapp-pll.h +++ b/drivers/media/i2c/smiapp-pll.h | |||
| @@ -46,7 +46,7 @@ struct smiapp_pll { | |||
| 46 | uint8_t bus_width; | 46 | uint8_t bus_width; |
| 47 | } parallel; | 47 | } parallel; |
| 48 | }; | 48 | }; |
| 49 | uint8_t flags; | 49 | unsigned long flags; |
| 50 | uint8_t binning_horizontal; | 50 | uint8_t binning_horizontal; |
| 51 | uint8_t binning_vertical; | 51 | uint8_t binning_vertical; |
| 52 | uint8_t scale_m; | 52 | uint8_t scale_m; |
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 8741cae9c9f2..06fb03291d59 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c | |||
| @@ -606,7 +606,7 @@ static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit, | |||
| 606 | if (rval) | 606 | if (rval) |
| 607 | return rval; | 607 | return rval; |
| 608 | sensor->limits[limit[i]] = val; | 608 | sensor->limits[limit[i]] = val; |
| 609 | dev_dbg(&client->dev, "0x%8.8x \"%s\" = %d, 0x%x\n", | 609 | dev_dbg(&client->dev, "0x%8.8x \"%s\" = %u, 0x%x\n", |
| 610 | smiapp_reg_limits[limit[i]].addr, | 610 | smiapp_reg_limits[limit[i]].addr, |
| 611 | smiapp_reg_limits[limit[i]].what, val, val); | 611 | smiapp_reg_limits[limit[i]].what, val, val); |
| 612 | } | 612 | } |
| @@ -741,8 +741,8 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) | |||
| 741 | if (rval) | 741 | if (rval) |
| 742 | return rval; | 742 | return rval; |
| 743 | 743 | ||
| 744 | dev_dbg(&client->dev, "bpp %d, compressed %d\n", | 744 | dev_dbg(&client->dev, "%u: bpp %u, compressed %u\n", |
| 745 | fmt >> 8, (u8)fmt); | 745 | i, fmt >> 8, (u8)fmt); |
| 746 | 746 | ||
| 747 | for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) { | 747 | for (j = 0; j < ARRAY_SIZE(smiapp_csi_data_formats); j++) { |
| 748 | const struct smiapp_csi_data_format *f = | 748 | const struct smiapp_csi_data_format *f = |
| @@ -1128,7 +1128,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) | |||
| 1128 | } | 1128 | } |
| 1129 | usleep_range(1000, 1000); | 1129 | usleep_range(1000, 1000); |
| 1130 | 1130 | ||
| 1131 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 1131 | if (gpio_is_valid(sensor->platform_data->xshutdown)) |
| 1132 | gpio_set_value(sensor->platform_data->xshutdown, 1); | 1132 | gpio_set_value(sensor->platform_data->xshutdown, 1); |
| 1133 | 1133 | ||
| 1134 | sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk); | 1134 | sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk); |
| @@ -1238,7 +1238,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) | |||
| 1238 | return 0; | 1238 | return 0; |
| 1239 | 1239 | ||
| 1240 | out_cci_addr_fail: | 1240 | out_cci_addr_fail: |
| 1241 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 1241 | if (gpio_is_valid(sensor->platform_data->xshutdown)) |
| 1242 | gpio_set_value(sensor->platform_data->xshutdown, 0); | 1242 | gpio_set_value(sensor->platform_data->xshutdown, 0); |
| 1243 | if (sensor->platform_data->set_xclk) | 1243 | if (sensor->platform_data->set_xclk) |
| 1244 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | 1244 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); |
| @@ -1264,7 +1264,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor) | |||
| 1264 | SMIAPP_REG_U8_SOFTWARE_RESET, | 1264 | SMIAPP_REG_U8_SOFTWARE_RESET, |
| 1265 | SMIAPP_SOFTWARE_RESET); | 1265 | SMIAPP_SOFTWARE_RESET); |
| 1266 | 1266 | ||
| 1267 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 1267 | if (gpio_is_valid(sensor->platform_data->xshutdown)) |
| 1268 | gpio_set_value(sensor->platform_data->xshutdown, 0); | 1268 | gpio_set_value(sensor->platform_data->xshutdown, 0); |
| 1269 | if (sensor->platform_data->set_xclk) | 1269 | if (sensor->platform_data->set_xclk) |
| 1270 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | 1270 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); |
| @@ -1766,7 +1766,7 @@ static void smiapp_set_compose_binner(struct v4l2_subdev *subdev, | |||
| 1766 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); | 1766 | struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); |
| 1767 | unsigned int i; | 1767 | unsigned int i; |
| 1768 | unsigned int binh = 1, binv = 1; | 1768 | unsigned int binh = 1, binv = 1; |
| 1769 | unsigned int best = scaling_goodness( | 1769 | int best = scaling_goodness( |
| 1770 | subdev, | 1770 | subdev, |
| 1771 | crops[SMIAPP_PAD_SINK]->width, sel->r.width, | 1771 | crops[SMIAPP_PAD_SINK]->width, sel->r.width, |
| 1772 | crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags); | 1772 | crops[SMIAPP_PAD_SINK]->height, sel->r.height, sel->flags); |
| @@ -2355,17 +2355,17 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
| 2355 | unsigned int i; | 2355 | unsigned int i; |
| 2356 | int rval; | 2356 | int rval; |
| 2357 | 2357 | ||
| 2358 | sensor->vana = devm_regulator_get(&client->dev, "VANA"); | 2358 | sensor->vana = devm_regulator_get(&client->dev, "vana"); |
| 2359 | if (IS_ERR(sensor->vana)) { | 2359 | if (IS_ERR(sensor->vana)) { |
| 2360 | dev_err(&client->dev, "could not get regulator for vana\n"); | 2360 | dev_err(&client->dev, "could not get regulator for vana\n"); |
| 2361 | return -ENODEV; | 2361 | return PTR_ERR(sensor->vana); |
| 2362 | } | 2362 | } |
| 2363 | 2363 | ||
| 2364 | if (!sensor->platform_data->set_xclk) { | 2364 | if (!sensor->platform_data->set_xclk) { |
| 2365 | sensor->ext_clk = devm_clk_get(&client->dev, "ext_clk"); | 2365 | sensor->ext_clk = devm_clk_get(&client->dev, "ext_clk"); |
| 2366 | if (IS_ERR(sensor->ext_clk)) { | 2366 | if (IS_ERR(sensor->ext_clk)) { |
| 2367 | dev_err(&client->dev, "could not get clock\n"); | 2367 | dev_err(&client->dev, "could not get clock\n"); |
| 2368 | return -ENODEV; | 2368 | return PTR_ERR(sensor->ext_clk); |
| 2369 | } | 2369 | } |
| 2370 | 2370 | ||
| 2371 | rval = clk_set_rate(sensor->ext_clk, | 2371 | rval = clk_set_rate(sensor->ext_clk, |
| @@ -2374,18 +2374,19 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
| 2374 | dev_err(&client->dev, | 2374 | dev_err(&client->dev, |
| 2375 | "unable to set clock freq to %u\n", | 2375 | "unable to set clock freq to %u\n", |
| 2376 | sensor->platform_data->ext_clk); | 2376 | sensor->platform_data->ext_clk); |
| 2377 | return -ENODEV; | 2377 | return rval; |
| 2378 | } | 2378 | } |
| 2379 | } | 2379 | } |
| 2380 | 2380 | ||
| 2381 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) { | 2381 | if (gpio_is_valid(sensor->platform_data->xshutdown)) { |
| 2382 | if (devm_gpio_request_one(&client->dev, | 2382 | rval = devm_gpio_request_one( |
| 2383 | sensor->platform_data->xshutdown, 0, | 2383 | &client->dev, sensor->platform_data->xshutdown, 0, |
| 2384 | "SMIA++ xshutdown") != 0) { | 2384 | "SMIA++ xshutdown"); |
| 2385 | if (rval < 0) { | ||
| 2385 | dev_err(&client->dev, | 2386 | dev_err(&client->dev, |
| 2386 | "unable to acquire reset gpio %d\n", | 2387 | "unable to acquire reset gpio %d\n", |
| 2387 | sensor->platform_data->xshutdown); | 2388 | sensor->platform_data->xshutdown); |
| 2388 | return -ENODEV; | 2389 | return rval; |
| 2389 | } | 2390 | } |
| 2390 | } | 2391 | } |
| 2391 | 2392 | ||
| @@ -2423,6 +2424,12 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
| 2423 | sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP | | 2424 | sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP | |
| 2424 | SMIAPP_IMAGE_ORIENTATION_VFLIP; | 2425 | SMIAPP_IMAGE_ORIENTATION_VFLIP; |
| 2425 | 2426 | ||
| 2427 | rval = smiapp_call_quirk(sensor, limits); | ||
| 2428 | if (rval) { | ||
| 2429 | dev_err(&client->dev, "limits quirks failed\n"); | ||
| 2430 | goto out_power_off; | ||
| 2431 | } | ||
| 2432 | |||
| 2426 | rval = smiapp_get_mbus_formats(sensor); | 2433 | rval = smiapp_get_mbus_formats(sensor); |
| 2427 | if (rval) { | 2434 | if (rval) { |
| 2428 | rval = -ENODEV; | 2435 | rval = -ENODEV; |
| @@ -2483,12 +2490,6 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
| 2483 | } | 2490 | } |
| 2484 | } | 2491 | } |
| 2485 | 2492 | ||
| 2486 | rval = smiapp_call_quirk(sensor, limits); | ||
| 2487 | if (rval) { | ||
| 2488 | dev_err(&client->dev, "limits quirks failed\n"); | ||
| 2489 | goto out_nvm_release; | ||
| 2490 | } | ||
| 2491 | |||
| 2492 | /* We consider this as profile 0 sensor if any of these are zero. */ | 2493 | /* We consider this as profile 0 sensor if any of these are zero. */ |
| 2493 | if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] || | 2494 | if (!sensor->limits[SMIAPP_LIMIT_MIN_OP_SYS_CLK_DIV] || |
| 2494 | !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] || | 2495 | !sensor->limits[SMIAPP_LIMIT_MAX_OP_SYS_CLK_DIV] || |
| @@ -2543,8 +2544,9 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
| 2543 | } | 2544 | } |
| 2544 | 2545 | ||
| 2545 | snprintf(this->sd.name, | 2546 | snprintf(this->sd.name, |
| 2546 | sizeof(this->sd.name), "%s %s", | 2547 | sizeof(this->sd.name), "%s %d-%4.4x %s", |
| 2547 | sensor->minfo.name, _this->name); | 2548 | sensor->minfo.name, i2c_adapter_id(client->adapter), |
| 2549 | client->addr, _this->name); | ||
| 2548 | 2550 | ||
| 2549 | this->sink_fmt.width = | 2551 | this->sink_fmt.width = |
| 2550 | sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; | 2552 | sensor->limits[SMIAPP_LIMIT_X_ADDR_MAX] + 1; |
| @@ -2616,12 +2618,11 @@ static int smiapp_registered(struct v4l2_subdev *subdev) | |||
| 2616 | pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; | 2618 | pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; |
| 2617 | pll->csi2.lanes = sensor->platform_data->lanes; | 2619 | pll->csi2.lanes = sensor->platform_data->lanes; |
| 2618 | pll->ext_clk_freq_hz = sensor->platform_data->ext_clk; | 2620 | pll->ext_clk_freq_hz = sensor->platform_data->ext_clk; |
| 2621 | pll->flags = smiapp_call_quirk(sensor, pll_flags); | ||
| 2622 | |||
| 2619 | /* Profile 0 sensors have no separate OP clock branch. */ | 2623 | /* Profile 0 sensors have no separate OP clock branch. */ |
| 2620 | if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) | 2624 | if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) |
| 2621 | pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; | 2625 | pll->flags |= SMIAPP_PLL_FLAG_NO_OP_CLOCKS; |
| 2622 | if (smiapp_needs_quirk(sensor, | ||
| 2623 | SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE)) | ||
| 2624 | pll->flags |= SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE; | ||
| 2625 | pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; | 2626 | pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; |
| 2626 | 2627 | ||
| 2627 | rval = smiapp_update_mode(sensor); | 2628 | rval = smiapp_update_mode(sensor); |
| @@ -2830,7 +2831,7 @@ static int smiapp_remove(struct i2c_client *client) | |||
| 2830 | unsigned int i; | 2831 | unsigned int i; |
| 2831 | 2832 | ||
| 2832 | if (sensor->power_count) { | 2833 | if (sensor->power_count) { |
| 2833 | if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) | 2834 | if (gpio_is_valid(sensor->platform_data->xshutdown)) |
| 2834 | gpio_set_value(sensor->platform_data->xshutdown, 0); | 2835 | gpio_set_value(sensor->platform_data->xshutdown, 0); |
| 2835 | if (sensor->platform_data->set_xclk) | 2836 | if (sensor->platform_data->set_xclk) |
| 2836 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); | 2837 | sensor->platform_data->set_xclk(&sensor->src->sd, 0); |
diff --git a/drivers/media/i2c/smiapp/smiapp-quirk.c b/drivers/media/i2c/smiapp/smiapp-quirk.c index bb8c506e0e3d..e0bee8752122 100644 --- a/drivers/media/i2c/smiapp/smiapp-quirk.c +++ b/drivers/media/i2c/smiapp/smiapp-quirk.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val) | 29 | static int smiapp_write_8(struct smiapp_sensor *sensor, u16 reg, u8 val) |
| 30 | { | 30 | { |
| 31 | return smiapp_write(sensor, (SMIA_REG_8BIT << 16) | reg, val); | 31 | return smiapp_write(sensor, SMIAPP_REG_MK_U8(reg), val); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | static int smiapp_write_8s(struct smiapp_sensor *sensor, | 34 | static int smiapp_write_8s(struct smiapp_sensor *sensor, |
| @@ -61,52 +61,6 @@ void smiapp_replace_limit(struct smiapp_sensor *sensor, | |||
| 61 | sensor->limits[limit] = val; | 61 | sensor->limits[limit] = val; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | bool smiapp_quirk_reg(struct smiapp_sensor *sensor, | ||
| 65 | u32 reg, u32 *val) | ||
| 66 | { | ||
| 67 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); | ||
| 68 | const struct smia_reg *sreg; | ||
| 69 | |||
| 70 | if (!sensor->minfo.quirk) | ||
| 71 | return false; | ||
| 72 | |||
| 73 | sreg = sensor->minfo.quirk->regs; | ||
| 74 | |||
| 75 | if (!sreg) | ||
| 76 | return false; | ||
| 77 | |||
| 78 | while (sreg->type) { | ||
| 79 | u16 type = reg >> 16; | ||
| 80 | u16 reg16 = reg; | ||
| 81 | |||
| 82 | if (sreg->type != type || sreg->reg != reg16) { | ||
| 83 | sreg++; | ||
| 84 | continue; | ||
| 85 | } | ||
| 86 | |||
| 87 | switch ((u8)type) { | ||
| 88 | case SMIA_REG_8BIT: | ||
| 89 | dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%2.2x\n", | ||
| 90 | reg, sreg->val); | ||
| 91 | break; | ||
| 92 | case SMIA_REG_16BIT: | ||
| 93 | dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%4.4x\n", | ||
| 94 | reg, sreg->val); | ||
| 95 | break; | ||
| 96 | case SMIA_REG_32BIT: | ||
| 97 | dev_dbg(&client->dev, "quirk: 0x%8.8x: 0x%8.8x\n", | ||
| 98 | reg, sreg->val); | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | |||
| 102 | *val = sreg->val; | ||
| 103 | |||
| 104 | return true; | ||
| 105 | } | ||
| 106 | |||
| 107 | return false; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int jt8ew9_limits(struct smiapp_sensor *sensor) | 64 | static int jt8ew9_limits(struct smiapp_sensor *sensor) |
| 111 | { | 65 | { |
| 112 | if (sensor->minfo.revision_number_major < 0x03) | 66 | if (sensor->minfo.revision_number_major < 0x03) |
| @@ -266,12 +220,17 @@ static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor) | |||
| 266 | return smiapp_write_8(sensor, 0x3328, 0x80); | 220 | return smiapp_write_8(sensor, 0x3328, 0x80); |
| 267 | } | 221 | } |
| 268 | 222 | ||
| 223 | static unsigned long jt8ev1_pll_flags(struct smiapp_sensor *sensor) | ||
| 224 | { | ||
| 225 | return SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE; | ||
| 226 | } | ||
| 227 | |||
| 269 | const struct smiapp_quirk smiapp_jt8ev1_quirk = { | 228 | const struct smiapp_quirk smiapp_jt8ev1_quirk = { |
| 270 | .limits = jt8ev1_limits, | 229 | .limits = jt8ev1_limits, |
| 271 | .post_poweron = jt8ev1_post_poweron, | 230 | .post_poweron = jt8ev1_post_poweron, |
| 272 | .pre_streamon = jt8ev1_pre_streamon, | 231 | .pre_streamon = jt8ev1_pre_streamon, |
| 273 | .post_streamoff = jt8ev1_post_streamoff, | 232 | .post_streamoff = jt8ev1_post_streamoff, |
| 274 | .flags = SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE, | 233 | .pll_flags = jt8ev1_pll_flags, |
| 275 | }; | 234 | }; |
| 276 | 235 | ||
| 277 | static int tcm8500md_limits(struct smiapp_sensor *sensor) | 236 | static int tcm8500md_limits(struct smiapp_sensor *sensor) |
diff --git a/drivers/media/i2c/smiapp/smiapp-quirk.h b/drivers/media/i2c/smiapp/smiapp-quirk.h index 504a6d80ced5..46e9ea8bfa08 100644 --- a/drivers/media/i2c/smiapp/smiapp-quirk.h +++ b/drivers/media/i2c/smiapp/smiapp-quirk.h | |||
| @@ -35,19 +35,30 @@ struct smiapp_sensor; | |||
| 35 | * @post_poweron: Called always after the sensor has been fully powered on. | 35 | * @post_poweron: Called always after the sensor has been fully powered on. |
| 36 | * @pre_streamon: Called just before streaming is enabled. | 36 | * @pre_streamon: Called just before streaming is enabled. |
| 37 | * @post_streamon: Called right after stopping streaming. | 37 | * @post_streamon: Called right after stopping streaming. |
| 38 | * @reg_access: Register access quirk. The quirk may divert the access | ||
| 39 | * to another register, or no register at all. | ||
| 40 | * | ||
| 41 | * @write: Is this read (false) or write (true) access? | ||
| 42 | * @reg: Pointer to the register to access | ||
| 43 | * @value: Register value, set by the caller on write, or | ||
| 44 | * by the quirk on read | ||
| 45 | * | ||
| 46 | * @return: 0 on success, -ENOIOCTLCMD if no register | ||
| 47 | * access may be done by the caller (default read | ||
| 48 | * value is zero), else negative error code on error | ||
| 38 | */ | 49 | */ |
| 39 | struct smiapp_quirk { | 50 | struct smiapp_quirk { |
| 40 | int (*limits)(struct smiapp_sensor *sensor); | 51 | int (*limits)(struct smiapp_sensor *sensor); |
| 41 | int (*post_poweron)(struct smiapp_sensor *sensor); | 52 | int (*post_poweron)(struct smiapp_sensor *sensor); |
| 42 | int (*pre_streamon)(struct smiapp_sensor *sensor); | 53 | int (*pre_streamon)(struct smiapp_sensor *sensor); |
| 43 | int (*post_streamoff)(struct smiapp_sensor *sensor); | 54 | int (*post_streamoff)(struct smiapp_sensor *sensor); |
| 44 | const struct smia_reg *regs; | 55 | unsigned long (*pll_flags)(struct smiapp_sensor *sensor); |
| 56 | int (*reg_access)(struct smiapp_sensor *sensor, bool write, u32 *reg, | ||
| 57 | u32 *val); | ||
| 45 | unsigned long flags; | 58 | unsigned long flags; |
| 46 | }; | 59 | }; |
| 47 | 60 | ||
| 48 | /* op pix clock is for all lanes in total normally */ | 61 | #define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY (1 << 0) |
| 49 | #define SMIAPP_QUIRK_FLAG_OP_PIX_CLOCK_PER_LANE (1 << 0) | ||
| 50 | #define SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY (1 << 1) | ||
| 51 | 62 | ||
| 52 | struct smiapp_reg_8 { | 63 | struct smiapp_reg_8 { |
| 53 | u16 reg; | 64 | u16 reg; |
| @@ -56,12 +67,9 @@ struct smiapp_reg_8 { | |||
| 56 | 67 | ||
| 57 | void smiapp_replace_limit(struct smiapp_sensor *sensor, | 68 | void smiapp_replace_limit(struct smiapp_sensor *sensor, |
| 58 | u32 limit, u32 val); | 69 | u32 limit, u32 val); |
| 59 | bool smiapp_quirk_reg(struct smiapp_sensor *sensor, | ||
| 60 | u32 reg, u32 *val); | ||
| 61 | 70 | ||
| 62 | #define SMIAPP_MK_QUIRK_REG(_reg, _val) \ | 71 | #define SMIAPP_MK_QUIRK_REG_8(_reg, _val) \ |
| 63 | { \ | 72 | { \ |
| 64 | .type = (_reg >> 16), \ | ||
| 65 | .reg = (u16)_reg, \ | 73 | .reg = (u16)_reg, \ |
| 66 | .val = _val, \ | 74 | .val = _val, \ |
| 67 | } | 75 | } |
diff --git a/drivers/media/i2c/smiapp/smiapp-reg-defs.h b/drivers/media/i2c/smiapp/smiapp-reg-defs.h index 3aa0ca948d87..c488ef028074 100644 --- a/drivers/media/i2c/smiapp/smiapp-reg-defs.h +++ b/drivers/media/i2c/smiapp/smiapp-reg-defs.h | |||
| @@ -21,11 +21,11 @@ | |||
| 21 | * 02110-1301 USA | 21 | * 02110-1301 USA |
| 22 | * | 22 | * |
| 23 | */ | 23 | */ |
| 24 | #define SMIAPP_REG_MK_U8(r) ((SMIA_REG_8BIT << 16) | (r)) | 24 | #define SMIAPP_REG_MK_U8(r) ((SMIAPP_REG_8BIT << 16) | (r)) |
| 25 | #define SMIAPP_REG_MK_U16(r) ((SMIA_REG_16BIT << 16) | (r)) | 25 | #define SMIAPP_REG_MK_U16(r) ((SMIAPP_REG_16BIT << 16) | (r)) |
| 26 | #define SMIAPP_REG_MK_U32(r) ((SMIA_REG_32BIT << 16) | (r)) | 26 | #define SMIAPP_REG_MK_U32(r) ((SMIAPP_REG_32BIT << 16) | (r)) |
| 27 | 27 | ||
| 28 | #define SMIAPP_REG_MK_F32(r) (SMIA_REG_FLAG_FLOAT | (SMIA_REG_32BIT << 16) | (r)) | 28 | #define SMIAPP_REG_MK_F32(r) (SMIAPP_REG_FLAG_FLOAT | (SMIAPP_REG_32BIT << 16) | (r)) |
| 29 | 29 | ||
| 30 | #define SMIAPP_REG_U16_MODEL_ID SMIAPP_REG_MK_U16(0x0000) | 30 | #define SMIAPP_REG_U16_MODEL_ID SMIAPP_REG_MK_U16(0x0000) |
| 31 | #define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR SMIAPP_REG_MK_U8(0x0002) | 31 | #define SMIAPP_REG_U8_REVISION_NUMBER_MAJOR SMIAPP_REG_MK_U8(0x0002) |
diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c index 4fac32cfcb3f..a2098007fb70 100644 --- a/drivers/media/i2c/smiapp/smiapp-regs.c +++ b/drivers/media/i2c/smiapp/smiapp-regs.c | |||
| @@ -114,14 +114,14 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg, | |||
| 114 | *val = 0; | 114 | *val = 0; |
| 115 | /* high byte comes first */ | 115 | /* high byte comes first */ |
| 116 | switch (len) { | 116 | switch (len) { |
| 117 | case SMIA_REG_32BIT: | 117 | case SMIAPP_REG_32BIT: |
| 118 | *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + | 118 | *val = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + |
| 119 | data[3]; | 119 | data[3]; |
| 120 | break; | 120 | break; |
| 121 | case SMIA_REG_16BIT: | 121 | case SMIAPP_REG_16BIT: |
| 122 | *val = (data[0] << 8) + data[1]; | 122 | *val = (data[0] << 8) + data[1]; |
| 123 | break; | 123 | break; |
| 124 | case SMIA_REG_8BIT: | 124 | case SMIAPP_REG_8BIT: |
| 125 | *val = data[0]; | 125 | *val = data[0]; |
| 126 | break; | 126 | break; |
| 127 | default: | 127 | default: |
| @@ -165,31 +165,28 @@ static int __smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val, | |||
| 165 | bool only8) | 165 | bool only8) |
| 166 | { | 166 | { |
| 167 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); | 167 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); |
| 168 | unsigned int len = (u8)(reg >> 16); | 168 | u8 len = SMIAPP_REG_WIDTH(reg); |
| 169 | int rval; | 169 | int rval; |
| 170 | 170 | ||
| 171 | if (len != SMIA_REG_8BIT && len != SMIA_REG_16BIT | 171 | if (len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT |
| 172 | && len != SMIA_REG_32BIT) | 172 | && len != SMIAPP_REG_32BIT) |
| 173 | return -EINVAL; | 173 | return -EINVAL; |
| 174 | 174 | ||
| 175 | if (smiapp_quirk_reg(sensor, reg, val)) | 175 | if (len == SMIAPP_REG_8BIT || !only8) |
| 176 | goto found_quirk; | 176 | rval = ____smiapp_read(sensor, SMIAPP_REG_ADDR(reg), len, val); |
| 177 | |||
| 178 | if (len == SMIA_REG_8BIT && !only8) | ||
| 179 | rval = ____smiapp_read(sensor, (u16)reg, len, val); | ||
| 180 | else | 177 | else |
| 181 | rval = ____smiapp_read_8only(sensor, (u16)reg, len, val); | 178 | rval = ____smiapp_read_8only(sensor, SMIAPP_REG_ADDR(reg), len, |
| 179 | val); | ||
| 182 | if (rval < 0) | 180 | if (rval < 0) |
| 183 | return rval; | 181 | return rval; |
| 184 | 182 | ||
| 185 | found_quirk: | 183 | if (reg & SMIAPP_REG_FLAG_FLOAT) |
| 186 | if (reg & SMIA_REG_FLAG_FLOAT) | ||
| 187 | *val = float_to_u32_mul_1000000(client, *val); | 184 | *val = float_to_u32_mul_1000000(client, *val); |
| 188 | 185 | ||
| 189 | return 0; | 186 | return 0; |
| 190 | } | 187 | } |
| 191 | 188 | ||
| 192 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) | 189 | int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val) |
| 193 | { | 190 | { |
| 194 | return __smiapp_read( | 191 | return __smiapp_read( |
| 195 | sensor, reg, val, | 192 | sensor, reg, val, |
| @@ -197,28 +194,47 @@ int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) | |||
| 197 | SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY)); | 194 | SMIAPP_QUIRK_FLAG_8BIT_READ_ONLY)); |
| 198 | } | 195 | } |
| 199 | 196 | ||
| 197 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val) | ||
| 198 | { | ||
| 199 | int rval; | ||
| 200 | |||
| 201 | *val = 0; | ||
| 202 | rval = smiapp_call_quirk(sensor, reg_access, false, ®, val); | ||
| 203 | if (rval == -ENOIOCTLCMD) | ||
| 204 | return 0; | ||
| 205 | if (rval < 0) | ||
| 206 | return rval; | ||
| 207 | |||
| 208 | return smiapp_read_no_quirk(sensor, reg, val); | ||
| 209 | } | ||
| 210 | |||
| 200 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val) | 211 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val) |
| 201 | { | 212 | { |
| 213 | int rval; | ||
| 214 | |||
| 215 | *val = 0; | ||
| 216 | rval = smiapp_call_quirk(sensor, reg_access, false, ®, val); | ||
| 217 | if (rval == -ENOIOCTLCMD) | ||
| 218 | return 0; | ||
| 219 | if (rval < 0) | ||
| 220 | return rval; | ||
| 221 | |||
| 202 | return __smiapp_read(sensor, reg, val, true); | 222 | return __smiapp_read(sensor, reg, val, true); |
| 203 | } | 223 | } |
| 204 | 224 | ||
| 205 | /* | 225 | int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) |
| 206 | * Write to a 8/16-bit register. | ||
| 207 | * Returns zero if successful, or non-zero otherwise. | ||
| 208 | */ | ||
| 209 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | ||
| 210 | { | 226 | { |
| 211 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); | 227 | struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); |
| 212 | struct i2c_msg msg; | 228 | struct i2c_msg msg; |
| 213 | unsigned char data[6]; | 229 | unsigned char data[6]; |
| 214 | unsigned int retries; | 230 | unsigned int retries; |
| 215 | unsigned int flags = reg >> 24; | 231 | u8 flags = SMIAPP_REG_FLAGS(reg); |
| 216 | unsigned int len = (u8)(reg >> 16); | 232 | u8 len = SMIAPP_REG_WIDTH(reg); |
| 217 | u16 offset = reg; | 233 | u16 offset = SMIAPP_REG_ADDR(reg); |
| 218 | int r; | 234 | int r; |
| 219 | 235 | ||
| 220 | if ((len != SMIA_REG_8BIT && len != SMIA_REG_16BIT && | 236 | if ((len != SMIAPP_REG_8BIT && len != SMIAPP_REG_16BIT && |
| 221 | len != SMIA_REG_32BIT) || flags) | 237 | len != SMIAPP_REG_32BIT) || flags) |
| 222 | return -EINVAL; | 238 | return -EINVAL; |
| 223 | 239 | ||
| 224 | msg.addr = client->addr; | 240 | msg.addr = client->addr; |
| @@ -231,14 +247,14 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | |||
| 231 | data[1] = (u8) (reg & 0xff); | 247 | data[1] = (u8) (reg & 0xff); |
| 232 | 248 | ||
| 233 | switch (len) { | 249 | switch (len) { |
| 234 | case SMIA_REG_8BIT: | 250 | case SMIAPP_REG_8BIT: |
| 235 | data[2] = val; | 251 | data[2] = val; |
| 236 | break; | 252 | break; |
| 237 | case SMIA_REG_16BIT: | 253 | case SMIAPP_REG_16BIT: |
| 238 | data[2] = val >> 8; | 254 | data[2] = val >> 8; |
| 239 | data[3] = val; | 255 | data[3] = val; |
| 240 | break; | 256 | break; |
| 241 | case SMIA_REG_32BIT: | 257 | case SMIAPP_REG_32BIT: |
| 242 | data[2] = val >> 24; | 258 | data[2] = val >> 24; |
| 243 | data[3] = val >> 16; | 259 | data[3] = val >> 16; |
| 244 | data[4] = val >> 8; | 260 | data[4] = val >> 8; |
| @@ -271,3 +287,20 @@ int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | |||
| 271 | 287 | ||
| 272 | return r; | 288 | return r; |
| 273 | } | 289 | } |
| 290 | |||
| 291 | /* | ||
| 292 | * Write to a 8/16-bit register. | ||
| 293 | * Returns zero if successful, or non-zero otherwise. | ||
| 294 | */ | ||
| 295 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val) | ||
| 296 | { | ||
| 297 | int rval; | ||
| 298 | |||
| 299 | rval = smiapp_call_quirk(sensor, reg_access, true, ®, &val); | ||
| 300 | if (rval == -ENOIOCTLCMD) | ||
| 301 | return 0; | ||
| 302 | if (rval < 0) | ||
| 303 | return rval; | ||
| 304 | |||
| 305 | return smiapp_write_no_quirk(sensor, reg, val); | ||
| 306 | } | ||
diff --git a/drivers/media/i2c/smiapp/smiapp-regs.h b/drivers/media/i2c/smiapp/smiapp-regs.h index eefc6c84d5fe..35521125a2cc 100644 --- a/drivers/media/i2c/smiapp/smiapp-regs.h +++ b/drivers/media/i2c/smiapp/smiapp-regs.h | |||
| @@ -28,22 +28,23 @@ | |||
| 28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
| 29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| 30 | 30 | ||
| 31 | #define SMIAPP_REG_ADDR(reg) ((u16)reg) | ||
| 32 | #define SMIAPP_REG_WIDTH(reg) ((u8)(reg >> 16)) | ||
| 33 | #define SMIAPP_REG_FLAGS(reg) ((u8)(reg >> 24)) | ||
| 34 | |||
| 31 | /* Use upper 8 bits of the type field for flags */ | 35 | /* Use upper 8 bits of the type field for flags */ |
| 32 | #define SMIA_REG_FLAG_FLOAT (1 << 24) | 36 | #define SMIAPP_REG_FLAG_FLOAT (1 << 24) |
| 33 | 37 | ||
| 34 | #define SMIA_REG_8BIT 1 | 38 | #define SMIAPP_REG_8BIT 1 |
| 35 | #define SMIA_REG_16BIT 2 | 39 | #define SMIAPP_REG_16BIT 2 |
| 36 | #define SMIA_REG_32BIT 4 | 40 | #define SMIAPP_REG_32BIT 4 |
| 37 | struct smia_reg { | ||
| 38 | u16 type; | ||
| 39 | u16 reg; /* 16-bit offset */ | ||
| 40 | u32 val; /* 8/16/32-bit value */ | ||
| 41 | }; | ||
| 42 | 41 | ||
| 43 | struct smiapp_sensor; | 42 | struct smiapp_sensor; |
| 44 | 43 | ||
| 44 | int smiapp_read_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 *val); | ||
| 45 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val); | 45 | int smiapp_read(struct smiapp_sensor *sensor, u32 reg, u32 *val); |
| 46 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val); | 46 | int smiapp_read_8only(struct smiapp_sensor *sensor, u32 reg, u32 *val); |
| 47 | int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val); | ||
| 47 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val); | 48 | int smiapp_write(struct smiapp_sensor *sensor, u32 reg, u32 val); |
| 48 | 49 | ||
| 49 | #endif | 50 | #endif |
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index ab54628d9411..416402eb4f82 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c | |||
| @@ -814,8 +814,6 @@ done: | |||
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { | 816 | static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { |
| 817 | .s_std = tw9910_s_std, | ||
| 818 | .g_std = tw9910_g_std, | ||
| 819 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 817 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 820 | .g_register = tw9910_g_register, | 818 | .g_register = tw9910_g_register, |
| 821 | .s_register = tw9910_s_register, | 819 | .s_register = tw9910_s_register, |
| @@ -872,7 +870,15 @@ static int tw9910_s_mbus_config(struct v4l2_subdev *sd, | |||
| 872 | return i2c_smbus_write_byte_data(client, OUTCTR1, val); | 870 | return i2c_smbus_write_byte_data(client, OUTCTR1, val); |
| 873 | } | 871 | } |
| 874 | 872 | ||
| 873 | static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm) | ||
| 874 | { | ||
| 875 | *norm = V4L2_STD_NTSC | V4L2_STD_PAL; | ||
| 876 | return 0; | ||
| 877 | } | ||
| 878 | |||
| 875 | static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { | 879 | static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { |
| 880 | .s_std = tw9910_s_std, | ||
| 881 | .g_std = tw9910_g_std, | ||
| 876 | .s_stream = tw9910_s_stream, | 882 | .s_stream = tw9910_s_stream, |
| 877 | .g_mbus_fmt = tw9910_g_fmt, | 883 | .g_mbus_fmt = tw9910_g_fmt, |
| 878 | .s_mbus_fmt = tw9910_s_fmt, | 884 | .s_mbus_fmt = tw9910_s_fmt, |
| @@ -882,6 +888,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { | |||
| 882 | .enum_mbus_fmt = tw9910_enum_fmt, | 888 | .enum_mbus_fmt = tw9910_enum_fmt, |
| 883 | .g_mbus_config = tw9910_g_mbus_config, | 889 | .g_mbus_config = tw9910_g_mbus_config, |
| 884 | .s_mbus_config = tw9910_s_mbus_config, | 890 | .s_mbus_config = tw9910_s_mbus_config, |
| 891 | .g_tvnorms = tw9910_g_tvnorms, | ||
| 885 | }; | 892 | }; |
| 886 | 893 | ||
| 887 | static struct v4l2_subdev_ops tw9910_subdev_ops = { | 894 | static struct v4l2_subdev_ops tw9910_subdev_ops = { |
diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c index 32d82320b485..1da8004f5a8e 100644 --- a/drivers/media/i2c/sony-btf-mpx.c +++ b/drivers/media/i2c/sony-btf-mpx.c | |||
| @@ -327,18 +327,18 @@ static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner | |||
| 327 | 327 | ||
| 328 | /* --------------------------------------------------------------------------*/ | 328 | /* --------------------------------------------------------------------------*/ |
| 329 | 329 | ||
| 330 | static const struct v4l2_subdev_core_ops sony_btf_mpx_core_ops = { | ||
| 331 | .s_std = sony_btf_mpx_s_std, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = { | 330 | static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = { |
| 335 | .s_tuner = sony_btf_mpx_s_tuner, | 331 | .s_tuner = sony_btf_mpx_s_tuner, |
| 336 | .g_tuner = sony_btf_mpx_g_tuner, | 332 | .g_tuner = sony_btf_mpx_g_tuner, |
| 337 | }; | 333 | }; |
| 338 | 334 | ||
| 335 | static const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = { | ||
| 336 | .s_std = sony_btf_mpx_s_std, | ||
| 337 | }; | ||
| 338 | |||
| 339 | static const struct v4l2_subdev_ops sony_btf_mpx_ops = { | 339 | static const struct v4l2_subdev_ops sony_btf_mpx_ops = { |
| 340 | .core = &sony_btf_mpx_core_ops, | ||
| 341 | .tuner = &sony_btf_mpx_tuner_ops, | 340 | .tuner = &sony_btf_mpx_tuner_ops, |
| 341 | .video = &sony_btf_mpx_video_ops, | ||
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | /* --------------------------------------------------------------------------*/ | 344 | /* --------------------------------------------------------------------------*/ |
diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c index f72561e79739..656d889c1c79 100644 --- a/drivers/media/i2c/ths8200.c +++ b/drivers/media/i2c/ths8200.c | |||
| @@ -410,6 +410,9 @@ static int ths8200_g_dv_timings(struct v4l2_subdev *sd, | |||
| 410 | static int ths8200_enum_dv_timings(struct v4l2_subdev *sd, | 410 | static int ths8200_enum_dv_timings(struct v4l2_subdev *sd, |
| 411 | struct v4l2_enum_dv_timings *timings) | 411 | struct v4l2_enum_dv_timings *timings) |
| 412 | { | 412 | { |
| 413 | if (timings->pad != 0) | ||
| 414 | return -EINVAL; | ||
| 415 | |||
| 413 | return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap, | 416 | return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap, |
| 414 | NULL, NULL); | 417 | NULL, NULL); |
| 415 | } | 418 | } |
| @@ -417,6 +420,9 @@ static int ths8200_enum_dv_timings(struct v4l2_subdev *sd, | |||
| 417 | static int ths8200_dv_timings_cap(struct v4l2_subdev *sd, | 420 | static int ths8200_dv_timings_cap(struct v4l2_subdev *sd, |
| 418 | struct v4l2_dv_timings_cap *cap) | 421 | struct v4l2_dv_timings_cap *cap) |
| 419 | { | 422 | { |
| 423 | if (cap->pad != 0) | ||
| 424 | return -EINVAL; | ||
| 425 | |||
| 420 | *cap = ths8200_timings_cap; | 426 | *cap = ths8200_timings_cap; |
| 421 | return 0; | 427 | return 0; |
| 422 | } | 428 | } |
| @@ -426,6 +432,9 @@ static const struct v4l2_subdev_video_ops ths8200_video_ops = { | |||
| 426 | .s_stream = ths8200_s_stream, | 432 | .s_stream = ths8200_s_stream, |
| 427 | .s_dv_timings = ths8200_s_dv_timings, | 433 | .s_dv_timings = ths8200_s_dv_timings, |
| 428 | .g_dv_timings = ths8200_g_dv_timings, | 434 | .g_dv_timings = ths8200_g_dv_timings, |
| 435 | }; | ||
| 436 | |||
| 437 | static const struct v4l2_subdev_pad_ops ths8200_pad_ops = { | ||
| 429 | .enum_dv_timings = ths8200_enum_dv_timings, | 438 | .enum_dv_timings = ths8200_enum_dv_timings, |
| 430 | .dv_timings_cap = ths8200_dv_timings_cap, | 439 | .dv_timings_cap = ths8200_dv_timings_cap, |
| 431 | }; | 440 | }; |
| @@ -434,6 +443,7 @@ static const struct v4l2_subdev_video_ops ths8200_video_ops = { | |||
| 434 | static const struct v4l2_subdev_ops ths8200_ops = { | 443 | static const struct v4l2_subdev_ops ths8200_ops = { |
| 435 | .core = &ths8200_core_ops, | 444 | .core = &ths8200_core_ops, |
| 436 | .video = &ths8200_video_ops, | 445 | .video = &ths8200_video_ops, |
| 446 | .pad = &ths8200_pad_ops, | ||
| 437 | }; | 447 | }; |
| 438 | 448 | ||
| 439 | static int ths8200_probe(struct i2c_client *client, | 449 | static int ths8200_probe(struct i2c_client *client, |
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index d76c53a8f027..070c152da95a 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c | |||
| @@ -1862,7 +1862,6 @@ static const struct v4l2_subdev_core_ops tvaudio_core_ops = { | |||
| 1862 | .s_ctrl = v4l2_subdev_s_ctrl, | 1862 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 1863 | .queryctrl = v4l2_subdev_queryctrl, | 1863 | .queryctrl = v4l2_subdev_queryctrl, |
| 1864 | .querymenu = v4l2_subdev_querymenu, | 1864 | .querymenu = v4l2_subdev_querymenu, |
| 1865 | .s_std = tvaudio_s_std, | ||
| 1866 | }; | 1865 | }; |
| 1867 | 1866 | ||
| 1868 | static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = { | 1867 | static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops = { |
| @@ -1876,10 +1875,15 @@ static const struct v4l2_subdev_audio_ops tvaudio_audio_ops = { | |||
| 1876 | .s_routing = tvaudio_s_routing, | 1875 | .s_routing = tvaudio_s_routing, |
| 1877 | }; | 1876 | }; |
| 1878 | 1877 | ||
| 1878 | static const struct v4l2_subdev_video_ops tvaudio_video_ops = { | ||
| 1879 | .s_std = tvaudio_s_std, | ||
| 1880 | }; | ||
| 1881 | |||
| 1879 | static const struct v4l2_subdev_ops tvaudio_ops = { | 1882 | static const struct v4l2_subdev_ops tvaudio_ops = { |
| 1880 | .core = &tvaudio_core_ops, | 1883 | .core = &tvaudio_core_ops, |
| 1881 | .tuner = &tvaudio_tuner_ops, | 1884 | .tuner = &tvaudio_tuner_ops, |
| 1882 | .audio = &tvaudio_audio_ops, | 1885 | .audio = &tvaudio_audio_ops, |
| 1886 | .video = &tvaudio_video_ops, | ||
| 1883 | }; | 1887 | }; |
| 1884 | 1888 | ||
| 1885 | /* ----------------------------------------------------------------------- */ | 1889 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index ca001178c5bf..b9dabc9f4050 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c | |||
| @@ -1010,10 +1010,10 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = { | |||
| 1010 | .s_ctrl = v4l2_subdev_s_ctrl, | 1010 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 1011 | .queryctrl = v4l2_subdev_queryctrl, | 1011 | .queryctrl = v4l2_subdev_queryctrl, |
| 1012 | .querymenu = v4l2_subdev_querymenu, | 1012 | .querymenu = v4l2_subdev_querymenu, |
| 1013 | .s_std = tvp514x_s_std, | ||
| 1014 | }; | 1013 | }; |
| 1015 | 1014 | ||
| 1016 | static const struct v4l2_subdev_video_ops tvp514x_video_ops = { | 1015 | static const struct v4l2_subdev_video_ops tvp514x_video_ops = { |
| 1016 | .s_std = tvp514x_s_std, | ||
| 1017 | .s_routing = tvp514x_s_routing, | 1017 | .s_routing = tvp514x_s_routing, |
| 1018 | .querystd = tvp514x_querystd, | 1018 | .querystd = tvp514x_querystd, |
| 1019 | .enum_mbus_fmt = tvp514x_enum_mbus_fmt, | 1019 | .enum_mbus_fmt = tvp514x_enum_mbus_fmt, |
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 4fd3688e1164..a9121254e37a 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c | |||
| @@ -913,7 +913,7 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) | |||
| 913 | 913 | ||
| 914 | static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 914 | static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
| 915 | { | 915 | { |
| 916 | struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); | 916 | struct tvp5150 *decoder = to_tvp5150(sd); |
| 917 | 917 | ||
| 918 | a->c = decoder->rect; | 918 | a->c = decoder->rect; |
| 919 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 919 | a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| @@ -923,7 +923,7 @@ static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
| 923 | 923 | ||
| 924 | static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) | 924 | static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) |
| 925 | { | 925 | { |
| 926 | struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); | 926 | struct tvp5150 *decoder = to_tvp5150(sd); |
| 927 | v4l2_std_id std; | 927 | v4l2_std_id std; |
| 928 | 928 | ||
| 929 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 929 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| @@ -1063,7 +1063,6 @@ static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = { | |||
| 1063 | 1063 | ||
| 1064 | static const struct v4l2_subdev_core_ops tvp5150_core_ops = { | 1064 | static const struct v4l2_subdev_core_ops tvp5150_core_ops = { |
| 1065 | .log_status = tvp5150_log_status, | 1065 | .log_status = tvp5150_log_status, |
| 1066 | .s_std = tvp5150_s_std, | ||
| 1067 | .reset = tvp5150_reset, | 1066 | .reset = tvp5150_reset, |
| 1068 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1067 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1069 | .g_register = tvp5150_g_register, | 1068 | .g_register = tvp5150_g_register, |
| @@ -1076,6 +1075,7 @@ static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { | |||
| 1076 | }; | 1075 | }; |
| 1077 | 1076 | ||
| 1078 | static const struct v4l2_subdev_video_ops tvp5150_video_ops = { | 1077 | static const struct v4l2_subdev_video_ops tvp5150_video_ops = { |
| 1078 | .s_std = tvp5150_s_std, | ||
| 1079 | .s_routing = tvp5150_s_routing, | 1079 | .s_routing = tvp5150_s_routing, |
| 1080 | .enum_mbus_fmt = tvp5150_enum_mbus_fmt, | 1080 | .enum_mbus_fmt = tvp5150_enum_mbus_fmt, |
| 1081 | .s_mbus_fmt = tvp5150_mbus_fmt, | 1081 | .s_mbus_fmt = tvp5150_mbus_fmt, |
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index c4e1e2cb3094..11f2387e1dab 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c | |||
| @@ -833,6 +833,9 @@ static int tvp7002_log_status(struct v4l2_subdev *sd) | |||
| 833 | static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd, | 833 | static int tvp7002_enum_dv_timings(struct v4l2_subdev *sd, |
| 834 | struct v4l2_enum_dv_timings *timings) | 834 | struct v4l2_enum_dv_timings *timings) |
| 835 | { | 835 | { |
| 836 | if (timings->pad != 0) | ||
| 837 | return -EINVAL; | ||
| 838 | |||
| 836 | /* Check requested format index is within range */ | 839 | /* Check requested format index is within range */ |
| 837 | if (timings->index >= NUM_TIMINGS) | 840 | if (timings->index >= NUM_TIMINGS) |
| 838 | return -EINVAL; | 841 | return -EINVAL; |
| @@ -924,7 +927,6 @@ static const struct v4l2_subdev_core_ops tvp7002_core_ops = { | |||
| 924 | static const struct v4l2_subdev_video_ops tvp7002_video_ops = { | 927 | static const struct v4l2_subdev_video_ops tvp7002_video_ops = { |
| 925 | .g_dv_timings = tvp7002_g_dv_timings, | 928 | .g_dv_timings = tvp7002_g_dv_timings, |
| 926 | .s_dv_timings = tvp7002_s_dv_timings, | 929 | .s_dv_timings = tvp7002_s_dv_timings, |
| 927 | .enum_dv_timings = tvp7002_enum_dv_timings, | ||
| 928 | .query_dv_timings = tvp7002_query_dv_timings, | 930 | .query_dv_timings = tvp7002_query_dv_timings, |
| 929 | .s_stream = tvp7002_s_stream, | 931 | .s_stream = tvp7002_s_stream, |
| 930 | .g_mbus_fmt = tvp7002_mbus_fmt, | 932 | .g_mbus_fmt = tvp7002_mbus_fmt, |
| @@ -938,6 +940,7 @@ static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = { | |||
| 938 | .enum_mbus_code = tvp7002_enum_mbus_code, | 940 | .enum_mbus_code = tvp7002_enum_mbus_code, |
| 939 | .get_fmt = tvp7002_get_pad_format, | 941 | .get_fmt = tvp7002_get_pad_format, |
| 940 | .set_fmt = tvp7002_set_pad_format, | 942 | .set_fmt = tvp7002_set_pad_format, |
| 943 | .enum_dv_timings = tvp7002_enum_dv_timings, | ||
| 941 | }; | 944 | }; |
| 942 | 945 | ||
| 943 | /* V4L2 top level operation handlers */ | 946 | /* V4L2 top level operation handlers */ |
diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c index f58607df6193..7347480c0b0c 100644 --- a/drivers/media/i2c/tw2804.c +++ b/drivers/media/i2c/tw2804.c | |||
| @@ -342,12 +342,12 @@ static const struct v4l2_ctrl_ops tw2804_ctrl_ops = { | |||
| 342 | }; | 342 | }; |
| 343 | 343 | ||
| 344 | static const struct v4l2_subdev_video_ops tw2804_video_ops = { | 344 | static const struct v4l2_subdev_video_ops tw2804_video_ops = { |
| 345 | .s_std = tw2804_s_std, | ||
| 345 | .s_routing = tw2804_s_video_routing, | 346 | .s_routing = tw2804_s_video_routing, |
| 346 | }; | 347 | }; |
| 347 | 348 | ||
| 348 | static const struct v4l2_subdev_core_ops tw2804_core_ops = { | 349 | static const struct v4l2_subdev_core_ops tw2804_core_ops = { |
| 349 | .log_status = tw2804_log_status, | 350 | .log_status = tw2804_log_status, |
| 350 | .s_std = tw2804_s_std, | ||
| 351 | }; | 351 | }; |
| 352 | 352 | ||
| 353 | static const struct v4l2_subdev_ops tw2804_ops = { | 353 | static const struct v4l2_subdev_ops tw2804_ops = { |
diff --git a/drivers/media/i2c/tw9903.c b/drivers/media/i2c/tw9903.c index 285b759a5f7f..12c7d211a4a4 100644 --- a/drivers/media/i2c/tw9903.c +++ b/drivers/media/i2c/tw9903.c | |||
| @@ -187,10 +187,10 @@ static const struct v4l2_ctrl_ops tw9903_ctrl_ops = { | |||
| 187 | 187 | ||
| 188 | static const struct v4l2_subdev_core_ops tw9903_core_ops = { | 188 | static const struct v4l2_subdev_core_ops tw9903_core_ops = { |
| 189 | .log_status = tw9903_log_status, | 189 | .log_status = tw9903_log_status, |
| 190 | .s_std = tw9903_s_std, | ||
| 191 | }; | 190 | }; |
| 192 | 191 | ||
| 193 | static const struct v4l2_subdev_video_ops tw9903_video_ops = { | 192 | static const struct v4l2_subdev_video_ops tw9903_video_ops = { |
| 193 | .s_std = tw9903_s_std, | ||
| 194 | .s_routing = tw9903_s_video_routing, | 194 | .s_routing = tw9903_s_video_routing, |
| 195 | }; | 195 | }; |
| 196 | 196 | ||
diff --git a/drivers/media/i2c/tw9906.c b/drivers/media/i2c/tw9906.c index f6bef25bd9ce..2672d89265ff 100644 --- a/drivers/media/i2c/tw9906.c +++ b/drivers/media/i2c/tw9906.c | |||
| @@ -157,10 +157,10 @@ static const struct v4l2_ctrl_ops tw9906_ctrl_ops = { | |||
| 157 | 157 | ||
| 158 | static const struct v4l2_subdev_core_ops tw9906_core_ops = { | 158 | static const struct v4l2_subdev_core_ops tw9906_core_ops = { |
| 159 | .log_status = tw9906_log_status, | 159 | .log_status = tw9906_log_status, |
| 160 | .s_std = tw9906_s_std, | ||
| 161 | }; | 160 | }; |
| 162 | 161 | ||
| 163 | static const struct v4l2_subdev_video_ops tw9906_video_ops = { | 162 | static const struct v4l2_subdev_video_ops tw9906_video_ops = { |
| 163 | .s_std = tw9906_s_std, | ||
| 164 | .s_routing = tw9906_s_video_routing, | 164 | .s_routing = tw9906_s_video_routing, |
| 165 | }; | 165 | }; |
| 166 | 166 | ||
diff --git a/drivers/media/i2c/vp27smpx.c b/drivers/media/i2c/vp27smpx.c index 6a3a3ff7ee6a..819ab6d12989 100644 --- a/drivers/media/i2c/vp27smpx.c +++ b/drivers/media/i2c/vp27smpx.c | |||
| @@ -124,7 +124,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd) | |||
| 124 | 124 | ||
| 125 | static const struct v4l2_subdev_core_ops vp27smpx_core_ops = { | 125 | static const struct v4l2_subdev_core_ops vp27smpx_core_ops = { |
| 126 | .log_status = vp27smpx_log_status, | 126 | .log_status = vp27smpx_log_status, |
| 127 | .s_std = vp27smpx_s_std, | ||
| 128 | }; | 127 | }; |
| 129 | 128 | ||
| 130 | static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = { | 129 | static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = { |
| @@ -133,9 +132,14 @@ static const struct v4l2_subdev_tuner_ops vp27smpx_tuner_ops = { | |||
| 133 | .g_tuner = vp27smpx_g_tuner, | 132 | .g_tuner = vp27smpx_g_tuner, |
| 134 | }; | 133 | }; |
| 135 | 134 | ||
| 135 | static const struct v4l2_subdev_video_ops vp27smpx_video_ops = { | ||
| 136 | .s_std = vp27smpx_s_std, | ||
| 137 | }; | ||
| 138 | |||
| 136 | static const struct v4l2_subdev_ops vp27smpx_ops = { | 139 | static const struct v4l2_subdev_ops vp27smpx_ops = { |
| 137 | .core = &vp27smpx_core_ops, | 140 | .core = &vp27smpx_core_ops, |
| 138 | .tuner = &vp27smpx_tuner_ops, | 141 | .tuner = &vp27smpx_tuner_ops, |
| 142 | .video = &vp27smpx_video_ops, | ||
| 139 | }; | 143 | }; |
| 140 | 144 | ||
| 141 | /* ----------------------------------------------------------------------- */ | 145 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c index ece90df6a043..016e766e72ba 100644 --- a/drivers/media/i2c/vpx3220.c +++ b/drivers/media/i2c/vpx3220.c | |||
| @@ -457,10 +457,10 @@ static const struct v4l2_subdev_core_ops vpx3220_core_ops = { | |||
| 457 | .s_ctrl = v4l2_subdev_s_ctrl, | 457 | .s_ctrl = v4l2_subdev_s_ctrl, |
| 458 | .queryctrl = v4l2_subdev_queryctrl, | 458 | .queryctrl = v4l2_subdev_queryctrl, |
| 459 | .querymenu = v4l2_subdev_querymenu, | 459 | .querymenu = v4l2_subdev_querymenu, |
| 460 | .s_std = vpx3220_s_std, | ||
| 461 | }; | 460 | }; |
| 462 | 461 | ||
| 463 | static const struct v4l2_subdev_video_ops vpx3220_video_ops = { | 462 | static const struct v4l2_subdev_video_ops vpx3220_video_ops = { |
| 463 | .s_std = vpx3220_s_std, | ||
| 464 | .s_routing = vpx3220_s_routing, | 464 | .s_routing = vpx3220_s_routing, |
| 465 | .s_stream = vpx3220_s_stream, | 465 | .s_stream = vpx3220_s_stream, |
| 466 | .querystd = vpx3220_querystd, | 466 | .querystd = vpx3220_querystd, |
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 703560fa5e73..88b97c9e64ac 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c | |||
| @@ -373,7 +373,8 @@ static void media_device_release(struct media_devnode *mdev) | |||
| 373 | * - dev must point to the parent device | 373 | * - dev must point to the parent device |
| 374 | * - model must be filled with the device model name | 374 | * - model must be filled with the device model name |
| 375 | */ | 375 | */ |
| 376 | int __must_check media_device_register(struct media_device *mdev) | 376 | int __must_check __media_device_register(struct media_device *mdev, |
| 377 | struct module *owner) | ||
| 377 | { | 378 | { |
| 378 | int ret; | 379 | int ret; |
| 379 | 380 | ||
| @@ -389,7 +390,7 @@ int __must_check media_device_register(struct media_device *mdev) | |||
| 389 | mdev->devnode.fops = &media_device_fops; | 390 | mdev->devnode.fops = &media_device_fops; |
| 390 | mdev->devnode.parent = mdev->dev; | 391 | mdev->devnode.parent = mdev->dev; |
| 391 | mdev->devnode.release = media_device_release; | 392 | mdev->devnode.release = media_device_release; |
| 392 | ret = media_devnode_register(&mdev->devnode); | 393 | ret = media_devnode_register(&mdev->devnode, owner); |
| 393 | if (ret < 0) | 394 | if (ret < 0) |
| 394 | return ret; | 395 | return ret; |
| 395 | 396 | ||
| @@ -401,7 +402,7 @@ int __must_check media_device_register(struct media_device *mdev) | |||
| 401 | 402 | ||
| 402 | return 0; | 403 | return 0; |
| 403 | } | 404 | } |
| 404 | EXPORT_SYMBOL_GPL(media_device_register); | 405 | EXPORT_SYMBOL_GPL(__media_device_register); |
| 405 | 406 | ||
| 406 | /** | 407 | /** |
| 407 | * media_device_unregister - unregister a media device | 408 | * media_device_unregister - unregister a media device |
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c index fb0f0469fad7..7acd19c881de 100644 --- a/drivers/media/media-devnode.c +++ b/drivers/media/media-devnode.c | |||
| @@ -232,7 +232,8 @@ static const struct file_operations media_devnode_fops = { | |||
| 232 | * the media_devnode structure is *not* called, so the caller is responsible for | 232 | * the media_devnode structure is *not* called, so the caller is responsible for |
| 233 | * freeing any data. | 233 | * freeing any data. |
| 234 | */ | 234 | */ |
| 235 | int __must_check media_devnode_register(struct media_devnode *mdev) | 235 | int __must_check media_devnode_register(struct media_devnode *mdev, |
| 236 | struct module *owner) | ||
| 236 | { | 237 | { |
| 237 | int minor; | 238 | int minor; |
| 238 | int ret; | 239 | int ret; |
| @@ -253,7 +254,7 @@ int __must_check media_devnode_register(struct media_devnode *mdev) | |||
| 253 | 254 | ||
| 254 | /* Part 2: Initialize and register the character device */ | 255 | /* Part 2: Initialize and register the character device */ |
| 255 | cdev_init(&mdev->cdev, &media_devnode_fops); | 256 | cdev_init(&mdev->cdev, &media_devnode_fops); |
| 256 | mdev->cdev.owner = mdev->fops->owner; | 257 | mdev->cdev.owner = owner; |
| 257 | 258 | ||
| 258 | ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1); | 259 | ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1); |
| 259 | if (ret < 0) { | 260 | if (ret < 0) { |
diff --git a/drivers/media/parport/bw-qcam.c b/drivers/media/parport/bw-qcam.c index 8a0e84c7d495..416507a83668 100644 --- a/drivers/media/parport/bw-qcam.c +++ b/drivers/media/parport/bw-qcam.c | |||
| @@ -937,7 +937,7 @@ static struct qcam *qcam_init(struct parport *port) | |||
| 937 | return NULL; | 937 | return NULL; |
| 938 | 938 | ||
| 939 | v4l2_dev = &qcam->v4l2_dev; | 939 | v4l2_dev = &qcam->v4l2_dev; |
| 940 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams); | 940 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%u", num_cams); |
| 941 | 941 | ||
| 942 | if (v4l2_device_register(port->dev, v4l2_dev) < 0) { | 942 | if (v4l2_device_register(port->dev, v4l2_dev) < 0) { |
| 943 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | 943 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); |
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index d06963b3dcf3..d8ec583c154c 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c | |||
| @@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); | |||
| 52 | static void modtec_eeprom(struct bttv *btv); | 52 | static void modtec_eeprom(struct bttv *btv); |
| 53 | static void init_PXC200(struct bttv *btv); | 53 | static void init_PXC200(struct bttv *btv); |
| 54 | static void init_RTV24(struct bttv *btv); | 54 | static void init_RTV24(struct bttv *btv); |
| 55 | static void init_PCI8604PW(struct bttv *btv); | ||
| 55 | 56 | ||
| 56 | static void rv605_muxsel(struct bttv *btv, unsigned int input); | 57 | static void rv605_muxsel(struct bttv *btv, unsigned int input); |
| 57 | static void eagle_muxsel(struct bttv *btv, unsigned int input); | 58 | static void eagle_muxsel(struct bttv *btv, unsigned int input); |
| @@ -2871,6 +2872,22 @@ struct tvcard bttv_tvcards[] = { | |||
| 2871 | .has_remote = 1, | 2872 | .has_remote = 1, |
| 2872 | .has_radio = 1, | 2873 | .has_radio = 1, |
| 2873 | }, | 2874 | }, |
| 2875 | /* ---- card 0xa6---------------------------------- */ | ||
| 2876 | [BTTV_BOARD_PCI_8604PW] = { | ||
| 2877 | /* PCI-8604PW with special unlock sequence */ | ||
| 2878 | .name = "PCI-8604PW", | ||
| 2879 | .video_inputs = 2, | ||
| 2880 | /* .audio_inputs= 0, */ | ||
| 2881 | .svhs = NO_SVHS, | ||
| 2882 | /* The second input is available on CN4, if populated. | ||
| 2883 | * The other 5x2 header (CN2?) connects to the same inputs | ||
| 2884 | * as the on-board BNCs */ | ||
| 2885 | .muxsel = MUXSEL(2, 3), | ||
| 2886 | .tuner_type = TUNER_ABSENT, | ||
| 2887 | .no_msp34xx = 1, | ||
| 2888 | .no_tda7432 = 1, | ||
| 2889 | .pll = PLL_35, | ||
| 2890 | }, | ||
| 2874 | }; | 2891 | }; |
| 2875 | 2892 | ||
| 2876 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2893 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
| @@ -3305,6 +3322,9 @@ void bttv_init_card1(struct bttv *btv) | |||
| 3305 | case BTTV_BOARD_ADLINK_RTV24: | 3322 | case BTTV_BOARD_ADLINK_RTV24: |
| 3306 | init_RTV24( btv ); | 3323 | init_RTV24( btv ); |
| 3307 | break; | 3324 | break; |
| 3325 | case BTTV_BOARD_PCI_8604PW: | ||
| 3326 | init_PCI8604PW(btv); | ||
| 3327 | break; | ||
| 3308 | 3328 | ||
| 3309 | } | 3329 | } |
| 3310 | if (!bttv_tvcards[btv->c.type].has_dvb) | 3330 | if (!bttv_tvcards[btv->c.type].has_dvb) |
| @@ -4185,6 +4205,96 @@ init_RTV24 (struct bttv *btv) | |||
| 4185 | 4205 | ||
| 4186 | 4206 | ||
| 4187 | /* ----------------------------------------------------------------------- */ | 4207 | /* ----------------------------------------------------------------------- */ |
| 4208 | /* | ||
| 4209 | * The PCI-8604PW contains a CPLD, probably an ispMACH 4A, that filters | ||
| 4210 | * the PCI REQ signals comming from the four BT878 chips. After power | ||
| 4211 | * up, the CPLD does not forward requests to the bus, which prevents | ||
| 4212 | * the BT878 from fetching RISC instructions from memory. While the | ||
| 4213 | * CPLD is connected to most of the GPIOs of PCI device 0xD, only | ||
| 4214 | * five appear to play a role in unlocking the REQ signal. The following | ||
| 4215 | * sequence has been determined by trial and error without access to the | ||
| 4216 | * original driver. | ||
| 4217 | * | ||
| 4218 | * Eight GPIOs of device 0xC are provided on connector CN4 (4 in, 4 out). | ||
| 4219 | * Devices 0xE and 0xF do not appear to have anything connected to their | ||
| 4220 | * GPIOs. | ||
| 4221 | * | ||
| 4222 | * The correct GPIO_OUT_EN value might have some more bits set. It should | ||
| 4223 | * be possible to derive it from a boundary scan of the CPLD. Its JTAG | ||
| 4224 | * pins are routed to test points. | ||
| 4225 | * | ||
| 4226 | */ | ||
| 4227 | /* ----------------------------------------------------------------------- */ | ||
| 4228 | static void | ||
| 4229 | init_PCI8604PW(struct bttv *btv) | ||
| 4230 | { | ||
| 4231 | int state; | ||
| 4232 | |||
| 4233 | if ((PCI_SLOT(btv->c.pci->devfn) & ~3) != 0xC) { | ||
| 4234 | pr_warn("This is not a PCI-8604PW\n"); | ||
| 4235 | return; | ||
| 4236 | } | ||
| 4237 | |||
| 4238 | if (PCI_SLOT(btv->c.pci->devfn) != 0xD) | ||
| 4239 | return; | ||
| 4240 | |||
| 4241 | btwrite(0x080002, BT848_GPIO_OUT_EN); | ||
| 4242 | |||
| 4243 | state = (btread(BT848_GPIO_DATA) >> 21) & 7; | ||
| 4244 | |||
| 4245 | for (;;) { | ||
| 4246 | switch (state) { | ||
| 4247 | case 1: | ||
| 4248 | case 5: | ||
| 4249 | case 6: | ||
| 4250 | case 4: | ||
| 4251 | pr_debug("PCI-8604PW in state %i, toggling pin\n", | ||
| 4252 | state); | ||
| 4253 | btwrite(0x080000, BT848_GPIO_DATA); | ||
| 4254 | msleep(1); | ||
| 4255 | btwrite(0x000000, BT848_GPIO_DATA); | ||
| 4256 | msleep(1); | ||
| 4257 | break; | ||
| 4258 | case 7: | ||
| 4259 | pr_info("PCI-8604PW unlocked\n"); | ||
| 4260 | return; | ||
| 4261 | case 0: | ||
| 4262 | /* FIXME: If we are in state 7 and toggle GPIO[19] one | ||
| 4263 | more time, the CPLD goes into state 0, where PCI bus | ||
| 4264 | mastering is inhibited again. We have not managed to | ||
| 4265 | get out of that state. */ | ||
| 4266 | |||
| 4267 | pr_err("PCI-8604PW locked until reset\n"); | ||
| 4268 | return; | ||
| 4269 | default: | ||
| 4270 | pr_err("PCI-8604PW in unknown state %i\n", state); | ||
| 4271 | return; | ||
| 4272 | } | ||
| 4273 | |||
| 4274 | state = (state << 4) | ((btread(BT848_GPIO_DATA) >> 21) & 7); | ||
| 4275 | |||
| 4276 | switch (state) { | ||
| 4277 | case 0x15: | ||
| 4278 | case 0x56: | ||
| 4279 | case 0x64: | ||
| 4280 | case 0x47: | ||
| 4281 | /* The transition from state 7 to state 0 is, as explained | ||
| 4282 | above, valid but undesired and with this code impossible | ||
| 4283 | as we exit as soon as we are in state 7. | ||
| 4284 | case 0x70: */ | ||
| 4285 | break; | ||
| 4286 | default: | ||
| 4287 | pr_err("PCI-8604PW invalid transition %i -> %i\n", | ||
| 4288 | state >> 4, state & 7); | ||
| 4289 | return; | ||
| 4290 | } | ||
| 4291 | state &= 7; | ||
| 4292 | } | ||
| 4293 | } | ||
| 4294 | |||
| 4295 | |||
| 4296 | |||
| 4297 | /* ----------------------------------------------------------------------- */ | ||
| 4188 | /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ | 4298 | /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ |
| 4189 | /* | 4299 | /* |
| 4190 | * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu> | 4300 | * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu> |
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index afcd53bfcf8e..da780f42b121 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c | |||
| @@ -1182,7 +1182,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) | |||
| 1182 | break; | 1182 | break; |
| 1183 | } | 1183 | } |
| 1184 | id = tvnorm->v4l2_id; | 1184 | id = tvnorm->v4l2_id; |
| 1185 | bttv_call_all(btv, core, s_std, id); | 1185 | bttv_call_all(btv, video, s_std, id); |
| 1186 | 1186 | ||
| 1187 | return 0; | 1187 | return 0; |
| 1188 | } | 1188 | } |
diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index bb5da349a46e..f08126244662 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h | |||
| @@ -189,6 +189,7 @@ | |||
| 189 | #define BTTV_BOARD_BT848_CAP_14 0xa3 | 189 | #define BTTV_BOARD_BT848_CAP_14 0xa3 |
| 190 | #define BTTV_BOARD_CYBERVISION_CV06 0xa4 | 190 | #define BTTV_BOARD_CYBERVISION_CV06 0xa4 |
| 191 | #define BTTV_BOARD_KWORLD_VSTREAM_XPERT 0xa5 | 191 | #define BTTV_BOARD_KWORLD_VSTREAM_XPERT 0xa5 |
| 192 | #define BTTV_BOARD_PCI_8604PW 0xa6 | ||
| 192 | 193 | ||
| 193 | /* more card-specific defines */ | 194 | /* more card-specific defines */ |
| 194 | #define PT2254_L_CHANNEL 0x10 | 195 | #define PT2254_L_CHANNEL 0x10 |
diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c index 430b3eb11815..f2261dfe5d1a 100644 --- a/drivers/media/pci/bt8xx/dst.c +++ b/drivers/media/pci/bt8xx/dst.c | |||
| @@ -1544,7 +1544,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) | |||
| 1544 | } | 1544 | } |
| 1545 | 1545 | ||
| 1546 | 1546 | ||
| 1547 | static int dst_init(struct dvb_frontend *fe) | 1547 | static int bt8xx_dst_init(struct dvb_frontend *fe) |
| 1548 | { | 1548 | { |
| 1549 | struct dst_state *state = fe->demodulator_priv; | 1549 | struct dst_state *state = fe->demodulator_priv; |
| 1550 | 1550 | ||
| @@ -1707,7 +1707,7 @@ static int dst_get_frontend(struct dvb_frontend *fe) | |||
| 1707 | return 0; | 1707 | return 0; |
| 1708 | } | 1708 | } |
| 1709 | 1709 | ||
| 1710 | static void dst_release(struct dvb_frontend *fe) | 1710 | static void bt8xx_dst_release(struct dvb_frontend *fe) |
| 1711 | { | 1711 | { |
| 1712 | struct dst_state *state = fe->demodulator_priv; | 1712 | struct dst_state *state = fe->demodulator_priv; |
| 1713 | if (state->dst_ca) { | 1713 | if (state->dst_ca) { |
| @@ -1776,8 +1776,8 @@ static struct dvb_frontend_ops dst_dvbt_ops = { | |||
| 1776 | FE_CAN_GUARD_INTERVAL_AUTO | 1776 | FE_CAN_GUARD_INTERVAL_AUTO |
| 1777 | }, | 1777 | }, |
| 1778 | 1778 | ||
| 1779 | .release = dst_release, | 1779 | .release = bt8xx_dst_release, |
| 1780 | .init = dst_init, | 1780 | .init = bt8xx_dst_init, |
| 1781 | .tune = dst_tune_frontend, | 1781 | .tune = dst_tune_frontend, |
| 1782 | .set_frontend = dst_set_frontend, | 1782 | .set_frontend = dst_set_frontend, |
| 1783 | .get_frontend = dst_get_frontend, | 1783 | .get_frontend = dst_get_frontend, |
| @@ -1801,8 +1801,8 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
| 1801 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK | 1801 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK |
| 1802 | }, | 1802 | }, |
| 1803 | 1803 | ||
| 1804 | .release = dst_release, | 1804 | .release = bt8xx_dst_release, |
| 1805 | .init = dst_init, | 1805 | .init = bt8xx_dst_init, |
| 1806 | .tune = dst_tune_frontend, | 1806 | .tune = dst_tune_frontend, |
| 1807 | .set_frontend = dst_set_frontend, | 1807 | .set_frontend = dst_set_frontend, |
| 1808 | .get_frontend = dst_get_frontend, | 1808 | .get_frontend = dst_get_frontend, |
| @@ -1834,8 +1834,8 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
| 1834 | FE_CAN_QAM_256 | 1834 | FE_CAN_QAM_256 |
| 1835 | }, | 1835 | }, |
| 1836 | 1836 | ||
| 1837 | .release = dst_release, | 1837 | .release = bt8xx_dst_release, |
| 1838 | .init = dst_init, | 1838 | .init = bt8xx_dst_init, |
| 1839 | .tune = dst_tune_frontend, | 1839 | .tune = dst_tune_frontend, |
| 1840 | .set_frontend = dst_set_frontend, | 1840 | .set_frontend = dst_set_frontend, |
| 1841 | .get_frontend = dst_get_frontend, | 1841 | .get_frontend = dst_get_frontend, |
| @@ -1857,8 +1857,8 @@ static struct dvb_frontend_ops dst_atsc_ops = { | |||
| 1857 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | 1857 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB |
| 1858 | }, | 1858 | }, |
| 1859 | 1859 | ||
| 1860 | .release = dst_release, | 1860 | .release = bt8xx_dst_release, |
| 1861 | .init = dst_init, | 1861 | .init = bt8xx_dst_init, |
| 1862 | .tune = dst_tune_frontend, | 1862 | .tune = dst_tune_frontend, |
| 1863 | .set_frontend = dst_set_frontend, | 1863 | .set_frontend = dst_set_frontend, |
| 1864 | .get_frontend = dst_get_frontend, | 1864 | .get_frontend = dst_get_frontend, |
diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index c4890a430dc6..2d3afe0431a9 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c | |||
| @@ -1263,7 +1263,6 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = { | |||
| 1263 | .log_status = cx18_av_log_status, | 1263 | .log_status = cx18_av_log_status, |
| 1264 | .load_fw = cx18_av_load_fw, | 1264 | .load_fw = cx18_av_load_fw, |
| 1265 | .reset = cx18_av_reset, | 1265 | .reset = cx18_av_reset, |
| 1266 | .s_std = cx18_av_s_std, | ||
| 1267 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1266 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1268 | .g_register = cx18_av_g_register, | 1267 | .g_register = cx18_av_g_register, |
| 1269 | .s_register = cx18_av_s_register, | 1268 | .s_register = cx18_av_s_register, |
| @@ -1283,6 +1282,7 @@ static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = { | |||
| 1283 | }; | 1282 | }; |
| 1284 | 1283 | ||
| 1285 | static const struct v4l2_subdev_video_ops cx18_av_video_ops = { | 1284 | static const struct v4l2_subdev_video_ops cx18_av_video_ops = { |
| 1285 | .s_std = cx18_av_s_std, | ||
| 1286 | .s_routing = cx18_av_s_video_routing, | 1286 | .s_routing = cx18_av_s_video_routing, |
| 1287 | .s_stream = cx18_av_s_stream, | 1287 | .s_stream = cx18_av_s_stream, |
| 1288 | .s_mbus_fmt = cx18_av_s_mbus_fmt, | 1288 | .s_mbus_fmt = cx18_av_s_mbus_fmt, |
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 4bfd865a4106..76a3b4ac541e 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c | |||
| @@ -760,7 +760,7 @@ int cx18_v4l2_close(struct file *filp) | |||
| 760 | /* Mark that the radio is no longer in use */ | 760 | /* Mark that the radio is no longer in use */ |
| 761 | clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags); | 761 | clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags); |
| 762 | /* Switch tuner to TV */ | 762 | /* Switch tuner to TV */ |
| 763 | cx18_call_all(cx, core, s_std, cx->std); | 763 | cx18_call_all(cx, video, s_std, cx->std); |
| 764 | /* Select correct audio input (i.e. TV tuner or Line in) */ | 764 | /* Select correct audio input (i.e. TV tuner or Line in) */ |
| 765 | cx18_audio_set_io(cx); | 765 | cx18_audio_set_io(cx); |
| 766 | if (atomic_read(&cx->ana_capturing) > 0) { | 766 | if (atomic_read(&cx->ana_capturing) > 0) { |
diff --git a/drivers/media/pci/cx18/cx18-gpio.c b/drivers/media/pci/cx18/cx18-gpio.c index 5374aeb0cd22..38dc6b8f8254 100644 --- a/drivers/media/pci/cx18/cx18-gpio.c +++ b/drivers/media/pci/cx18/cx18-gpio.c | |||
| @@ -180,7 +180,6 @@ static int gpiomux_s_audio_routing(struct v4l2_subdev *sd, | |||
| 180 | 180 | ||
| 181 | static const struct v4l2_subdev_core_ops gpiomux_core_ops = { | 181 | static const struct v4l2_subdev_core_ops gpiomux_core_ops = { |
| 182 | .log_status = gpiomux_log_status, | 182 | .log_status = gpiomux_log_status, |
| 183 | .s_std = gpiomux_s_std, | ||
| 184 | }; | 183 | }; |
| 185 | 184 | ||
| 186 | static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = { | 185 | static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = { |
| @@ -191,10 +190,15 @@ static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = { | |||
| 191 | .s_routing = gpiomux_s_audio_routing, | 190 | .s_routing = gpiomux_s_audio_routing, |
| 192 | }; | 191 | }; |
| 193 | 192 | ||
| 193 | static const struct v4l2_subdev_video_ops gpiomux_video_ops = { | ||
| 194 | .s_std = gpiomux_s_std, | ||
| 195 | }; | ||
| 196 | |||
| 194 | static const struct v4l2_subdev_ops gpiomux_ops = { | 197 | static const struct v4l2_subdev_ops gpiomux_ops = { |
| 195 | .core = &gpiomux_core_ops, | 198 | .core = &gpiomux_core_ops, |
| 196 | .tuner = &gpiomux_tuner_ops, | 199 | .tuner = &gpiomux_tuner_ops, |
| 197 | .audio = &gpiomux_audio_ops, | 200 | .audio = &gpiomux_audio_ops, |
| 201 | .video = &gpiomux_video_ops, | ||
| 198 | }; | 202 | }; |
| 199 | 203 | ||
| 200 | /* | 204 | /* |
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index 1110bcb14e2f..fefb2cd35838 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c | |||
| @@ -602,7 +602,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) | |||
| 602 | (unsigned long long) cx->std); | 602 | (unsigned long long) cx->std); |
| 603 | 603 | ||
| 604 | /* Tuner */ | 604 | /* Tuner */ |
| 605 | cx18_call_all(cx, core, s_std, cx->std); | 605 | cx18_call_all(cx, video, s_std, cx->std); |
| 606 | return 0; | 606 | return 0; |
| 607 | } | 607 | } |
| 608 | 608 | ||
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index 7891f34157d1..e0a59523cf3c 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c | |||
| @@ -326,7 +326,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) | |||
| 326 | 326 | ||
| 327 | dev->tvnorm = norm; | 327 | dev->tvnorm = norm; |
| 328 | 328 | ||
| 329 | call_all(dev, core, s_std, norm); | 329 | call_all(dev, video, s_std, norm); |
| 330 | 330 | ||
| 331 | return 0; | 331 | return 0; |
| 332 | } | 332 | } |
| @@ -1589,7 +1589,7 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
| 1589 | fe = &dev->ts1.analog_fe; | 1589 | fe = &dev->ts1.analog_fe; |
| 1590 | 1590 | ||
| 1591 | if (fe && fe->ops.tuner_ops.set_analog_params) { | 1591 | if (fe && fe->ops.tuner_ops.set_analog_params) { |
| 1592 | call_all(dev, core, s_std, dev->tvnorm); | 1592 | call_all(dev, video, s_std, dev->tvnorm); |
| 1593 | fe->ops.tuner_ops.set_analog_params(fe, ¶ms); | 1593 | fe->ops.tuner_ops.set_analog_params(fe, ¶ms); |
| 1594 | } | 1594 | } |
| 1595 | else | 1595 | else |
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index ad59dc9235ae..e061c88b697e 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c | |||
| @@ -1012,7 +1012,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) | |||
| 1012 | set_tvaudio(core); | 1012 | set_tvaudio(core); |
| 1013 | 1013 | ||
| 1014 | // tell i2c chips | 1014 | // tell i2c chips |
| 1015 | call_all(core, core, s_std, norm); | 1015 | call_all(core, video, s_std, norm); |
| 1016 | 1016 | ||
| 1017 | /* The chroma_agc control should be inaccessible if the video format is SECAM */ | 1017 | /* The chroma_agc control should be inaccessible if the video format is SECAM */ |
| 1018 | v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM); | 1018 | v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM); |
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c index e1863dbf4edc..7a9b98bc208b 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c | |||
| @@ -159,6 +159,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream) | |||
| 159 | 159 | ||
| 160 | /* Instruct the CX2341[56] to start sending packets */ | 160 | /* Instruct the CX2341[56] to start sending packets */ |
| 161 | snd_ivtv_lock(itvsc); | 161 | snd_ivtv_lock(itvsc); |
| 162 | |||
| 163 | if (ivtv_init_on_first_open(itv)) { | ||
| 164 | snd_ivtv_unlock(itvsc); | ||
| 165 | return -ENXIO; | ||
| 166 | } | ||
| 167 | |||
| 162 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; | 168 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM]; |
| 163 | 169 | ||
| 164 | v4l2_fh_init(&item.fh, s->vdev); | 170 | v4l2_fh_init(&item.fh, s->vdev); |
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c index 9caffd8aa995..e5ff6277ca85 100644 --- a/drivers/media/pci/ivtv/ivtv-fileops.c +++ b/drivers/media/pci/ivtv/ivtv-fileops.c | |||
| @@ -894,7 +894,7 @@ int ivtv_v4l2_close(struct file *filp) | |||
| 894 | /* Mark that the radio is no longer in use */ | 894 | /* Mark that the radio is no longer in use */ |
| 895 | clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); | 895 | clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); |
| 896 | /* Switch tuner to TV */ | 896 | /* Switch tuner to TV */ |
| 897 | ivtv_call_all(itv, core, s_std, itv->std); | 897 | ivtv_call_all(itv, video, s_std, itv->std); |
| 898 | /* Select correct audio input (i.e. TV tuner or Line in) */ | 898 | /* Select correct audio input (i.e. TV tuner or Line in) */ |
| 899 | ivtv_audio_set_io(itv); | 899 | ivtv_audio_set_io(itv); |
| 900 | if (itv->hw_flags & IVTV_HW_SAA711X) { | 900 | if (itv->hw_flags & IVTV_HW_SAA711X) { |
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 807b275a847e..b3667a00db3a 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c | |||
| @@ -1090,7 +1090,7 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std) | |||
| 1090 | itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; | 1090 | itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; |
| 1091 | 1091 | ||
| 1092 | /* Tuner */ | 1092 | /* Tuner */ |
| 1093 | ivtv_call_all(itv, core, s_std, itv->std); | 1093 | ivtv_call_all(itv, video, s_std, itv->std); |
| 1094 | } | 1094 | } |
| 1095 | 1095 | ||
| 1096 | void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std) | 1096 | void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id std) |
diff --git a/drivers/media/pci/saa7134/Kconfig b/drivers/media/pci/saa7134/Kconfig index 7883393571e5..18ae75546302 100644 --- a/drivers/media/pci/saa7134/Kconfig +++ b/drivers/media/pci/saa7134/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config VIDEO_SAA7134 | 1 | config VIDEO_SAA7134 |
| 2 | tristate "Philips SAA7134 support" | 2 | tristate "Philips SAA7134 support" |
| 3 | depends on VIDEO_DEV && PCI && I2C | 3 | depends on VIDEO_DEV && PCI && I2C |
| 4 | select VIDEOBUF_DMA_SG | 4 | select VIDEOBUF2_DMA_SG |
| 5 | select VIDEO_TUNER | 5 | select VIDEO_TUNER |
| 6 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
| 7 | select CRC32 | 7 | select CRC32 |
| @@ -37,7 +37,7 @@ config VIDEO_SAA7134_RC | |||
| 37 | config VIDEO_SAA7134_DVB | 37 | config VIDEO_SAA7134_DVB |
| 38 | tristate "DVB/ATSC Support for saa7134 based TV cards" | 38 | tristate "DVB/ATSC Support for saa7134 based TV cards" |
| 39 | depends on VIDEO_SAA7134 && DVB_CORE | 39 | depends on VIDEO_SAA7134 && DVB_CORE |
| 40 | select VIDEOBUF_DVB | 40 | select VIDEOBUF2_DVB |
| 41 | select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT | 41 | select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT |
| 42 | select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT | 42 | select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT |
| 43 | select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT | 43 | select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index e04a4d5d6672..40569894c1c9 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
| 28 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
| 29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
| 30 | #include <linux/vmalloc.h> | ||
| 30 | 31 | ||
| 31 | #include "saa7134.h" | 32 | #include "saa7134.h" |
| 32 | #include "saa7134-reg.h" | 33 | #include "saa7134-reg.h" |
| @@ -274,6 +275,82 @@ static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream | |||
| 274 | return err; | 275 | return err; |
| 275 | } | 276 | } |
| 276 | 277 | ||
| 278 | static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages) | ||
| 279 | { | ||
| 280 | struct saa7134_dmasound *dma = &dev->dmasound; | ||
| 281 | struct page *pg; | ||
| 282 | int i; | ||
| 283 | |||
| 284 | dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); | ||
| 285 | if (NULL == dma->vaddr) { | ||
| 286 | dprintk("vmalloc_32(%d pages) failed\n", nr_pages); | ||
| 287 | return -ENOMEM; | ||
| 288 | } | ||
| 289 | |||
| 290 | dprintk("vmalloc is at addr 0x%08lx, size=%d\n", | ||
| 291 | (unsigned long)dma->vaddr, | ||
| 292 | nr_pages << PAGE_SHIFT); | ||
| 293 | |||
| 294 | memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); | ||
| 295 | dma->nr_pages = nr_pages; | ||
| 296 | |||
| 297 | dma->sglist = vzalloc(dma->nr_pages * sizeof(*dma->sglist)); | ||
| 298 | if (NULL == dma->sglist) | ||
| 299 | goto vzalloc_err; | ||
| 300 | |||
| 301 | sg_init_table(dma->sglist, dma->nr_pages); | ||
| 302 | for (i = 0; i < dma->nr_pages; i++) { | ||
| 303 | pg = vmalloc_to_page(dma->vaddr + i * PAGE_SIZE); | ||
| 304 | if (NULL == pg) | ||
| 305 | goto vmalloc_to_page_err; | ||
| 306 | sg_set_page(&dma->sglist[i], pg, PAGE_SIZE, 0); | ||
| 307 | } | ||
| 308 | return 0; | ||
| 309 | |||
| 310 | vmalloc_to_page_err: | ||
| 311 | vfree(dma->sglist); | ||
| 312 | dma->sglist = NULL; | ||
| 313 | vzalloc_err: | ||
| 314 | vfree(dma->vaddr); | ||
| 315 | dma->vaddr = NULL; | ||
| 316 | return -ENOMEM; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int saa7134_alsa_dma_map(struct saa7134_dev *dev) | ||
| 320 | { | ||
| 321 | struct saa7134_dmasound *dma = &dev->dmasound; | ||
| 322 | |||
| 323 | dma->sglen = dma_map_sg(&dev->pci->dev, dma->sglist, | ||
| 324 | dma->nr_pages, PCI_DMA_FROMDEVICE); | ||
| 325 | |||
| 326 | if (0 == dma->sglen) { | ||
| 327 | pr_warn("%s: saa7134_alsa_map_sg failed\n", __func__); | ||
| 328 | return -ENOMEM; | ||
| 329 | } | ||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev) | ||
| 334 | { | ||
| 335 | struct saa7134_dmasound *dma = &dev->dmasound; | ||
| 336 | |||
| 337 | if (!dma->sglen) | ||
| 338 | return 0; | ||
| 339 | |||
| 340 | dma_unmap_sg(&dev->pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE); | ||
| 341 | dma->sglen = 0; | ||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | |||
| 345 | static int saa7134_alsa_dma_free(struct saa7134_dmasound *dma) | ||
| 346 | { | ||
| 347 | vfree(dma->sglist); | ||
| 348 | dma->sglist = NULL; | ||
| 349 | vfree(dma->vaddr); | ||
| 350 | dma->vaddr = NULL; | ||
| 351 | return 0; | ||
| 352 | } | ||
| 353 | |||
| 277 | /* | 354 | /* |
| 278 | * DMA buffer initialization | 355 | * DMA buffer initialization |
| 279 | * | 356 | * |
| @@ -291,9 +368,8 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
| 291 | 368 | ||
| 292 | BUG_ON(!dev->dmasound.bufsize); | 369 | BUG_ON(!dev->dmasound.bufsize); |
| 293 | 370 | ||
| 294 | videobuf_dma_init(&dev->dmasound.dma); | 371 | err = saa7134_alsa_dma_init(dev, |
| 295 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, | 372 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); |
| 296 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); | ||
| 297 | if (0 != err) | 373 | if (0 != err) |
| 298 | return err; | 374 | return err; |
| 299 | return 0; | 375 | return 0; |
| @@ -310,7 +386,7 @@ static int dsp_buffer_free(struct saa7134_dev *dev) | |||
| 310 | { | 386 | { |
| 311 | BUG_ON(!dev->dmasound.blksize); | 387 | BUG_ON(!dev->dmasound.blksize); |
| 312 | 388 | ||
| 313 | videobuf_dma_free(&dev->dmasound.dma); | 389 | saa7134_alsa_dma_free(&dev->dmasound); |
| 314 | 390 | ||
| 315 | dev->dmasound.blocks = 0; | 391 | dev->dmasound.blocks = 0; |
| 316 | dev->dmasound.blksize = 0; | 392 | dev->dmasound.blksize = 0; |
| @@ -632,7 +708,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, | |||
| 632 | /* release the old buffer */ | 708 | /* release the old buffer */ |
| 633 | if (substream->runtime->dma_area) { | 709 | if (substream->runtime->dma_area) { |
| 634 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | 710 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
| 635 | videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); | 711 | saa7134_alsa_dma_unmap(dev); |
| 636 | dsp_buffer_free(dev); | 712 | dsp_buffer_free(dev); |
| 637 | substream->runtime->dma_area = NULL; | 713 | substream->runtime->dma_area = NULL; |
| 638 | } | 714 | } |
| @@ -648,21 +724,22 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, | |||
| 648 | return err; | 724 | return err; |
| 649 | } | 725 | } |
| 650 | 726 | ||
| 651 | if (0 != (err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma))) { | 727 | err = saa7134_alsa_dma_map(dev); |
| 728 | if (err) { | ||
| 652 | dsp_buffer_free(dev); | 729 | dsp_buffer_free(dev); |
| 653 | return err; | 730 | return err; |
| 654 | } | 731 | } |
| 655 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) { | 732 | err = saa7134_pgtable_alloc(dev->pci, &dev->dmasound.pt); |
| 656 | videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); | 733 | if (err) { |
| 734 | saa7134_alsa_dma_unmap(dev); | ||
| 657 | dsp_buffer_free(dev); | 735 | dsp_buffer_free(dev); |
| 658 | return err; | 736 | return err; |
| 659 | } | 737 | } |
| 660 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, | 738 | err = saa7134_pgtable_build(dev->pci, &dev->dmasound.pt, |
| 661 | dev->dmasound.dma.sglist, | 739 | dev->dmasound.sglist, dev->dmasound.sglen, 0); |
| 662 | dev->dmasound.dma.sglen, | 740 | if (err) { |
| 663 | 0))) { | ||
| 664 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | 741 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
| 665 | videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); | 742 | saa7134_alsa_dma_unmap(dev); |
| 666 | dsp_buffer_free(dev); | 743 | dsp_buffer_free(dev); |
| 667 | return err; | 744 | return err; |
| 668 | } | 745 | } |
| @@ -671,7 +748,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, | |||
| 671 | byte, but it doesn't work. So I allocate the DMA using the | 748 | byte, but it doesn't work. So I allocate the DMA using the |
| 672 | V4L functions, and force ALSA to use that as the DMA area */ | 749 | V4L functions, and force ALSA to use that as the DMA area */ |
| 673 | 750 | ||
| 674 | substream->runtime->dma_area = dev->dmasound.dma.vaddr; | 751 | substream->runtime->dma_area = dev->dmasound.vaddr; |
| 675 | substream->runtime->dma_bytes = dev->dmasound.bufsize; | 752 | substream->runtime->dma_bytes = dev->dmasound.bufsize; |
| 676 | substream->runtime->dma_addr = 0; | 753 | substream->runtime->dma_addr = 0; |
| 677 | 754 | ||
| @@ -698,7 +775,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream) | |||
| 698 | 775 | ||
| 699 | if (substream->runtime->dma_area) { | 776 | if (substream->runtime->dma_area) { |
| 700 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); | 777 | saa7134_pgtable_free(dev->pci, &dev->dmasound.pt); |
| 701 | videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma); | 778 | saa7134_alsa_dma_unmap(dev); |
| 702 | dsp_buffer_free(dev); | 779 | dsp_buffer_free(dev); |
| 703 | substream->runtime->dma_area = NULL; | 780 | substream->runtime->dma_area = NULL; |
| 704 | } | 781 | } |
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 1362b4aab473..be19a051a492 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c | |||
| @@ -69,6 +69,10 @@ module_param_named(no_overlay, saa7134_no_overlay, int, 0444); | |||
| 69 | MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" | 69 | MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)" |
| 70 | " [some VIA/SIS chipsets are known to have problem with overlay]"); | 70 | " [some VIA/SIS chipsets are known to have problem with overlay]"); |
| 71 | 71 | ||
| 72 | bool saa7134_userptr; | ||
| 73 | module_param(saa7134_userptr, bool, 0644); | ||
| 74 | MODULE_PARM_DESC(saa7134_userptr, "enable page-aligned userptr support"); | ||
| 75 | |||
| 72 | static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 76 | static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
| 73 | static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 77 | static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
| 74 | static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; | 78 | static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; |
| @@ -203,16 +207,16 @@ int saa7134_buffer_count(unsigned int size, unsigned int count) | |||
| 203 | 207 | ||
| 204 | int saa7134_buffer_startpage(struct saa7134_buf *buf) | 208 | int saa7134_buffer_startpage(struct saa7134_buf *buf) |
| 205 | { | 209 | { |
| 206 | return saa7134_buffer_pages(buf->vb.bsize) * buf->vb.i; | 210 | return saa7134_buffer_pages(vb2_plane_size(&buf->vb2, 0)) * buf->vb2.v4l2_buf.index; |
| 207 | } | 211 | } |
| 208 | 212 | ||
| 209 | unsigned long saa7134_buffer_base(struct saa7134_buf *buf) | 213 | unsigned long saa7134_buffer_base(struct saa7134_buf *buf) |
| 210 | { | 214 | { |
| 211 | unsigned long base; | 215 | unsigned long base; |
| 212 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 216 | struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); |
| 213 | 217 | ||
| 214 | base = saa7134_buffer_startpage(buf) * 4096; | 218 | base = saa7134_buffer_startpage(buf) * 4096; |
| 215 | base += dma->sglist[0].offset; | 219 | base += dma->sgl[0].offset; |
| 216 | return base; | 220 | return base; |
| 217 | } | 221 | } |
| 218 | 222 | ||
| @@ -237,14 +241,16 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt, | |||
| 237 | unsigned int startpage) | 241 | unsigned int startpage) |
| 238 | { | 242 | { |
| 239 | __le32 *ptr; | 243 | __le32 *ptr; |
| 240 | unsigned int i,p; | 244 | unsigned int i, p; |
| 241 | 245 | ||
| 242 | BUG_ON(NULL == pt || NULL == pt->cpu); | 246 | BUG_ON(NULL == pt || NULL == pt->cpu); |
| 243 | 247 | ||
| 244 | ptr = pt->cpu + startpage; | 248 | ptr = pt->cpu + startpage; |
| 245 | for (i = 0; i < length; i++, list++) | 249 | for (i = 0; i < length; i++, list = sg_next(list)) { |
| 246 | for (p = 0; p * 4096 < list->length; p++, ptr++) | 250 | for (p = 0; p * 4096 < list->length; p++, ptr++) |
| 247 | *ptr = cpu_to_le32(sg_dma_address(list) - list->offset); | 251 | *ptr = cpu_to_le32(sg_dma_address(list) + |
| 252 | list->offset + p * 4096); | ||
| 253 | } | ||
| 248 | return 0; | 254 | return 0; |
| 249 | } | 255 | } |
| 250 | 256 | ||
| @@ -258,44 +264,31 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt) | |||
| 258 | 264 | ||
| 259 | /* ------------------------------------------------------------------ */ | 265 | /* ------------------------------------------------------------------ */ |
| 260 | 266 | ||
| 261 | void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) | ||
| 262 | { | ||
| 263 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | ||
| 264 | BUG_ON(in_interrupt()); | ||
| 265 | |||
| 266 | videobuf_waiton(q, &buf->vb, 0, 0); | ||
| 267 | videobuf_dma_unmap(q->dev, dma); | ||
| 268 | videobuf_dma_free(dma); | ||
| 269 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
| 270 | } | ||
| 271 | |||
| 272 | /* ------------------------------------------------------------------ */ | ||
| 273 | |||
| 274 | int saa7134_buffer_queue(struct saa7134_dev *dev, | 267 | int saa7134_buffer_queue(struct saa7134_dev *dev, |
| 275 | struct saa7134_dmaqueue *q, | 268 | struct saa7134_dmaqueue *q, |
| 276 | struct saa7134_buf *buf) | 269 | struct saa7134_buf *buf) |
| 277 | { | 270 | { |
| 278 | struct saa7134_buf *next = NULL; | 271 | struct saa7134_buf *next = NULL; |
| 272 | unsigned long flags; | ||
| 279 | 273 | ||
| 280 | assert_spin_locked(&dev->slock); | 274 | spin_lock_irqsave(&dev->slock, flags); |
| 281 | dprintk("buffer_queue %p\n",buf); | 275 | dprintk("buffer_queue %p\n", buf); |
| 282 | if (NULL == q->curr) { | 276 | if (NULL == q->curr) { |
| 283 | if (!q->need_two) { | 277 | if (!q->need_two) { |
| 284 | q->curr = buf; | 278 | q->curr = buf; |
| 285 | buf->activate(dev,buf,NULL); | 279 | buf->activate(dev, buf, NULL); |
| 286 | } else if (list_empty(&q->queue)) { | 280 | } else if (list_empty(&q->queue)) { |
| 287 | list_add_tail(&buf->vb.queue,&q->queue); | 281 | list_add_tail(&buf->entry, &q->queue); |
| 288 | buf->vb.state = VIDEOBUF_QUEUED; | ||
| 289 | } else { | 282 | } else { |
| 290 | next = list_entry(q->queue.next,struct saa7134_buf, | 283 | next = list_entry(q->queue.next, struct saa7134_buf, |
| 291 | vb.queue); | 284 | entry); |
| 292 | q->curr = buf; | 285 | q->curr = buf; |
| 293 | buf->activate(dev,buf,next); | 286 | buf->activate(dev, buf, next); |
| 294 | } | 287 | } |
| 295 | } else { | 288 | } else { |
| 296 | list_add_tail(&buf->vb.queue,&q->queue); | 289 | list_add_tail(&buf->entry, &q->queue); |
| 297 | buf->vb.state = VIDEOBUF_QUEUED; | ||
| 298 | } | 290 | } |
| 291 | spin_unlock_irqrestore(&dev->slock, flags); | ||
| 299 | return 0; | 292 | return 0; |
| 300 | } | 293 | } |
| 301 | 294 | ||
| @@ -303,13 +296,12 @@ void saa7134_buffer_finish(struct saa7134_dev *dev, | |||
| 303 | struct saa7134_dmaqueue *q, | 296 | struct saa7134_dmaqueue *q, |
| 304 | unsigned int state) | 297 | unsigned int state) |
| 305 | { | 298 | { |
| 306 | assert_spin_locked(&dev->slock); | 299 | dprintk("buffer_finish %p\n", q->curr); |
| 307 | dprintk("buffer_finish %p\n",q->curr); | ||
| 308 | 300 | ||
| 309 | /* finish current buffer */ | 301 | /* finish current buffer */ |
| 310 | q->curr->vb.state = state; | 302 | v4l2_get_timestamp(&q->curr->vb2.v4l2_buf.timestamp); |
| 311 | v4l2_get_timestamp(&q->curr->vb.ts); | 303 | q->curr->vb2.v4l2_buf.sequence = q->seq_nr++; |
| 312 | wake_up(&q->curr->vb.done); | 304 | vb2_buffer_done(&q->curr->vb2, state); |
| 313 | q->curr = NULL; | 305 | q->curr = NULL; |
| 314 | } | 306 | } |
| 315 | 307 | ||
| @@ -323,36 +315,31 @@ void saa7134_buffer_next(struct saa7134_dev *dev, | |||
| 323 | 315 | ||
| 324 | if (!list_empty(&q->queue)) { | 316 | if (!list_empty(&q->queue)) { |
| 325 | /* activate next one from queue */ | 317 | /* activate next one from queue */ |
| 326 | buf = list_entry(q->queue.next,struct saa7134_buf,vb.queue); | 318 | buf = list_entry(q->queue.next, struct saa7134_buf, entry); |
| 327 | dprintk("buffer_next %p [prev=%p/next=%p]\n", | 319 | dprintk("buffer_next %p [prev=%p/next=%p]\n", |
| 328 | buf,q->queue.prev,q->queue.next); | 320 | buf, q->queue.prev, q->queue.next); |
| 329 | list_del(&buf->vb.queue); | 321 | list_del(&buf->entry); |
| 330 | if (!list_empty(&q->queue)) | 322 | if (!list_empty(&q->queue)) |
| 331 | next = list_entry(q->queue.next,struct saa7134_buf, | 323 | next = list_entry(q->queue.next, struct saa7134_buf, entry); |
| 332 | vb.queue); | ||
| 333 | q->curr = buf; | 324 | q->curr = buf; |
| 334 | buf->activate(dev,buf,next); | 325 | buf->activate(dev, buf, next); |
| 335 | dprintk("buffer_next #2 prev=%p/next=%p\n", | 326 | dprintk("buffer_next #2 prev=%p/next=%p\n", |
| 336 | q->queue.prev,q->queue.next); | 327 | q->queue.prev, q->queue.next); |
| 337 | } else { | 328 | } else { |
| 338 | /* nothing to do -- just stop DMA */ | 329 | /* nothing to do -- just stop DMA */ |
| 339 | dprintk("buffer_next %p\n",NULL); | 330 | dprintk("buffer_next %p\n", NULL); |
| 340 | saa7134_set_dmabits(dev); | 331 | saa7134_set_dmabits(dev); |
| 341 | del_timer(&q->timeout); | 332 | del_timer(&q->timeout); |
| 342 | |||
| 343 | if (card_has_mpeg(dev)) | ||
| 344 | if (dev->ts_started) | ||
| 345 | saa7134_ts_stop(dev); | ||
| 346 | } | 333 | } |
| 347 | } | 334 | } |
| 348 | 335 | ||
| 349 | void saa7134_buffer_timeout(unsigned long data) | 336 | void saa7134_buffer_timeout(unsigned long data) |
| 350 | { | 337 | { |
| 351 | struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue*)data; | 338 | struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue *)data; |
| 352 | struct saa7134_dev *dev = q->dev; | 339 | struct saa7134_dev *dev = q->dev; |
| 353 | unsigned long flags; | 340 | unsigned long flags; |
| 354 | 341 | ||
| 355 | spin_lock_irqsave(&dev->slock,flags); | 342 | spin_lock_irqsave(&dev->slock, flags); |
| 356 | 343 | ||
| 357 | /* try to reset the hardware (SWRST) */ | 344 | /* try to reset the hardware (SWRST) */ |
| 358 | saa_writeb(SAA7134_REGION_ENABLE, 0x00); | 345 | saa_writeb(SAA7134_REGION_ENABLE, 0x00); |
| @@ -362,13 +349,33 @@ void saa7134_buffer_timeout(unsigned long data) | |||
| 362 | /* flag current buffer as failed, | 349 | /* flag current buffer as failed, |
| 363 | try to start over with the next one. */ | 350 | try to start over with the next one. */ |
| 364 | if (q->curr) { | 351 | if (q->curr) { |
| 365 | dprintk("timeout on %p\n",q->curr); | 352 | dprintk("timeout on %p\n", q->curr); |
| 366 | saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR); | 353 | saa7134_buffer_finish(dev, q, VB2_BUF_STATE_ERROR); |
| 367 | } | 354 | } |
| 368 | saa7134_buffer_next(dev,q); | 355 | saa7134_buffer_next(dev, q); |
| 369 | spin_unlock_irqrestore(&dev->slock,flags); | 356 | spin_unlock_irqrestore(&dev->slock, flags); |
| 370 | } | 357 | } |
| 371 | 358 | ||
| 359 | void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q) | ||
| 360 | { | ||
| 361 | unsigned long flags; | ||
| 362 | struct list_head *pos, *n; | ||
| 363 | struct saa7134_buf *tmp; | ||
| 364 | |||
| 365 | spin_lock_irqsave(&dev->slock, flags); | ||
| 366 | if (!list_empty(&q->queue)) { | ||
| 367 | list_for_each_safe(pos, n, &q->queue) { | ||
| 368 | tmp = list_entry(pos, struct saa7134_buf, entry); | ||
| 369 | vb2_buffer_done(&tmp->vb2, VB2_BUF_STATE_ERROR); | ||
| 370 | list_del(pos); | ||
| 371 | tmp = NULL; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | spin_unlock_irqrestore(&dev->slock, flags); | ||
| 375 | saa7134_buffer_timeout((unsigned long)q); /* also calls del_timer(&q->timeout) */ | ||
| 376 | } | ||
| 377 | EXPORT_SYMBOL_GPL(saa7134_stop_streaming); | ||
| 378 | |||
| 372 | /* ------------------------------------------------------------------ */ | 379 | /* ------------------------------------------------------------------ */ |
| 373 | 380 | ||
| 374 | int saa7134_set_dmabits(struct saa7134_dev *dev) | 381 | int saa7134_set_dmabits(struct saa7134_dev *dev) |
| @@ -388,12 +395,11 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
| 388 | ctrl |= SAA7134_MAIN_CTRL_TE0; | 395 | ctrl |= SAA7134_MAIN_CTRL_TE0; |
| 389 | irq |= SAA7134_IRQ1_INTE_RA0_1 | | 396 | irq |= SAA7134_IRQ1_INTE_RA0_1 | |
| 390 | SAA7134_IRQ1_INTE_RA0_0; | 397 | SAA7134_IRQ1_INTE_RA0_0; |
| 391 | cap = dev->video_q.curr->vb.field; | 398 | cap = dev->field; |
| 392 | } | 399 | } |
| 393 | 400 | ||
| 394 | /* video capture -- dma 1+2 (planar modes) */ | 401 | /* video capture -- dma 1+2 (planar modes) */ |
| 395 | if (dev->video_q.curr && | 402 | if (dev->video_q.curr && dev->fmt->planar) { |
| 396 | dev->video_q.curr->fmt->planar) { | ||
| 397 | ctrl |= SAA7134_MAIN_CTRL_TE4 | | 403 | ctrl |= SAA7134_MAIN_CTRL_TE4 | |
| 398 | SAA7134_MAIN_CTRL_TE5; | 404 | SAA7134_MAIN_CTRL_TE5; |
| 399 | } | 405 | } |
| @@ -1047,6 +1053,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev, | |||
| 1047 | 1053 | ||
| 1048 | dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); | 1054 | dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); |
| 1049 | dev->video_dev->ctrl_handler = &dev->ctrl_handler; | 1055 | dev->video_dev->ctrl_handler = &dev->ctrl_handler; |
| 1056 | dev->video_dev->lock = &dev->lock; | ||
| 1057 | dev->video_dev->queue = &dev->video_vbq; | ||
| 1050 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, | 1058 | err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, |
| 1051 | video_nr[dev->nr]); | 1059 | video_nr[dev->nr]); |
| 1052 | if (err < 0) { | 1060 | if (err < 0) { |
| @@ -1059,6 +1067,8 @@ static int saa7134_initdev(struct pci_dev *pci_dev, | |||
| 1059 | 1067 | ||
| 1060 | dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); | 1068 | dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); |
| 1061 | dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; | 1069 | dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; |
| 1070 | dev->vbi_dev->lock = &dev->lock; | ||
| 1071 | dev->vbi_dev->queue = &dev->vbi_vbq; | ||
| 1062 | 1072 | ||
| 1063 | err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, | 1073 | err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, |
| 1064 | vbi_nr[dev->nr]); | 1074 | vbi_nr[dev->nr]); |
| @@ -1070,6 +1080,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, | |||
| 1070 | if (card_has_radio(dev)) { | 1080 | if (card_has_radio(dev)) { |
| 1071 | dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); | 1081 | dev->radio_dev = vdev_init(dev,&saa7134_radio_template,"radio"); |
| 1072 | dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; | 1082 | dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; |
| 1083 | dev->radio_dev->lock = &dev->lock; | ||
| 1073 | err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, | 1084 | err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO, |
| 1074 | radio_nr[dev->nr]); | 1085 | radio_nr[dev->nr]); |
| 1075 | if (err < 0) | 1086 | if (err < 0) |
| @@ -1189,7 +1200,7 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev, | |||
| 1189 | 1200 | ||
| 1190 | if (!list_empty(&q->queue)) | 1201 | if (!list_empty(&q->queue)) |
| 1191 | next = list_entry(q->queue.next, struct saa7134_buf, | 1202 | next = list_entry(q->queue.next, struct saa7134_buf, |
| 1192 | vb.queue); | 1203 | entry); |
| 1193 | buf->activate(dev, buf, next); | 1204 | buf->activate(dev, buf, next); |
| 1194 | 1205 | ||
| 1195 | return 0; | 1206 | return 0; |
| @@ -1360,10 +1371,3 @@ EXPORT_SYMBOL(saa7134_pgtable_free); | |||
| 1360 | EXPORT_SYMBOL(saa7134_pgtable_build); | 1371 | EXPORT_SYMBOL(saa7134_pgtable_build); |
| 1361 | EXPORT_SYMBOL(saa7134_pgtable_alloc); | 1372 | EXPORT_SYMBOL(saa7134_pgtable_alloc); |
| 1362 | EXPORT_SYMBOL(saa7134_set_dmabits); | 1373 | EXPORT_SYMBOL(saa7134_set_dmabits); |
| 1363 | |||
| 1364 | /* ----------------------------------------------------------- */ | ||
| 1365 | /* | ||
| 1366 | * Local variables: | ||
| 1367 | * c-basic-offset: 8 | ||
| 1368 | * End: | ||
| 1369 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index 4a08ae31df2e..73ffbabf831c 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c | |||
| @@ -602,10 +602,10 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, | |||
| 602 | struct tda1004x_config *cdec_conf, | 602 | struct tda1004x_config *cdec_conf, |
| 603 | struct tda827x_config *tuner_conf) | 603 | struct tda827x_config *tuner_conf) |
| 604 | { | 604 | { |
| 605 | struct videobuf_dvb_frontend *fe0; | 605 | struct vb2_dvb_frontend *fe0; |
| 606 | 606 | ||
| 607 | /* Get the first frontend */ | 607 | /* Get the first frontend */ |
| 608 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | 608 | fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); |
| 609 | 609 | ||
| 610 | if (!fe0) | 610 | if (!fe0) |
| 611 | return -EINVAL; | 611 | return -EINVAL; |
| @@ -1215,29 +1215,38 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 1215 | { | 1215 | { |
| 1216 | int ret; | 1216 | int ret; |
| 1217 | int attach_xc3028 = 0; | 1217 | int attach_xc3028 = 0; |
| 1218 | struct videobuf_dvb_frontend *fe0; | 1218 | struct vb2_dvb_frontend *fe0; |
| 1219 | struct vb2_queue *q; | ||
| 1219 | 1220 | ||
| 1220 | /* FIXME: add support for multi-frontend */ | 1221 | /* FIXME: add support for multi-frontend */ |
| 1221 | mutex_init(&dev->frontends.lock); | 1222 | mutex_init(&dev->frontends.lock); |
| 1222 | INIT_LIST_HEAD(&dev->frontends.felist); | 1223 | INIT_LIST_HEAD(&dev->frontends.felist); |
| 1223 | 1224 | ||
| 1224 | printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); | 1225 | printk(KERN_INFO "%s() allocating 1 frontend\n", __func__); |
| 1225 | fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1); | 1226 | fe0 = vb2_dvb_alloc_frontend(&dev->frontends, 1); |
| 1226 | if (!fe0) { | 1227 | if (!fe0) { |
| 1227 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | 1228 | printk(KERN_ERR "%s() failed to alloc\n", __func__); |
| 1228 | return -ENOMEM; | 1229 | return -ENOMEM; |
| 1229 | } | 1230 | } |
| 1230 | 1231 | ||
| 1231 | /* init struct videobuf_dvb */ | 1232 | /* init struct vb2_dvb */ |
| 1232 | dev->ts.nr_bufs = 32; | 1233 | dev->ts.nr_bufs = 32; |
| 1233 | dev->ts.nr_packets = 32*4; | 1234 | dev->ts.nr_packets = 32*4; |
| 1234 | fe0->dvb.name = dev->name; | 1235 | fe0->dvb.name = dev->name; |
| 1235 | videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops, | 1236 | q = &fe0->dvb.dvbq; |
| 1236 | &dev->pci->dev, &dev->slock, | 1237 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 1237 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1238 | q->io_modes = VB2_MMAP | VB2_READ; |
| 1238 | V4L2_FIELD_ALTERNATE, | 1239 | q->drv_priv = &dev->ts_q; |
| 1239 | sizeof(struct saa7134_buf), | 1240 | q->ops = &saa7134_ts_qops; |
| 1240 | dev, NULL); | 1241 | q->mem_ops = &vb2_dma_sg_memops; |
| 1242 | q->buf_struct_size = sizeof(struct saa7134_buf); | ||
| 1243 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 1244 | q->lock = &dev->lock; | ||
| 1245 | ret = vb2_queue_init(q); | ||
| 1246 | if (ret) { | ||
| 1247 | vb2_dvb_dealloc_frontends(&dev->frontends); | ||
| 1248 | return ret; | ||
| 1249 | } | ||
| 1241 | 1250 | ||
| 1242 | switch (dev->board) { | 1251 | switch (dev->board) { |
| 1243 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: | 1252 | case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: |
| @@ -1876,7 +1885,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 1876 | fe0->dvb.frontend->callback = saa7134_tuner_callback; | 1885 | fe0->dvb.frontend->callback = saa7134_tuner_callback; |
| 1877 | 1886 | ||
| 1878 | /* register everything else */ | 1887 | /* register everything else */ |
| 1879 | ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, | 1888 | ret = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, |
| 1880 | &dev->pci->dev, adapter_nr, 0); | 1889 | &dev->pci->dev, adapter_nr, 0); |
| 1881 | 1890 | ||
| 1882 | /* this sequence is necessary to make the tda1004x load its firmware | 1891 | /* this sequence is necessary to make the tda1004x load its firmware |
| @@ -1893,16 +1902,17 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 1893 | return ret; | 1902 | return ret; |
| 1894 | 1903 | ||
| 1895 | detach_frontend: | 1904 | detach_frontend: |
| 1896 | videobuf_dvb_dealloc_frontends(&dev->frontends); | 1905 | vb2_dvb_dealloc_frontends(&dev->frontends); |
| 1906 | vb2_queue_release(&fe0->dvb.dvbq); | ||
| 1897 | return -EINVAL; | 1907 | return -EINVAL; |
| 1898 | } | 1908 | } |
| 1899 | 1909 | ||
| 1900 | static int dvb_fini(struct saa7134_dev *dev) | 1910 | static int dvb_fini(struct saa7134_dev *dev) |
| 1901 | { | 1911 | { |
| 1902 | struct videobuf_dvb_frontend *fe0; | 1912 | struct vb2_dvb_frontend *fe0; |
| 1903 | 1913 | ||
| 1904 | /* Get the first frontend */ | 1914 | /* Get the first frontend */ |
| 1905 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | 1915 | fe0 = vb2_dvb_get_frontend(&dev->frontends, 1); |
| 1906 | if (!fe0) | 1916 | if (!fe0) |
| 1907 | return -EINVAL; | 1917 | return -EINVAL; |
| 1908 | 1918 | ||
| @@ -1933,7 +1943,8 @@ static int dvb_fini(struct saa7134_dev *dev) | |||
| 1933 | } | 1943 | } |
| 1934 | } | 1944 | } |
| 1935 | } | 1945 | } |
| 1936 | videobuf_dvb_unregister_bus(&dev->frontends); | 1946 | vb2_dvb_unregister_bus(&dev->frontends); |
| 1947 | vb2_queue_release(&fe0->dvb.dvbq); | ||
| 1937 | return 0; | 1948 | return 0; |
| 1938 | } | 1949 | } |
| 1939 | 1950 | ||
| @@ -1955,10 +1966,3 @@ static void __exit dvb_unregister(void) | |||
| 1955 | 1966 | ||
| 1956 | module_init(dvb_register); | 1967 | module_init(dvb_register); |
| 1957 | module_exit(dvb_unregister); | 1968 | module_exit(dvb_unregister); |
| 1958 | |||
| 1959 | /* ------------------------------------------------------------------ */ | ||
| 1960 | /* | ||
| 1961 | * Local variables: | ||
| 1962 | * c-basic-offset: 8 | ||
| 1963 | * End: | ||
| 1964 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c index 0a9047e754b9..e65c760e4e8b 100644 --- a/drivers/media/pci/saa7134/saa7134-empress.c +++ b/drivers/media/pci/saa7134/saa7134-empress.c | |||
| @@ -48,21 +48,16 @@ MODULE_PARM_DESC(debug,"enable debug messages"); | |||
| 48 | 48 | ||
| 49 | /* ------------------------------------------------------------------ */ | 49 | /* ------------------------------------------------------------------ */ |
| 50 | 50 | ||
| 51 | static void ts_reset_encoder(struct saa7134_dev* dev) | 51 | static int start_streaming(struct vb2_queue *vq, unsigned int count) |
| 52 | { | ||
| 53 | if (!dev->empress_started) | ||
| 54 | return; | ||
| 55 | |||
| 56 | saa_writeb(SAA7134_SPECIAL_MODE, 0x00); | ||
| 57 | msleep(10); | ||
| 58 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); | ||
| 59 | msleep(100); | ||
| 60 | dev->empress_started = 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | static int ts_init_encoder(struct saa7134_dev* dev) | ||
| 64 | { | 52 | { |
| 53 | struct saa7134_dmaqueue *dmaq = vq->drv_priv; | ||
| 54 | struct saa7134_dev *dev = dmaq->dev; | ||
| 65 | u32 leading_null_bytes = 0; | 55 | u32 leading_null_bytes = 0; |
| 56 | int err; | ||
| 57 | |||
| 58 | err = saa7134_ts_start_streaming(vq, count); | ||
| 59 | if (err) | ||
| 60 | return err; | ||
| 66 | 61 | ||
| 67 | /* If more cards start to need this, then this | 62 | /* If more cards start to need this, then this |
| 68 | should probably be added to the card definitions. */ | 63 | should probably be added to the card definitions. */ |
| @@ -73,97 +68,43 @@ static int ts_init_encoder(struct saa7134_dev* dev) | |||
| 73 | leading_null_bytes = 1; | 68 | leading_null_bytes = 1; |
| 74 | break; | 69 | break; |
| 75 | } | 70 | } |
| 76 | ts_reset_encoder(dev); | ||
| 77 | saa_call_all(dev, core, init, leading_null_bytes); | 71 | saa_call_all(dev, core, init, leading_null_bytes); |
| 78 | dev->empress_started = 1; | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* ------------------------------------------------------------------ */ | ||
| 83 | |||
| 84 | static int ts_open(struct file *file) | ||
| 85 | { | ||
| 86 | struct video_device *vdev = video_devdata(file); | ||
| 87 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 88 | struct saa7134_fh *fh; | ||
| 89 | |||
| 90 | /* allocate + initialize per filehandle data */ | ||
| 91 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | ||
| 92 | if (NULL == fh) | ||
| 93 | return -ENOMEM; | ||
| 94 | |||
| 95 | v4l2_fh_init(&fh->fh, vdev); | ||
| 96 | file->private_data = fh; | ||
| 97 | fh->is_empress = true; | ||
| 98 | v4l2_fh_add(&fh->fh); | ||
| 99 | |||
| 100 | /* Unmute audio */ | 72 | /* Unmute audio */ |
| 101 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, | 73 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, |
| 102 | saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); | 74 | saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); |
| 103 | 75 | dev->empress_started = 1; | |
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int ts_release(struct file *file) | ||
| 108 | { | ||
| 109 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 110 | struct saa7134_fh *fh = file->private_data; | ||
| 111 | |||
| 112 | if (res_check(fh, RESOURCE_EMPRESS)) { | ||
| 113 | videobuf_stop(&dev->empress_tsq); | ||
| 114 | videobuf_mmap_free(&dev->empress_tsq); | ||
| 115 | |||
| 116 | /* stop the encoder */ | ||
| 117 | ts_reset_encoder(dev); | ||
| 118 | |||
| 119 | /* Mute audio */ | ||
| 120 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, | ||
| 121 | saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); | ||
| 122 | } | ||
| 123 | |||
| 124 | v4l2_fh_del(&fh->fh); | ||
| 125 | v4l2_fh_exit(&fh->fh); | ||
| 126 | return 0; | 76 | return 0; |
| 127 | } | 77 | } |
| 128 | 78 | ||
| 129 | static ssize_t | 79 | static void stop_streaming(struct vb2_queue *vq) |
| 130 | ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | ||
| 131 | { | 80 | { |
| 132 | struct saa7134_dev *dev = video_drvdata(file); | 81 | struct saa7134_dmaqueue *dmaq = vq->drv_priv; |
| 82 | struct saa7134_dev *dev = dmaq->dev; | ||
| 133 | 83 | ||
| 134 | if (res_locked(dev, RESOURCE_EMPRESS)) | 84 | saa7134_ts_stop_streaming(vq); |
| 135 | return -EBUSY; | 85 | saa_writeb(SAA7134_SPECIAL_MODE, 0x00); |
| 136 | if (!dev->empress_started) | 86 | msleep(20); |
| 137 | ts_init_encoder(dev); | 87 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); |
| 138 | 88 | msleep(100); | |
| 139 | return videobuf_read_stream(&dev->empress_tsq, | 89 | /* Mute audio */ |
| 140 | data, count, ppos, 0, | 90 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, |
| 141 | file->f_flags & O_NONBLOCK); | 91 | saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); |
| 142 | } | 92 | dev->empress_started = 0; |
| 143 | |||
| 144 | static unsigned int | ||
| 145 | ts_poll(struct file *file, struct poll_table_struct *wait) | ||
| 146 | { | ||
| 147 | unsigned long req_events = poll_requested_events(wait); | ||
| 148 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 149 | struct saa7134_fh *fh = file->private_data; | ||
| 150 | unsigned int rc = 0; | ||
| 151 | |||
| 152 | if (v4l2_event_pending(&fh->fh)) | ||
| 153 | rc = POLLPRI; | ||
| 154 | else if (req_events & POLLPRI) | ||
| 155 | poll_wait(file, &fh->fh.wait, wait); | ||
| 156 | return rc | videobuf_poll_stream(file, &dev->empress_tsq, wait); | ||
| 157 | } | 93 | } |
| 158 | 94 | ||
| 95 | static struct vb2_ops saa7134_empress_qops = { | ||
| 96 | .queue_setup = saa7134_ts_queue_setup, | ||
| 97 | .buf_init = saa7134_ts_buffer_init, | ||
| 98 | .buf_prepare = saa7134_ts_buffer_prepare, | ||
| 99 | .buf_finish = saa7134_ts_buffer_finish, | ||
| 100 | .buf_queue = saa7134_vb2_buffer_queue, | ||
| 101 | .wait_prepare = vb2_ops_wait_prepare, | ||
| 102 | .wait_finish = vb2_ops_wait_finish, | ||
| 103 | .start_streaming = start_streaming, | ||
| 104 | .stop_streaming = stop_streaming, | ||
| 105 | }; | ||
| 159 | 106 | ||
| 160 | static int | 107 | /* ------------------------------------------------------------------ */ |
| 161 | ts_mmap(struct file *file, struct vm_area_struct * vma) | ||
| 162 | { | ||
| 163 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 164 | |||
| 165 | return videobuf_mmap_mapper(&dev->empress_tsq, vma); | ||
| 166 | } | ||
| 167 | 108 | ||
| 168 | static int empress_enum_fmt_vid_cap(struct file *file, void *priv, | 109 | static int empress_enum_fmt_vid_cap(struct file *file, void *priv, |
| 169 | struct v4l2_fmtdesc *f) | 110 | struct v4l2_fmtdesc *f) |
| @@ -233,11 +174,11 @@ static int empress_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 233 | static const struct v4l2_file_operations ts_fops = | 174 | static const struct v4l2_file_operations ts_fops = |
| 234 | { | 175 | { |
| 235 | .owner = THIS_MODULE, | 176 | .owner = THIS_MODULE, |
| 236 | .open = ts_open, | 177 | .open = v4l2_fh_open, |
| 237 | .release = ts_release, | 178 | .release = vb2_fop_release, |
| 238 | .read = ts_read, | 179 | .read = vb2_fop_read, |
| 239 | .poll = ts_poll, | 180 | .poll = vb2_fop_poll, |
| 240 | .mmap = ts_mmap, | 181 | .mmap = vb2_fop_mmap, |
| 241 | .ioctl = video_ioctl2, | 182 | .ioctl = video_ioctl2, |
| 242 | }; | 183 | }; |
| 243 | 184 | ||
| @@ -247,12 +188,12 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { | |||
| 247 | .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, | 188 | .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, |
| 248 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, | 189 | .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, |
| 249 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, | 190 | .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, |
| 250 | .vidioc_reqbufs = saa7134_reqbufs, | 191 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
| 251 | .vidioc_querybuf = saa7134_querybuf, | 192 | .vidioc_querybuf = vb2_ioctl_querybuf, |
| 252 | .vidioc_qbuf = saa7134_qbuf, | 193 | .vidioc_qbuf = vb2_ioctl_qbuf, |
| 253 | .vidioc_dqbuf = saa7134_dqbuf, | 194 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
| 254 | .vidioc_streamon = saa7134_streamon, | 195 | .vidioc_streamon = vb2_ioctl_streamon, |
| 255 | .vidioc_streamoff = saa7134_streamoff, | 196 | .vidioc_streamoff = vb2_ioctl_streamoff, |
| 256 | .vidioc_g_frequency = saa7134_g_frequency, | 197 | .vidioc_g_frequency = saa7134_g_frequency, |
| 257 | .vidioc_s_frequency = saa7134_s_frequency, | 198 | .vidioc_s_frequency = saa7134_s_frequency, |
| 258 | .vidioc_g_tuner = saa7134_g_tuner, | 199 | .vidioc_g_tuner = saa7134_g_tuner, |
| @@ -262,6 +203,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { | |||
| 262 | .vidioc_s_input = saa7134_s_input, | 203 | .vidioc_s_input = saa7134_s_input, |
| 263 | .vidioc_s_std = saa7134_s_std, | 204 | .vidioc_s_std = saa7134_s_std, |
| 264 | .vidioc_g_std = saa7134_g_std, | 205 | .vidioc_g_std = saa7134_g_std, |
| 206 | .vidioc_querystd = saa7134_querystd, | ||
| 265 | .vidioc_log_status = v4l2_ctrl_log_status, | 207 | .vidioc_log_status = v4l2_ctrl_log_status, |
| 266 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | 208 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, |
| 267 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | 209 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, |
| @@ -314,6 +256,7 @@ static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl) | |||
| 314 | static int empress_init(struct saa7134_dev *dev) | 256 | static int empress_init(struct saa7134_dev *dev) |
| 315 | { | 257 | { |
| 316 | struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler; | 258 | struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler; |
| 259 | struct vb2_queue *q; | ||
| 317 | int err; | 260 | int err; |
| 318 | 261 | ||
| 319 | dprintk("%s: %s\n",dev->name,__func__); | 262 | dprintk("%s: %s\n",dev->name,__func__); |
| @@ -323,6 +266,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
| 323 | *(dev->empress_dev) = saa7134_empress_template; | 266 | *(dev->empress_dev) = saa7134_empress_template; |
| 324 | dev->empress_dev->v4l2_dev = &dev->v4l2_dev; | 267 | dev->empress_dev->v4l2_dev = &dev->v4l2_dev; |
| 325 | dev->empress_dev->release = video_device_release; | 268 | dev->empress_dev->release = video_device_release; |
| 269 | dev->empress_dev->lock = &dev->lock; | ||
| 326 | snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), | 270 | snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), |
| 327 | "%s empress (%s)", dev->name, | 271 | "%s empress (%s)", dev->name, |
| 328 | saa7134_boards[dev->board].name); | 272 | saa7134_boards[dev->board].name); |
| @@ -339,6 +283,26 @@ static int empress_init(struct saa7134_dev *dev) | |||
| 339 | 283 | ||
| 340 | INIT_WORK(&dev->empress_workqueue, empress_signal_update); | 284 | INIT_WORK(&dev->empress_workqueue, empress_signal_update); |
| 341 | 285 | ||
| 286 | q = &dev->empress_vbq; | ||
| 287 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 288 | /* | ||
| 289 | * Do not add VB2_USERPTR: the saa7134 DMA engine cannot handle | ||
| 290 | * transfers that do not start at the beginning of a page. A USERPTR | ||
| 291 | * can start anywhere in a page, so USERPTR support is a no-go. | ||
| 292 | */ | ||
| 293 | q->io_modes = VB2_MMAP | VB2_READ; | ||
| 294 | q->drv_priv = &dev->ts_q; | ||
| 295 | q->ops = &saa7134_empress_qops; | ||
| 296 | q->gfp_flags = GFP_DMA32; | ||
| 297 | q->mem_ops = &vb2_dma_sg_memops; | ||
| 298 | q->buf_struct_size = sizeof(struct saa7134_buf); | ||
| 299 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 300 | q->lock = &dev->lock; | ||
| 301 | err = vb2_queue_init(q); | ||
| 302 | if (err) | ||
| 303 | return err; | ||
| 304 | dev->empress_dev->queue = q; | ||
| 305 | |||
| 342 | video_set_drvdata(dev->empress_dev, dev); | 306 | video_set_drvdata(dev->empress_dev, dev); |
| 343 | err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, | 307 | err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, |
| 344 | empress_nr[dev->nr]); | 308 | empress_nr[dev->nr]); |
| @@ -352,13 +316,6 @@ static int empress_init(struct saa7134_dev *dev) | |||
| 352 | printk(KERN_INFO "%s: registered device %s [mpeg]\n", | 316 | printk(KERN_INFO "%s: registered device %s [mpeg]\n", |
| 353 | dev->name, video_device_node_name(dev->empress_dev)); | 317 | dev->name, video_device_node_name(dev->empress_dev)); |
| 354 | 318 | ||
| 355 | videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, | ||
| 356 | &dev->pci->dev, &dev->slock, | ||
| 357 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
| 358 | V4L2_FIELD_ALTERNATE, | ||
| 359 | sizeof(struct saa7134_buf), | ||
| 360 | dev, NULL); | ||
| 361 | |||
| 362 | empress_signal_update(&dev->empress_workqueue); | 319 | empress_signal_update(&dev->empress_workqueue); |
| 363 | return 0; | 320 | return 0; |
| 364 | } | 321 | } |
| @@ -371,6 +328,7 @@ static int empress_fini(struct saa7134_dev *dev) | |||
| 371 | return 0; | 328 | return 0; |
| 372 | flush_work(&dev->empress_workqueue); | 329 | flush_work(&dev->empress_workqueue); |
| 373 | video_unregister_device(dev->empress_dev); | 330 | video_unregister_device(dev->empress_dev); |
| 331 | vb2_queue_release(&dev->empress_vbq); | ||
| 374 | v4l2_ctrl_handler_free(&dev->empress_ctrl_handler); | 332 | v4l2_ctrl_handler_free(&dev->empress_ctrl_handler); |
| 375 | dev->empress_dev = NULL; | 333 | dev->empress_dev = NULL; |
| 376 | return 0; | 334 | return 0; |
| @@ -395,10 +353,3 @@ static void __exit empress_unregister(void) | |||
| 395 | 353 | ||
| 396 | module_init(empress_register); | 354 | module_init(empress_register); |
| 397 | module_exit(empress_unregister); | 355 | module_exit(empress_unregister); |
| 398 | |||
| 399 | /* ----------------------------------------------------------- */ | ||
| 400 | /* | ||
| 401 | * Local variables: | ||
| 402 | * c-basic-offset: 8 | ||
| 403 | * End: | ||
| 404 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index c68169d75804..f4da674e7f26 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c | |||
| @@ -427,10 +427,3 @@ int saa7134_i2c_unregister(struct saa7134_dev *dev) | |||
| 427 | i2c_del_adapter(&dev->i2c_adap); | 427 | i2c_del_adapter(&dev->i2c_adap); |
| 428 | return 0; | 428 | return 0; |
| 429 | } | 429 | } |
| 430 | |||
| 431 | /* ----------------------------------------------------------- */ | ||
| 432 | /* | ||
| 433 | * Local variables: | ||
| 434 | * c-basic-offset: 8 | ||
| 435 | * End: | ||
| 436 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-reg.h b/drivers/media/pci/saa7134/saa7134-reg.h index e7e0af101fa7..b6ea6f4f9b6c 100644 --- a/drivers/media/pci/saa7134/saa7134-reg.h +++ b/drivers/media/pci/saa7134/saa7134-reg.h | |||
| @@ -167,17 +167,22 @@ | |||
| 167 | #define SAA7134_HSYNC_START 0x106 | 167 | #define SAA7134_HSYNC_START 0x106 |
| 168 | #define SAA7134_HSYNC_STOP 0x107 | 168 | #define SAA7134_HSYNC_STOP 0x107 |
| 169 | #define SAA7134_SYNC_CTRL 0x108 | 169 | #define SAA7134_SYNC_CTRL 0x108 |
| 170 | #define SAA7134_SYNC_CTRL_AUFD (1 << 7) | ||
| 170 | #define SAA7134_LUMA_CTRL 0x109 | 171 | #define SAA7134_LUMA_CTRL 0x109 |
| 172 | #define SAA7134_LUMA_CTRL_LDEL (1 << 5) | ||
| 171 | #define SAA7134_DEC_LUMA_BRIGHT 0x10a | 173 | #define SAA7134_DEC_LUMA_BRIGHT 0x10a |
| 172 | #define SAA7134_DEC_LUMA_CONTRAST 0x10b | 174 | #define SAA7134_DEC_LUMA_CONTRAST 0x10b |
| 173 | #define SAA7134_DEC_CHROMA_SATURATION 0x10c | 175 | #define SAA7134_DEC_CHROMA_SATURATION 0x10c |
| 174 | #define SAA7134_DEC_CHROMA_HUE 0x10d | 176 | #define SAA7134_DEC_CHROMA_HUE 0x10d |
| 175 | #define SAA7134_CHROMA_CTRL1 0x10e | 177 | #define SAA7134_CHROMA_CTRL1 0x10e |
| 178 | #define SAA7134_CHROMA_CTRL1_AUTO0 (1 << 1) | ||
| 179 | #define SAA7134_CHROMA_CTRL1_FCTC (1 << 2) | ||
| 176 | #define SAA7134_CHROMA_GAIN 0x10f | 180 | #define SAA7134_CHROMA_GAIN 0x10f |
| 177 | #define SAA7134_CHROMA_CTRL2 0x110 | 181 | #define SAA7134_CHROMA_CTRL2 0x110 |
| 178 | #define SAA7134_MODE_DELAY_CTRL 0x111 | 182 | #define SAA7134_MODE_DELAY_CTRL 0x111 |
| 179 | 183 | ||
| 180 | #define SAA7134_ANALOG_ADC 0x114 | 184 | #define SAA7134_ANALOG_ADC 0x114 |
| 185 | #define SAA7134_ANALOG_ADC_AUTO1 (1 << 2) | ||
| 181 | #define SAA7134_VGATE_START 0x115 | 186 | #define SAA7134_VGATE_START 0x115 |
| 182 | #define SAA7134_VGATE_STOP 0x116 | 187 | #define SAA7134_VGATE_STOP 0x116 |
| 183 | #define SAA7134_MISC_VGATE_MSB 0x117 | 188 | #define SAA7134_MISC_VGATE_MSB 0x117 |
| @@ -369,10 +374,3 @@ | |||
| 369 | #define SAA7135_DSP_RWCLEAR_RERR 1 | 374 | #define SAA7135_DSP_RWCLEAR_RERR 1 |
| 370 | 375 | ||
| 371 | #define SAA7133_I2S_AUDIO_CONTROL 0x591 | 376 | #define SAA7133_I2S_AUDIO_CONTROL 0x591 |
| 372 | /* ------------------------------------------------------------------ */ | ||
| 373 | /* | ||
| 374 | * Local variables: | ||
| 375 | * c-basic-offset: 8 | ||
| 376 | * End: | ||
| 377 | */ | ||
| 378 | |||
diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 2e3f4b412d8c..bd25323bd947 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c | |||
| @@ -39,26 +39,29 @@ MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); | |||
| 39 | printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg) | 39 | printk(KERN_DEBUG "%s/ts: " fmt, dev->name , ## arg) |
| 40 | 40 | ||
| 41 | /* ------------------------------------------------------------------ */ | 41 | /* ------------------------------------------------------------------ */ |
| 42 | |||
| 43 | static int buffer_activate(struct saa7134_dev *dev, | 42 | static int buffer_activate(struct saa7134_dev *dev, |
| 44 | struct saa7134_buf *buf, | 43 | struct saa7134_buf *buf, |
| 45 | struct saa7134_buf *next) | 44 | struct saa7134_buf *next) |
| 46 | { | 45 | { |
| 47 | 46 | ||
| 48 | dprintk("buffer_activate [%p]",buf); | 47 | dprintk("buffer_activate [%p]",buf); |
| 49 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
| 50 | buf->top_seen = 0; | 48 | buf->top_seen = 0; |
| 51 | 49 | ||
| 50 | if (!dev->ts_started) | ||
| 51 | dev->ts_field = V4L2_FIELD_TOP; | ||
| 52 | |||
| 52 | if (NULL == next) | 53 | if (NULL == next) |
| 53 | next = buf; | 54 | next = buf; |
| 54 | if (V4L2_FIELD_TOP == buf->vb.field) { | 55 | if (V4L2_FIELD_TOP == dev->ts_field) { |
| 55 | dprintk("- [top] buf=%p next=%p\n",buf,next); | 56 | dprintk("- [top] buf=%p next=%p\n",buf,next); |
| 56 | saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); | 57 | saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); |
| 57 | saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); | 58 | saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); |
| 59 | dev->ts_field = V4L2_FIELD_BOTTOM; | ||
| 58 | } else { | 60 | } else { |
| 59 | dprintk("- [bottom] buf=%p next=%p\n",buf,next); | 61 | dprintk("- [bottom] buf=%p next=%p\n",buf,next); |
| 60 | saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); | 62 | saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); |
| 61 | saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); | 63 | saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); |
| 64 | dev->ts_field = V4L2_FIELD_TOP; | ||
| 62 | } | 65 | } |
| 63 | 66 | ||
| 64 | /* start DMA */ | 67 | /* start DMA */ |
| @@ -72,96 +75,123 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
| 72 | return 0; | 75 | return 0; |
| 73 | } | 76 | } |
| 74 | 77 | ||
| 75 | static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | 78 | int saa7134_ts_buffer_init(struct vb2_buffer *vb2) |
| 76 | enum v4l2_field field) | ||
| 77 | { | 79 | { |
| 78 | struct saa7134_dev *dev = q->priv_data; | 80 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; |
| 79 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 81 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); |
| 82 | |||
| 83 | dmaq->curr = NULL; | ||
| 84 | buf->activate = buffer_activate; | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | EXPORT_SYMBOL_GPL(saa7134_ts_buffer_init); | ||
| 89 | |||
| 90 | int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2) | ||
| 91 | { | ||
| 92 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; | ||
| 93 | struct saa7134_dev *dev = dmaq->dev; | ||
| 94 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | ||
| 95 | struct sg_table *dma = vb2_dma_sg_plane_desc(vb2, 0); | ||
| 80 | unsigned int lines, llength, size; | 96 | unsigned int lines, llength, size; |
| 81 | int err; | 97 | int ret; |
| 82 | 98 | ||
| 83 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); | 99 | dprintk("buffer_prepare [%p]\n", buf); |
| 84 | 100 | ||
| 85 | llength = TS_PACKET_SIZE; | 101 | llength = TS_PACKET_SIZE; |
| 86 | lines = dev->ts.nr_packets; | 102 | lines = dev->ts.nr_packets; |
| 87 | 103 | ||
| 88 | size = lines * llength; | 104 | size = lines * llength; |
| 89 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | 105 | if (vb2_plane_size(vb2, 0) < size) |
| 90 | return -EINVAL; | 106 | return -EINVAL; |
| 91 | 107 | ||
| 92 | if (buf->vb.size != size) { | 108 | vb2_set_plane_payload(vb2, 0, size); |
| 93 | saa7134_dma_free(q,buf); | 109 | vb2->v4l2_buf.field = dev->field; |
| 94 | } | ||
| 95 | |||
| 96 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
| 97 | |||
| 98 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | ||
| 99 | |||
| 100 | dprintk("buffer_prepare: needs_init\n"); | ||
| 101 | |||
| 102 | buf->vb.width = llength; | ||
| 103 | buf->vb.height = lines; | ||
| 104 | buf->vb.size = size; | ||
| 105 | buf->pt = &dev->ts.pt_ts; | ||
| 106 | |||
| 107 | err = videobuf_iolock(q,&buf->vb,NULL); | ||
| 108 | if (err) | ||
| 109 | goto oops; | ||
| 110 | err = saa7134_pgtable_build(dev->pci,buf->pt, | ||
| 111 | dma->sglist, | ||
| 112 | dma->sglen, | ||
| 113 | saa7134_buffer_startpage(buf)); | ||
| 114 | if (err) | ||
| 115 | goto oops; | ||
| 116 | } | ||
| 117 | |||
| 118 | buf->vb.state = VIDEOBUF_PREPARED; | ||
| 119 | buf->activate = buffer_activate; | ||
| 120 | buf->vb.field = field; | ||
| 121 | return 0; | ||
| 122 | 110 | ||
| 123 | oops: | 111 | ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); |
| 124 | saa7134_dma_free(q,buf); | 112 | if (!ret) |
| 125 | return err; | 113 | return -EIO; |
| 114 | return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, | ||
| 115 | saa7134_buffer_startpage(buf)); | ||
| 126 | } | 116 | } |
| 117 | EXPORT_SYMBOL_GPL(saa7134_ts_buffer_prepare); | ||
| 127 | 118 | ||
| 128 | static int | 119 | void saa7134_ts_buffer_finish(struct vb2_buffer *vb2) |
| 129 | buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | ||
| 130 | { | 120 | { |
| 131 | struct saa7134_dev *dev = q->priv_data; | 121 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; |
| 122 | struct saa7134_dev *dev = dmaq->dev; | ||
| 123 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | ||
| 124 | struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); | ||
| 132 | 125 | ||
| 133 | *size = TS_PACKET_SIZE * dev->ts.nr_packets; | 126 | dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); |
| 134 | if (0 == *count) | 127 | } |
| 135 | *count = dev->ts.nr_bufs; | 128 | EXPORT_SYMBOL_GPL(saa7134_ts_buffer_finish); |
| 136 | *count = saa7134_buffer_count(*size,*count); | ||
| 137 | 129 | ||
| 130 | int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, | ||
| 131 | unsigned int *nbuffers, unsigned int *nplanes, | ||
| 132 | unsigned int sizes[], void *alloc_ctxs[]) | ||
| 133 | { | ||
| 134 | struct saa7134_dmaqueue *dmaq = q->drv_priv; | ||
| 135 | struct saa7134_dev *dev = dmaq->dev; | ||
| 136 | int size = TS_PACKET_SIZE * dev->ts.nr_packets; | ||
| 137 | |||
| 138 | if (0 == *nbuffers) | ||
| 139 | *nbuffers = dev->ts.nr_bufs; | ||
| 140 | *nbuffers = saa7134_buffer_count(size, *nbuffers); | ||
| 141 | if (*nbuffers < 3) | ||
| 142 | *nbuffers = 3; | ||
| 143 | *nplanes = 1; | ||
| 144 | sizes[0] = size; | ||
| 138 | return 0; | 145 | return 0; |
| 139 | } | 146 | } |
| 147 | EXPORT_SYMBOL_GPL(saa7134_ts_queue_setup); | ||
| 140 | 148 | ||
| 141 | static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 149 | int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count) |
| 142 | { | 150 | { |
| 143 | struct saa7134_dev *dev = q->priv_data; | 151 | struct saa7134_dmaqueue *dmaq = vq->drv_priv; |
| 144 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 152 | struct saa7134_dev *dev = dmaq->dev; |
| 145 | 153 | ||
| 146 | saa7134_buffer_queue(dev,&dev->ts_q,buf); | 154 | /* |
| 155 | * Planar video capture and TS share the same DMA channel, | ||
| 156 | * so only one can be active at a time. | ||
| 157 | */ | ||
| 158 | if (vb2_is_busy(&dev->video_vbq) && dev->fmt->planar) { | ||
| 159 | struct saa7134_buf *buf, *tmp; | ||
| 160 | |||
| 161 | list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) { | ||
| 162 | list_del(&buf->entry); | ||
| 163 | vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED); | ||
| 164 | } | ||
| 165 | if (dmaq->curr) { | ||
| 166 | vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED); | ||
| 167 | dmaq->curr = NULL; | ||
| 168 | } | ||
| 169 | return -EBUSY; | ||
| 170 | } | ||
| 171 | dmaq->seq_nr = 0; | ||
| 172 | return 0; | ||
| 147 | } | 173 | } |
| 174 | EXPORT_SYMBOL_GPL(saa7134_ts_start_streaming); | ||
| 148 | 175 | ||
| 149 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 176 | void saa7134_ts_stop_streaming(struct vb2_queue *vq) |
| 150 | { | 177 | { |
| 151 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 178 | struct saa7134_dmaqueue *dmaq = vq->drv_priv; |
| 152 | struct saa7134_dev *dev = q->priv_data; | 179 | struct saa7134_dev *dev = dmaq->dev; |
| 153 | |||
| 154 | if (dev->ts_started) | ||
| 155 | saa7134_ts_stop(dev); | ||
| 156 | 180 | ||
| 157 | saa7134_dma_free(q,buf); | 181 | saa7134_ts_stop(dev); |
| 182 | saa7134_stop_streaming(dev, dmaq); | ||
| 158 | } | 183 | } |
| 159 | 184 | EXPORT_SYMBOL_GPL(saa7134_ts_stop_streaming); | |
| 160 | struct videobuf_queue_ops saa7134_ts_qops = { | 185 | |
| 161 | .buf_setup = buffer_setup, | 186 | struct vb2_ops saa7134_ts_qops = { |
| 162 | .buf_prepare = buffer_prepare, | 187 | .queue_setup = saa7134_ts_queue_setup, |
| 163 | .buf_queue = buffer_queue, | 188 | .buf_init = saa7134_ts_buffer_init, |
| 164 | .buf_release = buffer_release, | 189 | .buf_prepare = saa7134_ts_buffer_prepare, |
| 190 | .buf_finish = saa7134_ts_buffer_finish, | ||
| 191 | .buf_queue = saa7134_vb2_buffer_queue, | ||
| 192 | .wait_prepare = vb2_ops_wait_prepare, | ||
| 193 | .wait_finish = vb2_ops_wait_finish, | ||
| 194 | .stop_streaming = saa7134_ts_stop_streaming, | ||
| 165 | }; | 195 | }; |
| 166 | EXPORT_SYMBOL_GPL(saa7134_ts_qops); | 196 | EXPORT_SYMBOL_GPL(saa7134_ts_qops); |
| 167 | 197 | ||
| @@ -213,7 +243,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev) | |||
| 213 | dev->ts_q.dev = dev; | 243 | dev->ts_q.dev = dev; |
| 214 | dev->ts_q.need_two = 1; | 244 | dev->ts_q.need_two = 1; |
| 215 | dev->ts_started = 0; | 245 | dev->ts_started = 0; |
| 216 | saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts); | 246 | saa7134_pgtable_alloc(dev->pci, &dev->ts_q.pt); |
| 217 | 247 | ||
| 218 | /* init TS hw */ | 248 | /* init TS hw */ |
| 219 | saa7134_ts_init_hw(dev); | 249 | saa7134_ts_init_hw(dev); |
| @@ -226,7 +256,8 @@ int saa7134_ts_stop(struct saa7134_dev *dev) | |||
| 226 | { | 256 | { |
| 227 | dprintk("TS stop\n"); | 257 | dprintk("TS stop\n"); |
| 228 | 258 | ||
| 229 | BUG_ON(!dev->ts_started); | 259 | if (!dev->ts_started) |
| 260 | return 0; | ||
| 230 | 261 | ||
| 231 | /* Stop TS stream */ | 262 | /* Stop TS stream */ |
| 232 | switch (saa7134_boards[dev->board].ts_type) { | 263 | switch (saa7134_boards[dev->board].ts_type) { |
| @@ -247,7 +278,8 @@ int saa7134_ts_start(struct saa7134_dev *dev) | |||
| 247 | { | 278 | { |
| 248 | dprintk("TS start\n"); | 279 | dprintk("TS start\n"); |
| 249 | 280 | ||
| 250 | BUG_ON(dev->ts_started); | 281 | if (WARN_ON(dev->ts_started)) |
| 282 | return 0; | ||
| 251 | 283 | ||
| 252 | /* dma: setup channel 5 (= TS) */ | 284 | /* dma: setup channel 5 (= TS) */ |
| 253 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); | 285 | saa_writeb(SAA7134_TS_DMA0, (dev->ts.nr_packets - 1) & 0xff); |
| @@ -259,7 +291,7 @@ int saa7134_ts_start(struct saa7134_dev *dev) | |||
| 259 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); | 291 | saa_writel(SAA7134_RS_PITCH(5), TS_PACKET_SIZE); |
| 260 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | | 292 | saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_16 | |
| 261 | SAA7134_RS_CONTROL_ME | | 293 | SAA7134_RS_CONTROL_ME | |
| 262 | (dev->ts.pt_ts.dma >> 12)); | 294 | (dev->ts_q.pt.dma >> 12)); |
| 263 | 295 | ||
| 264 | /* reset hardware TS buffers */ | 296 | /* reset hardware TS buffers */ |
| 265 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); | 297 | saa_writeb(SAA7134_TS_SERIAL1, 0x00); |
| @@ -293,7 +325,7 @@ int saa7134_ts_start(struct saa7134_dev *dev) | |||
| 293 | 325 | ||
| 294 | int saa7134_ts_fini(struct saa7134_dev *dev) | 326 | int saa7134_ts_fini(struct saa7134_dev *dev) |
| 295 | { | 327 | { |
| 296 | saa7134_pgtable_free(dev->pci,&dev->ts.pt_ts); | 328 | saa7134_pgtable_free(dev->pci, &dev->ts_q.pt); |
| 297 | return 0; | 329 | return 0; |
| 298 | } | 330 | } |
| 299 | 331 | ||
| @@ -303,25 +335,18 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) | |||
| 303 | 335 | ||
| 304 | spin_lock(&dev->slock); | 336 | spin_lock(&dev->slock); |
| 305 | if (dev->ts_q.curr) { | 337 | if (dev->ts_q.curr) { |
| 306 | field = dev->ts_q.curr->vb.field; | 338 | field = dev->ts_field; |
| 307 | if (field == V4L2_FIELD_TOP) { | 339 | if (field != V4L2_FIELD_TOP) { |
| 308 | if ((status & 0x100000) != 0x000000) | 340 | if ((status & 0x100000) != 0x000000) |
| 309 | goto done; | 341 | goto done; |
| 310 | } else { | 342 | } else { |
| 311 | if ((status & 0x100000) != 0x100000) | 343 | if ((status & 0x100000) != 0x100000) |
| 312 | goto done; | 344 | goto done; |
| 313 | } | 345 | } |
| 314 | saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE); | 346 | saa7134_buffer_finish(dev, &dev->ts_q, VB2_BUF_STATE_DONE); |
| 315 | } | 347 | } |
| 316 | saa7134_buffer_next(dev,&dev->ts_q); | 348 | saa7134_buffer_next(dev,&dev->ts_q); |
| 317 | 349 | ||
| 318 | done: | 350 | done: |
| 319 | spin_unlock(&dev->slock); | 351 | spin_unlock(&dev->slock); |
| 320 | } | 352 | } |
| 321 | |||
| 322 | /* ----------------------------------------------------------- */ | ||
| 323 | /* | ||
| 324 | * Local variables: | ||
| 325 | * c-basic-offset: 8 | ||
| 326 | * End: | ||
| 327 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c index 0f34e09d98dc..3afbcb70b518 100644 --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c | |||
| @@ -1079,10 +1079,3 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) | |||
| 1079 | 1079 | ||
| 1080 | EXPORT_SYMBOL(saa_dsp_writel); | 1080 | EXPORT_SYMBOL(saa_dsp_writel); |
| 1081 | EXPORT_SYMBOL(saa7134_tvaudio_setmute); | 1081 | EXPORT_SYMBOL(saa7134_tvaudio_setmute); |
| 1082 | |||
| 1083 | /* ----------------------------------------------------------- */ | ||
| 1084 | /* | ||
| 1085 | * Local variables: | ||
| 1086 | * c-basic-offset: 8 | ||
| 1087 | * End: | ||
| 1088 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index d4da18d049f3..c06dbe17a87f 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c | |||
| @@ -67,10 +67,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf, | |||
| 67 | saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00); | 67 | saa_writeb(SAA7134_VBI_PHASE_OFFSET_LUMA(task), 0x00); |
| 68 | saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00); | 68 | saa_writeb(SAA7134_VBI_PHASE_OFFSET_CHROMA(task), 0x00); |
| 69 | 69 | ||
| 70 | saa_writeb(SAA7134_VBI_H_LEN1(task), buf->vb.width & 0xff); | 70 | saa_writeb(SAA7134_VBI_H_LEN1(task), dev->vbi_hlen & 0xff); |
| 71 | saa_writeb(SAA7134_VBI_H_LEN2(task), buf->vb.width >> 8); | 71 | saa_writeb(SAA7134_VBI_H_LEN2(task), dev->vbi_hlen >> 8); |
| 72 | saa_writeb(SAA7134_VBI_V_LEN1(task), buf->vb.height & 0xff); | 72 | saa_writeb(SAA7134_VBI_V_LEN1(task), dev->vbi_vlen & 0xff); |
| 73 | saa_writeb(SAA7134_VBI_V_LEN2(task), buf->vb.height >> 8); | 73 | saa_writeb(SAA7134_VBI_V_LEN2(task), dev->vbi_vlen >> 8); |
| 74 | 74 | ||
| 75 | saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00); | 75 | saa_andorb(SAA7134_DATA_PATH(task), 0xc0, 0x00); |
| 76 | } | 76 | } |
| @@ -81,14 +81,14 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
| 81 | struct saa7134_buf *buf, | 81 | struct saa7134_buf *buf, |
| 82 | struct saa7134_buf *next) | 82 | struct saa7134_buf *next) |
| 83 | { | 83 | { |
| 84 | unsigned long control,base; | 84 | struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv; |
| 85 | unsigned long control, base; | ||
| 85 | 86 | ||
| 86 | dprintk("buffer_activate [%p]\n",buf); | 87 | dprintk("buffer_activate [%p]\n", buf); |
| 87 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
| 88 | buf->top_seen = 0; | 88 | buf->top_seen = 0; |
| 89 | 89 | ||
| 90 | task_init(dev,buf,TASK_A); | 90 | task_init(dev, buf, TASK_A); |
| 91 | task_init(dev,buf,TASK_B); | 91 | task_init(dev, buf, TASK_B); |
| 92 | saa_writeb(SAA7134_OFMT_DATA_A, 0x06); | 92 | saa_writeb(SAA7134_OFMT_DATA_A, 0x06); |
| 93 | saa_writeb(SAA7134_OFMT_DATA_B, 0x06); | 93 | saa_writeb(SAA7134_OFMT_DATA_B, 0x06); |
| 94 | 94 | ||
| @@ -96,107 +96,99 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
| 96 | base = saa7134_buffer_base(buf); | 96 | base = saa7134_buffer_base(buf); |
| 97 | control = SAA7134_RS_CONTROL_BURST_16 | | 97 | control = SAA7134_RS_CONTROL_BURST_16 | |
| 98 | SAA7134_RS_CONTROL_ME | | 98 | SAA7134_RS_CONTROL_ME | |
| 99 | (buf->pt->dma >> 12); | 99 | (dmaq->pt.dma >> 12); |
| 100 | saa_writel(SAA7134_RS_BA1(2),base); | 100 | saa_writel(SAA7134_RS_BA1(2), base); |
| 101 | saa_writel(SAA7134_RS_BA2(2),base + buf->vb.size/2); | 101 | saa_writel(SAA7134_RS_BA2(2), base + dev->vbi_hlen * dev->vbi_vlen); |
| 102 | saa_writel(SAA7134_RS_PITCH(2),buf->vb.width); | 102 | saa_writel(SAA7134_RS_PITCH(2), dev->vbi_hlen); |
| 103 | saa_writel(SAA7134_RS_CONTROL(2),control); | 103 | saa_writel(SAA7134_RS_CONTROL(2), control); |
| 104 | saa_writel(SAA7134_RS_BA1(3),base); | 104 | saa_writel(SAA7134_RS_BA1(3), base); |
| 105 | saa_writel(SAA7134_RS_BA2(3),base + buf->vb.size/2); | 105 | saa_writel(SAA7134_RS_BA2(3), base + dev->vbi_hlen * dev->vbi_vlen); |
| 106 | saa_writel(SAA7134_RS_PITCH(3),buf->vb.width); | 106 | saa_writel(SAA7134_RS_PITCH(3), dev->vbi_hlen); |
| 107 | saa_writel(SAA7134_RS_CONTROL(3),control); | 107 | saa_writel(SAA7134_RS_CONTROL(3), control); |
| 108 | 108 | ||
| 109 | /* start DMA */ | 109 | /* start DMA */ |
| 110 | saa7134_set_dmabits(dev); | 110 | saa7134_set_dmabits(dev); |
| 111 | mod_timer(&dev->vbi_q.timeout, jiffies+BUFFER_TIMEOUT); | 111 | mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT); |
| 112 | 112 | ||
| 113 | return 0; | 113 | return 0; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | static int buffer_prepare(struct videobuf_queue *q, | 116 | static int buffer_prepare(struct vb2_buffer *vb2) |
| 117 | struct videobuf_buffer *vb, | ||
| 118 | enum v4l2_field field) | ||
| 119 | { | 117 | { |
| 120 | struct saa7134_dev *dev = q->priv_data; | 118 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; |
| 121 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 119 | struct saa7134_dev *dev = dmaq->dev; |
| 122 | struct saa7134_tvnorm *norm = dev->tvnorm; | 120 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); |
| 123 | unsigned int lines, llength, size; | 121 | struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); |
| 124 | int err; | 122 | unsigned int size; |
| 125 | 123 | int ret; | |
| 126 | lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1; | 124 | |
| 127 | if (lines > VBI_LINE_COUNT) | 125 | if (dma->sgl->offset) { |
| 128 | lines = VBI_LINE_COUNT; | 126 | pr_err("The buffer is not page-aligned\n"); |
| 129 | llength = VBI_LINE_LENGTH; | ||
| 130 | size = lines * llength * 2; | ||
| 131 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | ||
| 132 | return -EINVAL; | 127 | return -EINVAL; |
| 133 | |||
| 134 | if (buf->vb.size != size) | ||
| 135 | saa7134_dma_free(q,buf); | ||
| 136 | |||
| 137 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
| 138 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | ||
| 139 | |||
| 140 | buf->vb.width = llength; | ||
| 141 | buf->vb.height = lines; | ||
| 142 | buf->vb.size = size; | ||
| 143 | buf->pt = &dev->pt_vbi; | ||
| 144 | |||
| 145 | err = videobuf_iolock(q,&buf->vb,NULL); | ||
| 146 | if (err) | ||
| 147 | goto oops; | ||
| 148 | err = saa7134_pgtable_build(dev->pci,buf->pt, | ||
| 149 | dma->sglist, | ||
| 150 | dma->sglen, | ||
| 151 | saa7134_buffer_startpage(buf)); | ||
| 152 | if (err) | ||
| 153 | goto oops; | ||
| 154 | } | 128 | } |
| 155 | buf->vb.state = VIDEOBUF_PREPARED; | 129 | size = dev->vbi_hlen * dev->vbi_vlen * 2; |
| 156 | buf->activate = buffer_activate; | 130 | if (vb2_plane_size(vb2, 0) < size) |
| 157 | buf->vb.field = field; | 131 | return -EINVAL; |
| 158 | return 0; | 132 | |
| 133 | vb2_set_plane_payload(vb2, 0, size); | ||
| 159 | 134 | ||
| 160 | oops: | 135 | ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); |
| 161 | saa7134_dma_free(q,buf); | 136 | if (!ret) |
| 162 | return err; | 137 | return -EIO; |
| 138 | return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, | ||
| 139 | saa7134_buffer_startpage(buf)); | ||
| 163 | } | 140 | } |
| 164 | 141 | ||
| 165 | static int | 142 | static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, |
| 166 | buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | 143 | unsigned int *nbuffers, unsigned int *nplanes, |
| 144 | unsigned int sizes[], void *alloc_ctxs[]) | ||
| 167 | { | 145 | { |
| 168 | struct saa7134_dev *dev = q->priv_data; | 146 | struct saa7134_dmaqueue *dmaq = q->drv_priv; |
| 169 | int llength,lines; | 147 | struct saa7134_dev *dev = dmaq->dev; |
| 170 | 148 | unsigned int size; | |
| 171 | lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1; | 149 | |
| 172 | llength = VBI_LINE_LENGTH; | 150 | dev->vbi_vlen = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 + 1; |
| 173 | *size = lines * llength * 2; | 151 | if (dev->vbi_vlen > VBI_LINE_COUNT) |
| 174 | if (0 == *count) | 152 | dev->vbi_vlen = VBI_LINE_COUNT; |
| 175 | *count = vbibufs; | 153 | dev->vbi_hlen = VBI_LINE_LENGTH; |
| 176 | *count = saa7134_buffer_count(*size,*count); | 154 | size = dev->vbi_hlen * dev->vbi_vlen * 2; |
| 155 | |||
| 156 | *nbuffers = saa7134_buffer_count(size, *nbuffers); | ||
| 157 | *nplanes = 1; | ||
| 158 | sizes[0] = size; | ||
| 177 | return 0; | 159 | return 0; |
| 178 | } | 160 | } |
| 179 | 161 | ||
| 180 | static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 162 | static int buffer_init(struct vb2_buffer *vb2) |
| 181 | { | 163 | { |
| 182 | struct saa7134_dev *dev = q->priv_data; | 164 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; |
| 183 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 165 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); |
| 184 | 166 | ||
| 185 | saa7134_buffer_queue(dev,&dev->vbi_q,buf); | 167 | dmaq->curr = NULL; |
| 168 | buf->activate = buffer_activate; | ||
| 169 | return 0; | ||
| 186 | } | 170 | } |
| 187 | 171 | ||
| 188 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 172 | static void buffer_finish(struct vb2_buffer *vb2) |
| 189 | { | 173 | { |
| 190 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 174 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; |
| 175 | struct saa7134_dev *dev = dmaq->dev; | ||
| 176 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | ||
| 177 | struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); | ||
| 191 | 178 | ||
| 192 | saa7134_dma_free(q,buf); | 179 | dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); |
| 193 | } | 180 | } |
| 194 | 181 | ||
| 195 | struct videobuf_queue_ops saa7134_vbi_qops = { | 182 | struct vb2_ops saa7134_vbi_qops = { |
| 196 | .buf_setup = buffer_setup, | 183 | .queue_setup = queue_setup, |
| 197 | .buf_prepare = buffer_prepare, | 184 | .buf_init = buffer_init, |
| 198 | .buf_queue = buffer_queue, | 185 | .buf_prepare = buffer_prepare, |
| 199 | .buf_release = buffer_release, | 186 | .buf_finish = buffer_finish, |
| 187 | .buf_queue = saa7134_vb2_buffer_queue, | ||
| 188 | .wait_prepare = vb2_ops_wait_prepare, | ||
| 189 | .wait_finish = vb2_ops_wait_finish, | ||
| 190 | .start_streaming = saa7134_vb2_start_streaming, | ||
| 191 | .stop_streaming = saa7134_vb2_stop_streaming, | ||
| 200 | }; | 192 | }; |
| 201 | 193 | ||
| 202 | /* ------------------------------------------------------------------ */ | 194 | /* ------------------------------------------------------------------ */ |
| @@ -226,7 +218,6 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status) | |||
| 226 | { | 218 | { |
| 227 | spin_lock(&dev->slock); | 219 | spin_lock(&dev->slock); |
| 228 | if (dev->vbi_q.curr) { | 220 | if (dev->vbi_q.curr) { |
| 229 | dev->vbi_fieldcount++; | ||
| 230 | /* make sure we have seen both fields */ | 221 | /* make sure we have seen both fields */ |
| 231 | if ((status & 0x10) == 0x00) { | 222 | if ((status & 0x10) == 0x00) { |
| 232 | dev->vbi_q.curr->top_seen = 1; | 223 | dev->vbi_q.curr->top_seen = 1; |
| @@ -235,18 +226,10 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status) | |||
| 235 | if (!dev->vbi_q.curr->top_seen) | 226 | if (!dev->vbi_q.curr->top_seen) |
| 236 | goto done; | 227 | goto done; |
| 237 | 228 | ||
| 238 | dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount; | 229 | saa7134_buffer_finish(dev, &dev->vbi_q, VB2_BUF_STATE_DONE); |
| 239 | saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE); | ||
| 240 | } | 230 | } |
| 241 | saa7134_buffer_next(dev,&dev->vbi_q); | 231 | saa7134_buffer_next(dev, &dev->vbi_q); |
| 242 | 232 | ||
| 243 | done: | 233 | done: |
| 244 | spin_unlock(&dev->slock); | 234 | spin_unlock(&dev->slock); |
| 245 | } | 235 | } |
| 246 | |||
| 247 | /* ----------------------------------------------------------- */ | ||
| 248 | /* | ||
| 249 | * Local variables: | ||
| 250 | * c-basic-offset: 8 | ||
| 251 | * End: | ||
| 252 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index eb472b5b26a0..d37599980768 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c | |||
| @@ -381,42 +381,6 @@ static struct saa7134_format* format_by_fourcc(unsigned int fourcc) | |||
| 381 | return NULL; | 381 | return NULL; |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | /* ----------------------------------------------------------------------- */ | ||
| 385 | /* resource management */ | ||
| 386 | |||
| 387 | static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit) | ||
| 388 | { | ||
| 389 | if (fh->resources & bit) | ||
| 390 | /* have it already allocated */ | ||
| 391 | return 1; | ||
| 392 | |||
| 393 | /* is it free? */ | ||
| 394 | mutex_lock(&dev->lock); | ||
| 395 | if (dev->resources & bit) { | ||
| 396 | /* no, someone else uses it */ | ||
| 397 | mutex_unlock(&dev->lock); | ||
| 398 | return 0; | ||
| 399 | } | ||
| 400 | /* it's free, grab it */ | ||
| 401 | fh->resources |= bit; | ||
| 402 | dev->resources |= bit; | ||
| 403 | dprintk("res: get %d\n",bit); | ||
| 404 | mutex_unlock(&dev->lock); | ||
| 405 | return 1; | ||
| 406 | } | ||
| 407 | |||
| 408 | static | ||
| 409 | void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) | ||
| 410 | { | ||
| 411 | BUG_ON((fh->resources & bits) != bits); | ||
| 412 | |||
| 413 | mutex_lock(&dev->lock); | ||
| 414 | fh->resources &= ~bits; | ||
| 415 | dev->resources &= ~bits; | ||
| 416 | dprintk("res: put %d\n",bits); | ||
| 417 | mutex_unlock(&dev->lock); | ||
| 418 | } | ||
| 419 | |||
| 420 | /* ------------------------------------------------------------------ */ | 384 | /* ------------------------------------------------------------------ */ |
| 421 | 385 | ||
| 422 | static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) | 386 | static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) |
| @@ -452,19 +416,26 @@ static void video_mux(struct saa7134_dev *dev, int input) | |||
| 452 | 416 | ||
| 453 | static void saa7134_set_decoder(struct saa7134_dev *dev) | 417 | static void saa7134_set_decoder(struct saa7134_dev *dev) |
| 454 | { | 418 | { |
| 455 | int luma_control, sync_control, mux; | 419 | int luma_control, sync_control, chroma_ctrl1, mux; |
| 456 | 420 | ||
| 457 | struct saa7134_tvnorm *norm = dev->tvnorm; | 421 | struct saa7134_tvnorm *norm = dev->tvnorm; |
| 458 | mux = card_in(dev, dev->ctl_input).vmux; | 422 | mux = card_in(dev, dev->ctl_input).vmux; |
| 459 | 423 | ||
| 460 | luma_control = norm->luma_control; | 424 | luma_control = norm->luma_control; |
| 461 | sync_control = norm->sync_control; | 425 | sync_control = norm->sync_control; |
| 426 | chroma_ctrl1 = norm->chroma_ctrl1; | ||
| 462 | 427 | ||
| 463 | if (mux > 5) | 428 | if (mux > 5) |
| 464 | luma_control |= 0x80; /* svideo */ | 429 | luma_control |= 0x80; /* svideo */ |
| 465 | if (noninterlaced || dev->nosignal) | 430 | if (noninterlaced || dev->nosignal) |
| 466 | sync_control |= 0x20; | 431 | sync_control |= 0x20; |
| 467 | 432 | ||
| 433 | /* switch on auto standard detection */ | ||
| 434 | sync_control |= SAA7134_SYNC_CTRL_AUFD; | ||
| 435 | chroma_ctrl1 |= SAA7134_CHROMA_CTRL1_AUTO0; | ||
| 436 | chroma_ctrl1 &= ~SAA7134_CHROMA_CTRL1_FCTC; | ||
| 437 | luma_control &= ~SAA7134_LUMA_CTRL_LDEL; | ||
| 438 | |||
| 468 | /* setup video decoder */ | 439 | /* setup video decoder */ |
| 469 | saa_writeb(SAA7134_INCR_DELAY, 0x08); | 440 | saa_writeb(SAA7134_INCR_DELAY, 0x08); |
| 470 | saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux); | 441 | saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux); |
| @@ -487,7 +458,7 @@ static void saa7134_set_decoder(struct saa7134_dev *dev) | |||
| 487 | dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); | 458 | dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation); |
| 488 | 459 | ||
| 489 | saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue); | 460 | saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue); |
| 490 | saa_writeb(SAA7134_CHROMA_CTRL1, norm->chroma_ctrl1); | 461 | saa_writeb(SAA7134_CHROMA_CTRL1, chroma_ctrl1); |
| 491 | saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain); | 462 | saa_writeb(SAA7134_CHROMA_GAIN, norm->chroma_gain); |
| 492 | 463 | ||
| 493 | saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2); | 464 | saa_writeb(SAA7134_CHROMA_CTRL2, norm->chroma_ctrl2); |
| @@ -506,10 +477,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev) | |||
| 506 | saa7134_set_decoder(dev); | 477 | saa7134_set_decoder(dev); |
| 507 | 478 | ||
| 508 | if (card_in(dev, dev->ctl_input).tv) | 479 | if (card_in(dev, dev->ctl_input).tv) |
| 509 | saa_call_all(dev, core, s_std, dev->tvnorm->id); | 480 | saa_call_all(dev, video, s_std, dev->tvnorm->id); |
| 510 | /* Set the correct norm for the saa6752hs. This function | 481 | /* Set the correct norm for the saa6752hs. This function |
| 511 | does nothing if there is no saa6752hs. */ | 482 | does nothing if there is no saa6752hs. */ |
| 512 | saa_call_empress(dev, core, s_std, dev->tvnorm->id); | 483 | saa_call_empress(dev, video, s_std, dev->tvnorm->id); |
| 513 | } | 484 | } |
| 514 | 485 | ||
| 515 | static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) | 486 | static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) |
| @@ -817,35 +788,35 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
| 817 | struct saa7134_buf *buf, | 788 | struct saa7134_buf *buf, |
| 818 | struct saa7134_buf *next) | 789 | struct saa7134_buf *next) |
| 819 | { | 790 | { |
| 791 | struct saa7134_dmaqueue *dmaq = buf->vb2.vb2_queue->drv_priv; | ||
| 820 | unsigned long base,control,bpl; | 792 | unsigned long base,control,bpl; |
| 821 | unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ | 793 | unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ |
| 822 | 794 | ||
| 823 | dprintk("buffer_activate buf=%p\n",buf); | 795 | dprintk("buffer_activate buf=%p\n",buf); |
| 824 | buf->vb.state = VIDEOBUF_ACTIVE; | ||
| 825 | buf->top_seen = 0; | 796 | buf->top_seen = 0; |
| 826 | 797 | ||
| 827 | set_size(dev,TASK_A,buf->vb.width,buf->vb.height, | 798 | set_size(dev, TASK_A, dev->width, dev->height, |
| 828 | V4L2_FIELD_HAS_BOTH(buf->vb.field)); | 799 | V4L2_FIELD_HAS_BOTH(dev->field)); |
| 829 | if (buf->fmt->yuv) | 800 | if (dev->fmt->yuv) |
| 830 | saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03); | 801 | saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03); |
| 831 | else | 802 | else |
| 832 | saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01); | 803 | saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01); |
| 833 | saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm); | 804 | saa_writeb(SAA7134_OFMT_VIDEO_A, dev->fmt->pm); |
| 834 | 805 | ||
| 835 | /* DMA: setup channel 0 (= Video Task A0) */ | 806 | /* DMA: setup channel 0 (= Video Task A0) */ |
| 836 | base = saa7134_buffer_base(buf); | 807 | base = saa7134_buffer_base(buf); |
| 837 | if (buf->fmt->planar) | 808 | if (dev->fmt->planar) |
| 838 | bpl = buf->vb.width; | 809 | bpl = dev->width; |
| 839 | else | 810 | else |
| 840 | bpl = (buf->vb.width * buf->fmt->depth) / 8; | 811 | bpl = (dev->width * dev->fmt->depth) / 8; |
| 841 | control = SAA7134_RS_CONTROL_BURST_16 | | 812 | control = SAA7134_RS_CONTROL_BURST_16 | |
| 842 | SAA7134_RS_CONTROL_ME | | 813 | SAA7134_RS_CONTROL_ME | |
| 843 | (buf->pt->dma >> 12); | 814 | (dmaq->pt.dma >> 12); |
| 844 | if (buf->fmt->bswap) | 815 | if (dev->fmt->bswap) |
| 845 | control |= SAA7134_RS_CONTROL_BSWAP; | 816 | control |= SAA7134_RS_CONTROL_BSWAP; |
| 846 | if (buf->fmt->wswap) | 817 | if (dev->fmt->wswap) |
| 847 | control |= SAA7134_RS_CONTROL_WSWAP; | 818 | control |= SAA7134_RS_CONTROL_WSWAP; |
| 848 | if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) { | 819 | if (V4L2_FIELD_HAS_BOTH(dev->field)) { |
| 849 | /* interlaced */ | 820 | /* interlaced */ |
| 850 | saa_writel(SAA7134_RS_BA1(0),base); | 821 | saa_writel(SAA7134_RS_BA1(0),base); |
| 851 | saa_writel(SAA7134_RS_BA2(0),base+bpl); | 822 | saa_writel(SAA7134_RS_BA2(0),base+bpl); |
| @@ -858,17 +829,17 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
| 858 | } | 829 | } |
| 859 | saa_writel(SAA7134_RS_CONTROL(0),control); | 830 | saa_writel(SAA7134_RS_CONTROL(0),control); |
| 860 | 831 | ||
| 861 | if (buf->fmt->planar) { | 832 | if (dev->fmt->planar) { |
| 862 | /* DMA: setup channel 4+5 (= planar task A) */ | 833 | /* DMA: setup channel 4+5 (= planar task A) */ |
| 863 | bpl_uv = bpl >> buf->fmt->hshift; | 834 | bpl_uv = bpl >> dev->fmt->hshift; |
| 864 | lines_uv = buf->vb.height >> buf->fmt->vshift; | 835 | lines_uv = dev->height >> dev->fmt->vshift; |
| 865 | base2 = base + bpl * buf->vb.height; | 836 | base2 = base + bpl * dev->height; |
| 866 | base3 = base2 + bpl_uv * lines_uv; | 837 | base3 = base2 + bpl_uv * lines_uv; |
| 867 | if (buf->fmt->uvswap) | 838 | if (dev->fmt->uvswap) |
| 868 | tmp = base2, base2 = base3, base3 = tmp; | 839 | tmp = base2, base2 = base3, base3 = tmp; |
| 869 | dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n", | 840 | dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n", |
| 870 | bpl_uv,lines_uv,base2,base3); | 841 | bpl_uv,lines_uv,base2,base3); |
| 871 | if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) { | 842 | if (V4L2_FIELD_HAS_BOTH(dev->field)) { |
| 872 | /* interlaced */ | 843 | /* interlaced */ |
| 873 | saa_writel(SAA7134_RS_BA1(4),base2); | 844 | saa_writel(SAA7134_RS_BA1(4),base2); |
| 874 | saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv); | 845 | saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv); |
| @@ -891,22 +862,65 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
| 891 | 862 | ||
| 892 | /* start DMA */ | 863 | /* start DMA */ |
| 893 | saa7134_set_dmabits(dev); | 864 | saa7134_set_dmabits(dev); |
| 894 | mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT); | 865 | mod_timer(&dmaq->timeout, jiffies + BUFFER_TIMEOUT); |
| 866 | return 0; | ||
| 867 | } | ||
| 868 | |||
| 869 | static int buffer_init(struct vb2_buffer *vb2) | ||
| 870 | { | ||
| 871 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; | ||
| 872 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | ||
| 873 | |||
| 874 | dmaq->curr = NULL; | ||
| 875 | buf->activate = buffer_activate; | ||
| 895 | return 0; | 876 | return 0; |
| 896 | } | 877 | } |
| 897 | 878 | ||
| 898 | static int buffer_prepare(struct videobuf_queue *q, | 879 | static int buffer_prepare(struct vb2_buffer *vb2) |
| 899 | struct videobuf_buffer *vb, | ||
| 900 | enum v4l2_field field) | ||
| 901 | { | 880 | { |
| 902 | struct saa7134_dev *dev = q->priv_data; | 881 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; |
| 903 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 882 | struct saa7134_dev *dev = dmaq->dev; |
| 883 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | ||
| 884 | struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); | ||
| 904 | unsigned int size; | 885 | unsigned int size; |
| 905 | int err; | 886 | int ret; |
| 906 | 887 | ||
| 907 | /* sanity checks */ | 888 | if (dma->sgl->offset) { |
| 908 | if (NULL == dev->fmt) | 889 | pr_err("The buffer is not page-aligned\n"); |
| 909 | return -EINVAL; | 890 | return -EINVAL; |
| 891 | } | ||
| 892 | size = (dev->width * dev->height * dev->fmt->depth) >> 3; | ||
| 893 | if (vb2_plane_size(vb2, 0) < size) | ||
| 894 | return -EINVAL; | ||
| 895 | |||
| 896 | vb2_set_plane_payload(vb2, 0, size); | ||
| 897 | vb2->v4l2_buf.field = dev->field; | ||
| 898 | |||
| 899 | ret = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); | ||
| 900 | if (!ret) | ||
| 901 | return -EIO; | ||
| 902 | return saa7134_pgtable_build(dev->pci, &dmaq->pt, dma->sgl, dma->nents, | ||
| 903 | saa7134_buffer_startpage(buf)); | ||
| 904 | } | ||
| 905 | |||
| 906 | static void buffer_finish(struct vb2_buffer *vb2) | ||
| 907 | { | ||
| 908 | struct saa7134_dmaqueue *dmaq = vb2->vb2_queue->drv_priv; | ||
| 909 | struct saa7134_dev *dev = dmaq->dev; | ||
| 910 | struct saa7134_buf *buf = container_of(vb2, struct saa7134_buf, vb2); | ||
| 911 | struct sg_table *dma = vb2_dma_sg_plane_desc(&buf->vb2, 0); | ||
| 912 | |||
| 913 | dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE); | ||
| 914 | } | ||
| 915 | |||
| 916 | static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, | ||
| 917 | unsigned int *nbuffers, unsigned int *nplanes, | ||
| 918 | unsigned int sizes[], void *alloc_ctxs[]) | ||
| 919 | { | ||
| 920 | struct saa7134_dmaqueue *dmaq = q->drv_priv; | ||
| 921 | struct saa7134_dev *dev = dmaq->dev; | ||
| 922 | int size = dev->fmt->depth * dev->width * dev->height >> 3; | ||
| 923 | |||
| 910 | if (dev->width < 48 || | 924 | if (dev->width < 48 || |
| 911 | dev->height < 32 || | 925 | dev->height < 32 || |
| 912 | dev->width/4 > dev->crop_current.width || | 926 | dev->width/4 > dev->crop_current.width || |
| @@ -914,83 +928,88 @@ static int buffer_prepare(struct videobuf_queue *q, | |||
| 914 | dev->width > dev->crop_bounds.width || | 928 | dev->width > dev->crop_bounds.width || |
| 915 | dev->height > dev->crop_bounds.height) | 929 | dev->height > dev->crop_bounds.height) |
| 916 | return -EINVAL; | 930 | return -EINVAL; |
| 917 | size = (dev->width * dev->height * dev->fmt->depth) >> 3; | ||
| 918 | if (0 != buf->vb.baddr && buf->vb.bsize < size) | ||
| 919 | return -EINVAL; | ||
| 920 | |||
| 921 | dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n", | ||
| 922 | vb->i, dev->width, dev->height, size, v4l2_field_names[field], | ||
| 923 | dev->fmt->name); | ||
| 924 | if (buf->vb.width != dev->width || | ||
| 925 | buf->vb.height != dev->height || | ||
| 926 | buf->vb.size != size || | ||
| 927 | buf->vb.field != field || | ||
| 928 | buf->fmt != dev->fmt) { | ||
| 929 | saa7134_dma_free(q,buf); | ||
| 930 | } | ||
| 931 | 931 | ||
| 932 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 932 | *nbuffers = saa7134_buffer_count(size, *nbuffers); |
| 933 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 933 | *nplanes = 1; |
| 934 | 934 | sizes[0] = size; | |
| 935 | buf->vb.width = dev->width; | ||
| 936 | buf->vb.height = dev->height; | ||
| 937 | buf->vb.size = size; | ||
| 938 | buf->vb.field = field; | ||
| 939 | buf->fmt = dev->fmt; | ||
| 940 | buf->pt = &dev->pt_cap; | ||
| 941 | dev->video_q.curr = NULL; | ||
| 942 | |||
| 943 | err = videobuf_iolock(q,&buf->vb,&dev->ovbuf); | ||
| 944 | if (err) | ||
| 945 | goto oops; | ||
| 946 | err = saa7134_pgtable_build(dev->pci,buf->pt, | ||
| 947 | dma->sglist, | ||
| 948 | dma->sglen, | ||
| 949 | saa7134_buffer_startpage(buf)); | ||
| 950 | if (err) | ||
| 951 | goto oops; | ||
| 952 | } | ||
| 953 | buf->vb.state = VIDEOBUF_PREPARED; | ||
| 954 | buf->activate = buffer_activate; | ||
| 955 | return 0; | 935 | return 0; |
| 956 | |||
| 957 | oops: | ||
| 958 | saa7134_dma_free(q,buf); | ||
| 959 | return err; | ||
| 960 | } | 936 | } |
| 961 | 937 | ||
| 962 | static int | 938 | /* |
| 963 | buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | 939 | * move buffer to hardware queue |
| 940 | */ | ||
| 941 | void saa7134_vb2_buffer_queue(struct vb2_buffer *vb) | ||
| 964 | { | 942 | { |
| 965 | struct saa7134_dev *dev = q->priv_data; | 943 | struct saa7134_dmaqueue *dmaq = vb->vb2_queue->drv_priv; |
| 944 | struct saa7134_dev *dev = dmaq->dev; | ||
| 945 | struct saa7134_buf *buf = container_of(vb, struct saa7134_buf, vb2); | ||
| 966 | 946 | ||
| 967 | *size = dev->fmt->depth * dev->width * dev->height >> 3; | 947 | saa7134_buffer_queue(dev, dmaq, buf); |
| 968 | if (0 == *count) | ||
| 969 | *count = gbuffers; | ||
| 970 | *count = saa7134_buffer_count(*size,*count); | ||
| 971 | return 0; | ||
| 972 | } | 948 | } |
| 949 | EXPORT_SYMBOL_GPL(saa7134_vb2_buffer_queue); | ||
| 973 | 950 | ||
| 974 | static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 951 | int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) |
| 975 | { | 952 | { |
| 976 | struct saa7134_dev *dev = q->priv_data; | 953 | struct saa7134_dmaqueue *dmaq = vq->drv_priv; |
| 977 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 954 | struct saa7134_dev *dev = dmaq->dev; |
| 955 | |||
| 956 | /* | ||
| 957 | * Planar video capture and TS share the same DMA channel, | ||
| 958 | * so only one can be active at a time. | ||
| 959 | */ | ||
| 960 | if (card_is_empress(dev) && vb2_is_busy(&dev->empress_vbq) && | ||
| 961 | dmaq == &dev->video_q && dev->fmt->planar) { | ||
| 962 | struct saa7134_buf *buf, *tmp; | ||
| 978 | 963 | ||
| 979 | saa7134_buffer_queue(dev, &dev->video_q, buf); | 964 | list_for_each_entry_safe(buf, tmp, &dmaq->queue, entry) { |
| 965 | list_del(&buf->entry); | ||
| 966 | vb2_buffer_done(&buf->vb2, VB2_BUF_STATE_QUEUED); | ||
| 967 | } | ||
| 968 | if (dmaq->curr) { | ||
| 969 | vb2_buffer_done(&dmaq->curr->vb2, VB2_BUF_STATE_QUEUED); | ||
| 970 | dmaq->curr = NULL; | ||
| 971 | } | ||
| 972 | return -EBUSY; | ||
| 973 | } | ||
| 974 | |||
| 975 | /* The SAA7134 has a 1K FIFO; the datasheet suggests that when | ||
| 976 | * configured conservatively, there's 22 usec of buffering for video. | ||
| 977 | * We therefore request a DMA latency of 20 usec, giving us 2 usec of | ||
| 978 | * margin in case the FIFO is configured differently to the datasheet. | ||
| 979 | * Unfortunately, I lack register-level documentation to check the | ||
| 980 | * Linux FIFO setup and confirm the perfect value. | ||
| 981 | */ | ||
| 982 | if ((dmaq == &dev->video_q && !vb2_is_streaming(&dev->vbi_vbq)) || | ||
| 983 | (dmaq == &dev->vbi_q && !vb2_is_streaming(&dev->video_vbq))) | ||
| 984 | pm_qos_add_request(&dev->qos_request, | ||
| 985 | PM_QOS_CPU_DMA_LATENCY, 20); | ||
| 986 | dmaq->seq_nr = 0; | ||
| 987 | |||
| 988 | return 0; | ||
| 980 | } | 989 | } |
| 981 | 990 | ||
| 982 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 991 | void saa7134_vb2_stop_streaming(struct vb2_queue *vq) |
| 983 | { | 992 | { |
| 984 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 993 | struct saa7134_dmaqueue *dmaq = vq->drv_priv; |
| 994 | struct saa7134_dev *dev = dmaq->dev; | ||
| 995 | |||
| 996 | saa7134_stop_streaming(dev, dmaq); | ||
| 985 | 997 | ||
| 986 | saa7134_dma_free(q,buf); | 998 | if ((dmaq == &dev->video_q && !vb2_is_streaming(&dev->vbi_vbq)) || |
| 999 | (dmaq == &dev->vbi_q && !vb2_is_streaming(&dev->video_vbq))) | ||
| 1000 | pm_qos_remove_request(&dev->qos_request); | ||
| 987 | } | 1001 | } |
| 988 | 1002 | ||
| 989 | static struct videobuf_queue_ops video_qops = { | 1003 | static struct vb2_ops vb2_qops = { |
| 990 | .buf_setup = buffer_setup, | 1004 | .queue_setup = queue_setup, |
| 991 | .buf_prepare = buffer_prepare, | 1005 | .buf_init = buffer_init, |
| 992 | .buf_queue = buffer_queue, | 1006 | .buf_prepare = buffer_prepare, |
| 993 | .buf_release = buffer_release, | 1007 | .buf_finish = buffer_finish, |
| 1008 | .buf_queue = saa7134_vb2_buffer_queue, | ||
| 1009 | .wait_prepare = vb2_ops_wait_prepare, | ||
| 1010 | .wait_finish = vb2_ops_wait_finish, | ||
| 1011 | .start_streaming = saa7134_vb2_start_streaming, | ||
| 1012 | .stop_streaming = saa7134_vb2_stop_streaming, | ||
| 994 | }; | 1013 | }; |
| 995 | 1014 | ||
| 996 | /* ------------------------------------------------------------------ */ | 1015 | /* ------------------------------------------------------------------ */ |
| @@ -1068,7 +1087,7 @@ static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 1068 | default: | 1087 | default: |
| 1069 | return -EINVAL; | 1088 | return -EINVAL; |
| 1070 | } | 1089 | } |
| 1071 | if (restart_overlay && res_locked(dev, RESOURCE_OVERLAY)) { | 1090 | if (restart_overlay && dev->overlay_owner) { |
| 1072 | spin_lock_irqsave(&dev->slock, flags); | 1091 | spin_lock_irqsave(&dev->slock, flags); |
| 1073 | stop_preview(dev); | 1092 | stop_preview(dev); |
| 1074 | start_preview(dev); | 1093 | start_preview(dev); |
| @@ -1079,182 +1098,57 @@ static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 1079 | 1098 | ||
| 1080 | /* ------------------------------------------------------------------ */ | 1099 | /* ------------------------------------------------------------------ */ |
| 1081 | 1100 | ||
| 1082 | static struct videobuf_queue *saa7134_queue(struct file *file) | 1101 | static inline struct vb2_queue *saa7134_queue(struct file *file) |
| 1083 | { | 1102 | { |
| 1084 | struct video_device *vdev = video_devdata(file); | 1103 | return video_devdata(file)->queue; |
| 1085 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 1086 | struct saa7134_fh *fh = file->private_data; | ||
| 1087 | struct videobuf_queue *q = NULL; | ||
| 1088 | |||
| 1089 | switch (vdev->vfl_type) { | ||
| 1090 | case VFL_TYPE_GRABBER: | ||
| 1091 | q = fh->is_empress ? &dev->empress_tsq : &dev->cap; | ||
| 1092 | break; | ||
| 1093 | case VFL_TYPE_VBI: | ||
| 1094 | q = &dev->vbi; | ||
| 1095 | break; | ||
| 1096 | default: | ||
| 1097 | BUG(); | ||
| 1098 | } | ||
| 1099 | return q; | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | static int saa7134_resource(struct file *file) | ||
| 1103 | { | ||
| 1104 | struct video_device *vdev = video_devdata(file); | ||
| 1105 | struct saa7134_fh *fh = file->private_data; | ||
| 1106 | |||
| 1107 | if (vdev->vfl_type == VFL_TYPE_GRABBER) | ||
| 1108 | return fh->is_empress ? RESOURCE_EMPRESS : RESOURCE_VIDEO; | ||
| 1109 | |||
| 1110 | if (vdev->vfl_type == VFL_TYPE_VBI) | ||
| 1111 | return RESOURCE_VBI; | ||
| 1112 | |||
| 1113 | BUG(); | ||
| 1114 | return 0; | ||
| 1115 | } | 1104 | } |
| 1116 | 1105 | ||
| 1117 | static int video_open(struct file *file) | 1106 | static int video_open(struct file *file) |
| 1118 | { | 1107 | { |
| 1119 | struct video_device *vdev = video_devdata(file); | 1108 | struct video_device *vdev = video_devdata(file); |
| 1120 | struct saa7134_dev *dev = video_drvdata(file); | 1109 | struct saa7134_dev *dev = video_drvdata(file); |
| 1121 | struct saa7134_fh *fh; | 1110 | int ret = v4l2_fh_open(file); |
| 1122 | |||
| 1123 | /* allocate + initialize per filehandle data */ | ||
| 1124 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | ||
| 1125 | if (NULL == fh) | ||
| 1126 | return -ENOMEM; | ||
| 1127 | 1111 | ||
| 1128 | v4l2_fh_init(&fh->fh, vdev); | 1112 | if (ret < 0) |
| 1129 | file->private_data = fh; | 1113 | return ret; |
| 1130 | 1114 | ||
| 1115 | mutex_lock(&dev->lock); | ||
| 1131 | if (vdev->vfl_type == VFL_TYPE_RADIO) { | 1116 | if (vdev->vfl_type == VFL_TYPE_RADIO) { |
| 1132 | /* switch to radio mode */ | 1117 | /* switch to radio mode */ |
| 1133 | saa7134_tvaudio_setinput(dev,&card(dev).radio); | 1118 | saa7134_tvaudio_setinput(dev, &card(dev).radio); |
| 1134 | saa_call_all(dev, tuner, s_radio); | 1119 | saa_call_all(dev, tuner, s_radio); |
| 1135 | } else { | 1120 | } else { |
| 1136 | /* switch to video/vbi mode */ | 1121 | /* switch to video/vbi mode */ |
| 1137 | video_mux(dev,dev->ctl_input); | 1122 | video_mux(dev, dev->ctl_input); |
| 1138 | } | 1123 | } |
| 1139 | v4l2_fh_add(&fh->fh); | 1124 | mutex_unlock(&dev->lock); |
| 1140 | 1125 | ||
| 1141 | return 0; | 1126 | return 0; |
| 1142 | } | 1127 | } |
| 1143 | 1128 | ||
| 1144 | static ssize_t | ||
| 1145 | video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | ||
| 1146 | { | ||
| 1147 | struct video_device *vdev = video_devdata(file); | ||
| 1148 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 1149 | struct saa7134_fh *fh = file->private_data; | ||
| 1150 | |||
| 1151 | switch (vdev->vfl_type) { | ||
| 1152 | case VFL_TYPE_GRABBER: | ||
| 1153 | if (res_locked(dev, RESOURCE_VIDEO)) | ||
| 1154 | return -EBUSY; | ||
| 1155 | return videobuf_read_one(saa7134_queue(file), | ||
| 1156 | data, count, ppos, | ||
| 1157 | file->f_flags & O_NONBLOCK); | ||
| 1158 | case VFL_TYPE_VBI: | ||
| 1159 | if (!res_get(dev, fh, RESOURCE_VBI)) | ||
| 1160 | return -EBUSY; | ||
| 1161 | return videobuf_read_stream(saa7134_queue(file), | ||
| 1162 | data, count, ppos, 1, | ||
| 1163 | file->f_flags & O_NONBLOCK); | ||
| 1164 | break; | ||
| 1165 | default: | ||
| 1166 | BUG(); | ||
| 1167 | return 0; | ||
| 1168 | } | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | static unsigned int | ||
| 1172 | video_poll(struct file *file, struct poll_table_struct *wait) | ||
| 1173 | { | ||
| 1174 | unsigned long req_events = poll_requested_events(wait); | ||
| 1175 | struct video_device *vdev = video_devdata(file); | ||
| 1176 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 1177 | struct saa7134_fh *fh = file->private_data; | ||
| 1178 | struct videobuf_buffer *buf = NULL; | ||
| 1179 | unsigned int rc = 0; | ||
| 1180 | |||
| 1181 | if (v4l2_event_pending(&fh->fh)) | ||
| 1182 | rc = POLLPRI; | ||
| 1183 | else if (req_events & POLLPRI) | ||
| 1184 | poll_wait(file, &fh->fh.wait, wait); | ||
| 1185 | |||
| 1186 | if (vdev->vfl_type == VFL_TYPE_VBI) | ||
| 1187 | return rc | videobuf_poll_stream(file, &dev->vbi, wait); | ||
| 1188 | |||
| 1189 | if (res_check(fh, RESOURCE_VIDEO)) { | ||
| 1190 | mutex_lock(&dev->cap.vb_lock); | ||
| 1191 | if (!list_empty(&dev->cap.stream)) | ||
| 1192 | buf = list_entry(dev->cap.stream.next, struct videobuf_buffer, stream); | ||
| 1193 | } else { | ||
| 1194 | mutex_lock(&dev->cap.vb_lock); | ||
| 1195 | if (UNSET == dev->cap.read_off) { | ||
| 1196 | /* need to capture a new frame */ | ||
| 1197 | if (res_locked(dev, RESOURCE_VIDEO)) | ||
| 1198 | goto err; | ||
| 1199 | if (0 != dev->cap.ops->buf_prepare(&dev->cap, | ||
| 1200 | dev->cap.read_buf, dev->cap.field)) | ||
| 1201 | goto err; | ||
| 1202 | dev->cap.ops->buf_queue(&dev->cap, dev->cap.read_buf); | ||
| 1203 | dev->cap.read_off = 0; | ||
| 1204 | } | ||
| 1205 | buf = dev->cap.read_buf; | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | if (!buf) | ||
| 1209 | goto err; | ||
| 1210 | |||
| 1211 | poll_wait(file, &buf->done, wait); | ||
| 1212 | if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) | ||
| 1213 | rc |= POLLIN | POLLRDNORM; | ||
| 1214 | mutex_unlock(&dev->cap.vb_lock); | ||
| 1215 | return rc; | ||
| 1216 | |||
| 1217 | err: | ||
| 1218 | mutex_unlock(&dev->cap.vb_lock); | ||
| 1219 | return rc | POLLERR; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | static int video_release(struct file *file) | 1129 | static int video_release(struct file *file) |
| 1223 | { | 1130 | { |
| 1224 | struct video_device *vdev = video_devdata(file); | 1131 | struct video_device *vdev = video_devdata(file); |
| 1225 | struct saa7134_dev *dev = video_drvdata(file); | 1132 | struct saa7134_dev *dev = video_drvdata(file); |
| 1226 | struct saa7134_fh *fh = file->private_data; | 1133 | struct v4l2_fh *fh = file->private_data; |
| 1227 | struct saa6588_command cmd; | 1134 | struct saa6588_command cmd; |
| 1228 | unsigned long flags; | 1135 | unsigned long flags; |
| 1229 | 1136 | ||
| 1137 | mutex_lock(&dev->lock); | ||
| 1230 | saa7134_tvaudio_close(dev); | 1138 | saa7134_tvaudio_close(dev); |
| 1231 | 1139 | ||
| 1232 | /* turn off overlay */ | 1140 | /* turn off overlay */ |
| 1233 | if (res_check(fh, RESOURCE_OVERLAY)) { | 1141 | if (fh == dev->overlay_owner) { |
| 1234 | spin_lock_irqsave(&dev->slock,flags); | 1142 | spin_lock_irqsave(&dev->slock,flags); |
| 1235 | stop_preview(dev); | 1143 | stop_preview(dev); |
| 1236 | spin_unlock_irqrestore(&dev->slock,flags); | 1144 | spin_unlock_irqrestore(&dev->slock,flags); |
| 1237 | res_free(dev, fh, RESOURCE_OVERLAY); | 1145 | dev->overlay_owner = NULL; |
| 1238 | } | ||
| 1239 | |||
| 1240 | /* stop video capture */ | ||
| 1241 | if (res_check(fh, RESOURCE_VIDEO)) { | ||
| 1242 | pm_qos_remove_request(&dev->qos_request); | ||
| 1243 | videobuf_streamoff(&dev->cap); | ||
| 1244 | res_free(dev, fh, RESOURCE_VIDEO); | ||
| 1245 | videobuf_mmap_free(&dev->cap); | ||
| 1246 | } | ||
| 1247 | if (dev->cap.read_buf) { | ||
| 1248 | buffer_release(&dev->cap, dev->cap.read_buf); | ||
| 1249 | kfree(dev->cap.read_buf); | ||
| 1250 | } | 1146 | } |
| 1251 | 1147 | ||
| 1252 | /* stop vbi capture */ | 1148 | if (vdev->vfl_type == VFL_TYPE_RADIO) |
| 1253 | if (res_check(fh, RESOURCE_VBI)) { | 1149 | v4l2_fh_release(file); |
| 1254 | videobuf_stop(&dev->vbi); | 1150 | else |
| 1255 | res_free(dev, fh, RESOURCE_VBI); | 1151 | _vb2_fop_release(file, NULL); |
| 1256 | videobuf_mmap_free(&dev->vbi); | ||
| 1257 | } | ||
| 1258 | 1152 | ||
| 1259 | /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/ | 1153 | /* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/ |
| 1260 | saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0); | 1154 | saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0); |
| @@ -1265,19 +1159,11 @@ static int video_release(struct file *file) | |||
| 1265 | saa_call_all(dev, core, s_power, 0); | 1159 | saa_call_all(dev, core, s_power, 0); |
| 1266 | if (vdev->vfl_type == VFL_TYPE_RADIO) | 1160 | if (vdev->vfl_type == VFL_TYPE_RADIO) |
| 1267 | saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); | 1161 | saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); |
| 1162 | mutex_unlock(&dev->lock); | ||
| 1268 | 1163 | ||
| 1269 | v4l2_fh_del(&fh->fh); | ||
| 1270 | v4l2_fh_exit(&fh->fh); | ||
| 1271 | file->private_data = NULL; | ||
| 1272 | kfree(fh); | ||
| 1273 | return 0; | 1164 | return 0; |
| 1274 | } | 1165 | } |
| 1275 | 1166 | ||
| 1276 | static int video_mmap(struct file *file, struct vm_area_struct * vma) | ||
| 1277 | { | ||
| 1278 | return videobuf_mmap_mapper(saa7134_queue(file), vma); | ||
| 1279 | } | ||
| 1280 | |||
| 1281 | static ssize_t radio_read(struct file *file, char __user *data, | 1167 | static ssize_t radio_read(struct file *file, char __user *data, |
| 1282 | size_t count, loff_t *ppos) | 1168 | size_t count, loff_t *ppos) |
| 1283 | { | 1169 | { |
| @@ -1290,7 +1176,9 @@ static ssize_t radio_read(struct file *file, char __user *data, | |||
| 1290 | cmd.instance = file; | 1176 | cmd.instance = file; |
| 1291 | cmd.result = -ENODEV; | 1177 | cmd.result = -ENODEV; |
| 1292 | 1178 | ||
| 1179 | mutex_lock(&dev->lock); | ||
| 1293 | saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); | 1180 | saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); |
| 1181 | mutex_unlock(&dev->lock); | ||
| 1294 | 1182 | ||
| 1295 | return cmd.result; | 1183 | return cmd.result; |
| 1296 | } | 1184 | } |
| @@ -1304,7 +1192,9 @@ static unsigned int radio_poll(struct file *file, poll_table *wait) | |||
| 1304 | cmd.instance = file; | 1192 | cmd.instance = file; |
| 1305 | cmd.event_list = wait; | 1193 | cmd.event_list = wait; |
| 1306 | cmd.result = 0; | 1194 | cmd.result = 0; |
| 1195 | mutex_lock(&dev->lock); | ||
| 1307 | saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); | 1196 | saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); |
| 1197 | mutex_unlock(&dev->lock); | ||
| 1308 | 1198 | ||
| 1309 | return rc | cmd.result; | 1199 | return rc | cmd.result; |
| 1310 | } | 1200 | } |
| @@ -1338,7 +1228,7 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv, | |||
| 1338 | 1228 | ||
| 1339 | f->fmt.pix.width = dev->width; | 1229 | f->fmt.pix.width = dev->width; |
| 1340 | f->fmt.pix.height = dev->height; | 1230 | f->fmt.pix.height = dev->height; |
| 1341 | f->fmt.pix.field = dev->cap.field; | 1231 | f->fmt.pix.field = dev->field; |
| 1342 | f->fmt.pix.pixelformat = dev->fmt->fourcc; | 1232 | f->fmt.pix.pixelformat = dev->fmt->fourcc; |
| 1343 | f->fmt.pix.bytesperline = | 1233 | f->fmt.pix.bytesperline = |
| 1344 | (f->fmt.pix.width * dev->fmt->depth) >> 3; | 1234 | (f->fmt.pix.width * dev->fmt->depth) >> 3; |
| @@ -1362,7 +1252,6 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, | |||
| 1362 | printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | 1252 | printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); |
| 1363 | return -EINVAL; | 1253 | return -EINVAL; |
| 1364 | } | 1254 | } |
| 1365 | mutex_lock(&dev->lock); | ||
| 1366 | f->fmt.win = dev->win; | 1255 | f->fmt.win = dev->win; |
| 1367 | f->fmt.win.clips = clips; | 1256 | f->fmt.win.clips = clips; |
| 1368 | if (clips == NULL) | 1257 | if (clips == NULL) |
| @@ -1376,7 +1265,6 @@ static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, | |||
| 1376 | sizeof(struct v4l2_rect))) | 1265 | sizeof(struct v4l2_rect))) |
| 1377 | err = -EFAULT; | 1266 | err = -EFAULT; |
| 1378 | } | 1267 | } |
| 1379 | mutex_unlock(&dev->lock); | ||
| 1380 | 1268 | ||
| 1381 | return err; | 1269 | return err; |
| 1382 | } | 1270 | } |
| @@ -1457,10 +1345,10 @@ static int saa7134_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 1457 | if (0 != err) | 1345 | if (0 != err) |
| 1458 | return err; | 1346 | return err; |
| 1459 | 1347 | ||
| 1460 | dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1348 | dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
| 1461 | dev->width = f->fmt.pix.width; | 1349 | dev->width = f->fmt.pix.width; |
| 1462 | dev->height = f->fmt.pix.height; | 1350 | dev->height = f->fmt.pix.height; |
| 1463 | dev->cap.field = f->fmt.pix.field; | 1351 | dev->field = f->fmt.pix.field; |
| 1464 | return 0; | 1352 | return 0; |
| 1465 | } | 1353 | } |
| 1466 | 1354 | ||
| @@ -1481,25 +1369,20 @@ static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv, | |||
| 1481 | if (0 != err) | 1369 | if (0 != err) |
| 1482 | return err; | 1370 | return err; |
| 1483 | 1371 | ||
| 1484 | mutex_lock(&dev->lock); | ||
| 1485 | |||
| 1486 | dev->win = f->fmt.win; | 1372 | dev->win = f->fmt.win; |
| 1487 | dev->nclips = f->fmt.win.clipcount; | 1373 | dev->nclips = f->fmt.win.clipcount; |
| 1488 | 1374 | ||
| 1489 | if (copy_from_user(dev->clips, f->fmt.win.clips, | 1375 | if (copy_from_user(dev->clips, f->fmt.win.clips, |
| 1490 | sizeof(struct v4l2_clip) * dev->nclips)) { | 1376 | sizeof(struct v4l2_clip) * dev->nclips)) |
| 1491 | mutex_unlock(&dev->lock); | ||
| 1492 | return -EFAULT; | 1377 | return -EFAULT; |
| 1493 | } | ||
| 1494 | 1378 | ||
| 1495 | if (res_check(priv, RESOURCE_OVERLAY)) { | 1379 | if (priv == dev->overlay_owner) { |
| 1496 | spin_lock_irqsave(&dev->slock, flags); | 1380 | spin_lock_irqsave(&dev->slock, flags); |
| 1497 | stop_preview(dev); | 1381 | stop_preview(dev); |
| 1498 | start_preview(dev); | 1382 | start_preview(dev); |
| 1499 | spin_unlock_irqrestore(&dev->slock, flags); | 1383 | spin_unlock_irqrestore(&dev->slock, flags); |
| 1500 | } | 1384 | } |
| 1501 | 1385 | ||
| 1502 | mutex_unlock(&dev->lock); | ||
| 1503 | return 0; | 1386 | return 0; |
| 1504 | } | 1387 | } |
| 1505 | 1388 | ||
| @@ -1551,9 +1434,7 @@ int saa7134_s_input(struct file *file, void *priv, unsigned int i) | |||
| 1551 | return -EINVAL; | 1434 | return -EINVAL; |
| 1552 | if (NULL == card_in(dev, i).name) | 1435 | if (NULL == card_in(dev, i).name) |
| 1553 | return -EINVAL; | 1436 | return -EINVAL; |
| 1554 | mutex_lock(&dev->lock); | ||
| 1555 | video_mux(dev, i); | 1437 | video_mux(dev, i); |
| 1556 | mutex_unlock(&dev->lock); | ||
| 1557 | return 0; | 1438 | return 0; |
| 1558 | } | 1439 | } |
| 1559 | EXPORT_SYMBOL_GPL(saa7134_s_input); | 1440 | EXPORT_SYMBOL_GPL(saa7134_s_input); |
| @@ -1563,7 +1444,6 @@ int saa7134_querycap(struct file *file, void *priv, | |||
| 1563 | { | 1444 | { |
| 1564 | struct saa7134_dev *dev = video_drvdata(file); | 1445 | struct saa7134_dev *dev = video_drvdata(file); |
| 1565 | struct video_device *vdev = video_devdata(file); | 1446 | struct video_device *vdev = video_devdata(file); |
| 1566 | struct saa7134_fh *fh = priv; | ||
| 1567 | u32 radio_caps, video_caps, vbi_caps; | 1447 | u32 radio_caps, video_caps, vbi_caps; |
| 1568 | 1448 | ||
| 1569 | unsigned int tuner_type = dev->tuner_type; | 1449 | unsigned int tuner_type = dev->tuner_type; |
| @@ -1582,7 +1462,7 @@ int saa7134_querycap(struct file *file, void *priv, | |||
| 1582 | radio_caps |= V4L2_CAP_RDS_CAPTURE; | 1462 | radio_caps |= V4L2_CAP_RDS_CAPTURE; |
| 1583 | 1463 | ||
| 1584 | video_caps = V4L2_CAP_VIDEO_CAPTURE; | 1464 | video_caps = V4L2_CAP_VIDEO_CAPTURE; |
| 1585 | if (saa7134_no_overlay <= 0 && !fh->is_empress) | 1465 | if (saa7134_no_overlay <= 0 && !is_empress(file)) |
| 1586 | video_caps |= V4L2_CAP_VIDEO_OVERLAY; | 1466 | video_caps |= V4L2_CAP_VIDEO_OVERLAY; |
| 1587 | 1467 | ||
| 1588 | vbi_caps = V4L2_CAP_VBI_CAPTURE; | 1468 | vbi_caps = V4L2_CAP_VBI_CAPTURE; |
| @@ -1613,12 +1493,12 @@ EXPORT_SYMBOL_GPL(saa7134_querycap); | |||
| 1613 | int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) | 1493 | int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) |
| 1614 | { | 1494 | { |
| 1615 | struct saa7134_dev *dev = video_drvdata(file); | 1495 | struct saa7134_dev *dev = video_drvdata(file); |
| 1616 | struct saa7134_fh *fh = priv; | 1496 | struct v4l2_fh *fh = priv; |
| 1617 | unsigned long flags; | 1497 | unsigned long flags; |
| 1618 | unsigned int i; | 1498 | unsigned int i; |
| 1619 | v4l2_std_id fixup; | 1499 | v4l2_std_id fixup; |
| 1620 | 1500 | ||
| 1621 | if (fh->is_empress && res_locked(dev, RESOURCE_OVERLAY)) { | 1501 | if (is_empress(file) && dev->overlay_owner) { |
| 1622 | /* Don't change the std from the mpeg device | 1502 | /* Don't change the std from the mpeg device |
| 1623 | if overlay is active. */ | 1503 | if overlay is active. */ |
| 1624 | return -EBUSY; | 1504 | return -EBUSY; |
| @@ -1657,8 +1537,7 @@ int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) | |||
| 1657 | 1537 | ||
| 1658 | id = tvnorms[i].id; | 1538 | id = tvnorms[i].id; |
| 1659 | 1539 | ||
| 1660 | mutex_lock(&dev->lock); | 1540 | if (!is_empress(file) && fh == dev->overlay_owner) { |
| 1661 | if (!fh->is_empress && res_check(fh, RESOURCE_OVERLAY)) { | ||
| 1662 | spin_lock_irqsave(&dev->slock, flags); | 1541 | spin_lock_irqsave(&dev->slock, flags); |
| 1663 | stop_preview(dev); | 1542 | stop_preview(dev); |
| 1664 | spin_unlock_irqrestore(&dev->slock, flags); | 1543 | spin_unlock_irqrestore(&dev->slock, flags); |
| @@ -1672,7 +1551,6 @@ int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) | |||
| 1672 | set_tvnorm(dev, &tvnorms[i]); | 1551 | set_tvnorm(dev, &tvnorms[i]); |
| 1673 | 1552 | ||
| 1674 | saa7134_tvaudio_do_scan(dev); | 1553 | saa7134_tvaudio_do_scan(dev); |
| 1675 | mutex_unlock(&dev->lock); | ||
| 1676 | return 0; | 1554 | return 0; |
| 1677 | } | 1555 | } |
| 1678 | EXPORT_SYMBOL_GPL(saa7134_s_std); | 1556 | EXPORT_SYMBOL_GPL(saa7134_s_std); |
| @@ -1686,6 +1564,35 @@ int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id) | |||
| 1686 | } | 1564 | } |
| 1687 | EXPORT_SYMBOL_GPL(saa7134_g_std); | 1565 | EXPORT_SYMBOL_GPL(saa7134_g_std); |
| 1688 | 1566 | ||
| 1567 | static v4l2_std_id saa7134_read_std(struct saa7134_dev *dev) | ||
| 1568 | { | ||
| 1569 | static v4l2_std_id stds[] = { | ||
| 1570 | V4L2_STD_UNKNOWN, | ||
| 1571 | V4L2_STD_NTSC, | ||
| 1572 | V4L2_STD_PAL, | ||
| 1573 | V4L2_STD_SECAM }; | ||
| 1574 | |||
| 1575 | v4l2_std_id result = 0; | ||
| 1576 | |||
| 1577 | u8 st1 = saa_readb(SAA7134_STATUS_VIDEO1); | ||
| 1578 | u8 st2 = saa_readb(SAA7134_STATUS_VIDEO2); | ||
| 1579 | |||
| 1580 | if (!(st2 & 0x1)) /* RDCAP == 0 */ | ||
| 1581 | result = V4L2_STD_UNKNOWN; | ||
| 1582 | else | ||
| 1583 | result = stds[st1 & 0x03]; | ||
| 1584 | |||
| 1585 | return result; | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std) | ||
| 1589 | { | ||
| 1590 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 1591 | *std &= saa7134_read_std(dev); | ||
| 1592 | return 0; | ||
| 1593 | } | ||
| 1594 | EXPORT_SYMBOL_GPL(saa7134_querystd); | ||
| 1595 | |||
| 1689 | static int saa7134_cropcap(struct file *file, void *priv, | 1596 | static int saa7134_cropcap(struct file *file, void *priv, |
| 1690 | struct v4l2_cropcap *cap) | 1597 | struct v4l2_cropcap *cap) |
| 1691 | { | 1598 | { |
| @@ -1730,9 +1637,9 @@ static int saa7134_s_crop(struct file *file, void *f, const struct v4l2_crop *cr | |||
| 1730 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 1637 | crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
| 1731 | return -EINVAL; | 1638 | return -EINVAL; |
| 1732 | 1639 | ||
| 1733 | if (res_locked(dev, RESOURCE_OVERLAY)) | 1640 | if (dev->overlay_owner) |
| 1734 | return -EBUSY; | 1641 | return -EBUSY; |
| 1735 | if (res_locked(dev, RESOURCE_VIDEO)) | 1642 | if (vb2_is_streaming(&dev->video_vbq)) |
| 1736 | return -EBUSY; | 1643 | return -EBUSY; |
| 1737 | 1644 | ||
| 1738 | *c = crop->c; | 1645 | *c = crop->c; |
| @@ -1826,12 +1733,10 @@ int saa7134_s_frequency(struct file *file, void *priv, | |||
| 1826 | 1733 | ||
| 1827 | if (0 != f->tuner) | 1734 | if (0 != f->tuner) |
| 1828 | return -EINVAL; | 1735 | return -EINVAL; |
| 1829 | mutex_lock(&dev->lock); | ||
| 1830 | 1736 | ||
| 1831 | saa_call_all(dev, tuner, s_frequency, f); | 1737 | saa_call_all(dev, tuner, s_frequency, f); |
| 1832 | 1738 | ||
| 1833 | saa7134_tvaudio_do_scan(dev); | 1739 | saa7134_tvaudio_do_scan(dev); |
| 1834 | mutex_unlock(&dev->lock); | ||
| 1835 | return 0; | 1740 | return 0; |
| 1836 | } | 1741 | } |
| 1837 | EXPORT_SYMBOL_GPL(saa7134_s_frequency); | 1742 | EXPORT_SYMBOL_GPL(saa7134_s_frequency); |
| @@ -1915,92 +1820,24 @@ static int saa7134_overlay(struct file *file, void *priv, unsigned int on) | |||
| 1915 | return -EINVAL; | 1820 | return -EINVAL; |
| 1916 | } | 1821 | } |
| 1917 | 1822 | ||
| 1918 | if (!res_get(dev, priv, RESOURCE_OVERLAY)) | 1823 | if (dev->overlay_owner && priv != dev->overlay_owner) |
| 1919 | return -EBUSY; | 1824 | return -EBUSY; |
| 1825 | dev->overlay_owner = priv; | ||
| 1920 | spin_lock_irqsave(&dev->slock, flags); | 1826 | spin_lock_irqsave(&dev->slock, flags); |
| 1921 | start_preview(dev); | 1827 | start_preview(dev); |
| 1922 | spin_unlock_irqrestore(&dev->slock, flags); | 1828 | spin_unlock_irqrestore(&dev->slock, flags); |
| 1923 | } | 1829 | } |
| 1924 | if (!on) { | 1830 | if (!on) { |
| 1925 | if (!res_check(priv, RESOURCE_OVERLAY)) | 1831 | if (priv != dev->overlay_owner) |
| 1926 | return -EINVAL; | 1832 | return -EINVAL; |
| 1927 | spin_lock_irqsave(&dev->slock, flags); | 1833 | spin_lock_irqsave(&dev->slock, flags); |
| 1928 | stop_preview(dev); | 1834 | stop_preview(dev); |
| 1929 | spin_unlock_irqrestore(&dev->slock, flags); | 1835 | spin_unlock_irqrestore(&dev->slock, flags); |
| 1930 | res_free(dev, priv, RESOURCE_OVERLAY); | 1836 | dev->overlay_owner = NULL; |
| 1931 | } | 1837 | } |
| 1932 | return 0; | 1838 | return 0; |
| 1933 | } | 1839 | } |
| 1934 | 1840 | ||
| 1935 | int saa7134_reqbufs(struct file *file, void *priv, | ||
| 1936 | struct v4l2_requestbuffers *p) | ||
| 1937 | { | ||
| 1938 | return videobuf_reqbufs(saa7134_queue(file), p); | ||
| 1939 | } | ||
| 1940 | EXPORT_SYMBOL_GPL(saa7134_reqbufs); | ||
| 1941 | |||
| 1942 | int saa7134_querybuf(struct file *file, void *priv, | ||
| 1943 | struct v4l2_buffer *b) | ||
| 1944 | { | ||
| 1945 | return videobuf_querybuf(saa7134_queue(file), b); | ||
| 1946 | } | ||
| 1947 | EXPORT_SYMBOL_GPL(saa7134_querybuf); | ||
| 1948 | |||
| 1949 | int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
| 1950 | { | ||
| 1951 | return videobuf_qbuf(saa7134_queue(file), b); | ||
| 1952 | } | ||
| 1953 | EXPORT_SYMBOL_GPL(saa7134_qbuf); | ||
| 1954 | |||
| 1955 | int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
| 1956 | { | ||
| 1957 | return videobuf_dqbuf(saa7134_queue(file), b, | ||
| 1958 | file->f_flags & O_NONBLOCK); | ||
| 1959 | } | ||
| 1960 | EXPORT_SYMBOL_GPL(saa7134_dqbuf); | ||
| 1961 | |||
| 1962 | int saa7134_streamon(struct file *file, void *priv, | ||
| 1963 | enum v4l2_buf_type type) | ||
| 1964 | { | ||
| 1965 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 1966 | int res = saa7134_resource(file); | ||
| 1967 | |||
| 1968 | if (!res_get(dev, priv, res)) | ||
| 1969 | return -EBUSY; | ||
| 1970 | |||
| 1971 | /* The SAA7134 has a 1K FIFO; the datasheet suggests that when | ||
| 1972 | * configured conservatively, there's 22 usec of buffering for video. | ||
| 1973 | * We therefore request a DMA latency of 20 usec, giving us 2 usec of | ||
| 1974 | * margin in case the FIFO is configured differently to the datasheet. | ||
| 1975 | * Unfortunately, I lack register-level documentation to check the | ||
| 1976 | * Linux FIFO setup and confirm the perfect value. | ||
| 1977 | */ | ||
| 1978 | if (res != RESOURCE_EMPRESS) | ||
| 1979 | pm_qos_add_request(&dev->qos_request, | ||
| 1980 | PM_QOS_CPU_DMA_LATENCY, 20); | ||
| 1981 | |||
| 1982 | return videobuf_streamon(saa7134_queue(file)); | ||
| 1983 | } | ||
| 1984 | EXPORT_SYMBOL_GPL(saa7134_streamon); | ||
| 1985 | |||
| 1986 | int saa7134_streamoff(struct file *file, void *priv, | ||
| 1987 | enum v4l2_buf_type type) | ||
| 1988 | { | ||
| 1989 | struct saa7134_dev *dev = video_drvdata(file); | ||
| 1990 | int err; | ||
| 1991 | int res = saa7134_resource(file); | ||
| 1992 | |||
| 1993 | if (res != RESOURCE_EMPRESS) | ||
| 1994 | pm_qos_remove_request(&dev->qos_request); | ||
| 1995 | |||
| 1996 | err = videobuf_streamoff(saa7134_queue(file)); | ||
| 1997 | if (err < 0) | ||
| 1998 | return err; | ||
| 1999 | res_free(dev, priv, res); | ||
| 2000 | return 0; | ||
| 2001 | } | ||
| 2002 | EXPORT_SYMBOL_GPL(saa7134_streamoff); | ||
| 2003 | |||
| 2004 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1841 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 2005 | static int vidioc_g_register (struct file *file, void *priv, | 1842 | static int vidioc_g_register (struct file *file, void *priv, |
| 2006 | struct v4l2_dbg_register *reg) | 1843 | struct v4l2_dbg_register *reg) |
| @@ -2058,10 +1895,10 @@ static const struct v4l2_file_operations video_fops = | |||
| 2058 | .owner = THIS_MODULE, | 1895 | .owner = THIS_MODULE, |
| 2059 | .open = video_open, | 1896 | .open = video_open, |
| 2060 | .release = video_release, | 1897 | .release = video_release, |
| 2061 | .read = video_read, | 1898 | .read = vb2_fop_read, |
| 2062 | .poll = video_poll, | 1899 | .poll = vb2_fop_poll, |
| 2063 | .mmap = video_mmap, | 1900 | .mmap = vb2_fop_mmap, |
| 2064 | .ioctl = video_ioctl2, | 1901 | .unlocked_ioctl = video_ioctl2, |
| 2065 | }; | 1902 | }; |
| 2066 | 1903 | ||
| 2067 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | 1904 | static const struct v4l2_ioctl_ops video_ioctl_ops = { |
| @@ -2078,17 +1915,18 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
| 2078 | .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, | 1915 | .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, |
| 2079 | .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, | 1916 | .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, |
| 2080 | .vidioc_cropcap = saa7134_cropcap, | 1917 | .vidioc_cropcap = saa7134_cropcap, |
| 2081 | .vidioc_reqbufs = saa7134_reqbufs, | 1918 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
| 2082 | .vidioc_querybuf = saa7134_querybuf, | 1919 | .vidioc_querybuf = vb2_ioctl_querybuf, |
| 2083 | .vidioc_qbuf = saa7134_qbuf, | 1920 | .vidioc_qbuf = vb2_ioctl_qbuf, |
| 2084 | .vidioc_dqbuf = saa7134_dqbuf, | 1921 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
| 2085 | .vidioc_s_std = saa7134_s_std, | 1922 | .vidioc_s_std = saa7134_s_std, |
| 2086 | .vidioc_g_std = saa7134_g_std, | 1923 | .vidioc_g_std = saa7134_g_std, |
| 1924 | .vidioc_querystd = saa7134_querystd, | ||
| 2087 | .vidioc_enum_input = saa7134_enum_input, | 1925 | .vidioc_enum_input = saa7134_enum_input, |
| 2088 | .vidioc_g_input = saa7134_g_input, | 1926 | .vidioc_g_input = saa7134_g_input, |
| 2089 | .vidioc_s_input = saa7134_s_input, | 1927 | .vidioc_s_input = saa7134_s_input, |
| 2090 | .vidioc_streamon = saa7134_streamon, | 1928 | .vidioc_streamon = vb2_ioctl_streamon, |
| 2091 | .vidioc_streamoff = saa7134_streamoff, | 1929 | .vidioc_streamoff = vb2_ioctl_streamoff, |
| 2092 | .vidioc_g_tuner = saa7134_g_tuner, | 1930 | .vidioc_g_tuner = saa7134_g_tuner, |
| 2093 | .vidioc_s_tuner = saa7134_s_tuner, | 1931 | .vidioc_s_tuner = saa7134_s_tuner, |
| 2094 | .vidioc_g_crop = saa7134_g_crop, | 1932 | .vidioc_g_crop = saa7134_g_crop, |
| @@ -2112,7 +1950,7 @@ static const struct v4l2_file_operations radio_fops = { | |||
| 2112 | .open = video_open, | 1950 | .open = video_open, |
| 2113 | .read = radio_read, | 1951 | .read = radio_read, |
| 2114 | .release = video_release, | 1952 | .release = video_release, |
| 2115 | .ioctl = video_ioctl2, | 1953 | .unlocked_ioctl = video_ioctl2, |
| 2116 | .poll = radio_poll, | 1954 | .poll = radio_poll, |
| 2117 | }; | 1955 | }; |
| 2118 | 1956 | ||
| @@ -2190,6 +2028,8 @@ static const struct v4l2_ctrl_config saa7134_ctrl_automute = { | |||
| 2190 | int saa7134_video_init1(struct saa7134_dev *dev) | 2028 | int saa7134_video_init1(struct saa7134_dev *dev) |
| 2191 | { | 2029 | { |
| 2192 | struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; | 2030 | struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; |
| 2031 | struct vb2_queue *q; | ||
| 2032 | int ret; | ||
| 2193 | 2033 | ||
| 2194 | /* sanitycheck insmod options */ | 2034 | /* sanitycheck insmod options */ |
| 2195 | if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) | 2035 | if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) |
| @@ -2241,6 +2081,7 @@ int saa7134_video_init1(struct saa7134_dev *dev) | |||
| 2241 | dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); | 2081 | dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); |
| 2242 | dev->width = 720; | 2082 | dev->width = 720; |
| 2243 | dev->height = 576; | 2083 | dev->height = 576; |
| 2084 | dev->field = V4L2_FIELD_INTERLACED; | ||
| 2244 | dev->win.w.width = dev->width; | 2085 | dev->win.w.width = dev->width; |
| 2245 | dev->win.w.height = dev->height; | 2086 | dev->win.w.height = dev->height; |
| 2246 | dev->win.field = V4L2_FIELD_INTERLACED; | 2087 | dev->win.field = V4L2_FIELD_INTERLACED; |
| @@ -2252,20 +2093,47 @@ int saa7134_video_init1(struct saa7134_dev *dev) | |||
| 2252 | if (saa7134_boards[dev->board].video_out) | 2093 | if (saa7134_boards[dev->board].video_out) |
| 2253 | saa7134_videoport_init(dev); | 2094 | saa7134_videoport_init(dev); |
| 2254 | 2095 | ||
| 2255 | videobuf_queue_sg_init(&dev->cap, &video_qops, | 2096 | q = &dev->video_vbq; |
| 2256 | &dev->pci->dev, &dev->slock, | 2097 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 2257 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 2098 | /* |
| 2258 | V4L2_FIELD_INTERLACED, | 2099 | * Do not add VB2_USERPTR unless explicitly requested: the saa7134 DMA |
| 2259 | sizeof(struct saa7134_buf), | 2100 | * engine cannot handle transfers that do not start at the beginning |
| 2260 | dev, NULL); | 2101 | * of a page. A user-provided pointer can start anywhere in a page, so |
| 2261 | videobuf_queue_sg_init(&dev->vbi, &saa7134_vbi_qops, | 2102 | * USERPTR support is a no-go unless the application knows about these |
| 2262 | &dev->pci->dev, &dev->slock, | 2103 | * limitations and has special support for this. |
| 2263 | V4L2_BUF_TYPE_VBI_CAPTURE, | 2104 | */ |
| 2264 | V4L2_FIELD_SEQ_TB, | 2105 | q->io_modes = VB2_MMAP | VB2_READ; |
| 2265 | sizeof(struct saa7134_buf), | 2106 | if (saa7134_userptr) |
| 2266 | dev, NULL); | 2107 | q->io_modes |= VB2_USERPTR; |
| 2267 | saa7134_pgtable_alloc(dev->pci, &dev->pt_cap); | 2108 | q->drv_priv = &dev->video_q; |
| 2268 | saa7134_pgtable_alloc(dev->pci, &dev->pt_vbi); | 2109 | q->ops = &vb2_qops; |
| 2110 | q->gfp_flags = GFP_DMA32; | ||
| 2111 | q->mem_ops = &vb2_dma_sg_memops; | ||
| 2112 | q->buf_struct_size = sizeof(struct saa7134_buf); | ||
| 2113 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 2114 | q->lock = &dev->lock; | ||
| 2115 | ret = vb2_queue_init(q); | ||
| 2116 | if (ret) | ||
| 2117 | return ret; | ||
| 2118 | saa7134_pgtable_alloc(dev->pci, &dev->video_q.pt); | ||
| 2119 | |||
| 2120 | q = &dev->vbi_vbq; | ||
| 2121 | q->type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
| 2122 | /* Don't add VB2_USERPTR, see comment above */ | ||
| 2123 | q->io_modes = VB2_MMAP | VB2_READ; | ||
| 2124 | if (saa7134_userptr) | ||
| 2125 | q->io_modes |= VB2_USERPTR; | ||
| 2126 | q->drv_priv = &dev->vbi_q; | ||
| 2127 | q->ops = &saa7134_vbi_qops; | ||
| 2128 | q->gfp_flags = GFP_DMA32; | ||
| 2129 | q->mem_ops = &vb2_dma_sg_memops; | ||
| 2130 | q->buf_struct_size = sizeof(struct saa7134_buf); | ||
| 2131 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 2132 | q->lock = &dev->lock; | ||
| 2133 | ret = vb2_queue_init(q); | ||
| 2134 | if (ret) | ||
| 2135 | return ret; | ||
| 2136 | saa7134_pgtable_alloc(dev->pci, &dev->vbi_q.pt); | ||
| 2269 | 2137 | ||
| 2270 | return 0; | 2138 | return 0; |
| 2271 | } | 2139 | } |
| @@ -2273,8 +2141,10 @@ int saa7134_video_init1(struct saa7134_dev *dev) | |||
| 2273 | void saa7134_video_fini(struct saa7134_dev *dev) | 2141 | void saa7134_video_fini(struct saa7134_dev *dev) |
| 2274 | { | 2142 | { |
| 2275 | /* free stuff */ | 2143 | /* free stuff */ |
| 2276 | saa7134_pgtable_free(dev->pci, &dev->pt_cap); | 2144 | vb2_queue_release(&dev->video_vbq); |
| 2277 | saa7134_pgtable_free(dev->pci, &dev->pt_vbi); | 2145 | saa7134_pgtable_free(dev->pci, &dev->video_q.pt); |
| 2146 | vb2_queue_release(&dev->vbi_vbq); | ||
| 2147 | saa7134_pgtable_free(dev->pci, &dev->vbi_q.pt); | ||
| 2278 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 2148 | v4l2_ctrl_handler_free(&dev->ctrl_handler); |
| 2279 | if (card_has_radio(dev)) | 2149 | if (card_has_radio(dev)) |
| 2280 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); | 2150 | v4l2_ctrl_handler_free(&dev->radio_ctrl_handler); |
| @@ -2367,8 +2237,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) | |||
| 2367 | 2237 | ||
| 2368 | spin_lock(&dev->slock); | 2238 | spin_lock(&dev->slock); |
| 2369 | if (dev->video_q.curr) { | 2239 | if (dev->video_q.curr) { |
| 2370 | dev->video_fieldcount++; | 2240 | field = dev->field; |
| 2371 | field = dev->video_q.curr->vb.field; | ||
| 2372 | if (V4L2_FIELD_HAS_BOTH(field)) { | 2241 | if (V4L2_FIELD_HAS_BOTH(field)) { |
| 2373 | /* make sure we have seen both fields */ | 2242 | /* make sure we have seen both fields */ |
| 2374 | if ((status & 0x10) == 0x00) { | 2243 | if ((status & 0x10) == 0x00) { |
| @@ -2384,18 +2253,10 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) | |||
| 2384 | if ((status & 0x10) != 0x00) | 2253 | if ((status & 0x10) != 0x00) |
| 2385 | goto done; | 2254 | goto done; |
| 2386 | } | 2255 | } |
| 2387 | dev->video_q.curr->vb.field_count = dev->video_fieldcount; | 2256 | saa7134_buffer_finish(dev, &dev->video_q, VB2_BUF_STATE_DONE); |
| 2388 | saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE); | ||
| 2389 | } | 2257 | } |
| 2390 | saa7134_buffer_next(dev,&dev->video_q); | 2258 | saa7134_buffer_next(dev, &dev->video_q); |
| 2391 | 2259 | ||
| 2392 | done: | 2260 | done: |
| 2393 | spin_unlock(&dev->slock); | 2261 | spin_unlock(&dev->slock); |
| 2394 | } | 2262 | } |
| 2395 | |||
| 2396 | /* ----------------------------------------------------------- */ | ||
| 2397 | /* | ||
| 2398 | * Local variables: | ||
| 2399 | * c-basic-offset: 8 | ||
| 2400 | * End: | ||
| 2401 | */ | ||
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 2474e848f2c0..e47edd4b57ce 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h | |||
| @@ -41,11 +41,11 @@ | |||
| 41 | #include <media/tuner.h> | 41 | #include <media/tuner.h> |
| 42 | #include <media/rc-core.h> | 42 | #include <media/rc-core.h> |
| 43 | #include <media/ir-kbd-i2c.h> | 43 | #include <media/ir-kbd-i2c.h> |
| 44 | #include <media/videobuf-dma-sg.h> | 44 | #include <media/videobuf2-dma-sg.h> |
| 45 | #include <sound/core.h> | 45 | #include <sound/core.h> |
| 46 | #include <sound/pcm.h> | 46 | #include <sound/pcm.h> |
| 47 | #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB) | 47 | #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB) |
| 48 | #include <media/videobuf-dvb.h> | 48 | #include <media/videobuf2-dvb.h> |
| 49 | #endif | 49 | #endif |
| 50 | #include "tda8290.h" | 50 | #include "tda8290.h" |
| 51 | 51 | ||
| @@ -453,17 +453,15 @@ struct saa7134_thread { | |||
| 453 | /* buffer for one video/vbi/ts frame */ | 453 | /* buffer for one video/vbi/ts frame */ |
| 454 | struct saa7134_buf { | 454 | struct saa7134_buf { |
| 455 | /* common v4l buffer stuff -- must be first */ | 455 | /* common v4l buffer stuff -- must be first */ |
| 456 | struct videobuf_buffer vb; | 456 | struct vb2_buffer vb2; |
| 457 | 457 | ||
| 458 | /* saa7134 specific */ | 458 | /* saa7134 specific */ |
| 459 | struct saa7134_format *fmt; | ||
| 460 | unsigned int top_seen; | 459 | unsigned int top_seen; |
| 461 | int (*activate)(struct saa7134_dev *dev, | 460 | int (*activate)(struct saa7134_dev *dev, |
| 462 | struct saa7134_buf *buf, | 461 | struct saa7134_buf *buf, |
| 463 | struct saa7134_buf *next); | 462 | struct saa7134_buf *next); |
| 464 | 463 | ||
| 465 | /* page tables */ | 464 | struct list_head entry; |
| 466 | struct saa7134_pgtable *pt; | ||
| 467 | }; | 465 | }; |
| 468 | 466 | ||
| 469 | struct saa7134_dmaqueue { | 467 | struct saa7134_dmaqueue { |
| @@ -472,13 +470,8 @@ struct saa7134_dmaqueue { | |||
| 472 | struct list_head queue; | 470 | struct list_head queue; |
| 473 | struct timer_list timeout; | 471 | struct timer_list timeout; |
| 474 | unsigned int need_two; | 472 | unsigned int need_two; |
| 475 | }; | 473 | unsigned int seq_nr; |
| 476 | 474 | struct saa7134_pgtable pt; | |
| 477 | /* video filehandle status */ | ||
| 478 | struct saa7134_fh { | ||
| 479 | struct v4l2_fh fh; | ||
| 480 | bool is_empress; | ||
| 481 | unsigned int resources; | ||
| 482 | }; | 475 | }; |
| 483 | 476 | ||
| 484 | /* dmasound dsp status */ | 477 | /* dmasound dsp status */ |
| @@ -504,7 +497,10 @@ struct saa7134_dmasound { | |||
| 504 | unsigned int blksize; | 497 | unsigned int blksize; |
| 505 | unsigned int bufsize; | 498 | unsigned int bufsize; |
| 506 | struct saa7134_pgtable pt; | 499 | struct saa7134_pgtable pt; |
| 507 | struct videobuf_dmabuf dma; | 500 | void *vaddr; |
| 501 | struct scatterlist *sglist; | ||
| 502 | int sglen; | ||
| 503 | int nr_pages; | ||
| 508 | unsigned int dma_blk; | 504 | unsigned int dma_blk; |
| 509 | unsigned int read_offset; | 505 | unsigned int read_offset; |
| 510 | unsigned int read_count; | 506 | unsigned int read_count; |
| @@ -515,7 +511,6 @@ struct saa7134_dmasound { | |||
| 515 | /* ts/mpeg status */ | 511 | /* ts/mpeg status */ |
| 516 | struct saa7134_ts { | 512 | struct saa7134_ts { |
| 517 | /* TS capture */ | 513 | /* TS capture */ |
| 518 | struct saa7134_pgtable pt_ts; | ||
| 519 | int nr_packets; | 514 | int nr_packets; |
| 520 | int nr_bufs; | 515 | int nr_bufs; |
| 521 | }; | 516 | }; |
| @@ -584,21 +579,35 @@ struct saa7134_dev { | |||
| 584 | struct v4l2_window win; | 579 | struct v4l2_window win; |
| 585 | struct v4l2_clip clips[8]; | 580 | struct v4l2_clip clips[8]; |
| 586 | unsigned int nclips; | 581 | unsigned int nclips; |
| 582 | struct v4l2_fh *overlay_owner; | ||
| 587 | 583 | ||
| 588 | 584 | ||
| 589 | /* video+ts+vbi capture */ | 585 | /* video+ts+vbi capture */ |
| 590 | struct saa7134_dmaqueue video_q; | 586 | struct saa7134_dmaqueue video_q; |
| 591 | struct videobuf_queue cap; | 587 | struct vb2_queue video_vbq; |
| 592 | struct saa7134_pgtable pt_cap; | ||
| 593 | struct saa7134_dmaqueue vbi_q; | 588 | struct saa7134_dmaqueue vbi_q; |
| 594 | struct videobuf_queue vbi; | 589 | struct vb2_queue vbi_vbq; |
| 595 | struct saa7134_pgtable pt_vbi; | 590 | enum v4l2_field field; |
| 596 | unsigned int video_fieldcount; | ||
| 597 | unsigned int vbi_fieldcount; | ||
| 598 | struct saa7134_format *fmt; | 591 | struct saa7134_format *fmt; |
| 599 | unsigned int width, height; | 592 | unsigned int width, height; |
| 593 | unsigned int vbi_hlen, vbi_vlen; | ||
| 600 | struct pm_qos_request qos_request; | 594 | struct pm_qos_request qos_request; |
| 601 | 595 | ||
| 596 | /* SAA7134_MPEG_* */ | ||
| 597 | struct saa7134_ts ts; | ||
| 598 | struct saa7134_dmaqueue ts_q; | ||
| 599 | enum v4l2_field ts_field; | ||
| 600 | int ts_started; | ||
| 601 | struct saa7134_mpeg_ops *mops; | ||
| 602 | |||
| 603 | /* SAA7134_MPEG_EMPRESS only */ | ||
| 604 | struct video_device *empress_dev; | ||
| 605 | struct v4l2_subdev *empress_sd; | ||
| 606 | struct vb2_queue empress_vbq; | ||
| 607 | struct work_struct empress_workqueue; | ||
| 608 | int empress_started; | ||
| 609 | struct v4l2_ctrl_handler empress_ctrl_handler; | ||
| 610 | |||
| 602 | /* various v4l controls */ | 611 | /* various v4l controls */ |
| 603 | struct saa7134_tvnorm *tvnorm; /* video */ | 612 | struct saa7134_tvnorm *tvnorm; /* video */ |
| 604 | struct saa7134_tvaudio *tvaudio; | 613 | struct saa7134_tvaudio *tvaudio; |
| @@ -635,23 +644,9 @@ struct saa7134_dev { | |||
| 635 | /* I2C keyboard data */ | 644 | /* I2C keyboard data */ |
| 636 | struct IR_i2c_init_data init_data; | 645 | struct IR_i2c_init_data init_data; |
| 637 | 646 | ||
| 638 | /* SAA7134_MPEG_* */ | ||
| 639 | struct saa7134_ts ts; | ||
| 640 | struct saa7134_dmaqueue ts_q; | ||
| 641 | int ts_started; | ||
| 642 | struct saa7134_mpeg_ops *mops; | ||
| 643 | |||
| 644 | /* SAA7134_MPEG_EMPRESS only */ | ||
| 645 | struct video_device *empress_dev; | ||
| 646 | struct v4l2_subdev *empress_sd; | ||
| 647 | struct videobuf_queue empress_tsq; | ||
| 648 | struct work_struct empress_workqueue; | ||
| 649 | int empress_started; | ||
| 650 | struct v4l2_ctrl_handler empress_ctrl_handler; | ||
| 651 | |||
| 652 | #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB) | 647 | #if IS_ENABLED(CONFIG_VIDEO_SAA7134_DVB) |
| 653 | /* SAA7134_MPEG_DVB only */ | 648 | /* SAA7134_MPEG_DVB only */ |
| 654 | struct videobuf_dvb_frontends frontends; | 649 | struct vb2_dvb_frontends frontends; |
| 655 | int (*original_demod_sleep)(struct dvb_frontend *fe); | 650 | int (*original_demod_sleep)(struct dvb_frontend *fe); |
| 656 | int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | 651 | int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); |
| 657 | int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); | 652 | int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg); |
| @@ -705,14 +700,12 @@ struct saa7134_dev { | |||
| 705 | _rc; \ | 700 | _rc; \ |
| 706 | }) | 701 | }) |
| 707 | 702 | ||
| 708 | static inline int res_check(struct saa7134_fh *fh, unsigned int bit) | 703 | static inline bool is_empress(struct file *file) |
| 709 | { | 704 | { |
| 710 | return fh->resources & bit; | 705 | struct video_device *vdev = video_devdata(file); |
| 711 | } | 706 | struct saa7134_dev *dev = video_get_drvdata(vdev); |
| 712 | 707 | ||
| 713 | static inline int res_locked(struct saa7134_dev *dev, unsigned int bit) | 708 | return vdev->queue == &dev->empress_vbq; |
| 714 | { | ||
| 715 | return dev->resources & bit; | ||
| 716 | } | 709 | } |
| 717 | 710 | ||
| 718 | /* ----------------------------------------------------------- */ | 711 | /* ----------------------------------------------------------- */ |
| @@ -721,6 +714,7 @@ static inline int res_locked(struct saa7134_dev *dev, unsigned int bit) | |||
| 721 | extern struct list_head saa7134_devlist; | 714 | extern struct list_head saa7134_devlist; |
| 722 | extern struct mutex saa7134_devlist_lock; | 715 | extern struct mutex saa7134_devlist_lock; |
| 723 | extern int saa7134_no_overlay; | 716 | extern int saa7134_no_overlay; |
| 717 | extern bool saa7134_userptr; | ||
| 724 | 718 | ||
| 725 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); | 719 | void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); |
| 726 | void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value); | 720 | 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, | |||
| 743 | unsigned int state); | 737 | unsigned int state); |
| 744 | void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); | 738 | void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); |
| 745 | void saa7134_buffer_timeout(unsigned long data); | 739 | void saa7134_buffer_timeout(unsigned long data); |
| 746 | void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf); | 740 | void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); |
| 747 | 741 | ||
| 748 | int saa7134_set_dmabits(struct saa7134_dev *dev); | 742 | int saa7134_set_dmabits(struct saa7134_dev *dev); |
| 749 | 743 | ||
| @@ -777,8 +771,13 @@ extern unsigned int video_debug; | |||
| 777 | extern struct video_device saa7134_video_template; | 771 | extern struct video_device saa7134_video_template; |
| 778 | extern struct video_device saa7134_radio_template; | 772 | extern struct video_device saa7134_radio_template; |
| 779 | 773 | ||
| 774 | void saa7134_vb2_buffer_queue(struct vb2_buffer *vb); | ||
| 775 | int saa7134_vb2_start_streaming(struct vb2_queue *vq, unsigned int count); | ||
| 776 | void saa7134_vb2_stop_streaming(struct vb2_queue *vq); | ||
| 777 | |||
| 780 | int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id); | 778 | int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id); |
| 781 | int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id); | 779 | int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id); |
| 780 | int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std); | ||
| 782 | int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i); | 781 | int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i); |
| 783 | int saa7134_g_input(struct file *file, void *priv, unsigned int *i); | 782 | int saa7134_g_input(struct file *file, void *priv, unsigned int *i); |
| 784 | int saa7134_s_input(struct file *file, void *priv, unsigned int i); | 783 | 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, | |||
| 792 | struct v4l2_frequency *f); | 791 | struct v4l2_frequency *f); |
| 793 | int saa7134_s_frequency(struct file *file, void *priv, | 792 | int saa7134_s_frequency(struct file *file, void *priv, |
| 794 | const struct v4l2_frequency *f); | 793 | const struct v4l2_frequency *f); |
| 795 | int saa7134_reqbufs(struct file *file, void *priv, | ||
| 796 | struct v4l2_requestbuffers *p); | ||
| 797 | int saa7134_querybuf(struct file *file, void *priv, | ||
| 798 | struct v4l2_buffer *b); | ||
| 799 | int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b); | ||
| 800 | int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b); | ||
| 801 | int saa7134_streamon(struct file *file, void *priv, | ||
| 802 | enum v4l2_buf_type type); | ||
| 803 | int saa7134_streamoff(struct file *file, void *priv, | ||
| 804 | enum v4l2_buf_type type); | ||
| 805 | 794 | ||
| 806 | int saa7134_videoport_init(struct saa7134_dev *dev); | 795 | int saa7134_videoport_init(struct saa7134_dev *dev); |
| 807 | void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); | 796 | void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); |
| @@ -818,7 +807,16 @@ void saa7134_video_fini(struct saa7134_dev *dev); | |||
| 818 | 807 | ||
| 819 | #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */ | 808 | #define TS_PACKET_SIZE 188 /* TS packets 188 bytes */ |
| 820 | 809 | ||
| 821 | extern struct videobuf_queue_ops saa7134_ts_qops; | 810 | int saa7134_ts_buffer_init(struct vb2_buffer *vb2); |
| 811 | int saa7134_ts_buffer_prepare(struct vb2_buffer *vb2); | ||
| 812 | void saa7134_ts_buffer_finish(struct vb2_buffer *vb2); | ||
| 813 | int saa7134_ts_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, | ||
| 814 | unsigned int *nbuffers, unsigned int *nplanes, | ||
| 815 | unsigned int sizes[], void *alloc_ctxs[]); | ||
| 816 | int saa7134_ts_start_streaming(struct vb2_queue *vq, unsigned int count); | ||
| 817 | void saa7134_ts_stop_streaming(struct vb2_queue *vq); | ||
| 818 | |||
| 819 | extern struct vb2_ops saa7134_ts_qops; | ||
| 822 | 820 | ||
| 823 | int saa7134_ts_init1(struct saa7134_dev *dev); | 821 | int saa7134_ts_init1(struct saa7134_dev *dev); |
| 824 | int saa7134_ts_fini(struct saa7134_dev *dev); | 822 | int saa7134_ts_fini(struct saa7134_dev *dev); |
| @@ -835,7 +833,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev); | |||
| 835 | /* ----------------------------------------------------------- */ | 833 | /* ----------------------------------------------------------- */ |
| 836 | /* saa7134-vbi.c */ | 834 | /* saa7134-vbi.c */ |
| 837 | 835 | ||
| 838 | extern struct videobuf_queue_ops saa7134_vbi_qops; | 836 | extern struct vb2_ops saa7134_vbi_qops; |
| 839 | extern struct video_device saa7134_vbi_template; | 837 | extern struct video_device saa7134_vbi_template; |
| 840 | 838 | ||
| 841 | int saa7134_vbi_init1(struct saa7134_dev *dev); | 839 | int saa7134_vbi_init1(struct saa7134_dev *dev); |
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index 33abe332d175..c4c8fce8f2b4 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c | |||
| @@ -357,7 +357,7 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 357 | tea6420_route(mxb, 6); | 357 | tea6420_route(mxb, 6); |
| 358 | 358 | ||
| 359 | /* select video mode in saa7111a */ | 359 | /* select video mode in saa7111a */ |
| 360 | saa7111a_call(mxb, core, s_std, std); | 360 | saa7111a_call(mxb, video, s_std, std); |
| 361 | 361 | ||
| 362 | /* select tuner-output on saa7111a */ | 362 | /* select tuner-output on saa7111a */ |
| 363 | i = 0; | 363 | i = 0; |
| @@ -379,8 +379,8 @@ static int mxb_init_done(struct saa7146_dev* dev) | |||
| 379 | /* These two gpio calls set the GPIO pins that control the tda9820 */ | 379 | /* These two gpio calls set the GPIO pins that control the tda9820 */ |
| 380 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 380 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 381 | saa7111a_call(mxb, core, s_gpio, 1); | 381 | saa7111a_call(mxb, core, s_gpio, 1); |
| 382 | saa7111a_call(mxb, core, s_std, std); | 382 | saa7111a_call(mxb, video, s_std, std); |
| 383 | tuner_call(mxb, core, s_std, std); | 383 | tuner_call(mxb, video, s_std, std); |
| 384 | 384 | ||
| 385 | /* switch to tuner-channel on tea6415c */ | 385 | /* switch to tuner-channel on tea6415c */ |
| 386 | tea6415c_call(mxb, video, s_routing, 3, 17, 0); | 386 | 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 | |||
| 771 | /* These two gpio calls set the GPIO pins that control the tda9820 */ | 771 | /* These two gpio calls set the GPIO pins that control the tda9820 */ |
| 772 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 772 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 773 | saa7111a_call(mxb, core, s_gpio, 0); | 773 | saa7111a_call(mxb, core, s_gpio, 0); |
| 774 | saa7111a_call(mxb, core, s_std, std); | 774 | saa7111a_call(mxb, video, s_std, std); |
| 775 | if (mxb->cur_input == 0) | 775 | if (mxb->cur_input == 0) |
| 776 | tuner_call(mxb, core, s_std, std); | 776 | tuner_call(mxb, video, s_std, std); |
| 777 | } else { | 777 | } else { |
| 778 | v4l2_std_id std = V4L2_STD_PAL_BG; | 778 | v4l2_std_id std = V4L2_STD_PAL_BG; |
| 779 | 779 | ||
| @@ -783,9 +783,9 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa | |||
| 783 | /* These two gpio calls set the GPIO pins that control the tda9820 */ | 783 | /* These two gpio calls set the GPIO pins that control the tda9820 */ |
| 784 | saa7146_write(dev, GPIO_CTRL, 0x00404050); | 784 | saa7146_write(dev, GPIO_CTRL, 0x00404050); |
| 785 | saa7111a_call(mxb, core, s_gpio, 1); | 785 | saa7111a_call(mxb, core, s_gpio, 1); |
| 786 | saa7111a_call(mxb, core, s_std, std); | 786 | saa7111a_call(mxb, video, s_std, std); |
| 787 | if (mxb->cur_input == 0) | 787 | if (mxb->cur_input == 0) |
| 788 | tuner_call(mxb, core, s_std, std); | 788 | tuner_call(mxb, video, s_std, std); |
| 789 | } | 789 | } |
| 790 | return 0; | 790 | return 0; |
| 791 | } | 791 | } |
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c index bb11443ed63e..d2abd3b5c2bf 100644 --- a/drivers/media/pci/sta2x11/sta2x11_vip.c +++ b/drivers/media/pci/sta2x11/sta2x11_vip.c | |||
| @@ -357,7 +357,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | /* abort streaming and wait for last buffer */ | 359 | /* abort streaming and wait for last buffer */ |
| 360 | static int stop_streaming(struct vb2_queue *vq) | 360 | static void stop_streaming(struct vb2_queue *vq) |
| 361 | { | 361 | { |
| 362 | struct sta2x11_vip *vip = vb2_get_drv_priv(vq); | 362 | struct sta2x11_vip *vip = vb2_get_drv_priv(vq); |
| 363 | struct vip_buffer *vip_buf, *node; | 363 | struct vip_buffer *vip_buf, *node; |
| @@ -374,7 +374,6 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 374 | list_del(&vip_buf->list); | 374 | list_del(&vip_buf->list); |
| 375 | } | 375 | } |
| 376 | spin_unlock(&vip->lock); | 376 | spin_unlock(&vip->lock); |
| 377 | return 0; | ||
| 378 | } | 377 | } |
| 379 | 378 | ||
| 380 | static struct vb2_ops vip_video_qops = { | 379 | 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) | |||
| 445 | int status; | 444 | int status; |
| 446 | 445 | ||
| 447 | if (V4L2_STD_ALL == std) { | 446 | if (V4L2_STD_ALL == std) { |
| 448 | v4l2_subdev_call(vip->decoder, core, s_std, std); | 447 | v4l2_subdev_call(vip->decoder, video, s_std, std); |
| 449 | ssleep(2); | 448 | ssleep(2); |
| 450 | v4l2_subdev_call(vip->decoder, video, querystd, &newstd); | 449 | v4l2_subdev_call(vip->decoder, video, querystd, &newstd); |
| 451 | v4l2_subdev_call(vip->decoder, video, g_input_status, &status); | 450 | 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) | |||
| 468 | vip->format = formats_50[0]; | 467 | vip->format = formats_50[0]; |
| 469 | } | 468 | } |
| 470 | 469 | ||
| 471 | return v4l2_subdev_call(vip->decoder, core, s_std, std); | 470 | return v4l2_subdev_call(vip->decoder, video, s_std, std); |
| 472 | } | 471 | } |
| 473 | 472 | ||
| 474 | /** | 473 | /** |
diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index 301029ca4535..9544cfc06601 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c | |||
| @@ -958,8 +958,10 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait) | |||
| 958 | if (av7110->playing) { | 958 | if (av7110->playing) { |
| 959 | if (FREE_COND) | 959 | if (FREE_COND) |
| 960 | mask |= (POLLOUT | POLLWRNORM); | 960 | mask |= (POLLOUT | POLLWRNORM); |
| 961 | } else /* if not playing: may play if asked for */ | 961 | } else { |
| 962 | mask |= (POLLOUT | POLLWRNORM); | 962 | /* if not playing: may play if asked for */ |
| 963 | mask |= (POLLOUT | POLLWRNORM); | ||
| 964 | } | ||
| 963 | } | 965 | } |
| 964 | 966 | ||
| 965 | return mask; | 967 | return mask; |
diff --git a/drivers/media/pci/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c index 519164c572c8..bf34b93f23ee 100644 --- a/drivers/media/pci/zoran/zoran_device.c +++ b/drivers/media/pci/zoran/zoran_device.c | |||
| @@ -1572,7 +1572,7 @@ zoran_init_hardware (struct zoran *zr) | |||
| 1572 | } | 1572 | } |
| 1573 | 1573 | ||
| 1574 | decoder_call(zr, core, init, 0); | 1574 | decoder_call(zr, core, init, 0); |
| 1575 | decoder_call(zr, core, s_std, zr->norm); | 1575 | decoder_call(zr, video, s_std, zr->norm); |
| 1576 | decoder_call(zr, video, s_routing, | 1576 | decoder_call(zr, video, s_routing, |
| 1577 | zr->card.input[zr->input].muxsel, 0, 0); | 1577 | zr->card.input[zr->input].muxsel, 0, 0); |
| 1578 | 1578 | ||
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index e7e9840c6c35..099d5fbebb7c 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c | |||
| @@ -1469,7 +1469,7 @@ zoran_set_norm (struct zoran *zr, | |||
| 1469 | if (on) | 1469 | if (on) |
| 1470 | zr36057_overlay(zr, 0); | 1470 | zr36057_overlay(zr, 0); |
| 1471 | 1471 | ||
| 1472 | decoder_call(zr, core, s_std, norm); | 1472 | decoder_call(zr, video, s_std, norm); |
| 1473 | encoder_call(zr, video, s_std_output, norm); | 1473 | encoder_call(zr, video, s_std_output, norm); |
| 1474 | 1474 | ||
| 1475 | if (on) | 1475 | if (on) |
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c index 200bec91182e..16e4b1c525c4 100644 --- a/drivers/media/platform/blackfin/bfin_capture.c +++ b/drivers/media/platform/blackfin/bfin_capture.c | |||
| @@ -427,15 +427,12 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 427 | return 0; | 427 | return 0; |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | static int bcap_stop_streaming(struct vb2_queue *vq) | 430 | static void bcap_stop_streaming(struct vb2_queue *vq) |
| 431 | { | 431 | { |
| 432 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); | 432 | struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); |
| 433 | struct ppi_if *ppi = bcap_dev->ppi; | 433 | struct ppi_if *ppi = bcap_dev->ppi; |
| 434 | int ret; | 434 | int ret; |
| 435 | 435 | ||
| 436 | if (!vb2_is_streaming(vq)) | ||
| 437 | return 0; | ||
| 438 | |||
| 439 | bcap_dev->stop = true; | 436 | bcap_dev->stop = true; |
| 440 | wait_for_completion(&bcap_dev->comp); | 437 | wait_for_completion(&bcap_dev->comp); |
| 441 | ppi->ops->stop(ppi); | 438 | ppi->ops->stop(ppi); |
| @@ -452,7 +449,6 @@ static int bcap_stop_streaming(struct vb2_queue *vq) | |||
| 452 | list_del(&bcap_dev->cur_frm->list); | 449 | list_del(&bcap_dev->cur_frm->list); |
| 453 | vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR); | 450 | vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR); |
| 454 | } | 451 | } |
| 455 | return 0; | ||
| 456 | } | 452 | } |
| 457 | 453 | ||
| 458 | static struct vb2_ops bcap_video_qops = { | 454 | 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) | |||
| 635 | if (vb2_is_busy(&bcap_dev->buffer_queue)) | 631 | if (vb2_is_busy(&bcap_dev->buffer_queue)) |
| 636 | return -EBUSY; | 632 | return -EBUSY; |
| 637 | 633 | ||
| 638 | ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, std); | 634 | ret = v4l2_subdev_call(bcap_dev->sd, video, s_std, std); |
| 639 | if (ret < 0) | 635 | if (ret < 0) |
| 640 | return ret; | 636 | return ret; |
| 641 | 637 | ||
| @@ -648,7 +644,9 @@ static int bcap_enum_dv_timings(struct file *file, void *priv, | |||
| 648 | { | 644 | { |
| 649 | struct bcap_device *bcap_dev = video_drvdata(file); | 645 | struct bcap_device *bcap_dev = video_drvdata(file); |
| 650 | 646 | ||
| 651 | return v4l2_subdev_call(bcap_dev->sd, video, | 647 | timings->pad = 0; |
| 648 | |||
| 649 | return v4l2_subdev_call(bcap_dev->sd, pad, | ||
| 652 | enum_dv_timings, timings); | 650 | enum_dv_timings, timings); |
| 653 | } | 651 | } |
| 654 | 652 | ||
| @@ -1069,7 +1067,7 @@ static int bcap_probe(struct platform_device *pdev) | |||
| 1069 | /* now we can probe the default state */ | 1067 | /* now we can probe the default state */ |
| 1070 | if (config->inputs[0].capabilities & V4L2_IN_CAP_STD) { | 1068 | if (config->inputs[0].capabilities & V4L2_IN_CAP_STD) { |
| 1071 | v4l2_std_id std; | 1069 | v4l2_std_id std; |
| 1072 | ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std); | 1070 | ret = v4l2_subdev_call(bcap_dev->sd, video, g_std, &std); |
| 1073 | if (ret) { | 1071 | if (ret) { |
| 1074 | v4l2_err(&bcap_dev->v4l2_dev, | 1072 | v4l2_err(&bcap_dev->v4l2_dev, |
| 1075 | "Unable to get std\n"); | 1073 | "Unable to get std\n"); |
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 3e5199ee5d25..b1783791d426 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c | |||
| @@ -2269,7 +2269,7 @@ out: | |||
| 2269 | return ret; | 2269 | return ret; |
| 2270 | } | 2270 | } |
| 2271 | 2271 | ||
| 2272 | static int coda_stop_streaming(struct vb2_queue *q) | 2272 | static void coda_stop_streaming(struct vb2_queue *q) |
| 2273 | { | 2273 | { |
| 2274 | struct coda_ctx *ctx = vb2_get_drv_priv(q); | 2274 | struct coda_ctx *ctx = vb2_get_drv_priv(q); |
| 2275 | struct coda_dev *dev = ctx->dev; | 2275 | struct coda_dev *dev = ctx->dev; |
| @@ -2295,8 +2295,6 @@ static int coda_stop_streaming(struct vb2_queue *q) | |||
| 2295 | ctx->bitstream.vaddr, ctx->bitstream.size); | 2295 | ctx->bitstream.vaddr, ctx->bitstream.size); |
| 2296 | ctx->runcounter = 0; | 2296 | ctx->runcounter = 0; |
| 2297 | } | 2297 | } |
| 2298 | |||
| 2299 | return 0; | ||
| 2300 | } | 2298 | } |
| 2301 | 2299 | ||
| 2302 | static struct vb2_ops coda_qops = { | 2300 | static struct vb2_ops coda_qops = { |
| @@ -3235,7 +3233,7 @@ static int coda_probe(struct platform_device *pdev) | |||
| 3235 | } | 3233 | } |
| 3236 | 3234 | ||
| 3237 | if (devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler, | 3235 | if (devm_request_threaded_irq(&pdev->dev, irq, NULL, coda_irq_handler, |
| 3238 | IRQF_ONESHOT, CODA_NAME, dev) < 0) { | 3236 | IRQF_ONESHOT, dev_name(&pdev->dev), dev) < 0) { |
| 3239 | dev_err(&pdev->dev, "failed to request irq\n"); | 3237 | dev_err(&pdev->dev, "failed to request irq\n"); |
| 3240 | return -ENOENT; | 3238 | return -ENOENT; |
| 3241 | } | 3239 | } |
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 656708252962..bf5eff99452b 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c | |||
| @@ -355,8 +355,17 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 355 | 355 | ||
| 356 | /* Set parameters in OSD and VENC */ | 356 | /* Set parameters in OSD and VENC */ |
| 357 | ret = vpbe_set_osd_display_params(fh->disp_dev, layer); | 357 | ret = vpbe_set_osd_display_params(fh->disp_dev, layer); |
| 358 | if (ret < 0) | 358 | if (ret < 0) { |
| 359 | struct vpbe_disp_buffer *buf, *tmp; | ||
| 360 | |||
| 361 | vb2_buffer_done(&layer->cur_frm->vb, VB2_BUF_STATE_QUEUED); | ||
| 362 | list_for_each_entry_safe(buf, tmp, &layer->dma_queue, list) { | ||
| 363 | list_del(&buf->list); | ||
| 364 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
| 365 | } | ||
| 366 | |||
| 359 | return ret; | 367 | return ret; |
| 368 | } | ||
| 360 | 369 | ||
| 361 | /* | 370 | /* |
| 362 | * if request format is yuv420 semiplanar, need to | 371 | * if request format is yuv420 semiplanar, need to |
| @@ -368,7 +377,7 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 368 | return ret; | 377 | return ret; |
| 369 | } | 378 | } |
| 370 | 379 | ||
| 371 | static int vpbe_stop_streaming(struct vb2_queue *vq) | 380 | static void vpbe_stop_streaming(struct vb2_queue *vq) |
| 372 | { | 381 | { |
| 373 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); | 382 | struct vpbe_fh *fh = vb2_get_drv_priv(vq); |
| 374 | struct vpbe_layer *layer = fh->layer; | 383 | struct vpbe_layer *layer = fh->layer; |
| @@ -376,7 +385,7 @@ static int vpbe_stop_streaming(struct vb2_queue *vq) | |||
| 376 | unsigned long flags; | 385 | unsigned long flags; |
| 377 | 386 | ||
| 378 | if (!vb2_is_streaming(vq)) | 387 | if (!vb2_is_streaming(vq)) |
| 379 | return 0; | 388 | return; |
| 380 | 389 | ||
| 381 | /* release all active buffers */ | 390 | /* release all active buffers */ |
| 382 | spin_lock_irqsave(&disp->dma_queue_lock, flags); | 391 | spin_lock_irqsave(&disp->dma_queue_lock, flags); |
| @@ -398,7 +407,6 @@ static int vpbe_stop_streaming(struct vb2_queue *vq) | |||
| 398 | vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR); | 407 | vb2_buffer_done(&layer->next_frm->vb, VB2_BUF_STATE_ERROR); |
| 399 | } | 408 | } |
| 400 | spin_unlock_irqrestore(&disp->dma_queue_lock, flags); | 409 | spin_unlock_irqrestore(&disp->dma_queue_lock, flags); |
| 401 | return 0; | ||
| 402 | } | 410 | } |
| 403 | 411 | ||
| 404 | static struct vb2_ops video_qops = { | 412 | static struct vb2_ops video_qops = { |
| @@ -680,29 +688,6 @@ static int vpbe_try_format(struct vpbe_display *disp_dev, | |||
| 680 | return 0; | 688 | return 0; |
| 681 | } | 689 | } |
| 682 | 690 | ||
| 683 | static int vpbe_display_g_priority(struct file *file, void *priv, | ||
| 684 | enum v4l2_priority *p) | ||
| 685 | { | ||
| 686 | struct vpbe_fh *fh = file->private_data; | ||
| 687 | struct vpbe_layer *layer = fh->layer; | ||
| 688 | |||
| 689 | *p = v4l2_prio_max(&layer->prio); | ||
| 690 | |||
| 691 | return 0; | ||
| 692 | } | ||
| 693 | |||
| 694 | static int vpbe_display_s_priority(struct file *file, void *priv, | ||
| 695 | enum v4l2_priority p) | ||
| 696 | { | ||
| 697 | struct vpbe_fh *fh = file->private_data; | ||
| 698 | struct vpbe_layer *layer = fh->layer; | ||
| 699 | int ret; | ||
| 700 | |||
| 701 | ret = v4l2_prio_change(&layer->prio, &fh->prio, p); | ||
| 702 | |||
| 703 | return ret; | ||
| 704 | } | ||
| 705 | |||
| 706 | static int vpbe_display_querycap(struct file *file, void *priv, | 691 | static int vpbe_display_querycap(struct file *file, void *priv, |
| 707 | struct v4l2_capability *cap) | 692 | struct v4l2_capability *cap) |
| 708 | { | 693 | { |
| @@ -1492,6 +1477,7 @@ static int vpbe_display_open(struct file *file) | |||
| 1492 | { | 1477 | { |
| 1493 | struct vpbe_fh *fh = NULL; | 1478 | struct vpbe_fh *fh = NULL; |
| 1494 | struct vpbe_layer *layer = video_drvdata(file); | 1479 | struct vpbe_layer *layer = video_drvdata(file); |
| 1480 | struct video_device *vdev = video_devdata(file); | ||
| 1495 | struct vpbe_display *disp_dev = layer->disp_dev; | 1481 | struct vpbe_display *disp_dev = layer->disp_dev; |
| 1496 | struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; | 1482 | struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; |
| 1497 | struct osd_state *osd_device = disp_dev->osd_device; | 1483 | struct osd_state *osd_device = disp_dev->osd_device; |
| @@ -1504,6 +1490,7 @@ static int vpbe_display_open(struct file *file) | |||
| 1504 | "unable to allocate memory for file handle object\n"); | 1490 | "unable to allocate memory for file handle object\n"); |
| 1505 | return -ENOMEM; | 1491 | return -ENOMEM; |
| 1506 | } | 1492 | } |
| 1493 | v4l2_fh_init(&fh->fh, vdev); | ||
| 1507 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, | 1494 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, |
| 1508 | "vpbe display open plane = %d\n", | 1495 | "vpbe display open plane = %d\n", |
| 1509 | layer->device_id); | 1496 | layer->device_id); |
| @@ -1532,9 +1519,7 @@ static int vpbe_display_open(struct file *file) | |||
| 1532 | layer->usrs++; | 1519 | layer->usrs++; |
| 1533 | /* Set io_allowed member to false */ | 1520 | /* Set io_allowed member to false */ |
| 1534 | fh->io_allowed = 0; | 1521 | fh->io_allowed = 0; |
| 1535 | /* Initialize priority of this instance to default priority */ | 1522 | v4l2_fh_add(&fh->fh); |
| 1536 | fh->prio = V4L2_PRIORITY_UNSET; | ||
| 1537 | v4l2_prio_open(&layer->prio, &fh->prio); | ||
| 1538 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, | 1523 | v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, |
| 1539 | "vpbe display device opened successfully\n"); | 1524 | "vpbe display device opened successfully\n"); |
| 1540 | return 0; | 1525 | return 0; |
| @@ -1589,8 +1574,9 @@ static int vpbe_display_release(struct file *file) | |||
| 1589 | osd_device->ops.release_layer(osd_device, | 1574 | osd_device->ops.release_layer(osd_device, |
| 1590 | layer->layer_info.id); | 1575 | layer->layer_info.id); |
| 1591 | } | 1576 | } |
| 1592 | /* Close the priority */ | 1577 | |
| 1593 | v4l2_prio_close(&layer->prio, fh->prio); | 1578 | v4l2_fh_del(&fh->fh); |
| 1579 | v4l2_fh_exit(&fh->fh); | ||
| 1594 | file->private_data = NULL; | 1580 | file->private_data = NULL; |
| 1595 | mutex_unlock(&layer->opslock); | 1581 | mutex_unlock(&layer->opslock); |
| 1596 | 1582 | ||
| @@ -1618,8 +1604,6 @@ static const struct v4l2_ioctl_ops vpbe_ioctl_ops = { | |||
| 1618 | .vidioc_cropcap = vpbe_display_cropcap, | 1604 | .vidioc_cropcap = vpbe_display_cropcap, |
| 1619 | .vidioc_g_crop = vpbe_display_g_crop, | 1605 | .vidioc_g_crop = vpbe_display_g_crop, |
| 1620 | .vidioc_s_crop = vpbe_display_s_crop, | 1606 | .vidioc_s_crop = vpbe_display_s_crop, |
| 1621 | .vidioc_g_priority = vpbe_display_g_priority, | ||
| 1622 | .vidioc_s_priority = vpbe_display_s_priority, | ||
| 1623 | .vidioc_s_std = vpbe_display_s_std, | 1607 | .vidioc_s_std = vpbe_display_s_std, |
| 1624 | .vidioc_g_std = vpbe_display_g_std, | 1608 | .vidioc_g_std = vpbe_display_g_std, |
| 1625 | .vidioc_enum_output = vpbe_display_enum_output, | 1609 | .vidioc_enum_output = vpbe_display_enum_output, |
| @@ -1699,8 +1683,6 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev, | |||
| 1699 | vpbe_display_layer->layer_info.id = | 1683 | vpbe_display_layer->layer_info.id = |
| 1700 | ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1); | 1684 | ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1); |
| 1701 | 1685 | ||
| 1702 | /* Initialize prio member of layer object */ | ||
| 1703 | v4l2_prio_init(&vpbe_display_layer->prio); | ||
| 1704 | 1686 | ||
| 1705 | return 0; | 1687 | return 0; |
| 1706 | } | 1688 | } |
| @@ -1727,6 +1709,7 @@ static int register_device(struct vpbe_layer *vpbe_display_layer, | |||
| 1727 | vpbe_display_layer->disp_dev = disp_dev; | 1709 | vpbe_display_layer->disp_dev = disp_dev; |
| 1728 | /* set the driver data in platform device */ | 1710 | /* set the driver data in platform device */ |
| 1729 | platform_set_drvdata(pdev, disp_dev); | 1711 | platform_set_drvdata(pdev, disp_dev); |
| 1712 | set_bit(V4L2_FL_USE_FH_PRIO, &vpbe_display_layer->video_dev.flags); | ||
| 1730 | video_set_drvdata(&vpbe_display_layer->video_dev, | 1713 | video_set_drvdata(&vpbe_display_layer->video_dev, |
| 1731 | vpbe_display_layer); | 1714 | vpbe_display_layer); |
| 1732 | 1715 | ||
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 0379cb9f9a9c..a51bda2fb637 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c | |||
| @@ -498,6 +498,7 @@ unlock: | |||
| 498 | static int vpfe_open(struct file *file) | 498 | static int vpfe_open(struct file *file) |
| 499 | { | 499 | { |
| 500 | struct vpfe_device *vpfe_dev = video_drvdata(file); | 500 | struct vpfe_device *vpfe_dev = video_drvdata(file); |
| 501 | struct video_device *vdev = video_devdata(file); | ||
| 501 | struct vpfe_fh *fh; | 502 | struct vpfe_fh *fh; |
| 502 | 503 | ||
| 503 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n"); | 504 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n"); |
| @@ -517,6 +518,7 @@ static int vpfe_open(struct file *file) | |||
| 517 | /* store pointer to fh in private_data member of file */ | 518 | /* store pointer to fh in private_data member of file */ |
| 518 | file->private_data = fh; | 519 | file->private_data = fh; |
| 519 | fh->vpfe_dev = vpfe_dev; | 520 | fh->vpfe_dev = vpfe_dev; |
| 521 | v4l2_fh_init(&fh->fh, vdev); | ||
| 520 | mutex_lock(&vpfe_dev->lock); | 522 | mutex_lock(&vpfe_dev->lock); |
| 521 | /* If decoder is not initialized. initialize it */ | 523 | /* If decoder is not initialized. initialize it */ |
| 522 | if (!vpfe_dev->initialized) { | 524 | if (!vpfe_dev->initialized) { |
| @@ -529,9 +531,7 @@ static int vpfe_open(struct file *file) | |||
| 529 | vpfe_dev->usrs++; | 531 | vpfe_dev->usrs++; |
| 530 | /* Set io_allowed member to false */ | 532 | /* Set io_allowed member to false */ |
| 531 | fh->io_allowed = 0; | 533 | fh->io_allowed = 0; |
| 532 | /* Initialize priority of this instance to default priority */ | 534 | v4l2_fh_add(&fh->fh); |
| 533 | fh->prio = V4L2_PRIORITY_UNSET; | ||
| 534 | v4l2_prio_open(&vpfe_dev->prio, &fh->prio); | ||
| 535 | mutex_unlock(&vpfe_dev->lock); | 535 | mutex_unlock(&vpfe_dev->lock); |
| 536 | return 0; | 536 | return 0; |
| 537 | } | 537 | } |
| @@ -740,8 +740,8 @@ static int vpfe_release(struct file *file) | |||
| 740 | 740 | ||
| 741 | /* Decrement device usrs counter */ | 741 | /* Decrement device usrs counter */ |
| 742 | vpfe_dev->usrs--; | 742 | vpfe_dev->usrs--; |
| 743 | /* Close the priority */ | 743 | v4l2_fh_del(&fh->fh); |
| 744 | v4l2_prio_close(&vpfe_dev->prio, fh->prio); | 744 | v4l2_fh_exit(&fh->fh); |
| 745 | /* If this is the last file handle */ | 745 | /* If this is the last file handle */ |
| 746 | if (!vpfe_dev->usrs) { | 746 | if (!vpfe_dev->usrs) { |
| 747 | vpfe_dev->initialized = 0; | 747 | vpfe_dev->initialized = 0; |
| @@ -1217,7 +1217,7 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
| 1217 | } | 1217 | } |
| 1218 | 1218 | ||
| 1219 | ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, | 1219 | ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, |
| 1220 | core, s_std, std_id); | 1220 | video, s_std, std_id); |
| 1221 | if (ret < 0) { | 1221 | if (ret < 0) { |
| 1222 | v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n"); | 1222 | v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n"); |
| 1223 | goto unlock_out; | 1223 | goto unlock_out; |
| @@ -1910,14 +1910,13 @@ static int vpfe_probe(struct platform_device *pdev) | |||
| 1910 | /* Initialize field of the device objects */ | 1910 | /* Initialize field of the device objects */ |
| 1911 | vpfe_dev->numbuffers = config_params.numbuffers; | 1911 | vpfe_dev->numbuffers = config_params.numbuffers; |
| 1912 | 1912 | ||
| 1913 | /* Initialize prio member of device object */ | ||
| 1914 | v4l2_prio_init(&vpfe_dev->prio); | ||
| 1915 | /* register video device */ | 1913 | /* register video device */ |
| 1916 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, | 1914 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, |
| 1917 | "trying to register vpfe device.\n"); | 1915 | "trying to register vpfe device.\n"); |
| 1918 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, | 1916 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, |
| 1919 | "video_dev=%x\n", (int)&vpfe_dev->video_dev); | 1917 | "video_dev=%x\n", (int)&vpfe_dev->video_dev); |
| 1920 | vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1918 | vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 1919 | set_bit(V4L2_FL_USE_FH_PRIO, &vpfe_dev->video_dev->flags); | ||
| 1921 | ret = video_register_device(vpfe_dev->video_dev, | 1920 | ret = video_register_device(vpfe_dev->video_dev, |
| 1922 | VFL_TYPE_GRABBER, -1); | 1921 | VFL_TYPE_GRABBER, -1); |
| 1923 | 1922 | ||
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 8dea0b84a3ad..a7ed16497903 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2009 Texas Instruments Inc | 2 | * Copyright (C) 2009 Texas Instruments Inc |
| 3 | * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com> | ||
| 3 | * | 4 | * |
| 4 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
| @@ -65,14 +66,26 @@ static struct vpif_config_params config_params = { | |||
| 65 | .channel_bufsize[1] = 720 * 576 * 2, | 66 | .channel_bufsize[1] = 720 * 576 * 2, |
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| 69 | #define VPIF_DRIVER_NAME "vpif_capture" | ||
| 70 | |||
| 68 | /* global variables */ | 71 | /* global variables */ |
| 69 | static struct vpif_device vpif_obj = { {NULL} }; | 72 | static struct vpif_device vpif_obj = { {NULL} }; |
| 70 | static struct device *vpif_dev; | 73 | static struct device *vpif_dev; |
| 71 | static void vpif_calculate_offsets(struct channel_obj *ch); | 74 | static void vpif_calculate_offsets(struct channel_obj *ch); |
| 72 | static void vpif_config_addr(struct channel_obj *ch, int muxmode); | 75 | static void vpif_config_addr(struct channel_obj *ch, int muxmode); |
| 73 | 76 | ||
| 77 | static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = { {1, 1} }; | ||
| 78 | |||
| 79 | /* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */ | ||
| 80 | static int ycmux_mode; | ||
| 81 | |||
| 82 | static inline struct vpif_cap_buffer *to_vpif_buffer(struct vb2_buffer *vb) | ||
| 83 | { | ||
| 84 | return container_of(vb, struct vpif_cap_buffer, vb); | ||
| 85 | } | ||
| 86 | |||
| 74 | /** | 87 | /** |
| 75 | * buffer_prepare : callback function for buffer prepare | 88 | * vpif_buffer_prepare : callback function for buffer prepare |
| 76 | * @vb: ptr to vb2_buffer | 89 | * @vb: ptr to vb2_buffer |
| 77 | * | 90 | * |
| 78 | * This is the callback function for buffer prepare when vb2_qbuf() | 91 | * This is the callback function for buffer prepare when vb2_qbuf() |
| @@ -81,10 +94,8 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode); | |||
| 81 | */ | 94 | */ |
| 82 | static int vpif_buffer_prepare(struct vb2_buffer *vb) | 95 | static int vpif_buffer_prepare(struct vb2_buffer *vb) |
| 83 | { | 96 | { |
| 84 | /* Get the file handle object and channel object */ | ||
| 85 | struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | ||
| 86 | struct vb2_queue *q = vb->vb2_queue; | 97 | struct vb2_queue *q = vb->vb2_queue; |
| 87 | struct channel_obj *ch = fh->channel; | 98 | struct channel_obj *ch = vb2_get_drv_priv(q); |
| 88 | struct common_obj *common; | 99 | struct common_obj *common; |
| 89 | unsigned long addr; | 100 | unsigned long addr; |
| 90 | 101 | ||
| @@ -92,26 +103,22 @@ static int vpif_buffer_prepare(struct vb2_buffer *vb) | |||
| 92 | 103 | ||
| 93 | common = &ch->common[VPIF_VIDEO_INDEX]; | 104 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 94 | 105 | ||
| 95 | if (vb->state != VB2_BUF_STATE_ACTIVE && | 106 | vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage); |
| 96 | vb->state != VB2_BUF_STATE_PREPARED) { | 107 | if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) |
| 97 | vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage); | 108 | return -EINVAL; |
| 98 | if (vb2_plane_vaddr(vb, 0) && | ||
| 99 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) | ||
| 100 | goto exit; | ||
| 101 | addr = vb2_dma_contig_plane_dma_addr(vb, 0); | ||
| 102 | 109 | ||
| 103 | if (q->streaming) { | 110 | vb->v4l2_buf.field = common->fmt.fmt.pix.field; |
| 104 | if (!IS_ALIGNED((addr + common->ytop_off), 8) || | 111 | |
| 105 | !IS_ALIGNED((addr + common->ybtm_off), 8) || | 112 | addr = vb2_dma_contig_plane_dma_addr(vb, 0); |
| 106 | !IS_ALIGNED((addr + common->ctop_off), 8) || | 113 | if (!IS_ALIGNED((addr + common->ytop_off), 8) || |
| 107 | !IS_ALIGNED((addr + common->cbtm_off), 8)) | 114 | !IS_ALIGNED((addr + common->ybtm_off), 8) || |
| 108 | goto exit; | 115 | !IS_ALIGNED((addr + common->ctop_off), 8) || |
| 109 | } | 116 | !IS_ALIGNED((addr + common->cbtm_off), 8)) { |
| 117 | vpif_dbg(1, debug, "offset is not aligned\n"); | ||
| 118 | return -EINVAL; | ||
| 110 | } | 119 | } |
| 120 | |||
| 111 | return 0; | 121 | return 0; |
| 112 | exit: | ||
| 113 | vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n"); | ||
| 114 | return -EINVAL; | ||
| 115 | } | 122 | } |
| 116 | 123 | ||
| 117 | /** | 124 | /** |
| @@ -131,49 +138,26 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq, | |||
| 131 | unsigned int *nbuffers, unsigned int *nplanes, | 138 | unsigned int *nbuffers, unsigned int *nplanes, |
| 132 | unsigned int sizes[], void *alloc_ctxs[]) | 139 | unsigned int sizes[], void *alloc_ctxs[]) |
| 133 | { | 140 | { |
| 134 | /* Get the file handle object and channel object */ | 141 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
| 135 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | ||
| 136 | struct channel_obj *ch = fh->channel; | ||
| 137 | struct common_obj *common; | 142 | struct common_obj *common; |
| 138 | unsigned long size; | ||
| 139 | 143 | ||
| 140 | common = &ch->common[VPIF_VIDEO_INDEX]; | 144 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 141 | 145 | ||
| 142 | vpif_dbg(2, debug, "vpif_buffer_setup\n"); | 146 | vpif_dbg(2, debug, "vpif_buffer_setup\n"); |
| 143 | 147 | ||
| 144 | /* If memory type is not mmap, return */ | 148 | if (fmt && fmt->fmt.pix.sizeimage < common->fmt.fmt.pix.sizeimage) |
| 145 | if (V4L2_MEMORY_MMAP == common->memory) { | 149 | return -EINVAL; |
| 146 | /* Calculate the size of the buffer */ | ||
| 147 | size = config_params.channel_bufsize[ch->channel_id]; | ||
| 148 | /* | ||
| 149 | * Checking if the buffer size exceeds the available buffer | ||
| 150 | * ycmux_mode = 0 means 1 channel mode HD and | ||
| 151 | * ycmux_mode = 1 means 2 channels mode SD | ||
| 152 | */ | ||
| 153 | if (ch->vpifparams.std_info.ycmux_mode == 0) { | ||
| 154 | if (config_params.video_limit[ch->channel_id]) | ||
| 155 | while (size * *nbuffers > | ||
| 156 | (config_params.video_limit[0] | ||
| 157 | + config_params.video_limit[1])) | ||
| 158 | (*nbuffers)--; | ||
| 159 | } else { | ||
| 160 | if (config_params.video_limit[ch->channel_id]) | ||
| 161 | while (size * *nbuffers > | ||
| 162 | config_params.video_limit[ch->channel_id]) | ||
| 163 | (*nbuffers)--; | ||
| 164 | } | ||
| 165 | |||
| 166 | } else { | ||
| 167 | size = common->fmt.fmt.pix.sizeimage; | ||
| 168 | } | ||
| 169 | 150 | ||
| 170 | if (*nbuffers < config_params.min_numbuffers) | 151 | if (vq->num_buffers + *nbuffers < 3) |
| 171 | *nbuffers = config_params.min_numbuffers; | 152 | *nbuffers = 3 - vq->num_buffers; |
| 172 | 153 | ||
| 173 | *nplanes = 1; | 154 | *nplanes = 1; |
| 174 | sizes[0] = size; | 155 | sizes[0] = fmt ? fmt->fmt.pix.sizeimage : common->fmt.fmt.pix.sizeimage; |
| 175 | alloc_ctxs[0] = common->alloc_ctx; | 156 | alloc_ctxs[0] = common->alloc_ctx; |
| 176 | 157 | ||
| 158 | /* Calculate the offset for Y and C data in the buffer */ | ||
| 159 | vpif_calculate_offsets(ch); | ||
| 160 | |||
| 177 | return 0; | 161 | return 0; |
| 178 | } | 162 | } |
| 179 | 163 | ||
| @@ -183,11 +167,8 @@ static int vpif_buffer_queue_setup(struct vb2_queue *vq, | |||
| 183 | */ | 167 | */ |
| 184 | static void vpif_buffer_queue(struct vb2_buffer *vb) | 168 | static void vpif_buffer_queue(struct vb2_buffer *vb) |
| 185 | { | 169 | { |
| 186 | /* Get the file handle object and channel object */ | 170 | struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue); |
| 187 | struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | 171 | struct vpif_cap_buffer *buf = to_vpif_buffer(vb); |
| 188 | struct channel_obj *ch = fh->channel; | ||
| 189 | struct vpif_cap_buffer *buf = container_of(vb, | ||
| 190 | struct vpif_cap_buffer, vb); | ||
| 191 | struct common_obj *common; | 172 | struct common_obj *common; |
| 192 | unsigned long flags; | 173 | unsigned long flags; |
| 193 | 174 | ||
| @@ -202,102 +183,25 @@ static void vpif_buffer_queue(struct vb2_buffer *vb) | |||
| 202 | } | 183 | } |
| 203 | 184 | ||
| 204 | /** | 185 | /** |
| 205 | * vpif_buf_cleanup : Callback function to free buffer | 186 | * vpif_start_streaming : Starts the DMA engine for streaming |
| 206 | * @vb: ptr to vb2_buffer | 187 | * @vb: ptr to vb2_buffer |
| 207 | * | 188 | * @count: number of buffers |
| 208 | * This function is called from the videobuf2 layer to free memory | ||
| 209 | * allocated to the buffers | ||
| 210 | */ | 189 | */ |
| 211 | static void vpif_buf_cleanup(struct vb2_buffer *vb) | ||
| 212 | { | ||
| 213 | /* Get the file handle object and channel object */ | ||
| 214 | struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | ||
| 215 | struct vpif_cap_buffer *buf = container_of(vb, | ||
| 216 | struct vpif_cap_buffer, vb); | ||
| 217 | struct channel_obj *ch = fh->channel; | ||
| 218 | struct common_obj *common; | ||
| 219 | unsigned long flags; | ||
| 220 | |||
| 221 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 222 | |||
| 223 | spin_lock_irqsave(&common->irqlock, flags); | ||
| 224 | if (vb->state == VB2_BUF_STATE_ACTIVE) | ||
| 225 | list_del_init(&buf->list); | ||
| 226 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
| 227 | |||
| 228 | } | ||
| 229 | |||
| 230 | static void vpif_wait_prepare(struct vb2_queue *vq) | ||
| 231 | { | ||
| 232 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | ||
| 233 | struct channel_obj *ch = fh->channel; | ||
| 234 | struct common_obj *common; | ||
| 235 | |||
| 236 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 237 | mutex_unlock(&common->lock); | ||
| 238 | } | ||
| 239 | |||
| 240 | static void vpif_wait_finish(struct vb2_queue *vq) | ||
| 241 | { | ||
| 242 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | ||
| 243 | struct channel_obj *ch = fh->channel; | ||
| 244 | struct common_obj *common; | ||
| 245 | |||
| 246 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 247 | mutex_lock(&common->lock); | ||
| 248 | } | ||
| 249 | |||
| 250 | static int vpif_buffer_init(struct vb2_buffer *vb) | ||
| 251 | { | ||
| 252 | struct vpif_cap_buffer *buf = container_of(vb, | ||
| 253 | struct vpif_cap_buffer, vb); | ||
| 254 | |||
| 255 | INIT_LIST_HEAD(&buf->list); | ||
| 256 | |||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] = | ||
| 261 | { {1, 1} }; | ||
| 262 | |||
| 263 | static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | 190 | static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) |
| 264 | { | 191 | { |
| 265 | struct vpif_capture_config *vpif_config_data = | 192 | struct vpif_capture_config *vpif_config_data = |
| 266 | vpif_dev->platform_data; | 193 | vpif_dev->platform_data; |
| 267 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | 194 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
| 268 | struct channel_obj *ch = fh->channel; | ||
| 269 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 195 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 270 | struct vpif_params *vpif = &ch->vpifparams; | 196 | struct vpif_params *vpif = &ch->vpifparams; |
| 271 | unsigned long addr = 0; | 197 | struct vpif_cap_buffer *buf, *tmp; |
| 272 | unsigned long flags; | 198 | unsigned long addr, flags; |
| 273 | int ret; | 199 | int ret; |
| 274 | 200 | ||
| 275 | spin_lock_irqsave(&common->irqlock, flags); | 201 | spin_lock_irqsave(&common->irqlock, flags); |
| 276 | 202 | ||
| 277 | /* Get the next frame from the buffer queue */ | 203 | /* Initialize field_id */ |
| 278 | common->cur_frm = common->next_frm = list_entry(common->dma_queue.next, | ||
| 279 | struct vpif_cap_buffer, list); | ||
| 280 | /* Remove buffer from the buffer queue */ | ||
| 281 | list_del(&common->cur_frm->list); | ||
| 282 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
| 283 | /* Mark state of the current frame to active */ | ||
| 284 | common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; | ||
| 285 | /* Initialize field_id and started member */ | ||
| 286 | ch->field_id = 0; | 204 | ch->field_id = 0; |
| 287 | common->started = 1; | ||
| 288 | addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0); | ||
| 289 | |||
| 290 | /* Calculate the offset for Y and C data in the buffer */ | ||
| 291 | vpif_calculate_offsets(ch); | ||
| 292 | |||
| 293 | if ((vpif->std_info.frm_fmt && | ||
| 294 | ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) && | ||
| 295 | (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) || | ||
| 296 | (!vpif->std_info.frm_fmt && | ||
| 297 | (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) { | ||
| 298 | vpif_dbg(1, debug, "conflict in field format and std format\n"); | ||
| 299 | return -EINVAL; | ||
| 300 | } | ||
| 301 | 205 | ||
| 302 | /* configure 1 or 2 channel mode */ | 206 | /* configure 1 or 2 channel mode */ |
| 303 | if (vpif_config_data->setup_input_channel_mode) { | 207 | if (vpif_config_data->setup_input_channel_mode) { |
| @@ -305,21 +209,37 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 305 | setup_input_channel_mode(vpif->std_info.ycmux_mode); | 209 | setup_input_channel_mode(vpif->std_info.ycmux_mode); |
| 306 | if (ret < 0) { | 210 | if (ret < 0) { |
| 307 | vpif_dbg(1, debug, "can't set vpif channel mode\n"); | 211 | vpif_dbg(1, debug, "can't set vpif channel mode\n"); |
| 308 | return ret; | 212 | goto err; |
| 309 | } | 213 | } |
| 310 | } | 214 | } |
| 311 | 215 | ||
| 216 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 1); | ||
| 217 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { | ||
| 218 | vpif_dbg(1, debug, "stream on failed in subdev\n"); | ||
| 219 | goto err; | ||
| 220 | } | ||
| 221 | |||
| 312 | /* Call vpif_set_params function to set the parameters and addresses */ | 222 | /* Call vpif_set_params function to set the parameters and addresses */ |
| 313 | ret = vpif_set_video_params(vpif, ch->channel_id); | 223 | ret = vpif_set_video_params(vpif, ch->channel_id); |
| 314 | |||
| 315 | if (ret < 0) { | 224 | if (ret < 0) { |
| 316 | vpif_dbg(1, debug, "can't set video params\n"); | 225 | vpif_dbg(1, debug, "can't set video params\n"); |
| 317 | return ret; | 226 | goto err; |
| 318 | } | 227 | } |
| 319 | 228 | ||
| 320 | common->started = ret; | 229 | ycmux_mode = ret; |
| 321 | vpif_config_addr(ch, ret); | 230 | vpif_config_addr(ch, ret); |
| 322 | 231 | ||
| 232 | /* Get the next frame from the buffer queue */ | ||
| 233 | common->cur_frm = common->next_frm = list_entry(common->dma_queue.next, | ||
| 234 | struct vpif_cap_buffer, list); | ||
| 235 | /* Remove buffer from the buffer queue */ | ||
| 236 | list_del(&common->cur_frm->list); | ||
| 237 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
| 238 | /* Mark state of the current frame to active */ | ||
| 239 | common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; | ||
| 240 | |||
| 241 | addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0); | ||
| 242 | |||
| 323 | common->set_addr(addr + common->ytop_off, | 243 | common->set_addr(addr + common->ytop_off, |
| 324 | addr + common->ybtm_off, | 244 | addr + common->ybtm_off, |
| 325 | addr + common->ctop_off, | 245 | addr + common->ctop_off, |
| @@ -330,31 +250,42 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 330 | * VPIF register | 250 | * VPIF register |
| 331 | */ | 251 | */ |
| 332 | channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; | 252 | channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; |
| 333 | if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) { | 253 | if (VPIF_CHANNEL0_VIDEO == ch->channel_id) { |
| 334 | channel0_intr_assert(); | 254 | channel0_intr_assert(); |
| 335 | channel0_intr_enable(1); | 255 | channel0_intr_enable(1); |
| 336 | enable_channel0(1); | 256 | enable_channel0(1); |
| 337 | } | 257 | } |
| 338 | if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) || | 258 | if (VPIF_CHANNEL1_VIDEO == ch->channel_id || |
| 339 | (common->started == 2)) { | 259 | ycmux_mode == 2) { |
| 340 | channel1_intr_assert(); | 260 | channel1_intr_assert(); |
| 341 | channel1_intr_enable(1); | 261 | channel1_intr_enable(1); |
| 342 | enable_channel1(1); | 262 | enable_channel1(1); |
| 343 | } | 263 | } |
| 344 | 264 | ||
| 345 | return 0; | 265 | return 0; |
| 266 | |||
| 267 | err: | ||
| 268 | list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) { | ||
| 269 | list_del(&buf->list); | ||
| 270 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
| 271 | } | ||
| 272 | |||
| 273 | return ret; | ||
| 346 | } | 274 | } |
| 347 | 275 | ||
| 348 | /* abort streaming and wait for last buffer */ | 276 | /** |
| 349 | static int vpif_stop_streaming(struct vb2_queue *vq) | 277 | * vpif_stop_streaming : Stop the DMA engine |
| 278 | * @vq: ptr to vb2_queue | ||
| 279 | * | ||
| 280 | * This callback stops the DMA engine and any remaining buffers | ||
| 281 | * in the DMA queue are released. | ||
| 282 | */ | ||
| 283 | static void vpif_stop_streaming(struct vb2_queue *vq) | ||
| 350 | { | 284 | { |
| 351 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | 285 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
| 352 | struct channel_obj *ch = fh->channel; | ||
| 353 | struct common_obj *common; | 286 | struct common_obj *common; |
| 354 | unsigned long flags; | 287 | unsigned long flags; |
| 355 | 288 | int ret; | |
| 356 | if (!vb2_is_streaming(vq)) | ||
| 357 | return 0; | ||
| 358 | 289 | ||
| 359 | common = &ch->common[VPIF_VIDEO_INDEX]; | 290 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 360 | 291 | ||
| @@ -363,12 +294,17 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
| 363 | enable_channel0(0); | 294 | enable_channel0(0); |
| 364 | channel0_intr_enable(0); | 295 | channel0_intr_enable(0); |
| 365 | } | 296 | } |
| 366 | if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) || | 297 | if (VPIF_CHANNEL1_VIDEO == ch->channel_id || |
| 367 | (2 == common->started)) { | 298 | ycmux_mode == 2) { |
| 368 | enable_channel1(0); | 299 | enable_channel1(0); |
| 369 | channel1_intr_enable(0); | 300 | channel1_intr_enable(0); |
| 370 | } | 301 | } |
| 371 | common->started = 0; | 302 | |
| 303 | ycmux_mode = 0; | ||
| 304 | |||
| 305 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 0); | ||
| 306 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) | ||
| 307 | vpif_dbg(1, debug, "stream off failed in subdev\n"); | ||
| 372 | 308 | ||
| 373 | /* release all active buffers */ | 309 | /* release all active buffers */ |
| 374 | spin_lock_irqsave(&common->irqlock, flags); | 310 | spin_lock_irqsave(&common->irqlock, flags); |
| @@ -390,19 +326,13 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
| 390 | vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); | 326 | vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); |
| 391 | } | 327 | } |
| 392 | spin_unlock_irqrestore(&common->irqlock, flags); | 328 | spin_unlock_irqrestore(&common->irqlock, flags); |
| 393 | |||
| 394 | return 0; | ||
| 395 | } | 329 | } |
| 396 | 330 | ||
| 397 | static struct vb2_ops video_qops = { | 331 | static struct vb2_ops video_qops = { |
| 398 | .queue_setup = vpif_buffer_queue_setup, | 332 | .queue_setup = vpif_buffer_queue_setup, |
| 399 | .wait_prepare = vpif_wait_prepare, | ||
| 400 | .wait_finish = vpif_wait_finish, | ||
| 401 | .buf_init = vpif_buffer_init, | ||
| 402 | .buf_prepare = vpif_buffer_prepare, | 333 | .buf_prepare = vpif_buffer_prepare, |
| 403 | .start_streaming = vpif_start_streaming, | 334 | .start_streaming = vpif_start_streaming, |
| 404 | .stop_streaming = vpif_stop_streaming, | 335 | .stop_streaming = vpif_stop_streaming, |
| 405 | .buf_cleanup = vpif_buf_cleanup, | ||
| 406 | .buf_queue = vpif_buffer_queue, | 336 | .buf_queue = vpif_buffer_queue, |
| 407 | }; | 337 | }; |
| 408 | 338 | ||
| @@ -479,9 +409,6 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) | |||
| 479 | for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) { | 409 | for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) { |
| 480 | common = &ch->common[i]; | 410 | common = &ch->common[i]; |
| 481 | /* skip If streaming is not started in this channel */ | 411 | /* skip If streaming is not started in this channel */ |
| 482 | if (0 == common->started) | ||
| 483 | continue; | ||
| 484 | |||
| 485 | /* Check the field format */ | 412 | /* Check the field format */ |
| 486 | if (1 == ch->vpifparams.std_info.frm_fmt) { | 413 | if (1 == ch->vpifparams.std_info.frm_fmt) { |
| 487 | /* Progressive mode */ | 414 | /* Progressive mode */ |
| @@ -683,11 +610,6 @@ static void vpif_config_format(struct channel_obj *ch) | |||
| 683 | vpif_dbg(2, debug, "vpif_config_format\n"); | 610 | vpif_dbg(2, debug, "vpif_config_format\n"); |
| 684 | 611 | ||
| 685 | common->fmt.fmt.pix.field = V4L2_FIELD_ANY; | 612 | common->fmt.fmt.pix.field = V4L2_FIELD_ANY; |
| 686 | if (config_params.numbuffers[ch->channel_id] == 0) | ||
| 687 | common->memory = V4L2_MEMORY_USERPTR; | ||
| 688 | else | ||
| 689 | common->memory = V4L2_MEMORY_MMAP; | ||
| 690 | |||
| 691 | common->fmt.fmt.pix.sizeimage | 613 | common->fmt.fmt.pix.sizeimage |
| 692 | = config_params.channel_bufsize[ch->channel_id]; | 614 | = config_params.channel_bufsize[ch->channel_id]; |
| 693 | 615 | ||
| @@ -837,415 +759,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode) | |||
| 837 | } | 759 | } |
| 838 | 760 | ||
| 839 | /** | 761 | /** |
| 840 | * vpif_mmap : It is used to map kernel space buffers into user spaces | ||
| 841 | * @filep: file pointer | ||
| 842 | * @vma: ptr to vm_area_struct | ||
| 843 | */ | ||
| 844 | static int vpif_mmap(struct file *filep, struct vm_area_struct *vma) | ||
| 845 | { | ||
| 846 | /* Get the channel object and file handle object */ | ||
| 847 | struct vpif_fh *fh = filep->private_data; | ||
| 848 | struct channel_obj *ch = fh->channel; | ||
| 849 | struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); | ||
| 850 | int ret; | ||
| 851 | |||
| 852 | vpif_dbg(2, debug, "vpif_mmap\n"); | ||
| 853 | |||
| 854 | if (mutex_lock_interruptible(&common->lock)) | ||
| 855 | return -ERESTARTSYS; | ||
| 856 | ret = vb2_mmap(&common->buffer_queue, vma); | ||
| 857 | mutex_unlock(&common->lock); | ||
| 858 | return ret; | ||
| 859 | } | ||
| 860 | |||
| 861 | /** | ||
| 862 | * vpif_poll: It is used for select/poll system call | ||
| 863 | * @filep: file pointer | ||
| 864 | * @wait: poll table to wait | ||
| 865 | */ | ||
| 866 | static unsigned int vpif_poll(struct file *filep, poll_table * wait) | ||
| 867 | { | ||
| 868 | struct vpif_fh *fh = filep->private_data; | ||
| 869 | struct channel_obj *channel = fh->channel; | ||
| 870 | struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]); | ||
| 871 | unsigned int res = 0; | ||
| 872 | |||
| 873 | vpif_dbg(2, debug, "vpif_poll\n"); | ||
| 874 | |||
| 875 | if (common->started) { | ||
| 876 | mutex_lock(&common->lock); | ||
| 877 | res = vb2_poll(&common->buffer_queue, filep, wait); | ||
| 878 | mutex_unlock(&common->lock); | ||
| 879 | } | ||
| 880 | return res; | ||
| 881 | } | ||
| 882 | |||
| 883 | /** | ||
| 884 | * vpif_open : vpif open handler | ||
| 885 | * @filep: file ptr | ||
| 886 | * | ||
| 887 | * It creates object of file handle structure and stores it in private_data | ||
| 888 | * member of filepointer | ||
| 889 | */ | ||
| 890 | static int vpif_open(struct file *filep) | ||
| 891 | { | ||
| 892 | struct video_device *vdev = video_devdata(filep); | ||
| 893 | struct common_obj *common; | ||
| 894 | struct video_obj *vid_ch; | ||
| 895 | struct channel_obj *ch; | ||
| 896 | struct vpif_fh *fh; | ||
| 897 | |||
| 898 | vpif_dbg(2, debug, "vpif_open\n"); | ||
| 899 | |||
| 900 | ch = video_get_drvdata(vdev); | ||
| 901 | |||
| 902 | vid_ch = &ch->video; | ||
| 903 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 904 | |||
| 905 | /* Allocate memory for the file handle object */ | ||
| 906 | fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); | ||
| 907 | if (NULL == fh) { | ||
| 908 | vpif_err("unable to allocate memory for file handle object\n"); | ||
| 909 | return -ENOMEM; | ||
| 910 | } | ||
| 911 | |||
| 912 | if (mutex_lock_interruptible(&common->lock)) { | ||
| 913 | kfree(fh); | ||
| 914 | return -ERESTARTSYS; | ||
| 915 | } | ||
| 916 | /* store pointer to fh in private_data member of filep */ | ||
| 917 | filep->private_data = fh; | ||
| 918 | fh->channel = ch; | ||
| 919 | fh->initialized = 0; | ||
| 920 | /* If decoder is not initialized. initialize it */ | ||
| 921 | if (!ch->initialized) { | ||
| 922 | fh->initialized = 1; | ||
| 923 | ch->initialized = 1; | ||
| 924 | memset(&(ch->vpifparams), 0, sizeof(struct vpif_params)); | ||
| 925 | } | ||
| 926 | /* Increment channel usrs counter */ | ||
| 927 | ch->usrs++; | ||
| 928 | /* Set io_allowed member to false */ | ||
| 929 | fh->io_allowed[VPIF_VIDEO_INDEX] = 0; | ||
| 930 | /* Initialize priority of this instance to default priority */ | ||
| 931 | fh->prio = V4L2_PRIORITY_UNSET; | ||
| 932 | v4l2_prio_open(&ch->prio, &fh->prio); | ||
| 933 | mutex_unlock(&common->lock); | ||
| 934 | return 0; | ||
| 935 | } | ||
| 936 | |||
| 937 | /** | ||
| 938 | * vpif_release : function to clean up file close | ||
| 939 | * @filep: file pointer | ||
| 940 | * | ||
| 941 | * This function deletes buffer queue, frees the buffers and the vpif file | ||
| 942 | * handle | ||
| 943 | */ | ||
| 944 | static int vpif_release(struct file *filep) | ||
| 945 | { | ||
| 946 | struct vpif_fh *fh = filep->private_data; | ||
| 947 | struct channel_obj *ch = fh->channel; | ||
| 948 | struct common_obj *common; | ||
| 949 | |||
| 950 | vpif_dbg(2, debug, "vpif_release\n"); | ||
| 951 | |||
| 952 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 953 | |||
| 954 | mutex_lock(&common->lock); | ||
| 955 | /* if this instance is doing IO */ | ||
| 956 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 957 | /* Reset io_usrs member of channel object */ | ||
| 958 | common->io_usrs = 0; | ||
| 959 | /* Free buffers allocated */ | ||
| 960 | vb2_queue_release(&common->buffer_queue); | ||
| 961 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 962 | } | ||
| 963 | |||
| 964 | /* Decrement channel usrs counter */ | ||
| 965 | ch->usrs--; | ||
| 966 | |||
| 967 | /* Close the priority */ | ||
| 968 | v4l2_prio_close(&ch->prio, fh->prio); | ||
| 969 | |||
| 970 | if (fh->initialized) | ||
| 971 | ch->initialized = 0; | ||
| 972 | |||
| 973 | mutex_unlock(&common->lock); | ||
| 974 | filep->private_data = NULL; | ||
| 975 | kfree(fh); | ||
| 976 | return 0; | ||
| 977 | } | ||
| 978 | |||
| 979 | /** | ||
| 980 | * vpif_reqbufs() - request buffer handler | ||
| 981 | * @file: file ptr | ||
| 982 | * @priv: file handle | ||
| 983 | * @reqbuf: request buffer structure ptr | ||
| 984 | */ | ||
| 985 | static int vpif_reqbufs(struct file *file, void *priv, | ||
| 986 | struct v4l2_requestbuffers *reqbuf) | ||
| 987 | { | ||
| 988 | struct vpif_fh *fh = priv; | ||
| 989 | struct channel_obj *ch = fh->channel; | ||
| 990 | struct common_obj *common; | ||
| 991 | u8 index = 0; | ||
| 992 | struct vb2_queue *q; | ||
| 993 | int ret; | ||
| 994 | |||
| 995 | vpif_dbg(2, debug, "vpif_reqbufs\n"); | ||
| 996 | |||
| 997 | /** | ||
| 998 | * This file handle has not initialized the channel, | ||
| 999 | * It is not allowed to do settings | ||
| 1000 | */ | ||
| 1001 | if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) | ||
| 1002 | || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) { | ||
| 1003 | if (!fh->initialized) { | ||
| 1004 | vpif_dbg(1, debug, "Channel Busy\n"); | ||
| 1005 | return -EBUSY; | ||
| 1006 | } | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev) | ||
| 1010 | return -EINVAL; | ||
| 1011 | |||
| 1012 | index = VPIF_VIDEO_INDEX; | ||
| 1013 | |||
| 1014 | common = &ch->common[index]; | ||
| 1015 | |||
| 1016 | if (0 != common->io_usrs) | ||
| 1017 | return -EBUSY; | ||
| 1018 | |||
| 1019 | /* Initialize videobuf2 queue as per the buffer type */ | ||
| 1020 | common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); | ||
| 1021 | if (IS_ERR(common->alloc_ctx)) { | ||
| 1022 | vpif_err("Failed to get the context\n"); | ||
| 1023 | return PTR_ERR(common->alloc_ctx); | ||
| 1024 | } | ||
| 1025 | q = &common->buffer_queue; | ||
| 1026 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 1027 | q->io_modes = VB2_MMAP | VB2_USERPTR; | ||
| 1028 | q->drv_priv = fh; | ||
| 1029 | q->ops = &video_qops; | ||
| 1030 | q->mem_ops = &vb2_dma_contig_memops; | ||
| 1031 | q->buf_struct_size = sizeof(struct vpif_cap_buffer); | ||
| 1032 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 1033 | q->min_buffers_needed = 1; | ||
| 1034 | |||
| 1035 | ret = vb2_queue_init(q); | ||
| 1036 | if (ret) { | ||
| 1037 | vpif_err("vpif_capture: vb2_queue_init() failed\n"); | ||
| 1038 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 1039 | return ret; | ||
| 1040 | } | ||
| 1041 | /* Set io allowed member of file handle to TRUE */ | ||
| 1042 | fh->io_allowed[index] = 1; | ||
| 1043 | /* Increment io usrs member of channel object to 1 */ | ||
| 1044 | common->io_usrs = 1; | ||
| 1045 | /* Store type of memory requested in channel object */ | ||
| 1046 | common->memory = reqbuf->memory; | ||
| 1047 | INIT_LIST_HEAD(&common->dma_queue); | ||
| 1048 | |||
| 1049 | /* Allocate buffers */ | ||
| 1050 | return vb2_reqbufs(&common->buffer_queue, reqbuf); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | /** | ||
| 1054 | * vpif_querybuf() - query buffer handler | ||
| 1055 | * @file: file ptr | ||
| 1056 | * @priv: file handle | ||
| 1057 | * @buf: v4l2 buffer structure ptr | ||
| 1058 | */ | ||
| 1059 | static int vpif_querybuf(struct file *file, void *priv, | ||
| 1060 | struct v4l2_buffer *buf) | ||
| 1061 | { | ||
| 1062 | struct vpif_fh *fh = priv; | ||
| 1063 | struct channel_obj *ch = fh->channel; | ||
| 1064 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1065 | |||
| 1066 | vpif_dbg(2, debug, "vpif_querybuf\n"); | ||
| 1067 | |||
| 1068 | if (common->fmt.type != buf->type) | ||
| 1069 | return -EINVAL; | ||
| 1070 | |||
| 1071 | if (common->memory != V4L2_MEMORY_MMAP) { | ||
| 1072 | vpif_dbg(1, debug, "Invalid memory\n"); | ||
| 1073 | return -EINVAL; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | return vb2_querybuf(&common->buffer_queue, buf); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | /** | ||
| 1080 | * vpif_qbuf() - query buffer handler | ||
| 1081 | * @file: file ptr | ||
| 1082 | * @priv: file handle | ||
| 1083 | * @buf: v4l2 buffer structure ptr | ||
| 1084 | */ | ||
| 1085 | static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
| 1086 | { | ||
| 1087 | |||
| 1088 | struct vpif_fh *fh = priv; | ||
| 1089 | struct channel_obj *ch = fh->channel; | ||
| 1090 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1091 | struct v4l2_buffer tbuf = *buf; | ||
| 1092 | |||
| 1093 | vpif_dbg(2, debug, "vpif_qbuf\n"); | ||
| 1094 | |||
| 1095 | if (common->fmt.type != tbuf.type) { | ||
| 1096 | vpif_err("invalid buffer type\n"); | ||
| 1097 | return -EINVAL; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 1101 | vpif_err("fh io not allowed\n"); | ||
| 1102 | return -EACCES; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | return vb2_qbuf(&common->buffer_queue, buf); | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | /** | ||
| 1109 | * vpif_dqbuf() - query buffer handler | ||
| 1110 | * @file: file ptr | ||
| 1111 | * @priv: file handle | ||
| 1112 | * @buf: v4l2 buffer structure ptr | ||
| 1113 | */ | ||
| 1114 | static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | ||
| 1115 | { | ||
| 1116 | struct vpif_fh *fh = priv; | ||
| 1117 | struct channel_obj *ch = fh->channel; | ||
| 1118 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1119 | |||
| 1120 | vpif_dbg(2, debug, "vpif_dqbuf\n"); | ||
| 1121 | |||
| 1122 | return vb2_dqbuf(&common->buffer_queue, buf, | ||
| 1123 | (file->f_flags & O_NONBLOCK)); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | /** | ||
| 1127 | * vpif_streamon() - streamon handler | ||
| 1128 | * @file: file ptr | ||
| 1129 | * @priv: file handle | ||
| 1130 | * @buftype: v4l2 buffer type | ||
| 1131 | */ | ||
| 1132 | static int vpif_streamon(struct file *file, void *priv, | ||
| 1133 | enum v4l2_buf_type buftype) | ||
| 1134 | { | ||
| 1135 | |||
| 1136 | struct vpif_fh *fh = priv; | ||
| 1137 | struct channel_obj *ch = fh->channel; | ||
| 1138 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1139 | struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id]; | ||
| 1140 | struct vpif_params *vpif; | ||
| 1141 | int ret = 0; | ||
| 1142 | |||
| 1143 | vpif_dbg(2, debug, "vpif_streamon\n"); | ||
| 1144 | |||
| 1145 | vpif = &ch->vpifparams; | ||
| 1146 | |||
| 1147 | if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
| 1148 | vpif_dbg(1, debug, "buffer type not supported\n"); | ||
| 1149 | return -EINVAL; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* If file handle is not allowed IO, return error */ | ||
| 1153 | if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 1154 | vpif_dbg(1, debug, "io not allowed\n"); | ||
| 1155 | return -EACCES; | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | /* If Streaming is already started, return error */ | ||
| 1159 | if (common->started) { | ||
| 1160 | vpif_dbg(1, debug, "channel->started\n"); | ||
| 1161 | return -EBUSY; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | if ((ch->channel_id == VPIF_CHANNEL0_VIDEO && | ||
| 1165 | oth_ch->common[VPIF_VIDEO_INDEX].started && | ||
| 1166 | vpif->std_info.ycmux_mode == 0) || | ||
| 1167 | ((ch->channel_id == VPIF_CHANNEL1_VIDEO) && | ||
| 1168 | (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) { | ||
| 1169 | vpif_dbg(1, debug, "other channel is being used\n"); | ||
| 1170 | return -EBUSY; | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0); | ||
| 1174 | if (ret) | ||
| 1175 | return ret; | ||
| 1176 | |||
| 1177 | /* Enable streamon on the sub device */ | ||
| 1178 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 1); | ||
| 1179 | |||
| 1180 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { | ||
| 1181 | vpif_dbg(1, debug, "stream on failed in subdev\n"); | ||
| 1182 | return ret; | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | /* Call vb2_streamon to start streaming in videobuf2 */ | ||
| 1186 | ret = vb2_streamon(&common->buffer_queue, buftype); | ||
| 1187 | if (ret) { | ||
| 1188 | vpif_dbg(1, debug, "vb2_streamon\n"); | ||
| 1189 | return ret; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | return ret; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | /** | ||
| 1196 | * vpif_streamoff() - streamoff handler | ||
| 1197 | * @file: file ptr | ||
| 1198 | * @priv: file handle | ||
| 1199 | * @buftype: v4l2 buffer type | ||
| 1200 | */ | ||
| 1201 | static int vpif_streamoff(struct file *file, void *priv, | ||
| 1202 | enum v4l2_buf_type buftype) | ||
| 1203 | { | ||
| 1204 | |||
| 1205 | struct vpif_fh *fh = priv; | ||
| 1206 | struct channel_obj *ch = fh->channel; | ||
| 1207 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1208 | int ret; | ||
| 1209 | |||
| 1210 | vpif_dbg(2, debug, "vpif_streamoff\n"); | ||
| 1211 | |||
| 1212 | if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
| 1213 | vpif_dbg(1, debug, "buffer type not supported\n"); | ||
| 1214 | return -EINVAL; | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | /* If io is allowed for this file handle, return error */ | ||
| 1218 | if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 1219 | vpif_dbg(1, debug, "io not allowed\n"); | ||
| 1220 | return -EACCES; | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | /* If streaming is not started, return error */ | ||
| 1224 | if (!common->started) { | ||
| 1225 | vpif_dbg(1, debug, "channel->started\n"); | ||
| 1226 | return -EINVAL; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /* disable channel */ | ||
| 1230 | if (VPIF_CHANNEL0_VIDEO == ch->channel_id) { | ||
| 1231 | enable_channel0(0); | ||
| 1232 | channel0_intr_enable(0); | ||
| 1233 | } else { | ||
| 1234 | enable_channel1(0); | ||
| 1235 | channel1_intr_enable(0); | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | common->started = 0; | ||
| 1239 | |||
| 1240 | ret = v4l2_subdev_call(ch->sd, video, s_stream, 0); | ||
| 1241 | |||
| 1242 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) | ||
| 1243 | vpif_dbg(1, debug, "stream off failed in subdev\n"); | ||
| 1244 | |||
| 1245 | return vb2_streamoff(&common->buffer_queue, buftype); | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | /** | ||
| 1249 | * vpif_input_to_subdev() - Maps input to sub device | 762 | * vpif_input_to_subdev() - Maps input to sub device |
| 1250 | * @vpif_cfg - global config ptr | 763 | * @vpif_cfg - global config ptr |
| 1251 | * @chan_cfg - channel config ptr | 764 | * @chan_cfg - channel config ptr |
| @@ -1348,8 +861,8 @@ static int vpif_set_input( | |||
| 1348 | */ | 861 | */ |
| 1349 | static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id) | 862 | static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id) |
| 1350 | { | 863 | { |
| 1351 | struct vpif_fh *fh = priv; | 864 | struct video_device *vdev = video_devdata(file); |
| 1352 | struct channel_obj *ch = fh->channel; | 865 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1353 | int ret = 0; | 866 | int ret = 0; |
| 1354 | 867 | ||
| 1355 | vpif_dbg(2, debug, "vpif_querystd\n"); | 868 | vpif_dbg(2, debug, "vpif_querystd\n"); |
| @@ -1375,11 +888,22 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id) | |||
| 1375 | */ | 888 | */ |
| 1376 | static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) | 889 | static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) |
| 1377 | { | 890 | { |
| 1378 | struct vpif_fh *fh = priv; | 891 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1379 | struct channel_obj *ch = fh->channel; | 892 | struct video_device *vdev = video_devdata(file); |
| 893 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 894 | struct vpif_capture_chan_config *chan_cfg; | ||
| 895 | struct v4l2_input input; | ||
| 1380 | 896 | ||
| 1381 | vpif_dbg(2, debug, "vpif_g_std\n"); | 897 | vpif_dbg(2, debug, "vpif_g_std\n"); |
| 1382 | 898 | ||
| 899 | if (config->chan_config[ch->channel_id].inputs == NULL) | ||
| 900 | return -ENODATA; | ||
| 901 | |||
| 902 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 903 | input = chan_cfg->inputs[ch->input_idx].input; | ||
| 904 | if (input.capabilities != V4L2_IN_CAP_STD) | ||
| 905 | return -ENODATA; | ||
| 906 | |||
| 1383 | *std = ch->video.stdid; | 907 | *std = ch->video.stdid; |
| 1384 | return 0; | 908 | return 0; |
| 1385 | } | 909 | } |
| @@ -1392,31 +916,26 @@ static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) | |||
| 1392 | */ | 916 | */ |
| 1393 | static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | 917 | static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) |
| 1394 | { | 918 | { |
| 1395 | struct vpif_fh *fh = priv; | 919 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1396 | struct channel_obj *ch = fh->channel; | 920 | struct video_device *vdev = video_devdata(file); |
| 921 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1397 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 922 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1398 | int ret = 0; | 923 | struct vpif_capture_chan_config *chan_cfg; |
| 924 | struct v4l2_input input; | ||
| 925 | int ret; | ||
| 1399 | 926 | ||
| 1400 | vpif_dbg(2, debug, "vpif_s_std\n"); | 927 | vpif_dbg(2, debug, "vpif_s_std\n"); |
| 1401 | 928 | ||
| 1402 | if (common->started) { | 929 | if (config->chan_config[ch->channel_id].inputs == NULL) |
| 1403 | vpif_err("streaming in progress\n"); | 930 | return -ENODATA; |
| 1404 | return -EBUSY; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) || | ||
| 1408 | (VPIF_CHANNEL1_VIDEO == ch->channel_id)) { | ||
| 1409 | if (!fh->initialized) { | ||
| 1410 | vpif_dbg(1, debug, "Channel Busy\n"); | ||
| 1411 | return -EBUSY; | ||
| 1412 | } | ||
| 1413 | } | ||
| 1414 | 931 | ||
| 1415 | ret = v4l2_prio_check(&ch->prio, fh->prio); | 932 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1416 | if (0 != ret) | 933 | input = chan_cfg->inputs[ch->input_idx].input; |
| 1417 | return ret; | 934 | if (input.capabilities != V4L2_IN_CAP_STD) |
| 935 | return -ENODATA; | ||
| 1418 | 936 | ||
| 1419 | fh->initialized = 1; | 937 | if (vb2_is_busy(&common->buffer_queue)) |
| 938 | return -EBUSY; | ||
| 1420 | 939 | ||
| 1421 | /* Call encoder subdevice function to set the standard */ | 940 | /* Call encoder subdevice function to set the standard */ |
| 1422 | ch->video.stdid = std_id; | 941 | ch->video.stdid = std_id; |
| @@ -1432,7 +951,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
| 1432 | vpif_config_format(ch); | 951 | vpif_config_format(ch); |
| 1433 | 952 | ||
| 1434 | /* set standard in the sub device */ | 953 | /* set standard in the sub device */ |
| 1435 | ret = v4l2_subdev_call(ch->sd, core, s_std, std_id); | 954 | ret = v4l2_subdev_call(ch->sd, video, s_std, std_id); |
| 1436 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { | 955 | if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) { |
| 1437 | vpif_dbg(1, debug, "Failed to set standard for sub devices\n"); | 956 | vpif_dbg(1, debug, "Failed to set standard for sub devices\n"); |
| 1438 | return ret; | 957 | return ret; |
| @@ -1451,9 +970,9 @@ static int vpif_enum_input(struct file *file, void *priv, | |||
| 1451 | { | 970 | { |
| 1452 | 971 | ||
| 1453 | struct vpif_capture_config *config = vpif_dev->platform_data; | 972 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 973 | struct video_device *vdev = video_devdata(file); | ||
| 974 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1454 | struct vpif_capture_chan_config *chan_cfg; | 975 | struct vpif_capture_chan_config *chan_cfg; |
| 1455 | struct vpif_fh *fh = priv; | ||
| 1456 | struct channel_obj *ch = fh->channel; | ||
| 1457 | 976 | ||
| 1458 | chan_cfg = &config->chan_config[ch->channel_id]; | 977 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1459 | 978 | ||
| @@ -1475,8 +994,8 @@ static int vpif_enum_input(struct file *file, void *priv, | |||
| 1475 | */ | 994 | */ |
| 1476 | static int vpif_g_input(struct file *file, void *priv, unsigned int *index) | 995 | static int vpif_g_input(struct file *file, void *priv, unsigned int *index) |
| 1477 | { | 996 | { |
| 1478 | struct vpif_fh *fh = priv; | 997 | struct video_device *vdev = video_devdata(file); |
| 1479 | struct channel_obj *ch = fh->channel; | 998 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1480 | 999 | ||
| 1481 | *index = ch->input_idx; | 1000 | *index = ch->input_idx; |
| 1482 | return 0; | 1001 | return 0; |
| @@ -1491,35 +1010,19 @@ static int vpif_g_input(struct file *file, void *priv, unsigned int *index) | |||
| 1491 | static int vpif_s_input(struct file *file, void *priv, unsigned int index) | 1010 | static int vpif_s_input(struct file *file, void *priv, unsigned int index) |
| 1492 | { | 1011 | { |
| 1493 | struct vpif_capture_config *config = vpif_dev->platform_data; | 1012 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1494 | struct vpif_capture_chan_config *chan_cfg; | 1013 | struct video_device *vdev = video_devdata(file); |
| 1495 | struct vpif_fh *fh = priv; | 1014 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1496 | struct channel_obj *ch = fh->channel; | ||
| 1497 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 1015 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1498 | int ret; | 1016 | struct vpif_capture_chan_config *chan_cfg; |
| 1499 | 1017 | ||
| 1500 | chan_cfg = &config->chan_config[ch->channel_id]; | 1018 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1501 | 1019 | ||
| 1502 | if (index >= chan_cfg->input_count) | 1020 | if (index >= chan_cfg->input_count) |
| 1503 | return -EINVAL; | 1021 | return -EINVAL; |
| 1504 | 1022 | ||
| 1505 | if (common->started) { | 1023 | if (vb2_is_busy(&common->buffer_queue)) |
| 1506 | vpif_err("Streaming in progress\n"); | ||
| 1507 | return -EBUSY; | 1024 | return -EBUSY; |
| 1508 | } | ||
| 1509 | |||
| 1510 | if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) || | ||
| 1511 | (VPIF_CHANNEL1_VIDEO == ch->channel_id)) { | ||
| 1512 | if (!fh->initialized) { | ||
| 1513 | vpif_dbg(1, debug, "Channel Busy\n"); | ||
| 1514 | return -EBUSY; | ||
| 1515 | } | ||
| 1516 | } | ||
| 1517 | |||
| 1518 | ret = v4l2_prio_check(&ch->prio, fh->prio); | ||
| 1519 | if (0 != ret) | ||
| 1520 | return ret; | ||
| 1521 | 1025 | ||
| 1522 | fh->initialized = 1; | ||
| 1523 | return vpif_set_input(config, ch, index); | 1026 | return vpif_set_input(config, ch, index); |
| 1524 | } | 1027 | } |
| 1525 | 1028 | ||
| @@ -1532,8 +1035,8 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index) | |||
| 1532 | static int vpif_enum_fmt_vid_cap(struct file *file, void *priv, | 1035 | static int vpif_enum_fmt_vid_cap(struct file *file, void *priv, |
| 1533 | struct v4l2_fmtdesc *fmt) | 1036 | struct v4l2_fmtdesc *fmt) |
| 1534 | { | 1037 | { |
| 1535 | struct vpif_fh *fh = priv; | 1038 | struct video_device *vdev = video_devdata(file); |
| 1536 | struct channel_obj *ch = fh->channel; | 1039 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1537 | 1040 | ||
| 1538 | if (fmt->index != 0) { | 1041 | if (fmt->index != 0) { |
| 1539 | vpif_dbg(1, debug, "Invalid format index\n"); | 1042 | vpif_dbg(1, debug, "Invalid format index\n"); |
| @@ -1562,8 +1065,8 @@ static int vpif_enum_fmt_vid_cap(struct file *file, void *priv, | |||
| 1562 | static int vpif_try_fmt_vid_cap(struct file *file, void *priv, | 1065 | static int vpif_try_fmt_vid_cap(struct file *file, void *priv, |
| 1563 | struct v4l2_format *fmt) | 1066 | struct v4l2_format *fmt) |
| 1564 | { | 1067 | { |
| 1565 | struct vpif_fh *fh = priv; | 1068 | struct video_device *vdev = video_devdata(file); |
| 1566 | struct channel_obj *ch = fh->channel; | 1069 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1567 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | 1070 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; |
| 1568 | 1071 | ||
| 1569 | return vpif_check_format(ch, pixfmt, 1); | 1072 | return vpif_check_format(ch, pixfmt, 1); |
| @@ -1579,8 +1082,8 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1579 | static int vpif_g_fmt_vid_cap(struct file *file, void *priv, | 1082 | static int vpif_g_fmt_vid_cap(struct file *file, void *priv, |
| 1580 | struct v4l2_format *fmt) | 1083 | struct v4l2_format *fmt) |
| 1581 | { | 1084 | { |
| 1582 | struct vpif_fh *fh = priv; | 1085 | struct video_device *vdev = video_devdata(file); |
| 1583 | struct channel_obj *ch = fh->channel; | 1086 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1584 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 1087 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1585 | 1088 | ||
| 1586 | /* Check the validity of the buffer type */ | 1089 | /* Check the validity of the buffer type */ |
| @@ -1601,33 +1104,16 @@ static int vpif_g_fmt_vid_cap(struct file *file, void *priv, | |||
| 1601 | static int vpif_s_fmt_vid_cap(struct file *file, void *priv, | 1104 | static int vpif_s_fmt_vid_cap(struct file *file, void *priv, |
| 1602 | struct v4l2_format *fmt) | 1105 | struct v4l2_format *fmt) |
| 1603 | { | 1106 | { |
| 1604 | struct vpif_fh *fh = priv; | 1107 | struct video_device *vdev = video_devdata(file); |
| 1605 | struct channel_obj *ch = fh->channel; | 1108 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1606 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 1109 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1607 | struct v4l2_pix_format *pixfmt; | 1110 | struct v4l2_pix_format *pixfmt; |
| 1608 | int ret = 0; | 1111 | int ret = 0; |
| 1609 | 1112 | ||
| 1610 | vpif_dbg(2, debug, "%s\n", __func__); | 1113 | vpif_dbg(2, debug, "%s\n", __func__); |
| 1611 | 1114 | ||
| 1612 | /* If streaming is started, return error */ | 1115 | if (vb2_is_busy(&common->buffer_queue)) |
| 1613 | if (common->started) { | ||
| 1614 | vpif_dbg(1, debug, "Streaming is started\n"); | ||
| 1615 | return -EBUSY; | 1116 | return -EBUSY; |
| 1616 | } | ||
| 1617 | |||
| 1618 | if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) || | ||
| 1619 | (VPIF_CHANNEL1_VIDEO == ch->channel_id)) { | ||
| 1620 | if (!fh->initialized) { | ||
| 1621 | vpif_dbg(1, debug, "Channel Busy\n"); | ||
| 1622 | return -EBUSY; | ||
| 1623 | } | ||
| 1624 | } | ||
| 1625 | |||
| 1626 | ret = v4l2_prio_check(&ch->prio, fh->prio); | ||
| 1627 | if (0 != ret) | ||
| 1628 | return ret; | ||
| 1629 | |||
| 1630 | fh->initialized = 1; | ||
| 1631 | 1117 | ||
| 1632 | pixfmt = &fmt->fmt.pix; | 1118 | pixfmt = &fmt->fmt.pix; |
| 1633 | /* Check for valid field format */ | 1119 | /* Check for valid field format */ |
| @@ -1653,7 +1139,7 @@ static int vpif_querycap(struct file *file, void *priv, | |||
| 1653 | 1139 | ||
| 1654 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1140 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
| 1655 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 1141 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
| 1656 | snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev)); | 1142 | strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); |
| 1657 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", | 1143 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
| 1658 | dev_name(vpif_dev)); | 1144 | dev_name(vpif_dev)); |
| 1659 | strlcpy(cap->card, config->card_name, sizeof(cap->card)); | 1145 | strlcpy(cap->card, config->card_name, sizeof(cap->card)); |
| @@ -1662,61 +1148,6 @@ static int vpif_querycap(struct file *file, void *priv, | |||
| 1662 | } | 1148 | } |
| 1663 | 1149 | ||
| 1664 | /** | 1150 | /** |
| 1665 | * vpif_g_priority() - get priority handler | ||
| 1666 | * @file: file ptr | ||
| 1667 | * @priv: file handle | ||
| 1668 | * @prio: ptr to v4l2_priority structure | ||
| 1669 | */ | ||
| 1670 | static int vpif_g_priority(struct file *file, void *priv, | ||
| 1671 | enum v4l2_priority *prio) | ||
| 1672 | { | ||
| 1673 | struct vpif_fh *fh = priv; | ||
| 1674 | struct channel_obj *ch = fh->channel; | ||
| 1675 | |||
| 1676 | *prio = v4l2_prio_max(&ch->prio); | ||
| 1677 | |||
| 1678 | return 0; | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | /** | ||
| 1682 | * vpif_s_priority() - set priority handler | ||
| 1683 | * @file: file ptr | ||
| 1684 | * @priv: file handle | ||
| 1685 | * @prio: ptr to v4l2_priority structure | ||
| 1686 | */ | ||
| 1687 | static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p) | ||
| 1688 | { | ||
| 1689 | struct vpif_fh *fh = priv; | ||
| 1690 | struct channel_obj *ch = fh->channel; | ||
| 1691 | |||
| 1692 | return v4l2_prio_change(&ch->prio, &fh->prio, p); | ||
| 1693 | } | ||
| 1694 | |||
| 1695 | /** | ||
| 1696 | * vpif_cropcap() - cropcap handler | ||
| 1697 | * @file: file ptr | ||
| 1698 | * @priv: file handle | ||
| 1699 | * @crop: ptr to v4l2_cropcap structure | ||
| 1700 | */ | ||
| 1701 | static int vpif_cropcap(struct file *file, void *priv, | ||
| 1702 | struct v4l2_cropcap *crop) | ||
| 1703 | { | ||
| 1704 | struct vpif_fh *fh = priv; | ||
| 1705 | struct channel_obj *ch = fh->channel; | ||
| 1706 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1707 | |||
| 1708 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type) | ||
| 1709 | return -EINVAL; | ||
| 1710 | |||
| 1711 | crop->bounds.left = 0; | ||
| 1712 | crop->bounds.top = 0; | ||
| 1713 | crop->bounds.height = common->height; | ||
| 1714 | crop->bounds.width = common->width; | ||
| 1715 | crop->defrect = crop->bounds; | ||
| 1716 | return 0; | ||
| 1717 | } | ||
| 1718 | |||
| 1719 | /** | ||
| 1720 | * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler | 1151 | * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler |
| 1721 | * @file: file ptr | 1152 | * @file: file ptr |
| 1722 | * @priv: file handle | 1153 | * @priv: file handle |
| @@ -1726,13 +1157,27 @@ static int | |||
| 1726 | vpif_enum_dv_timings(struct file *file, void *priv, | 1157 | vpif_enum_dv_timings(struct file *file, void *priv, |
| 1727 | struct v4l2_enum_dv_timings *timings) | 1158 | struct v4l2_enum_dv_timings *timings) |
| 1728 | { | 1159 | { |
| 1729 | struct vpif_fh *fh = priv; | 1160 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1730 | struct channel_obj *ch = fh->channel; | 1161 | struct video_device *vdev = video_devdata(file); |
| 1162 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1163 | struct vpif_capture_chan_config *chan_cfg; | ||
| 1164 | struct v4l2_input input; | ||
| 1731 | int ret; | 1165 | int ret; |
| 1732 | 1166 | ||
| 1733 | ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings); | 1167 | if (config->chan_config[ch->channel_id].inputs == NULL) |
| 1168 | return -ENODATA; | ||
| 1169 | |||
| 1170 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 1171 | input = chan_cfg->inputs[ch->input_idx].input; | ||
| 1172 | if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS) | ||
| 1173 | return -ENODATA; | ||
| 1174 | |||
| 1175 | timings->pad = 0; | ||
| 1176 | |||
| 1177 | ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings); | ||
| 1734 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) | 1178 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) |
| 1735 | return -EINVAL; | 1179 | return -EINVAL; |
| 1180 | |||
| 1736 | return ret; | 1181 | return ret; |
| 1737 | } | 1182 | } |
| 1738 | 1183 | ||
| @@ -1746,13 +1191,25 @@ static int | |||
| 1746 | vpif_query_dv_timings(struct file *file, void *priv, | 1191 | vpif_query_dv_timings(struct file *file, void *priv, |
| 1747 | struct v4l2_dv_timings *timings) | 1192 | struct v4l2_dv_timings *timings) |
| 1748 | { | 1193 | { |
| 1749 | struct vpif_fh *fh = priv; | 1194 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1750 | struct channel_obj *ch = fh->channel; | 1195 | struct video_device *vdev = video_devdata(file); |
| 1196 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1197 | struct vpif_capture_chan_config *chan_cfg; | ||
| 1198 | struct v4l2_input input; | ||
| 1751 | int ret; | 1199 | int ret; |
| 1752 | 1200 | ||
| 1201 | if (config->chan_config[ch->channel_id].inputs == NULL) | ||
| 1202 | return -ENODATA; | ||
| 1203 | |||
| 1204 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 1205 | input = chan_cfg->inputs[ch->input_idx].input; | ||
| 1206 | if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS) | ||
| 1207 | return -ENODATA; | ||
| 1208 | |||
| 1753 | ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings); | 1209 | ret = v4l2_subdev_call(ch->sd, video, query_dv_timings, timings); |
| 1754 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) | 1210 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) |
| 1755 | return -ENODATA; | 1211 | return -ENODATA; |
| 1212 | |||
| 1756 | return ret; | 1213 | return ret; |
| 1757 | } | 1214 | } |
| 1758 | 1215 | ||
| @@ -1765,19 +1222,34 @@ vpif_query_dv_timings(struct file *file, void *priv, | |||
| 1765 | static int vpif_s_dv_timings(struct file *file, void *priv, | 1222 | static int vpif_s_dv_timings(struct file *file, void *priv, |
| 1766 | struct v4l2_dv_timings *timings) | 1223 | struct v4l2_dv_timings *timings) |
| 1767 | { | 1224 | { |
| 1768 | struct vpif_fh *fh = priv; | 1225 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1769 | struct channel_obj *ch = fh->channel; | 1226 | struct video_device *vdev = video_devdata(file); |
| 1227 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1770 | struct vpif_params *vpifparams = &ch->vpifparams; | 1228 | struct vpif_params *vpifparams = &ch->vpifparams; |
| 1771 | struct vpif_channel_config_params *std_info = &vpifparams->std_info; | 1229 | struct vpif_channel_config_params *std_info = &vpifparams->std_info; |
| 1230 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1772 | struct video_obj *vid_ch = &ch->video; | 1231 | struct video_obj *vid_ch = &ch->video; |
| 1773 | struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt; | 1232 | struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt; |
| 1233 | struct vpif_capture_chan_config *chan_cfg; | ||
| 1234 | struct v4l2_input input; | ||
| 1774 | int ret; | 1235 | int ret; |
| 1775 | 1236 | ||
| 1237 | if (config->chan_config[ch->channel_id].inputs == NULL) | ||
| 1238 | return -ENODATA; | ||
| 1239 | |||
| 1240 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 1241 | input = chan_cfg->inputs[ch->input_idx].input; | ||
| 1242 | if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS) | ||
| 1243 | return -ENODATA; | ||
| 1244 | |||
| 1776 | if (timings->type != V4L2_DV_BT_656_1120) { | 1245 | if (timings->type != V4L2_DV_BT_656_1120) { |
| 1777 | vpif_dbg(2, debug, "Timing type not defined\n"); | 1246 | vpif_dbg(2, debug, "Timing type not defined\n"); |
| 1778 | return -EINVAL; | 1247 | return -EINVAL; |
| 1779 | } | 1248 | } |
| 1780 | 1249 | ||
| 1250 | if (vb2_is_busy(&common->buffer_queue)) | ||
| 1251 | return -EBUSY; | ||
| 1252 | |||
| 1781 | /* Configure subdevice timings, if any */ | 1253 | /* Configure subdevice timings, if any */ |
| 1782 | ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings); | 1254 | ret = v4l2_subdev_call(ch->sd, video, s_dv_timings, timings); |
| 1783 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) | 1255 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) |
| @@ -1853,9 +1325,20 @@ static int vpif_s_dv_timings(struct file *file, void *priv, | |||
| 1853 | static int vpif_g_dv_timings(struct file *file, void *priv, | 1325 | static int vpif_g_dv_timings(struct file *file, void *priv, |
| 1854 | struct v4l2_dv_timings *timings) | 1326 | struct v4l2_dv_timings *timings) |
| 1855 | { | 1327 | { |
| 1856 | struct vpif_fh *fh = priv; | 1328 | struct vpif_capture_config *config = vpif_dev->platform_data; |
| 1857 | struct channel_obj *ch = fh->channel; | 1329 | struct video_device *vdev = video_devdata(file); |
| 1330 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1858 | struct video_obj *vid_ch = &ch->video; | 1331 | struct video_obj *vid_ch = &ch->video; |
| 1332 | struct vpif_capture_chan_config *chan_cfg; | ||
| 1333 | struct v4l2_input input; | ||
| 1334 | |||
| 1335 | if (config->chan_config[ch->channel_id].inputs == NULL) | ||
| 1336 | return -ENODATA; | ||
| 1337 | |||
| 1338 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 1339 | input = chan_cfg->inputs[ch->input_idx].input; | ||
| 1340 | if (input.capabilities != V4L2_IN_CAP_DV_TIMINGS) | ||
| 1341 | return -ENODATA; | ||
| 1859 | 1342 | ||
| 1860 | *timings = vid_ch->dv_timings; | 1343 | *timings = vid_ch->dv_timings; |
| 1861 | 1344 | ||
| @@ -1879,49 +1362,45 @@ static int vpif_log_status(struct file *filep, void *priv) | |||
| 1879 | 1362 | ||
| 1880 | /* vpif capture ioctl operations */ | 1363 | /* vpif capture ioctl operations */ |
| 1881 | static const struct v4l2_ioctl_ops vpif_ioctl_ops = { | 1364 | static const struct v4l2_ioctl_ops vpif_ioctl_ops = { |
| 1882 | .vidioc_querycap = vpif_querycap, | 1365 | .vidioc_querycap = vpif_querycap, |
| 1883 | .vidioc_g_priority = vpif_g_priority, | ||
| 1884 | .vidioc_s_priority = vpif_s_priority, | ||
| 1885 | .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap, | 1366 | .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap, |
| 1886 | .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap, | 1367 | .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap, |
| 1887 | .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap, | 1368 | .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap, |
| 1888 | .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap, | 1369 | .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap, |
| 1370 | |||
| 1889 | .vidioc_enum_input = vpif_enum_input, | 1371 | .vidioc_enum_input = vpif_enum_input, |
| 1890 | .vidioc_s_input = vpif_s_input, | 1372 | .vidioc_s_input = vpif_s_input, |
| 1891 | .vidioc_g_input = vpif_g_input, | 1373 | .vidioc_g_input = vpif_g_input, |
| 1892 | .vidioc_reqbufs = vpif_reqbufs, | 1374 | |
| 1893 | .vidioc_querybuf = vpif_querybuf, | 1375 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
| 1376 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | ||
| 1377 | .vidioc_querybuf = vb2_ioctl_querybuf, | ||
| 1378 | .vidioc_qbuf = vb2_ioctl_qbuf, | ||
| 1379 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | ||
| 1380 | .vidioc_expbuf = vb2_ioctl_expbuf, | ||
| 1381 | .vidioc_streamon = vb2_ioctl_streamon, | ||
| 1382 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
| 1383 | |||
| 1894 | .vidioc_querystd = vpif_querystd, | 1384 | .vidioc_querystd = vpif_querystd, |
| 1895 | .vidioc_s_std = vpif_s_std, | 1385 | .vidioc_s_std = vpif_s_std, |
| 1896 | .vidioc_g_std = vpif_g_std, | 1386 | .vidioc_g_std = vpif_g_std, |
| 1897 | .vidioc_qbuf = vpif_qbuf, | 1387 | |
| 1898 | .vidioc_dqbuf = vpif_dqbuf, | 1388 | .vidioc_enum_dv_timings = vpif_enum_dv_timings, |
| 1899 | .vidioc_streamon = vpif_streamon, | 1389 | .vidioc_query_dv_timings = vpif_query_dv_timings, |
| 1900 | .vidioc_streamoff = vpif_streamoff, | 1390 | .vidioc_s_dv_timings = vpif_s_dv_timings, |
| 1901 | .vidioc_cropcap = vpif_cropcap, | 1391 | .vidioc_g_dv_timings = vpif_g_dv_timings, |
| 1902 | .vidioc_enum_dv_timings = vpif_enum_dv_timings, | 1392 | |
| 1903 | .vidioc_query_dv_timings = vpif_query_dv_timings, | ||
| 1904 | .vidioc_s_dv_timings = vpif_s_dv_timings, | ||
| 1905 | .vidioc_g_dv_timings = vpif_g_dv_timings, | ||
| 1906 | .vidioc_log_status = vpif_log_status, | 1393 | .vidioc_log_status = vpif_log_status, |
| 1907 | }; | 1394 | }; |
| 1908 | 1395 | ||
| 1909 | /* vpif file operations */ | 1396 | /* vpif file operations */ |
| 1910 | static struct v4l2_file_operations vpif_fops = { | 1397 | static struct v4l2_file_operations vpif_fops = { |
| 1911 | .owner = THIS_MODULE, | 1398 | .owner = THIS_MODULE, |
| 1912 | .open = vpif_open, | 1399 | .open = v4l2_fh_open, |
| 1913 | .release = vpif_release, | 1400 | .release = vb2_fop_release, |
| 1914 | .unlocked_ioctl = video_ioctl2, | 1401 | .unlocked_ioctl = video_ioctl2, |
| 1915 | .mmap = vpif_mmap, | 1402 | .mmap = vb2_fop_mmap, |
| 1916 | .poll = vpif_poll | 1403 | .poll = vb2_fop_poll |
| 1917 | }; | ||
| 1918 | |||
| 1919 | /* vpif video template */ | ||
| 1920 | static struct video_device vpif_video_template = { | ||
| 1921 | .name = "vpif", | ||
| 1922 | .fops = &vpif_fops, | ||
| 1923 | .minor = -1, | ||
| 1924 | .ioctl_ops = &vpif_ioctl_ops, | ||
| 1925 | }; | 1404 | }; |
| 1926 | 1405 | ||
| 1927 | /** | 1406 | /** |
| @@ -1999,7 +1478,9 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier, | |||
| 1999 | static int vpif_probe_complete(void) | 1478 | static int vpif_probe_complete(void) |
| 2000 | { | 1479 | { |
| 2001 | struct common_obj *common; | 1480 | struct common_obj *common; |
| 1481 | struct video_device *vdev; | ||
| 2002 | struct channel_obj *ch; | 1482 | struct channel_obj *ch; |
| 1483 | struct vb2_queue *q; | ||
| 2003 | int i, j, err, k; | 1484 | int i, j, err, k; |
| 2004 | 1485 | ||
| 2005 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { | 1486 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { |
| @@ -2008,17 +1489,52 @@ static int vpif_probe_complete(void) | |||
| 2008 | common = &(ch->common[VPIF_VIDEO_INDEX]); | 1489 | common = &(ch->common[VPIF_VIDEO_INDEX]); |
| 2009 | spin_lock_init(&common->irqlock); | 1490 | spin_lock_init(&common->irqlock); |
| 2010 | mutex_init(&common->lock); | 1491 | mutex_init(&common->lock); |
| 2011 | ch->video_dev->lock = &common->lock; | ||
| 2012 | /* Initialize prio member of channel object */ | ||
| 2013 | v4l2_prio_init(&ch->prio); | ||
| 2014 | video_set_drvdata(ch->video_dev, ch); | ||
| 2015 | 1492 | ||
| 2016 | /* select input 0 */ | 1493 | /* select input 0 */ |
| 2017 | err = vpif_set_input(vpif_obj.config, ch, 0); | 1494 | err = vpif_set_input(vpif_obj.config, ch, 0); |
| 2018 | if (err) | 1495 | if (err) |
| 2019 | goto probe_out; | 1496 | goto probe_out; |
| 2020 | 1497 | ||
| 2021 | err = video_register_device(ch->video_dev, | 1498 | /* Initialize vb2 queue */ |
| 1499 | q = &common->buffer_queue; | ||
| 1500 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 1501 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; | ||
| 1502 | q->drv_priv = ch; | ||
| 1503 | q->ops = &video_qops; | ||
| 1504 | q->mem_ops = &vb2_dma_contig_memops; | ||
| 1505 | q->buf_struct_size = sizeof(struct vpif_cap_buffer); | ||
| 1506 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 1507 | q->min_buffers_needed = 1; | ||
| 1508 | q->lock = &common->lock; | ||
| 1509 | |||
| 1510 | err = vb2_queue_init(q); | ||
| 1511 | if (err) { | ||
| 1512 | vpif_err("vpif_capture: vb2_queue_init() failed\n"); | ||
| 1513 | goto probe_out; | ||
| 1514 | } | ||
| 1515 | |||
| 1516 | common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); | ||
| 1517 | if (IS_ERR(common->alloc_ctx)) { | ||
| 1518 | vpif_err("Failed to get the context\n"); | ||
| 1519 | err = PTR_ERR(common->alloc_ctx); | ||
| 1520 | goto probe_out; | ||
| 1521 | } | ||
| 1522 | |||
| 1523 | INIT_LIST_HEAD(&common->dma_queue); | ||
| 1524 | |||
| 1525 | /* Initialize the video_device structure */ | ||
| 1526 | vdev = ch->video_dev; | ||
| 1527 | strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); | ||
| 1528 | vdev->release = video_device_release; | ||
| 1529 | vdev->fops = &vpif_fops; | ||
| 1530 | vdev->ioctl_ops = &vpif_ioctl_ops; | ||
| 1531 | vdev->v4l2_dev = &vpif_obj.v4l2_dev; | ||
| 1532 | vdev->vfl_dir = VFL_DIR_RX; | ||
| 1533 | vdev->queue = q; | ||
| 1534 | vdev->lock = &common->lock; | ||
| 1535 | set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); | ||
| 1536 | video_set_drvdata(ch->video_dev, ch); | ||
| 1537 | err = video_register_device(vdev, | ||
| 2022 | VFL_TYPE_GRABBER, (j ? 1 : 0)); | 1538 | VFL_TYPE_GRABBER, (j ? 1 : 0)); |
| 2023 | if (err) | 1539 | if (err) |
| 2024 | goto probe_out; | 1540 | goto probe_out; |
| @@ -2031,6 +1547,8 @@ probe_out: | |||
| 2031 | for (k = 0; k < j; k++) { | 1547 | for (k = 0; k < j; k++) { |
| 2032 | /* Get the pointer to the channel object */ | 1548 | /* Get the pointer to the channel object */ |
| 2033 | ch = vpif_obj.dev[k]; | 1549 | ch = vpif_obj.dev[k]; |
| 1550 | common = &ch->common[k]; | ||
| 1551 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 2034 | /* Unregister video device */ | 1552 | /* Unregister video device */ |
| 2035 | video_unregister_device(ch->video_dev); | 1553 | video_unregister_device(ch->video_dev); |
| 2036 | } | 1554 | } |
| @@ -2067,7 +1585,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
| 2067 | struct video_device *vfd; | 1585 | struct video_device *vfd; |
| 2068 | struct resource *res; | 1586 | struct resource *res; |
| 2069 | int subdev_count; | 1587 | int subdev_count; |
| 2070 | size_t size; | ||
| 2071 | 1588 | ||
| 2072 | vpif_dev = &pdev->dev; | 1589 | vpif_dev = &pdev->dev; |
| 2073 | 1590 | ||
| @@ -2085,7 +1602,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
| 2085 | 1602 | ||
| 2086 | while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) { | 1603 | while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) { |
| 2087 | err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr, | 1604 | err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr, |
| 2088 | IRQF_SHARED, "VPIF_Capture", | 1605 | IRQF_SHARED, VPIF_DRIVER_NAME, |
| 2089 | (void *)(&vpif_obj.dev[res_idx]-> | 1606 | (void *)(&vpif_obj.dev[res_idx]-> |
| 2090 | channel_id)); | 1607 | channel_id)); |
| 2091 | if (err) { | 1608 | if (err) { |
| @@ -2109,34 +1626,10 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
| 2109 | goto vpif_unregister; | 1626 | goto vpif_unregister; |
| 2110 | } | 1627 | } |
| 2111 | 1628 | ||
| 2112 | /* Initialize field of video device */ | ||
| 2113 | *vfd = vpif_video_template; | ||
| 2114 | vfd->v4l2_dev = &vpif_obj.v4l2_dev; | ||
| 2115 | vfd->release = video_device_release; | ||
| 2116 | snprintf(vfd->name, sizeof(vfd->name), | ||
| 2117 | "VPIF_Capture_DRIVER_V%s", | ||
| 2118 | VPIF_CAPTURE_VERSION); | ||
| 2119 | /* Set video_dev to the video device */ | 1629 | /* Set video_dev to the video device */ |
| 2120 | ch->video_dev = vfd; | 1630 | ch->video_dev = vfd; |
| 2121 | } | 1631 | } |
| 2122 | 1632 | ||
| 2123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 2124 | if (res) { | ||
| 2125 | size = resource_size(res); | ||
| 2126 | /* The resources are divided into two equal memory and when we | ||
| 2127 | * have HD output we can add them together | ||
| 2128 | */ | ||
| 2129 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { | ||
| 2130 | ch = vpif_obj.dev[j]; | ||
| 2131 | ch->channel_id = j; | ||
| 2132 | /* only enabled if second resource exists */ | ||
| 2133 | config_params.video_limit[ch->channel_id] = 0; | ||
| 2134 | if (size) | ||
| 2135 | config_params.video_limit[ch->channel_id] = | ||
| 2136 | size/2; | ||
| 2137 | } | ||
| 2138 | } | ||
| 2139 | |||
| 2140 | vpif_obj.config = pdev->dev.platform_data; | 1633 | vpif_obj.config = pdev->dev.platform_data; |
| 2141 | 1634 | ||
| 2142 | subdev_count = vpif_obj.config->subdev_count; | 1635 | subdev_count = vpif_obj.config->subdev_count; |
| @@ -2209,6 +1702,7 @@ vpif_unregister: | |||
| 2209 | */ | 1702 | */ |
| 2210 | static int vpif_remove(struct platform_device *device) | 1703 | static int vpif_remove(struct platform_device *device) |
| 2211 | { | 1704 | { |
| 1705 | struct common_obj *common; | ||
| 2212 | struct channel_obj *ch; | 1706 | struct channel_obj *ch; |
| 2213 | int i; | 1707 | int i; |
| 2214 | 1708 | ||
| @@ -2219,6 +1713,8 @@ static int vpif_remove(struct platform_device *device) | |||
| 2219 | for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { | 1713 | for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { |
| 2220 | /* Get the pointer to the channel object */ | 1714 | /* Get the pointer to the channel object */ |
| 2221 | ch = vpif_obj.dev[i]; | 1715 | ch = vpif_obj.dev[i]; |
| 1716 | common = &ch->common[i]; | ||
| 1717 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 2222 | /* Unregister video device */ | 1718 | /* Unregister video device */ |
| 2223 | video_unregister_device(ch->video_dev); | 1719 | video_unregister_device(ch->video_dev); |
| 2224 | kfree(vpif_obj.dev[i]); | 1720 | kfree(vpif_obj.dev[i]); |
| @@ -2226,7 +1722,7 @@ static int vpif_remove(struct platform_device *device) | |||
| 2226 | return 0; | 1722 | return 0; |
| 2227 | } | 1723 | } |
| 2228 | 1724 | ||
| 2229 | #ifdef CONFIG_PM | 1725 | #ifdef CONFIG_PM_SLEEP |
| 2230 | /** | 1726 | /** |
| 2231 | * vpif_suspend: vpif device suspend | 1727 | * vpif_suspend: vpif device suspend |
| 2232 | */ | 1728 | */ |
| @@ -2241,18 +1737,20 @@ static int vpif_suspend(struct device *dev) | |||
| 2241 | /* Get the pointer to the channel object */ | 1737 | /* Get the pointer to the channel object */ |
| 2242 | ch = vpif_obj.dev[i]; | 1738 | ch = vpif_obj.dev[i]; |
| 2243 | common = &ch->common[VPIF_VIDEO_INDEX]; | 1739 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1740 | |||
| 1741 | if (!vb2_is_streaming(&common->buffer_queue)) | ||
| 1742 | continue; | ||
| 1743 | |||
| 2244 | mutex_lock(&common->lock); | 1744 | mutex_lock(&common->lock); |
| 2245 | if (ch->usrs && common->io_usrs) { | 1745 | /* Disable channel */ |
| 2246 | /* Disable channel */ | 1746 | if (ch->channel_id == VPIF_CHANNEL0_VIDEO) { |
| 2247 | if (ch->channel_id == VPIF_CHANNEL0_VIDEO) { | 1747 | enable_channel0(0); |
| 2248 | enable_channel0(0); | 1748 | channel0_intr_enable(0); |
| 2249 | channel0_intr_enable(0); | 1749 | } |
| 2250 | } | 1750 | if (ch->channel_id == VPIF_CHANNEL1_VIDEO || |
| 2251 | if (ch->channel_id == VPIF_CHANNEL1_VIDEO || | 1751 | ycmux_mode == 2) { |
| 2252 | common->started == 2) { | 1752 | enable_channel1(0); |
| 2253 | enable_channel1(0); | 1753 | channel1_intr_enable(0); |
| 2254 | channel1_intr_enable(0); | ||
| 2255 | } | ||
| 2256 | } | 1754 | } |
| 2257 | mutex_unlock(&common->lock); | 1755 | mutex_unlock(&common->lock); |
| 2258 | } | 1756 | } |
| @@ -2273,40 +1771,35 @@ static int vpif_resume(struct device *dev) | |||
| 2273 | /* Get the pointer to the channel object */ | 1771 | /* Get the pointer to the channel object */ |
| 2274 | ch = vpif_obj.dev[i]; | 1772 | ch = vpif_obj.dev[i]; |
| 2275 | common = &ch->common[VPIF_VIDEO_INDEX]; | 1773 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1774 | |||
| 1775 | if (!vb2_is_streaming(&common->buffer_queue)) | ||
| 1776 | continue; | ||
| 1777 | |||
| 2276 | mutex_lock(&common->lock); | 1778 | mutex_lock(&common->lock); |
| 2277 | if (ch->usrs && common->io_usrs) { | 1779 | /* Enable channel */ |
| 2278 | /* Disable channel */ | 1780 | if (ch->channel_id == VPIF_CHANNEL0_VIDEO) { |
| 2279 | if (ch->channel_id == VPIF_CHANNEL0_VIDEO) { | 1781 | enable_channel0(1); |
| 2280 | enable_channel0(1); | 1782 | channel0_intr_enable(1); |
| 2281 | channel0_intr_enable(1); | 1783 | } |
| 2282 | } | 1784 | if (ch->channel_id == VPIF_CHANNEL1_VIDEO || |
| 2283 | if (ch->channel_id == VPIF_CHANNEL1_VIDEO || | 1785 | ycmux_mode == 2) { |
| 2284 | common->started == 2) { | 1786 | enable_channel1(1); |
| 2285 | enable_channel1(1); | 1787 | channel1_intr_enable(1); |
| 2286 | channel1_intr_enable(1); | ||
| 2287 | } | ||
| 2288 | } | 1788 | } |
| 2289 | mutex_unlock(&common->lock); | 1789 | mutex_unlock(&common->lock); |
| 2290 | } | 1790 | } |
| 2291 | 1791 | ||
| 2292 | return 0; | 1792 | return 0; |
| 2293 | } | 1793 | } |
| 2294 | |||
| 2295 | static const struct dev_pm_ops vpif_dev_pm_ops = { | ||
| 2296 | .suspend = vpif_suspend, | ||
| 2297 | .resume = vpif_resume, | ||
| 2298 | }; | ||
| 2299 | |||
| 2300 | #define vpif_pm_ops (&vpif_dev_pm_ops) | ||
| 2301 | #else | ||
| 2302 | #define vpif_pm_ops NULL | ||
| 2303 | #endif | 1794 | #endif |
| 2304 | 1795 | ||
| 1796 | static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume); | ||
| 1797 | |||
| 2305 | static __refdata struct platform_driver vpif_driver = { | 1798 | static __refdata struct platform_driver vpif_driver = { |
| 2306 | .driver = { | 1799 | .driver = { |
| 2307 | .name = "vpif_capture", | 1800 | .name = VPIF_DRIVER_NAME, |
| 2308 | .owner = THIS_MODULE, | 1801 | .owner = THIS_MODULE, |
| 2309 | .pm = vpif_pm_ops, | 1802 | .pm = &vpif_pm_ops, |
| 2310 | }, | 1803 | }, |
| 2311 | .probe = vpif_probe, | 1804 | .probe = vpif_probe, |
| 2312 | .remove = vpif_remove, | 1805 | .remove = vpif_remove, |
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h index 5a29d9a0cae1..1ee17824f484 100644 --- a/drivers/media/platform/davinci/vpif_capture.h +++ b/drivers/media/platform/davinci/vpif_capture.h | |||
| @@ -19,8 +19,6 @@ | |||
| 19 | #ifndef VPIF_CAPTURE_H | 19 | #ifndef VPIF_CAPTURE_H |
| 20 | #define VPIF_CAPTURE_H | 20 | #define VPIF_CAPTURE_H |
| 21 | 21 | ||
| 22 | #ifdef __KERNEL__ | ||
| 23 | |||
| 24 | /* Header files */ | 22 | /* Header files */ |
| 25 | #include <media/videobuf2-dma-contig.h> | 23 | #include <media/videobuf2-dma-contig.h> |
| 26 | #include <media/v4l2-device.h> | 24 | #include <media/v4l2-device.h> |
| @@ -63,11 +61,6 @@ struct common_obj { | |||
| 63 | struct vpif_cap_buffer *cur_frm; | 61 | struct vpif_cap_buffer *cur_frm; |
| 64 | /* Pointer pointing to current v4l2_buffer */ | 62 | /* Pointer pointing to current v4l2_buffer */ |
| 65 | struct vpif_cap_buffer *next_frm; | 63 | struct vpif_cap_buffer *next_frm; |
| 66 | /* | ||
| 67 | * This field keeps track of type of buffer exchange mechanism | ||
| 68 | * user has selected | ||
| 69 | */ | ||
| 70 | enum v4l2_memory memory; | ||
| 71 | /* Used to store pixel format */ | 64 | /* Used to store pixel format */ |
| 72 | struct v4l2_format fmt; | 65 | struct v4l2_format fmt; |
| 73 | /* Buffer queue used in video-buf */ | 66 | /* Buffer queue used in video-buf */ |
| @@ -80,10 +73,6 @@ struct common_obj { | |||
| 80 | spinlock_t irqlock; | 73 | spinlock_t irqlock; |
| 81 | /* lock used to access this structure */ | 74 | /* lock used to access this structure */ |
| 82 | struct mutex lock; | 75 | struct mutex lock; |
| 83 | /* number of users performing IO */ | ||
| 84 | u32 io_usrs; | ||
| 85 | /* Indicates whether streaming started */ | ||
| 86 | u8 started; | ||
| 87 | /* Function pointer to set the addresses */ | 76 | /* Function pointer to set the addresses */ |
| 88 | void (*set_addr) (unsigned long, unsigned long, unsigned long, | 77 | void (*set_addr) (unsigned long, unsigned long, unsigned long, |
| 89 | unsigned long); | 78 | unsigned long); |
| @@ -104,10 +93,6 @@ struct common_obj { | |||
| 104 | struct channel_obj { | 93 | struct channel_obj { |
| 105 | /* Identifies video device for this channel */ | 94 | /* Identifies video device for this channel */ |
| 106 | struct video_device *video_dev; | 95 | struct video_device *video_dev; |
| 107 | /* Used to keep track of state of the priority */ | ||
| 108 | struct v4l2_prio_state prio; | ||
| 109 | /* number of open instances of the channel */ | ||
| 110 | int usrs; | ||
| 111 | /* Indicates id of the field which is being displayed */ | 96 | /* Indicates id of the field which is being displayed */ |
| 112 | u32 field_id; | 97 | u32 field_id; |
| 113 | /* flag to indicate whether decoder is initialized */ | 98 | /* flag to indicate whether decoder is initialized */ |
| @@ -126,18 +111,6 @@ struct channel_obj { | |||
| 126 | struct video_obj video; | 111 | struct video_obj video; |
| 127 | }; | 112 | }; |
| 128 | 113 | ||
| 129 | /* File handle structure */ | ||
| 130 | struct vpif_fh { | ||
| 131 | /* pointer to channel object for opened device */ | ||
| 132 | struct channel_obj *channel; | ||
| 133 | /* Indicates whether this file handle is doing IO */ | ||
| 134 | u8 io_allowed[VPIF_NUMBER_OF_OBJECTS]; | ||
| 135 | /* Used to keep track priority of this instance */ | ||
| 136 | enum v4l2_priority prio; | ||
| 137 | /* Used to indicate channel is initialize or not */ | ||
| 138 | u8 initialized; | ||
| 139 | }; | ||
| 140 | |||
| 141 | struct vpif_device { | 114 | struct vpif_device { |
| 142 | struct v4l2_device v4l2_dev; | 115 | struct v4l2_device v4l2_dev; |
| 143 | struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS]; | 116 | struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS]; |
| @@ -157,5 +130,4 @@ struct vpif_config_params { | |||
| 157 | u8 max_device_type; | 130 | u8 max_device_type; |
| 158 | }; | 131 | }; |
| 159 | 132 | ||
| 160 | #endif /* End of __KERNEL__ */ | ||
| 161 | #endif /* VPIF_CAPTURE_H */ | 133 | #endif /* VPIF_CAPTURE_H */ |
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index aed41edd0501..5bb085b19bcb 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * Display driver for TI DaVinci VPIF | 3 | * Display driver for TI DaVinci VPIF |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | 5 | * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ |
| 6 | * Copyright (C) 2014 Lad, Prabhakar <prabhakar.csengg@gmail.com> | ||
| 6 | * | 7 | * |
| 7 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License as | 9 | * modify it under the terms of the GNU General Public License as |
| @@ -35,129 +36,110 @@ MODULE_VERSION(VPIF_DISPLAY_VERSION); | |||
| 35 | v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg) | 36 | v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg) |
| 36 | 37 | ||
| 37 | static int debug = 1; | 38 | static int debug = 1; |
| 38 | static u32 ch2_numbuffers = 3; | ||
| 39 | static u32 ch3_numbuffers = 3; | ||
| 40 | static u32 ch2_bufsize = 1920 * 1080 * 2; | ||
| 41 | static u32 ch3_bufsize = 720 * 576 * 2; | ||
| 42 | 39 | ||
| 43 | module_param(debug, int, 0644); | 40 | module_param(debug, int, 0644); |
| 44 | module_param(ch2_numbuffers, uint, S_IRUGO); | ||
| 45 | module_param(ch3_numbuffers, uint, S_IRUGO); | ||
| 46 | module_param(ch2_bufsize, uint, S_IRUGO); | ||
| 47 | module_param(ch3_bufsize, uint, S_IRUGO); | ||
| 48 | 41 | ||
| 49 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | 42 | MODULE_PARM_DESC(debug, "Debug level 0-1"); |
| 50 | MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)"); | 43 | |
| 51 | MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)"); | 44 | #define VPIF_DRIVER_NAME "vpif_display" |
| 52 | MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)"); | 45 | |
| 53 | MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)"); | 46 | /* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */ |
| 54 | 47 | static int ycmux_mode; | |
| 55 | static struct vpif_config_params config_params = { | 48 | |
| 56 | .min_numbuffers = 3, | 49 | static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} }; |
| 57 | .numbuffers[0] = 3, | ||
| 58 | .numbuffers[1] = 3, | ||
| 59 | .min_bufsize[0] = 720 * 480 * 2, | ||
| 60 | .min_bufsize[1] = 720 * 480 * 2, | ||
| 61 | .channel_bufsize[0] = 1920 * 1080 * 2, | ||
| 62 | .channel_bufsize[1] = 720 * 576 * 2, | ||
| 63 | }; | ||
| 64 | 50 | ||
| 65 | static struct vpif_device vpif_obj = { {NULL} }; | 51 | static struct vpif_device vpif_obj = { {NULL} }; |
| 66 | static struct device *vpif_dev; | 52 | static struct device *vpif_dev; |
| 67 | static void vpif_calculate_offsets(struct channel_obj *ch); | 53 | static void vpif_calculate_offsets(struct channel_obj *ch); |
| 68 | static void vpif_config_addr(struct channel_obj *ch, int muxmode); | 54 | static void vpif_config_addr(struct channel_obj *ch, int muxmode); |
| 69 | 55 | ||
| 70 | /* | 56 | static inline struct vpif_disp_buffer *to_vpif_buffer(struct vb2_buffer *vb) |
| 71 | * buffer_prepare: This is the callback function called from vb2_qbuf() | 57 | { |
| 72 | * function the buffer is prepared and user space virtual address is converted | 58 | return container_of(vb, struct vpif_disp_buffer, vb); |
| 73 | * into physical address | 59 | } |
| 60 | |||
| 61 | /** | ||
| 62 | * vpif_buffer_prepare : callback function for buffer prepare | ||
| 63 | * @vb: ptr to vb2_buffer | ||
| 64 | * | ||
| 65 | * This is the callback function for buffer prepare when vb2_qbuf() | ||
| 66 | * function is called. The buffer is prepared and user space virtual address | ||
| 67 | * or user address is converted into physical address | ||
| 74 | */ | 68 | */ |
| 75 | static int vpif_buffer_prepare(struct vb2_buffer *vb) | 69 | static int vpif_buffer_prepare(struct vb2_buffer *vb) |
| 76 | { | 70 | { |
| 77 | struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | 71 | struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue); |
| 78 | struct vb2_queue *q = vb->vb2_queue; | ||
| 79 | struct common_obj *common; | 72 | struct common_obj *common; |
| 80 | unsigned long addr; | 73 | |
| 81 | 74 | common = &ch->common[VPIF_VIDEO_INDEX]; | |
| 82 | common = &fh->channel->common[VPIF_VIDEO_INDEX]; | 75 | |
| 83 | if (vb->state != VB2_BUF_STATE_ACTIVE && | 76 | vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage); |
| 84 | vb->state != VB2_BUF_STATE_PREPARED) { | 77 | if (vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) |
| 85 | vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage); | 78 | return -EINVAL; |
| 86 | if (vb2_plane_vaddr(vb, 0) && | 79 | |
| 87 | vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) | 80 | vb->v4l2_buf.field = common->fmt.fmt.pix.field; |
| 88 | goto buf_align_exit; | 81 | |
| 89 | 82 | if (vb->vb2_queue->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { | |
| 90 | addr = vb2_dma_contig_plane_dma_addr(vb, 0); | 83 | unsigned long addr = vb2_dma_contig_plane_dma_addr(vb, 0); |
| 91 | if (q->streaming && | 84 | |
| 92 | (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) { | 85 | if (!ISALIGNED(addr + common->ytop_off) || |
| 93 | if (!ISALIGNED(addr + common->ytop_off) || | ||
| 94 | !ISALIGNED(addr + common->ybtm_off) || | 86 | !ISALIGNED(addr + common->ybtm_off) || |
| 95 | !ISALIGNED(addr + common->ctop_off) || | 87 | !ISALIGNED(addr + common->ctop_off) || |
| 96 | !ISALIGNED(addr + common->cbtm_off)) | 88 | !ISALIGNED(addr + common->cbtm_off)) { |
| 97 | goto buf_align_exit; | 89 | vpif_err("buffer offset not aligned to 8 bytes\n"); |
| 90 | return -EINVAL; | ||
| 98 | } | 91 | } |
| 99 | } | 92 | } |
| 100 | return 0; | ||
| 101 | 93 | ||
| 102 | buf_align_exit: | 94 | return 0; |
| 103 | vpif_err("buffer offset not aligned to 8 bytes\n"); | ||
| 104 | return -EINVAL; | ||
| 105 | } | 95 | } |
| 106 | 96 | ||
| 107 | /* | 97 | /** |
| 108 | * vpif_buffer_queue_setup: This function allocates memory for the buffers | 98 | * vpif_buffer_queue_setup : Callback function for buffer setup. |
| 99 | * @vq: vb2_queue ptr | ||
| 100 | * @fmt: v4l2 format | ||
| 101 | * @nbuffers: ptr to number of buffers requested by application | ||
| 102 | * @nplanes:: contains number of distinct video planes needed to hold a frame | ||
| 103 | * @sizes[]: contains the size (in bytes) of each plane. | ||
| 104 | * @alloc_ctxs: ptr to allocation context | ||
| 105 | * | ||
| 106 | * This callback function is called when reqbuf() is called to adjust | ||
| 107 | * the buffer count and buffer size | ||
| 109 | */ | 108 | */ |
| 110 | static int vpif_buffer_queue_setup(struct vb2_queue *vq, | 109 | static int vpif_buffer_queue_setup(struct vb2_queue *vq, |
| 111 | const struct v4l2_format *fmt, | 110 | const struct v4l2_format *fmt, |
| 112 | unsigned int *nbuffers, unsigned int *nplanes, | 111 | unsigned int *nbuffers, unsigned int *nplanes, |
| 113 | unsigned int sizes[], void *alloc_ctxs[]) | 112 | unsigned int sizes[], void *alloc_ctxs[]) |
| 114 | { | 113 | { |
| 115 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | 114 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
| 116 | struct channel_obj *ch = fh->channel; | ||
| 117 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 115 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 118 | unsigned long size; | ||
| 119 | |||
| 120 | if (V4L2_MEMORY_MMAP == common->memory) { | ||
| 121 | size = config_params.channel_bufsize[ch->channel_id]; | ||
| 122 | /* | ||
| 123 | * Checking if the buffer size exceeds the available buffer | ||
| 124 | * ycmux_mode = 0 means 1 channel mode HD and | ||
| 125 | * ycmux_mode = 1 means 2 channels mode SD | ||
| 126 | */ | ||
| 127 | if (ch->vpifparams.std_info.ycmux_mode == 0) { | ||
| 128 | if (config_params.video_limit[ch->channel_id]) | ||
| 129 | while (size * *nbuffers > | ||
| 130 | (config_params.video_limit[0] | ||
| 131 | + config_params.video_limit[1])) | ||
| 132 | (*nbuffers)--; | ||
| 133 | } else { | ||
| 134 | if (config_params.video_limit[ch->channel_id]) | ||
| 135 | while (size * *nbuffers > | ||
| 136 | config_params.video_limit[ch->channel_id]) | ||
| 137 | (*nbuffers)--; | ||
| 138 | } | ||
| 139 | } else { | ||
| 140 | size = common->fmt.fmt.pix.sizeimage; | ||
| 141 | } | ||
| 142 | 116 | ||
| 143 | if (*nbuffers < config_params.min_numbuffers) | 117 | if (fmt && fmt->fmt.pix.sizeimage < common->fmt.fmt.pix.sizeimage) |
| 144 | *nbuffers = config_params.min_numbuffers; | 118 | return -EINVAL; |
| 119 | |||
| 120 | if (vq->num_buffers + *nbuffers < 3) | ||
| 121 | *nbuffers = 3 - vq->num_buffers; | ||
| 145 | 122 | ||
| 146 | *nplanes = 1; | 123 | *nplanes = 1; |
| 147 | sizes[0] = size; | 124 | sizes[0] = fmt ? fmt->fmt.pix.sizeimage : common->fmt.fmt.pix.sizeimage; |
| 148 | alloc_ctxs[0] = common->alloc_ctx; | 125 | alloc_ctxs[0] = common->alloc_ctx; |
| 126 | |||
| 127 | /* Calculate the offset for Y and C data in the buffer */ | ||
| 128 | vpif_calculate_offsets(ch); | ||
| 129 | |||
| 149 | return 0; | 130 | return 0; |
| 150 | } | 131 | } |
| 151 | 132 | ||
| 152 | /* | 133 | /** |
| 153 | * vpif_buffer_queue: This function adds the buffer to DMA queue | 134 | * vpif_buffer_queue : Callback function to add buffer to DMA queue |
| 135 | * @vb: ptr to vb2_buffer | ||
| 136 | * | ||
| 137 | * This callback fucntion queues the buffer to DMA engine | ||
| 154 | */ | 138 | */ |
| 155 | static void vpif_buffer_queue(struct vb2_buffer *vb) | 139 | static void vpif_buffer_queue(struct vb2_buffer *vb) |
| 156 | { | 140 | { |
| 157 | struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | 141 | struct vpif_disp_buffer *buf = to_vpif_buffer(vb); |
| 158 | struct vpif_disp_buffer *buf = container_of(vb, | 142 | struct channel_obj *ch = vb2_get_drv_priv(vb->vb2_queue); |
| 159 | struct vpif_disp_buffer, vb); | ||
| 160 | struct channel_obj *ch = fh->channel; | ||
| 161 | struct common_obj *common; | 143 | struct common_obj *common; |
| 162 | unsigned long flags; | 144 | unsigned long flags; |
| 163 | 145 | ||
| @@ -169,98 +151,26 @@ static void vpif_buffer_queue(struct vb2_buffer *vb) | |||
| 169 | spin_unlock_irqrestore(&common->irqlock, flags); | 151 | spin_unlock_irqrestore(&common->irqlock, flags); |
| 170 | } | 152 | } |
| 171 | 153 | ||
| 172 | /* | 154 | /** |
| 173 | * vpif_buf_cleanup: This function is called from the videobuf2 layer to | 155 | * vpif_start_streaming : Starts the DMA engine for streaming |
| 174 | * free memory allocated to the buffers | 156 | * @vb: ptr to vb2_buffer |
| 157 | * @count: number of buffers | ||
| 175 | */ | 158 | */ |
| 176 | static void vpif_buf_cleanup(struct vb2_buffer *vb) | ||
| 177 | { | ||
| 178 | struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue); | ||
| 179 | struct vpif_disp_buffer *buf = container_of(vb, | ||
| 180 | struct vpif_disp_buffer, vb); | ||
| 181 | struct channel_obj *ch = fh->channel; | ||
| 182 | struct common_obj *common; | ||
| 183 | unsigned long flags; | ||
| 184 | |||
| 185 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 186 | |||
| 187 | spin_lock_irqsave(&common->irqlock, flags); | ||
| 188 | if (vb->state == VB2_BUF_STATE_ACTIVE) | ||
| 189 | list_del_init(&buf->list); | ||
| 190 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
| 191 | } | ||
| 192 | |||
| 193 | static void vpif_wait_prepare(struct vb2_queue *vq) | ||
| 194 | { | ||
| 195 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | ||
| 196 | struct channel_obj *ch = fh->channel; | ||
| 197 | struct common_obj *common; | ||
| 198 | |||
| 199 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 200 | mutex_unlock(&common->lock); | ||
| 201 | } | ||
| 202 | |||
| 203 | static void vpif_wait_finish(struct vb2_queue *vq) | ||
| 204 | { | ||
| 205 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | ||
| 206 | struct channel_obj *ch = fh->channel; | ||
| 207 | struct common_obj *common; | ||
| 208 | |||
| 209 | common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 210 | mutex_lock(&common->lock); | ||
| 211 | } | ||
| 212 | |||
| 213 | static int vpif_buffer_init(struct vb2_buffer *vb) | ||
| 214 | { | ||
| 215 | struct vpif_disp_buffer *buf = container_of(vb, | ||
| 216 | struct vpif_disp_buffer, vb); | ||
| 217 | |||
| 218 | INIT_LIST_HEAD(&buf->list); | ||
| 219 | |||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | |||
| 223 | static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} }; | ||
| 224 | |||
| 225 | static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | 159 | static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) |
| 226 | { | 160 | { |
| 227 | struct vpif_display_config *vpif_config_data = | 161 | struct vpif_display_config *vpif_config_data = |
| 228 | vpif_dev->platform_data; | 162 | vpif_dev->platform_data; |
| 229 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | 163 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
| 230 | struct channel_obj *ch = fh->channel; | ||
| 231 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 164 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 232 | struct vpif_params *vpif = &ch->vpifparams; | 165 | struct vpif_params *vpif = &ch->vpifparams; |
| 233 | unsigned long addr = 0; | 166 | struct vpif_disp_buffer *buf, *tmp; |
| 234 | unsigned long flags; | 167 | unsigned long addr, flags; |
| 235 | int ret; | 168 | int ret; |
| 236 | 169 | ||
| 237 | spin_lock_irqsave(&common->irqlock, flags); | 170 | spin_lock_irqsave(&common->irqlock, flags); |
| 238 | 171 | ||
| 239 | /* Get the next frame from the buffer queue */ | 172 | /* Initialize field_id */ |
| 240 | common->next_frm = common->cur_frm = | ||
| 241 | list_entry(common->dma_queue.next, | ||
| 242 | struct vpif_disp_buffer, list); | ||
| 243 | |||
| 244 | list_del(&common->cur_frm->list); | ||
| 245 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
| 246 | /* Mark state of the current frame to active */ | ||
| 247 | common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; | ||
| 248 | |||
| 249 | /* Initialize field_id and started member */ | ||
| 250 | ch->field_id = 0; | 173 | ch->field_id = 0; |
| 251 | common->started = 1; | ||
| 252 | addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0); | ||
| 253 | /* Calculate the offset for Y and C data in the buffer */ | ||
| 254 | vpif_calculate_offsets(ch); | ||
| 255 | |||
| 256 | if ((ch->vpifparams.std_info.frm_fmt && | ||
| 257 | ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) | ||
| 258 | && (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) | ||
| 259 | || (!ch->vpifparams.std_info.frm_fmt | ||
| 260 | && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) { | ||
| 261 | vpif_err("conflict in field format and std format\n"); | ||
| 262 | return -EINVAL; | ||
| 263 | } | ||
| 264 | 174 | ||
| 265 | /* clock settings */ | 175 | /* clock settings */ |
| 266 | if (vpif_config_data->set_clock) { | 176 | if (vpif_config_data->set_clock) { |
| @@ -268,24 +178,37 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 268 | ycmux_mode, ch->vpifparams.std_info.hd_sd); | 178 | ycmux_mode, ch->vpifparams.std_info.hd_sd); |
| 269 | if (ret < 0) { | 179 | if (ret < 0) { |
| 270 | vpif_err("can't set clock\n"); | 180 | vpif_err("can't set clock\n"); |
| 271 | return ret; | 181 | goto err; |
| 272 | } | 182 | } |
| 273 | } | 183 | } |
| 274 | 184 | ||
| 275 | /* set the parameters and addresses */ | 185 | /* set the parameters and addresses */ |
| 276 | ret = vpif_set_video_params(vpif, ch->channel_id + 2); | 186 | ret = vpif_set_video_params(vpif, ch->channel_id + 2); |
| 277 | if (ret < 0) | 187 | if (ret < 0) |
| 278 | return ret; | 188 | goto err; |
| 279 | 189 | ||
| 280 | common->started = ret; | 190 | ycmux_mode = ret; |
| 281 | vpif_config_addr(ch, ret); | 191 | vpif_config_addr(ch, ret); |
| 192 | /* Get the next frame from the buffer queue */ | ||
| 193 | common->next_frm = common->cur_frm = | ||
| 194 | list_entry(common->dma_queue.next, | ||
| 195 | struct vpif_disp_buffer, list); | ||
| 196 | |||
| 197 | list_del(&common->cur_frm->list); | ||
| 198 | spin_unlock_irqrestore(&common->irqlock, flags); | ||
| 199 | /* Mark state of the current frame to active */ | ||
| 200 | common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE; | ||
| 201 | |||
| 202 | addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0); | ||
| 282 | common->set_addr((addr + common->ytop_off), | 203 | common->set_addr((addr + common->ytop_off), |
| 283 | (addr + common->ybtm_off), | 204 | (addr + common->ybtm_off), |
| 284 | (addr + common->ctop_off), | 205 | (addr + common->ctop_off), |
| 285 | (addr + common->cbtm_off)); | 206 | (addr + common->cbtm_off)); |
| 286 | 207 | ||
| 287 | /* Set interrupt for both the fields in VPIF | 208 | /* |
| 288 | Register enable channel in VPIF register */ | 209 | * Set interrupt for both the fields in VPIF |
| 210 | * Register enable channel in VPIF register | ||
| 211 | */ | ||
| 289 | channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; | 212 | channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; |
| 290 | if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { | 213 | if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { |
| 291 | channel2_intr_assert(); | 214 | channel2_intr_assert(); |
| @@ -295,8 +218,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 295 | channel2_clipping_enable(1); | 218 | channel2_clipping_enable(1); |
| 296 | } | 219 | } |
| 297 | 220 | ||
| 298 | if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) | 221 | if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) { |
| 299 | || (common->started == 2)) { | ||
| 300 | channel3_intr_assert(); | 222 | channel3_intr_assert(); |
| 301 | channel3_intr_enable(1); | 223 | channel3_intr_enable(1); |
| 302 | enable_channel3(1); | 224 | enable_channel3(1); |
| @@ -305,19 +227,29 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 305 | } | 227 | } |
| 306 | 228 | ||
| 307 | return 0; | 229 | return 0; |
| 230 | |||
| 231 | err: | ||
| 232 | list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) { | ||
| 233 | list_del(&buf->list); | ||
| 234 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
| 235 | } | ||
| 236 | |||
| 237 | return ret; | ||
| 308 | } | 238 | } |
| 309 | 239 | ||
| 310 | /* abort streaming and wait for last buffer */ | 240 | /** |
| 311 | static int vpif_stop_streaming(struct vb2_queue *vq) | 241 | * vpif_stop_streaming : Stop the DMA engine |
| 242 | * @vq: ptr to vb2_queue | ||
| 243 | * | ||
| 244 | * This callback stops the DMA engine and any remaining buffers | ||
| 245 | * in the DMA queue are released. | ||
| 246 | */ | ||
| 247 | static void vpif_stop_streaming(struct vb2_queue *vq) | ||
| 312 | { | 248 | { |
| 313 | struct vpif_fh *fh = vb2_get_drv_priv(vq); | 249 | struct channel_obj *ch = vb2_get_drv_priv(vq); |
| 314 | struct channel_obj *ch = fh->channel; | ||
| 315 | struct common_obj *common; | 250 | struct common_obj *common; |
| 316 | unsigned long flags; | 251 | unsigned long flags; |
| 317 | 252 | ||
| 318 | if (!vb2_is_streaming(vq)) | ||
| 319 | return 0; | ||
| 320 | |||
| 321 | common = &ch->common[VPIF_VIDEO_INDEX]; | 253 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 322 | 254 | ||
| 323 | /* Disable channel */ | 255 | /* Disable channel */ |
| @@ -325,12 +257,10 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
| 325 | enable_channel2(0); | 257 | enable_channel2(0); |
| 326 | channel2_intr_enable(0); | 258 | channel2_intr_enable(0); |
| 327 | } | 259 | } |
| 328 | if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || | 260 | if (VPIF_CHANNEL3_VIDEO == ch->channel_id || ycmux_mode == 2) { |
| 329 | (2 == common->started)) { | ||
| 330 | enable_channel3(0); | 261 | enable_channel3(0); |
| 331 | channel3_intr_enable(0); | 262 | channel3_intr_enable(0); |
| 332 | } | 263 | } |
| 333 | common->started = 0; | ||
| 334 | 264 | ||
| 335 | /* release all active buffers */ | 265 | /* release all active buffers */ |
| 336 | spin_lock_irqsave(&common->irqlock, flags); | 266 | spin_lock_irqsave(&common->irqlock, flags); |
| @@ -352,19 +282,15 @@ static int vpif_stop_streaming(struct vb2_queue *vq) | |||
| 352 | vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); | 282 | vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR); |
| 353 | } | 283 | } |
| 354 | spin_unlock_irqrestore(&common->irqlock, flags); | 284 | spin_unlock_irqrestore(&common->irqlock, flags); |
| 355 | |||
| 356 | return 0; | ||
| 357 | } | 285 | } |
| 358 | 286 | ||
| 359 | static struct vb2_ops video_qops = { | 287 | static struct vb2_ops video_qops = { |
| 360 | .queue_setup = vpif_buffer_queue_setup, | 288 | .queue_setup = vpif_buffer_queue_setup, |
| 361 | .wait_prepare = vpif_wait_prepare, | 289 | .wait_prepare = vb2_ops_wait_prepare, |
| 362 | .wait_finish = vpif_wait_finish, | 290 | .wait_finish = vb2_ops_wait_finish, |
| 363 | .buf_init = vpif_buffer_init, | ||
| 364 | .buf_prepare = vpif_buffer_prepare, | 291 | .buf_prepare = vpif_buffer_prepare, |
| 365 | .start_streaming = vpif_start_streaming, | 292 | .start_streaming = vpif_start_streaming, |
| 366 | .stop_streaming = vpif_stop_streaming, | 293 | .stop_streaming = vpif_stop_streaming, |
| 367 | .buf_cleanup = vpif_buf_cleanup, | ||
| 368 | .buf_queue = vpif_buffer_queue, | 294 | .buf_queue = vpif_buffer_queue, |
| 369 | }; | 295 | }; |
| 370 | 296 | ||
| @@ -446,8 +372,6 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) | |||
| 446 | for (i = 0; i < VPIF_NUMOBJECTS; i++) { | 372 | for (i = 0; i < VPIF_NUMOBJECTS; i++) { |
| 447 | common = &ch->common[i]; | 373 | common = &ch->common[i]; |
| 448 | /* If streaming is started in this channel */ | 374 | /* If streaming is started in this channel */ |
| 449 | if (0 == common->started) | ||
| 450 | continue; | ||
| 451 | 375 | ||
| 452 | if (1 == ch->vpifparams.std_info.frm_fmt) { | 376 | if (1 == ch->vpifparams.std_info.frm_fmt) { |
| 453 | spin_lock(&common->irqlock); | 377 | spin_lock(&common->irqlock); |
| @@ -543,6 +467,7 @@ static int vpif_update_resolution(struct channel_obj *ch) | |||
| 543 | return -EINVAL; | 467 | return -EINVAL; |
| 544 | } | 468 | } |
| 545 | 469 | ||
| 470 | common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; | ||
| 546 | common->fmt.fmt.pix.width = std_info->width; | 471 | common->fmt.fmt.pix.width = std_info->width; |
| 547 | common->fmt.fmt.pix.height = std_info->height; | 472 | common->fmt.fmt.pix.height = std_info->height; |
| 548 | vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n", | 473 | vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n", |
| @@ -551,6 +476,17 @@ static int vpif_update_resolution(struct channel_obj *ch) | |||
| 551 | /* Set height and width paramateres */ | 476 | /* Set height and width paramateres */ |
| 552 | common->height = std_info->height; | 477 | common->height = std_info->height; |
| 553 | common->width = std_info->width; | 478 | common->width = std_info->width; |
| 479 | common->fmt.fmt.pix.sizeimage = common->height * common->width * 2; | ||
| 480 | |||
| 481 | if (vid_ch->stdid) | ||
| 482 | common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 483 | else | ||
| 484 | common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709; | ||
| 485 | |||
| 486 | if (ch->vpifparams.std_info.frm_fmt) | ||
| 487 | common->fmt.fmt.pix.field = V4L2_FIELD_NONE; | ||
| 488 | else | ||
| 489 | common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
| 554 | 490 | ||
| 555 | return 0; | 491 | return 0; |
| 556 | } | 492 | } |
| @@ -621,70 +557,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch) | |||
| 621 | ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid; | 557 | ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid; |
| 622 | } | 558 | } |
| 623 | 559 | ||
| 624 | static void vpif_config_format(struct channel_obj *ch) | ||
| 625 | { | ||
| 626 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 627 | |||
| 628 | common->fmt.fmt.pix.field = V4L2_FIELD_ANY; | ||
| 629 | if (config_params.numbuffers[ch->channel_id] == 0) | ||
| 630 | common->memory = V4L2_MEMORY_USERPTR; | ||
| 631 | else | ||
| 632 | common->memory = V4L2_MEMORY_MMAP; | ||
| 633 | |||
| 634 | common->fmt.fmt.pix.sizeimage = | ||
| 635 | config_params.channel_bufsize[ch->channel_id]; | ||
| 636 | common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; | ||
| 637 | common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 638 | } | ||
| 639 | |||
| 640 | static int vpif_check_format(struct channel_obj *ch, | ||
| 641 | struct v4l2_pix_format *pixfmt) | ||
| 642 | { | ||
| 643 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 644 | enum v4l2_field field = pixfmt->field; | ||
| 645 | u32 sizeimage, hpitch, vpitch; | ||
| 646 | |||
| 647 | if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) | ||
| 648 | goto invalid_fmt_exit; | ||
| 649 | |||
| 650 | if (!(VPIF_VALID_FIELD(field))) | ||
| 651 | goto invalid_fmt_exit; | ||
| 652 | |||
| 653 | if (pixfmt->bytesperline <= 0) | ||
| 654 | goto invalid_pitch_exit; | ||
| 655 | |||
| 656 | sizeimage = pixfmt->sizeimage; | ||
| 657 | |||
| 658 | if (vpif_update_resolution(ch)) | ||
| 659 | return -EINVAL; | ||
| 660 | |||
| 661 | hpitch = pixfmt->bytesperline; | ||
| 662 | vpitch = sizeimage / (hpitch * 2); | ||
| 663 | |||
| 664 | /* Check for valid value of pitch */ | ||
| 665 | if ((hpitch < ch->vpifparams.std_info.width) || | ||
| 666 | (vpitch < ch->vpifparams.std_info.height)) | ||
| 667 | goto invalid_pitch_exit; | ||
| 668 | |||
| 669 | /* Check for 8 byte alignment */ | ||
| 670 | if (!ISALIGNED(hpitch)) { | ||
| 671 | vpif_err("invalid pitch alignment\n"); | ||
| 672 | return -EINVAL; | ||
| 673 | } | ||
| 674 | pixfmt->width = common->fmt.fmt.pix.width; | ||
| 675 | pixfmt->height = common->fmt.fmt.pix.height; | ||
| 676 | |||
| 677 | return 0; | ||
| 678 | |||
| 679 | invalid_fmt_exit: | ||
| 680 | vpif_err("invalid field format\n"); | ||
| 681 | return -EINVAL; | ||
| 682 | |||
| 683 | invalid_pitch_exit: | ||
| 684 | vpif_err("invalid pitch\n"); | ||
| 685 | return -EINVAL; | ||
| 686 | } | ||
| 687 | |||
| 688 | static void vpif_config_addr(struct channel_obj *ch, int muxmode) | 560 | static void vpif_config_addr(struct channel_obj *ch, int muxmode) |
| 689 | { | 561 | { |
| 690 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 562 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| @@ -699,127 +571,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode) | |||
| 699 | } | 571 | } |
| 700 | } | 572 | } |
| 701 | 573 | ||
| 702 | /* | ||
| 703 | * vpif_mmap: It is used to map kernel space buffers into user spaces | ||
| 704 | */ | ||
| 705 | static int vpif_mmap(struct file *filep, struct vm_area_struct *vma) | ||
| 706 | { | ||
| 707 | struct vpif_fh *fh = filep->private_data; | ||
| 708 | struct channel_obj *ch = fh->channel; | ||
| 709 | struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); | ||
| 710 | int ret; | ||
| 711 | |||
| 712 | vpif_dbg(2, debug, "vpif_mmap\n"); | ||
| 713 | |||
| 714 | if (mutex_lock_interruptible(&common->lock)) | ||
| 715 | return -ERESTARTSYS; | ||
| 716 | ret = vb2_mmap(&common->buffer_queue, vma); | ||
| 717 | mutex_unlock(&common->lock); | ||
| 718 | return ret; | ||
| 719 | } | ||
| 720 | |||
| 721 | /* | ||
| 722 | * vpif_poll: It is used for select/poll system call | ||
| 723 | */ | ||
| 724 | static unsigned int vpif_poll(struct file *filep, poll_table *wait) | ||
| 725 | { | ||
| 726 | struct vpif_fh *fh = filep->private_data; | ||
| 727 | struct channel_obj *ch = fh->channel; | ||
| 728 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 729 | unsigned int res = 0; | ||
| 730 | |||
| 731 | if (common->started) { | ||
| 732 | mutex_lock(&common->lock); | ||
| 733 | res = vb2_poll(&common->buffer_queue, filep, wait); | ||
| 734 | mutex_unlock(&common->lock); | ||
| 735 | } | ||
| 736 | |||
| 737 | return res; | ||
| 738 | } | ||
| 739 | |||
| 740 | /* | ||
| 741 | * vpif_open: It creates object of file handle structure and stores it in | ||
| 742 | * private_data member of filepointer | ||
| 743 | */ | ||
| 744 | static int vpif_open(struct file *filep) | ||
| 745 | { | ||
| 746 | struct video_device *vdev = video_devdata(filep); | ||
| 747 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 748 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 749 | struct vpif_fh *fh; | ||
| 750 | |||
| 751 | /* Allocate memory for the file handle object */ | ||
| 752 | fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); | ||
| 753 | if (fh == NULL) { | ||
| 754 | vpif_err("unable to allocate memory for file handle object\n"); | ||
| 755 | return -ENOMEM; | ||
| 756 | } | ||
| 757 | |||
| 758 | if (mutex_lock_interruptible(&common->lock)) { | ||
| 759 | kfree(fh); | ||
| 760 | return -ERESTARTSYS; | ||
| 761 | } | ||
| 762 | /* store pointer to fh in private_data member of filep */ | ||
| 763 | filep->private_data = fh; | ||
| 764 | fh->channel = ch; | ||
| 765 | fh->initialized = 0; | ||
| 766 | if (!ch->initialized) { | ||
| 767 | fh->initialized = 1; | ||
| 768 | ch->initialized = 1; | ||
| 769 | memset(&ch->vpifparams, 0, sizeof(ch->vpifparams)); | ||
| 770 | } | ||
| 771 | |||
| 772 | /* Increment channel usrs counter */ | ||
| 773 | atomic_inc(&ch->usrs); | ||
| 774 | /* Set io_allowed[VPIF_VIDEO_INDEX] member to false */ | ||
| 775 | fh->io_allowed[VPIF_VIDEO_INDEX] = 0; | ||
| 776 | /* Initialize priority of this instance to default priority */ | ||
| 777 | fh->prio = V4L2_PRIORITY_UNSET; | ||
| 778 | v4l2_prio_open(&ch->prio, &fh->prio); | ||
| 779 | mutex_unlock(&common->lock); | ||
| 780 | |||
| 781 | return 0; | ||
| 782 | } | ||
| 783 | |||
| 784 | /* | ||
| 785 | * vpif_release: This function deletes buffer queue, frees the buffers and | ||
| 786 | * the vpif file handle | ||
| 787 | */ | ||
| 788 | static int vpif_release(struct file *filep) | ||
| 789 | { | ||
| 790 | struct vpif_fh *fh = filep->private_data; | ||
| 791 | struct channel_obj *ch = fh->channel; | ||
| 792 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 793 | |||
| 794 | mutex_lock(&common->lock); | ||
| 795 | /* if this instance is doing IO */ | ||
| 796 | if (fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 797 | /* Reset io_usrs member of channel object */ | ||
| 798 | common->io_usrs = 0; | ||
| 799 | /* Free buffers allocated */ | ||
| 800 | vb2_queue_release(&common->buffer_queue); | ||
| 801 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 802 | |||
| 803 | common->numbuffers = | ||
| 804 | config_params.numbuffers[ch->channel_id]; | ||
| 805 | } | ||
| 806 | |||
| 807 | /* Decrement channel usrs counter */ | ||
| 808 | atomic_dec(&ch->usrs); | ||
| 809 | /* If this file handle has initialize encoder device, reset it */ | ||
| 810 | if (fh->initialized) | ||
| 811 | ch->initialized = 0; | ||
| 812 | |||
| 813 | /* Close the priority */ | ||
| 814 | v4l2_prio_close(&ch->prio, fh->prio); | ||
| 815 | filep->private_data = NULL; | ||
| 816 | fh->initialized = 0; | ||
| 817 | mutex_unlock(&common->lock); | ||
| 818 | kfree(fh); | ||
| 819 | |||
| 820 | return 0; | ||
| 821 | } | ||
| 822 | |||
| 823 | /* functions implementing ioctls */ | 574 | /* functions implementing ioctls */ |
| 824 | /** | 575 | /** |
| 825 | * vpif_querycap() - QUERYCAP handler | 576 | * vpif_querycap() - QUERYCAP handler |
| @@ -834,7 +585,7 @@ static int vpif_querycap(struct file *file, void *priv, | |||
| 834 | 585 | ||
| 835 | cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; | 586 | cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; |
| 836 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 587 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
| 837 | snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpif_dev)); | 588 | strlcpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); |
| 838 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", | 589 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
| 839 | dev_name(vpif_dev)); | 590 | dev_name(vpif_dev)); |
| 840 | strlcpy(cap->card, config->card_name, sizeof(cap->card)); | 591 | strlcpy(cap->card, config->card_name, sizeof(cap->card)); |
| @@ -845,24 +596,22 @@ static int vpif_querycap(struct file *file, void *priv, | |||
| 845 | static int vpif_enum_fmt_vid_out(struct file *file, void *priv, | 596 | static int vpif_enum_fmt_vid_out(struct file *file, void *priv, |
| 846 | struct v4l2_fmtdesc *fmt) | 597 | struct v4l2_fmtdesc *fmt) |
| 847 | { | 598 | { |
| 848 | if (fmt->index != 0) { | 599 | if (fmt->index != 0) |
| 849 | vpif_err("Invalid format index\n"); | ||
| 850 | return -EINVAL; | 600 | return -EINVAL; |
| 851 | } | ||
| 852 | 601 | ||
| 853 | /* Fill in the information about format */ | 602 | /* Fill in the information about format */ |
| 854 | fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | 603 | fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; |
| 855 | strcpy(fmt->description, "YCbCr4:2:2 YC Planar"); | 604 | strcpy(fmt->description, "YCbCr4:2:2 YC Planar"); |
| 856 | fmt->pixelformat = V4L2_PIX_FMT_YUV422P; | 605 | fmt->pixelformat = V4L2_PIX_FMT_YUV422P; |
| 857 | 606 | fmt->flags = 0; | |
| 858 | return 0; | 607 | return 0; |
| 859 | } | 608 | } |
| 860 | 609 | ||
| 861 | static int vpif_g_fmt_vid_out(struct file *file, void *priv, | 610 | static int vpif_g_fmt_vid_out(struct file *file, void *priv, |
| 862 | struct v4l2_format *fmt) | 611 | struct v4l2_format *fmt) |
| 863 | { | 612 | { |
| 864 | struct vpif_fh *fh = priv; | 613 | struct video_device *vdev = video_devdata(file); |
| 865 | struct channel_obj *ch = fh->channel; | 614 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 866 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 615 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 867 | 616 | ||
| 868 | /* Check the validity of the buffer type */ | 617 | /* Check the validity of the buffer type */ |
| @@ -875,193 +624,84 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv, | |||
| 875 | return 0; | 624 | return 0; |
| 876 | } | 625 | } |
| 877 | 626 | ||
| 878 | static int vpif_s_fmt_vid_out(struct file *file, void *priv, | 627 | static int vpif_try_fmt_vid_out(struct file *file, void *priv, |
| 879 | struct v4l2_format *fmt) | 628 | struct v4l2_format *fmt) |
| 880 | { | 629 | { |
| 881 | struct vpif_fh *fh = priv; | 630 | struct video_device *vdev = video_devdata(file); |
| 882 | struct v4l2_pix_format *pixfmt; | 631 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 883 | struct channel_obj *ch = fh->channel; | ||
| 884 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 632 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 885 | int ret = 0; | 633 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; |
| 886 | |||
| 887 | if ((VPIF_CHANNEL2_VIDEO == ch->channel_id) | ||
| 888 | || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) { | ||
| 889 | if (!fh->initialized) { | ||
| 890 | vpif_dbg(1, debug, "Channel Busy\n"); | ||
| 891 | return -EBUSY; | ||
| 892 | } | ||
| 893 | 634 | ||
| 894 | /* Check for the priority */ | 635 | /* |
| 895 | ret = v4l2_prio_check(&ch->prio, fh->prio); | 636 | * to supress v4l-compliance warnings silently correct |
| 896 | if (0 != ret) | 637 | * the pixelformat |
| 897 | return ret; | 638 | */ |
| 898 | fh->initialized = 1; | 639 | if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) |
| 899 | } | 640 | pixfmt->pixelformat = common->fmt.fmt.pix.pixelformat; |
| 900 | 641 | ||
| 901 | if (common->started) { | 642 | if (vpif_update_resolution(ch)) |
| 902 | vpif_dbg(1, debug, "Streaming in progress\n"); | 643 | return -EINVAL; |
| 903 | return -EBUSY; | ||
| 904 | } | ||
| 905 | 644 | ||
| 906 | pixfmt = &fmt->fmt.pix; | 645 | pixfmt->colorspace = common->fmt.fmt.pix.colorspace; |
| 907 | /* Check for valid field format */ | 646 | pixfmt->field = common->fmt.fmt.pix.field; |
| 908 | ret = vpif_check_format(ch, pixfmt); | 647 | pixfmt->bytesperline = common->fmt.fmt.pix.width; |
| 909 | if (ret) | 648 | pixfmt->width = common->fmt.fmt.pix.width; |
| 910 | return ret; | 649 | pixfmt->height = common->fmt.fmt.pix.height; |
| 650 | pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2; | ||
| 651 | pixfmt->priv = 0; | ||
| 911 | 652 | ||
| 912 | /* store the pix format in the channel object */ | ||
| 913 | common->fmt.fmt.pix = *pixfmt; | ||
| 914 | /* store the format in the channel object */ | ||
| 915 | common->fmt = *fmt; | ||
| 916 | return 0; | 653 | return 0; |
| 917 | } | 654 | } |
| 918 | 655 | ||
| 919 | static int vpif_try_fmt_vid_out(struct file *file, void *priv, | 656 | static int vpif_s_fmt_vid_out(struct file *file, void *priv, |
| 920 | struct v4l2_format *fmt) | 657 | struct v4l2_format *fmt) |
| 921 | { | 658 | { |
| 922 | struct vpif_fh *fh = priv; | 659 | struct video_device *vdev = video_devdata(file); |
| 923 | struct channel_obj *ch = fh->channel; | 660 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 924 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 661 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 925 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; | 662 | struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; |
| 926 | int ret = 0; | ||
| 927 | |||
| 928 | ret = vpif_check_format(ch, pixfmt); | ||
| 929 | if (ret) { | ||
| 930 | *pixfmt = common->fmt.fmt.pix; | ||
| 931 | pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2; | ||
| 932 | } | ||
| 933 | |||
| 934 | return ret; | ||
| 935 | } | ||
| 936 | |||
| 937 | static int vpif_reqbufs(struct file *file, void *priv, | ||
| 938 | struct v4l2_requestbuffers *reqbuf) | ||
| 939 | { | ||
| 940 | struct vpif_fh *fh = priv; | ||
| 941 | struct channel_obj *ch = fh->channel; | ||
| 942 | struct common_obj *common; | ||
| 943 | enum v4l2_field field; | ||
| 944 | struct vb2_queue *q; | ||
| 945 | u8 index = 0; | ||
| 946 | int ret; | 663 | int ret; |
| 947 | 664 | ||
| 948 | /* This file handle has not initialized the channel, | 665 | if (vb2_is_busy(&common->buffer_queue)) |
| 949 | It is not allowed to do settings */ | ||
| 950 | if ((VPIF_CHANNEL2_VIDEO == ch->channel_id) | ||
| 951 | || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) { | ||
| 952 | if (!fh->initialized) { | ||
| 953 | vpif_err("Channel Busy\n"); | ||
| 954 | return -EBUSY; | ||
| 955 | } | ||
| 956 | } | ||
| 957 | |||
| 958 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type) | ||
| 959 | return -EINVAL; | ||
| 960 | |||
| 961 | index = VPIF_VIDEO_INDEX; | ||
| 962 | |||
| 963 | common = &ch->common[index]; | ||
| 964 | |||
| 965 | if (common->fmt.type != reqbuf->type || !vpif_dev) | ||
| 966 | return -EINVAL; | ||
| 967 | if (0 != common->io_usrs) | ||
| 968 | return -EBUSY; | 666 | return -EBUSY; |
| 969 | 667 | ||
| 970 | if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | 668 | ret = vpif_try_fmt_vid_out(file, priv, fmt); |
| 971 | if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY) | 669 | if (ret) |
| 972 | field = V4L2_FIELD_INTERLACED; | ||
| 973 | else | ||
| 974 | field = common->fmt.fmt.pix.field; | ||
| 975 | } else { | ||
| 976 | field = V4L2_VBI_INTERLACED; | ||
| 977 | } | ||
| 978 | /* Initialize videobuf2 queue as per the buffer type */ | ||
| 979 | common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); | ||
| 980 | if (IS_ERR(common->alloc_ctx)) { | ||
| 981 | vpif_err("Failed to get the context\n"); | ||
| 982 | return PTR_ERR(common->alloc_ctx); | ||
| 983 | } | ||
| 984 | q = &common->buffer_queue; | ||
| 985 | q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 986 | q->io_modes = VB2_MMAP | VB2_USERPTR; | ||
| 987 | q->drv_priv = fh; | ||
| 988 | q->ops = &video_qops; | ||
| 989 | q->mem_ops = &vb2_dma_contig_memops; | ||
| 990 | q->buf_struct_size = sizeof(struct vpif_disp_buffer); | ||
| 991 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 992 | q->min_buffers_needed = 1; | ||
| 993 | |||
| 994 | ret = vb2_queue_init(q); | ||
| 995 | if (ret) { | ||
| 996 | vpif_err("vpif_display: vb2_queue_init() failed\n"); | ||
| 997 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 998 | return ret; | 670 | return ret; |
| 999 | } | ||
| 1000 | /* Set io allowed member of file handle to TRUE */ | ||
| 1001 | fh->io_allowed[index] = 1; | ||
| 1002 | /* Increment io usrs member of channel object to 1 */ | ||
| 1003 | common->io_usrs = 1; | ||
| 1004 | /* Store type of memory requested in channel object */ | ||
| 1005 | common->memory = reqbuf->memory; | ||
| 1006 | INIT_LIST_HEAD(&common->dma_queue); | ||
| 1007 | /* Allocate buffers */ | ||
| 1008 | return vb2_reqbufs(&common->buffer_queue, reqbuf); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | static int vpif_querybuf(struct file *file, void *priv, | ||
| 1012 | struct v4l2_buffer *tbuf) | ||
| 1013 | { | ||
| 1014 | struct vpif_fh *fh = priv; | ||
| 1015 | struct channel_obj *ch = fh->channel; | ||
| 1016 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1017 | 671 | ||
| 1018 | if (common->fmt.type != tbuf->type) | 672 | /* store the pix format in the channel object */ |
| 1019 | return -EINVAL; | 673 | common->fmt.fmt.pix = *pixfmt; |
| 1020 | 674 | ||
| 1021 | return vb2_querybuf(&common->buffer_queue, tbuf); | 675 | /* store the format in the channel object */ |
| 676 | common->fmt = *fmt; | ||
| 677 | return 0; | ||
| 1022 | } | 678 | } |
| 1023 | 679 | ||
| 1024 | static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) | 680 | static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) |
| 1025 | { | 681 | { |
| 1026 | struct vpif_fh *fh = NULL; | 682 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 1027 | struct channel_obj *ch = NULL; | 683 | struct video_device *vdev = video_devdata(file); |
| 1028 | struct common_obj *common = NULL; | 684 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1029 | 685 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | |
| 1030 | if (!buf || !priv) | 686 | struct vpif_display_chan_config *chan_cfg; |
| 1031 | return -EINVAL; | 687 | struct v4l2_output output; |
| 1032 | 688 | int ret; | |
| 1033 | fh = priv; | ||
| 1034 | ch = fh->channel; | ||
| 1035 | if (!ch) | ||
| 1036 | return -EINVAL; | ||
| 1037 | 689 | ||
| 1038 | common = &(ch->common[VPIF_VIDEO_INDEX]); | 690 | if (config->chan_config[ch->channel_id].outputs == NULL) |
| 1039 | if (common->fmt.type != buf->type) | 691 | return -ENODATA; |
| 1040 | return -EINVAL; | ||
| 1041 | 692 | ||
| 1042 | if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { | 693 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1043 | vpif_err("fh->io_allowed\n"); | 694 | output = chan_cfg->outputs[ch->output_idx].output; |
| 1044 | return -EACCES; | 695 | if (output.capabilities != V4L2_OUT_CAP_STD) |
| 1045 | } | 696 | return -ENODATA; |
| 1046 | 697 | ||
| 1047 | return vb2_qbuf(&common->buffer_queue, buf); | 698 | if (vb2_is_busy(&common->buffer_queue)) |
| 1048 | } | 699 | return -EBUSY; |
| 1049 | 700 | ||
| 1050 | static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | ||
| 1051 | { | ||
| 1052 | struct vpif_fh *fh = priv; | ||
| 1053 | struct channel_obj *ch = fh->channel; | ||
| 1054 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1055 | int ret = 0; | ||
| 1056 | 701 | ||
| 1057 | if (!(std_id & VPIF_V4L2_STD)) | 702 | if (!(std_id & VPIF_V4L2_STD)) |
| 1058 | return -EINVAL; | 703 | return -EINVAL; |
| 1059 | 704 | ||
| 1060 | if (common->started) { | ||
| 1061 | vpif_err("streaming in progress\n"); | ||
| 1062 | return -EBUSY; | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | /* Call encoder subdevice function to set the standard */ | 705 | /* Call encoder subdevice function to set the standard */ |
| 1066 | ch->video.stdid = std_id; | 706 | ch->video.stdid = std_id; |
| 1067 | memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings)); | 707 | memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings)); |
| @@ -1069,16 +709,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
| 1069 | if (vpif_update_resolution(ch)) | 709 | if (vpif_update_resolution(ch)) |
| 1070 | return -EINVAL; | 710 | return -EINVAL; |
| 1071 | 711 | ||
| 1072 | if ((ch->vpifparams.std_info.width * | ||
| 1073 | ch->vpifparams.std_info.height * 2) > | ||
| 1074 | config_params.channel_bufsize[ch->channel_id]) { | ||
| 1075 | vpif_err("invalid std for this size\n"); | ||
| 1076 | return -EINVAL; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width; | 712 | common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width; |
| 1080 | /* Configure the default format information */ | ||
| 1081 | vpif_config_format(ch); | ||
| 1082 | 713 | ||
| 1083 | ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, | 714 | ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, |
| 1084 | s_std_output, std_id); | 715 | s_std_output, std_id); |
| @@ -1087,7 +718,7 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
| 1087 | return ret; | 718 | return ret; |
| 1088 | } | 719 | } |
| 1089 | 720 | ||
| 1090 | ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core, | 721 | ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, |
| 1091 | s_std, std_id); | 722 | s_std, std_id); |
| 1092 | if (ret < 0) | 723 | if (ret < 0) |
| 1093 | vpif_err("Failed to set standard for sub devices\n"); | 724 | vpif_err("Failed to set standard for sub devices\n"); |
| @@ -1096,132 +727,21 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
| 1096 | 727 | ||
| 1097 | static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) | 728 | static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std) |
| 1098 | { | 729 | { |
| 1099 | struct vpif_fh *fh = priv; | 730 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 1100 | struct channel_obj *ch = fh->channel; | 731 | struct video_device *vdev = video_devdata(file); |
| 1101 | 732 | struct channel_obj *ch = video_get_drvdata(vdev); | |
| 1102 | *std = ch->video.stdid; | 733 | struct vpif_display_chan_config *chan_cfg; |
| 1103 | return 0; | 734 | struct v4l2_output output; |
| 1104 | } | ||
| 1105 | |||
| 1106 | static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | ||
| 1107 | { | ||
| 1108 | struct vpif_fh *fh = priv; | ||
| 1109 | struct channel_obj *ch = fh->channel; | ||
| 1110 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1111 | |||
| 1112 | return vb2_dqbuf(&common->buffer_queue, p, | ||
| 1113 | (file->f_flags & O_NONBLOCK)); | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | static int vpif_streamon(struct file *file, void *priv, | ||
| 1117 | enum v4l2_buf_type buftype) | ||
| 1118 | { | ||
| 1119 | struct vpif_fh *fh = priv; | ||
| 1120 | struct channel_obj *ch = fh->channel; | ||
| 1121 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1122 | struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id]; | ||
| 1123 | int ret = 0; | ||
| 1124 | |||
| 1125 | if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) { | ||
| 1126 | vpif_err("buffer type not supported\n"); | ||
| 1127 | return -EINVAL; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 1131 | vpif_err("fh->io_allowed\n"); | ||
| 1132 | return -EACCES; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | /* If Streaming is already started, return error */ | ||
| 1136 | if (common->started) { | ||
| 1137 | vpif_err("channel->started\n"); | ||
| 1138 | return -EBUSY; | ||
| 1139 | } | ||
| 1140 | |||
| 1141 | if ((ch->channel_id == VPIF_CHANNEL2_VIDEO | ||
| 1142 | && oth_ch->common[VPIF_VIDEO_INDEX].started && | ||
| 1143 | ch->vpifparams.std_info.ycmux_mode == 0) | ||
| 1144 | || ((ch->channel_id == VPIF_CHANNEL3_VIDEO) | ||
| 1145 | && (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) { | ||
| 1146 | vpif_err("other channel is using\n"); | ||
| 1147 | return -EBUSY; | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | ret = vpif_check_format(ch, &common->fmt.fmt.pix); | ||
| 1151 | if (ret < 0) | ||
| 1152 | return ret; | ||
| 1153 | |||
| 1154 | /* Call vb2_streamon to start streaming in videobuf2 */ | ||
| 1155 | ret = vb2_streamon(&common->buffer_queue, buftype); | ||
| 1156 | if (ret < 0) { | ||
| 1157 | vpif_err("vb2_streamon\n"); | ||
| 1158 | return ret; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | return ret; | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | static int vpif_streamoff(struct file *file, void *priv, | ||
| 1165 | enum v4l2_buf_type buftype) | ||
| 1166 | { | ||
| 1167 | struct vpif_fh *fh = priv; | ||
| 1168 | struct channel_obj *ch = fh->channel; | ||
| 1169 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1170 | struct vpif_display_config *vpif_config_data = | ||
| 1171 | vpif_dev->platform_data; | ||
| 1172 | |||
| 1173 | if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) { | ||
| 1174 | vpif_err("buffer type not supported\n"); | ||
| 1175 | return -EINVAL; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | if (!fh->io_allowed[VPIF_VIDEO_INDEX]) { | ||
| 1179 | vpif_err("fh->io_allowed\n"); | ||
| 1180 | return -EACCES; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | if (!common->started) { | ||
| 1184 | vpif_err("channel->started\n"); | ||
| 1185 | return -EINVAL; | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { | ||
| 1189 | /* disable channel */ | ||
| 1190 | if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { | ||
| 1191 | if (vpif_config_data-> | ||
| 1192 | chan_config[VPIF_CHANNEL2_VIDEO].clip_en) | ||
| 1193 | channel2_clipping_enable(0); | ||
| 1194 | enable_channel2(0); | ||
| 1195 | channel2_intr_enable(0); | ||
| 1196 | } | ||
| 1197 | if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || | ||
| 1198 | (2 == common->started)) { | ||
| 1199 | if (vpif_config_data-> | ||
| 1200 | chan_config[VPIF_CHANNEL3_VIDEO].clip_en) | ||
| 1201 | channel3_clipping_enable(0); | ||
| 1202 | enable_channel3(0); | ||
| 1203 | channel3_intr_enable(0); | ||
| 1204 | } | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | common->started = 0; | ||
| 1208 | return vb2_streamoff(&common->buffer_queue, buftype); | ||
| 1209 | } | ||
| 1210 | 735 | ||
| 1211 | static int vpif_cropcap(struct file *file, void *priv, | 736 | if (config->chan_config[ch->channel_id].outputs == NULL) |
| 1212 | struct v4l2_cropcap *crop) | 737 | return -ENODATA; |
| 1213 | { | ||
| 1214 | struct vpif_fh *fh = priv; | ||
| 1215 | struct channel_obj *ch = fh->channel; | ||
| 1216 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1217 | if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type) | ||
| 1218 | return -EINVAL; | ||
| 1219 | 738 | ||
| 1220 | crop->bounds.left = crop->bounds.top = 0; | 739 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1221 | crop->defrect.left = crop->defrect.top = 0; | 740 | output = chan_cfg->outputs[ch->output_idx].output; |
| 1222 | crop->defrect.height = crop->bounds.height = common->height; | 741 | if (output.capabilities != V4L2_OUT_CAP_STD) |
| 1223 | crop->defrect.width = crop->bounds.width = common->width; | 742 | return -ENODATA; |
| 1224 | 743 | ||
| 744 | *std = ch->video.stdid; | ||
| 1225 | return 0; | 745 | return 0; |
| 1226 | } | 746 | } |
| 1227 | 747 | ||
| @@ -1230,9 +750,9 @@ static int vpif_enum_output(struct file *file, void *fh, | |||
| 1230 | { | 750 | { |
| 1231 | 751 | ||
| 1232 | struct vpif_display_config *config = vpif_dev->platform_data; | 752 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 753 | struct video_device *vdev = video_devdata(file); | ||
| 754 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1233 | struct vpif_display_chan_config *chan_cfg; | 755 | struct vpif_display_chan_config *chan_cfg; |
| 1234 | struct vpif_fh *vpif_handler = fh; | ||
| 1235 | struct channel_obj *ch = vpif_handler->channel; | ||
| 1236 | 756 | ||
| 1237 | chan_cfg = &config->chan_config[ch->channel_id]; | 757 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1238 | if (output->index >= chan_cfg->output_count) { | 758 | if (output->index >= chan_cfg->output_count) { |
| @@ -1326,52 +846,32 @@ static int vpif_set_output(struct vpif_display_config *vpif_cfg, | |||
| 1326 | static int vpif_s_output(struct file *file, void *priv, unsigned int i) | 846 | static int vpif_s_output(struct file *file, void *priv, unsigned int i) |
| 1327 | { | 847 | { |
| 1328 | struct vpif_display_config *config = vpif_dev->platform_data; | 848 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 849 | struct video_device *vdev = video_devdata(file); | ||
| 850 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1329 | struct vpif_display_chan_config *chan_cfg; | 851 | struct vpif_display_chan_config *chan_cfg; |
| 1330 | struct vpif_fh *fh = priv; | ||
| 1331 | struct channel_obj *ch = fh->channel; | ||
| 1332 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | 852 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1333 | 853 | ||
| 854 | if (vb2_is_busy(&common->buffer_queue)) | ||
| 855 | return -EBUSY; | ||
| 856 | |||
| 1334 | chan_cfg = &config->chan_config[ch->channel_id]; | 857 | chan_cfg = &config->chan_config[ch->channel_id]; |
| 1335 | 858 | ||
| 1336 | if (i >= chan_cfg->output_count) | 859 | if (i >= chan_cfg->output_count) |
| 1337 | return -EINVAL; | 860 | return -EINVAL; |
| 1338 | 861 | ||
| 1339 | if (common->started) { | ||
| 1340 | vpif_err("Streaming in progress\n"); | ||
| 1341 | return -EBUSY; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | return vpif_set_output(config, ch, i); | 862 | return vpif_set_output(config, ch, i); |
| 1345 | } | 863 | } |
| 1346 | 864 | ||
| 1347 | static int vpif_g_output(struct file *file, void *priv, unsigned int *i) | 865 | static int vpif_g_output(struct file *file, void *priv, unsigned int *i) |
| 1348 | { | 866 | { |
| 1349 | struct vpif_fh *fh = priv; | 867 | struct video_device *vdev = video_devdata(file); |
| 1350 | struct channel_obj *ch = fh->channel; | 868 | struct channel_obj *ch = video_get_drvdata(vdev); |
| 1351 | 869 | ||
| 1352 | *i = ch->output_idx; | 870 | *i = ch->output_idx; |
| 1353 | 871 | ||
| 1354 | return 0; | 872 | return 0; |
| 1355 | } | 873 | } |
| 1356 | 874 | ||
| 1357 | static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p) | ||
| 1358 | { | ||
| 1359 | struct vpif_fh *fh = priv; | ||
| 1360 | struct channel_obj *ch = fh->channel; | ||
| 1361 | |||
| 1362 | *p = v4l2_prio_max(&ch->prio); | ||
| 1363 | |||
| 1364 | return 0; | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p) | ||
| 1368 | { | ||
| 1369 | struct vpif_fh *fh = priv; | ||
| 1370 | struct channel_obj *ch = fh->channel; | ||
| 1371 | |||
| 1372 | return v4l2_prio_change(&ch->prio, &fh->prio, p); | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | /** | 875 | /** |
| 1376 | * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler | 876 | * vpif_enum_dv_timings() - ENUM_DV_TIMINGS handler |
| 1377 | * @file: file ptr | 877 | * @file: file ptr |
| @@ -1382,11 +882,24 @@ static int | |||
| 1382 | vpif_enum_dv_timings(struct file *file, void *priv, | 882 | vpif_enum_dv_timings(struct file *file, void *priv, |
| 1383 | struct v4l2_enum_dv_timings *timings) | 883 | struct v4l2_enum_dv_timings *timings) |
| 1384 | { | 884 | { |
| 1385 | struct vpif_fh *fh = priv; | 885 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 1386 | struct channel_obj *ch = fh->channel; | 886 | struct video_device *vdev = video_devdata(file); |
| 887 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 888 | struct vpif_display_chan_config *chan_cfg; | ||
| 889 | struct v4l2_output output; | ||
| 1387 | int ret; | 890 | int ret; |
| 1388 | 891 | ||
| 1389 | ret = v4l2_subdev_call(ch->sd, video, enum_dv_timings, timings); | 892 | if (config->chan_config[ch->channel_id].outputs == NULL) |
| 893 | return -ENODATA; | ||
| 894 | |||
| 895 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 896 | output = chan_cfg->outputs[ch->output_idx].output; | ||
| 897 | if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS) | ||
| 898 | return -ENODATA; | ||
| 899 | |||
| 900 | timings->pad = 0; | ||
| 901 | |||
| 902 | ret = v4l2_subdev_call(ch->sd, pad, enum_dv_timings, timings); | ||
| 1390 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) | 903 | if (ret == -ENOIOCTLCMD || ret == -ENODEV) |
| 1391 | return -EINVAL; | 904 | return -EINVAL; |
| 1392 | return ret; | 905 | return ret; |
| @@ -1401,14 +914,29 @@ vpif_enum_dv_timings(struct file *file, void *priv, | |||
| 1401 | static int vpif_s_dv_timings(struct file *file, void *priv, | 914 | static int vpif_s_dv_timings(struct file *file, void *priv, |
| 1402 | struct v4l2_dv_timings *timings) | 915 | struct v4l2_dv_timings *timings) |
| 1403 | { | 916 | { |
| 1404 | struct vpif_fh *fh = priv; | 917 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 1405 | struct channel_obj *ch = fh->channel; | 918 | struct video_device *vdev = video_devdata(file); |
| 919 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1406 | struct vpif_params *vpifparams = &ch->vpifparams; | 920 | struct vpif_params *vpifparams = &ch->vpifparams; |
| 921 | struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; | ||
| 1407 | struct vpif_channel_config_params *std_info = &vpifparams->std_info; | 922 | struct vpif_channel_config_params *std_info = &vpifparams->std_info; |
| 1408 | struct video_obj *vid_ch = &ch->video; | 923 | struct video_obj *vid_ch = &ch->video; |
| 1409 | struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt; | 924 | struct v4l2_bt_timings *bt = &vid_ch->dv_timings.bt; |
| 925 | struct vpif_display_chan_config *chan_cfg; | ||
| 926 | struct v4l2_output output; | ||
| 1410 | int ret; | 927 | int ret; |
| 1411 | 928 | ||
| 929 | if (config->chan_config[ch->channel_id].outputs == NULL) | ||
| 930 | return -ENODATA; | ||
| 931 | |||
| 932 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 933 | output = chan_cfg->outputs[ch->output_idx].output; | ||
| 934 | if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS) | ||
| 935 | return -ENODATA; | ||
| 936 | |||
| 937 | if (vb2_is_busy(&common->buffer_queue)) | ||
| 938 | return -EBUSY; | ||
| 939 | |||
| 1412 | if (timings->type != V4L2_DV_BT_656_1120) { | 940 | if (timings->type != V4L2_DV_BT_656_1120) { |
| 1413 | vpif_dbg(2, debug, "Timing type not defined\n"); | 941 | vpif_dbg(2, debug, "Timing type not defined\n"); |
| 1414 | return -EINVAL; | 942 | return -EINVAL; |
| @@ -1490,13 +1018,27 @@ static int vpif_s_dv_timings(struct file *file, void *priv, | |||
| 1490 | static int vpif_g_dv_timings(struct file *file, void *priv, | 1018 | static int vpif_g_dv_timings(struct file *file, void *priv, |
| 1491 | struct v4l2_dv_timings *timings) | 1019 | struct v4l2_dv_timings *timings) |
| 1492 | { | 1020 | { |
| 1493 | struct vpif_fh *fh = priv; | 1021 | struct vpif_display_config *config = vpif_dev->platform_data; |
| 1494 | struct channel_obj *ch = fh->channel; | 1022 | struct video_device *vdev = video_devdata(file); |
| 1023 | struct channel_obj *ch = video_get_drvdata(vdev); | ||
| 1024 | struct vpif_display_chan_config *chan_cfg; | ||
| 1495 | struct video_obj *vid_ch = &ch->video; | 1025 | struct video_obj *vid_ch = &ch->video; |
| 1026 | struct v4l2_output output; | ||
| 1027 | |||
| 1028 | if (config->chan_config[ch->channel_id].outputs == NULL) | ||
| 1029 | goto error; | ||
| 1030 | |||
| 1031 | chan_cfg = &config->chan_config[ch->channel_id]; | ||
| 1032 | output = chan_cfg->outputs[ch->output_idx].output; | ||
| 1033 | |||
| 1034 | if (output.capabilities != V4L2_OUT_CAP_DV_TIMINGS) | ||
| 1035 | goto error; | ||
| 1496 | 1036 | ||
| 1497 | *timings = vid_ch->dv_timings; | 1037 | *timings = vid_ch->dv_timings; |
| 1498 | 1038 | ||
| 1499 | return 0; | 1039 | return 0; |
| 1040 | error: | ||
| 1041 | return -ENODATA; | ||
| 1500 | } | 1042 | } |
| 1501 | 1043 | ||
| 1502 | /* | 1044 | /* |
| @@ -1516,83 +1058,49 @@ static int vpif_log_status(struct file *filep, void *priv) | |||
| 1516 | 1058 | ||
| 1517 | /* vpif display ioctl operations */ | 1059 | /* vpif display ioctl operations */ |
| 1518 | static const struct v4l2_ioctl_ops vpif_ioctl_ops = { | 1060 | static const struct v4l2_ioctl_ops vpif_ioctl_ops = { |
| 1519 | .vidioc_querycap = vpif_querycap, | 1061 | .vidioc_querycap = vpif_querycap, |
| 1520 | .vidioc_g_priority = vpif_g_priority, | ||
| 1521 | .vidioc_s_priority = vpif_s_priority, | ||
| 1522 | .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out, | 1062 | .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out, |
| 1523 | .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out, | 1063 | .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out, |
| 1524 | .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out, | 1064 | .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out, |
| 1525 | .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out, | 1065 | .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out, |
| 1526 | .vidioc_reqbufs = vpif_reqbufs, | 1066 | |
| 1527 | .vidioc_querybuf = vpif_querybuf, | 1067 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
| 1528 | .vidioc_qbuf = vpif_qbuf, | 1068 | .vidioc_create_bufs = vb2_ioctl_create_bufs, |
| 1529 | .vidioc_dqbuf = vpif_dqbuf, | 1069 | .vidioc_querybuf = vb2_ioctl_querybuf, |
| 1530 | .vidioc_streamon = vpif_streamon, | 1070 | .vidioc_qbuf = vb2_ioctl_qbuf, |
| 1531 | .vidioc_streamoff = vpif_streamoff, | 1071 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
| 1532 | .vidioc_s_std = vpif_s_std, | 1072 | .vidioc_expbuf = vb2_ioctl_expbuf, |
| 1073 | .vidioc_streamon = vb2_ioctl_streamon, | ||
| 1074 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
| 1075 | |||
| 1076 | .vidioc_s_std = vpif_s_std, | ||
| 1533 | .vidioc_g_std = vpif_g_std, | 1077 | .vidioc_g_std = vpif_g_std, |
| 1078 | |||
| 1534 | .vidioc_enum_output = vpif_enum_output, | 1079 | .vidioc_enum_output = vpif_enum_output, |
| 1535 | .vidioc_s_output = vpif_s_output, | 1080 | .vidioc_s_output = vpif_s_output, |
| 1536 | .vidioc_g_output = vpif_g_output, | 1081 | .vidioc_g_output = vpif_g_output, |
| 1537 | .vidioc_cropcap = vpif_cropcap, | 1082 | |
| 1538 | .vidioc_enum_dv_timings = vpif_enum_dv_timings, | 1083 | .vidioc_enum_dv_timings = vpif_enum_dv_timings, |
| 1539 | .vidioc_s_dv_timings = vpif_s_dv_timings, | 1084 | .vidioc_s_dv_timings = vpif_s_dv_timings, |
| 1540 | .vidioc_g_dv_timings = vpif_g_dv_timings, | 1085 | .vidioc_g_dv_timings = vpif_g_dv_timings, |
| 1086 | |||
| 1541 | .vidioc_log_status = vpif_log_status, | 1087 | .vidioc_log_status = vpif_log_status, |
| 1542 | }; | 1088 | }; |
| 1543 | 1089 | ||
| 1544 | static const struct v4l2_file_operations vpif_fops = { | 1090 | static const struct v4l2_file_operations vpif_fops = { |
| 1545 | .owner = THIS_MODULE, | 1091 | .owner = THIS_MODULE, |
| 1546 | .open = vpif_open, | 1092 | .open = v4l2_fh_open, |
| 1547 | .release = vpif_release, | 1093 | .release = vb2_fop_release, |
| 1548 | .unlocked_ioctl = video_ioctl2, | 1094 | .unlocked_ioctl = video_ioctl2, |
| 1549 | .mmap = vpif_mmap, | 1095 | .mmap = vb2_fop_mmap, |
| 1550 | .poll = vpif_poll | 1096 | .poll = vb2_fop_poll |
| 1551 | }; | ||
| 1552 | |||
| 1553 | static struct video_device vpif_video_template = { | ||
| 1554 | .name = "vpif", | ||
| 1555 | .fops = &vpif_fops, | ||
| 1556 | .ioctl_ops = &vpif_ioctl_ops, | ||
| 1557 | }; | 1097 | }; |
| 1558 | 1098 | ||
| 1559 | /*Configure the channels, buffer sizei, request irq */ | 1099 | /*Configure the channels, buffer sizei, request irq */ |
| 1560 | static int initialize_vpif(void) | 1100 | static int initialize_vpif(void) |
| 1561 | { | 1101 | { |
| 1562 | int free_channel_objects_index; | 1102 | int free_channel_objects_index; |
| 1563 | int free_buffer_channel_index; | 1103 | int err, i, j; |
| 1564 | int free_buffer_index; | ||
| 1565 | int err = 0, i, j; | ||
| 1566 | |||
| 1567 | /* Default number of buffers should be 3 */ | ||
| 1568 | if ((ch2_numbuffers > 0) && | ||
| 1569 | (ch2_numbuffers < config_params.min_numbuffers)) | ||
| 1570 | ch2_numbuffers = config_params.min_numbuffers; | ||
| 1571 | if ((ch3_numbuffers > 0) && | ||
| 1572 | (ch3_numbuffers < config_params.min_numbuffers)) | ||
| 1573 | ch3_numbuffers = config_params.min_numbuffers; | ||
| 1574 | |||
| 1575 | /* Set buffer size to min buffers size if invalid buffer size is | ||
| 1576 | * given */ | ||
| 1577 | if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO]) | ||
| 1578 | ch2_bufsize = | ||
| 1579 | config_params.min_bufsize[VPIF_CHANNEL2_VIDEO]; | ||
| 1580 | if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO]) | ||
| 1581 | ch3_bufsize = | ||
| 1582 | config_params.min_bufsize[VPIF_CHANNEL3_VIDEO]; | ||
| 1583 | |||
| 1584 | config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers; | ||
| 1585 | |||
| 1586 | if (ch2_numbuffers) { | ||
| 1587 | config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] = | ||
| 1588 | ch2_bufsize; | ||
| 1589 | } | ||
| 1590 | config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers; | ||
| 1591 | |||
| 1592 | if (ch3_numbuffers) { | ||
| 1593 | config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] = | ||
| 1594 | ch3_bufsize; | ||
| 1595 | } | ||
| 1596 | 1104 | ||
| 1597 | /* Allocate memory for six channel objects */ | 1105 | /* Allocate memory for six channel objects */ |
| 1598 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { | 1106 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { |
| @@ -1606,10 +1114,6 @@ static int initialize_vpif(void) | |||
| 1606 | } | 1114 | } |
| 1607 | } | 1115 | } |
| 1608 | 1116 | ||
| 1609 | free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES; | ||
| 1610 | free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS; | ||
| 1611 | free_buffer_index = config_params.numbuffers[i - 1]; | ||
| 1612 | |||
| 1613 | return 0; | 1117 | return 0; |
| 1614 | 1118 | ||
| 1615 | vpif_init_free_channel_objects: | 1119 | vpif_init_free_channel_objects: |
| @@ -1638,21 +1142,18 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier, | |||
| 1638 | static int vpif_probe_complete(void) | 1142 | static int vpif_probe_complete(void) |
| 1639 | { | 1143 | { |
| 1640 | struct common_obj *common; | 1144 | struct common_obj *common; |
| 1145 | struct video_device *vdev; | ||
| 1641 | struct channel_obj *ch; | 1146 | struct channel_obj *ch; |
| 1147 | struct vb2_queue *q; | ||
| 1642 | int j, err, k; | 1148 | int j, err, k; |
| 1643 | 1149 | ||
| 1644 | for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) { | 1150 | for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) { |
| 1645 | ch = vpif_obj.dev[j]; | 1151 | ch = vpif_obj.dev[j]; |
| 1646 | /* Initialize field of the channel objects */ | 1152 | /* Initialize field of the channel objects */ |
| 1647 | atomic_set(&ch->usrs, 0); | ||
| 1648 | for (k = 0; k < VPIF_NUMOBJECTS; k++) { | 1153 | for (k = 0; k < VPIF_NUMOBJECTS; k++) { |
| 1649 | ch->common[k].numbuffers = 0; | ||
| 1650 | common = &ch->common[k]; | 1154 | common = &ch->common[k]; |
| 1651 | common->io_usrs = 0; | ||
| 1652 | common->started = 0; | ||
| 1653 | spin_lock_init(&common->irqlock); | 1155 | spin_lock_init(&common->irqlock); |
| 1654 | mutex_init(&common->lock); | 1156 | mutex_init(&common->lock); |
| 1655 | common->numbuffers = 0; | ||
| 1656 | common->set_addr = NULL; | 1157 | common->set_addr = NULL; |
| 1657 | common->ytop_off = 0; | 1158 | common->ytop_off = 0; |
| 1658 | common->ybtm_off = 0; | 1159 | common->ybtm_off = 0; |
| @@ -1661,38 +1162,71 @@ static int vpif_probe_complete(void) | |||
| 1661 | common->cur_frm = NULL; | 1162 | common->cur_frm = NULL; |
| 1662 | common->next_frm = NULL; | 1163 | common->next_frm = NULL; |
| 1663 | memset(&common->fmt, 0, sizeof(common->fmt)); | 1164 | memset(&common->fmt, 0, sizeof(common->fmt)); |
| 1664 | common->numbuffers = config_params.numbuffers[k]; | ||
| 1665 | } | 1165 | } |
| 1666 | ch->initialized = 0; | 1166 | ch->initialized = 0; |
| 1667 | if (vpif_obj.config->subdev_count) | 1167 | if (vpif_obj.config->subdev_count) |
| 1668 | ch->sd = vpif_obj.sd[0]; | 1168 | ch->sd = vpif_obj.sd[0]; |
| 1669 | ch->channel_id = j; | 1169 | ch->channel_id = j; |
| 1670 | if (j < 2) | ||
| 1671 | ch->common[VPIF_VIDEO_INDEX].numbuffers = | ||
| 1672 | config_params.numbuffers[ch->channel_id]; | ||
| 1673 | else | ||
| 1674 | ch->common[VPIF_VIDEO_INDEX].numbuffers = 0; | ||
| 1675 | 1170 | ||
| 1676 | memset(&ch->vpifparams, 0, sizeof(ch->vpifparams)); | 1171 | memset(&ch->vpifparams, 0, sizeof(ch->vpifparams)); |
| 1677 | 1172 | ||
| 1678 | /* Initialize prio member of channel object */ | ||
| 1679 | v4l2_prio_init(&ch->prio); | ||
| 1680 | ch->common[VPIF_VIDEO_INDEX].fmt.type = | 1173 | ch->common[VPIF_VIDEO_INDEX].fmt.type = |
| 1681 | V4L2_BUF_TYPE_VIDEO_OUTPUT; | 1174 | V4L2_BUF_TYPE_VIDEO_OUTPUT; |
| 1682 | ch->video_dev->lock = &common->lock; | ||
| 1683 | video_set_drvdata(ch->video_dev, ch); | ||
| 1684 | 1175 | ||
| 1685 | /* select output 0 */ | 1176 | /* select output 0 */ |
| 1686 | err = vpif_set_output(vpif_obj.config, ch, 0); | 1177 | err = vpif_set_output(vpif_obj.config, ch, 0); |
| 1687 | if (err) | 1178 | if (err) |
| 1688 | goto probe_out; | 1179 | goto probe_out; |
| 1689 | 1180 | ||
| 1181 | /* set initial format */ | ||
| 1182 | ch->video.stdid = V4L2_STD_525_60; | ||
| 1183 | memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings)); | ||
| 1184 | vpif_update_resolution(ch); | ||
| 1185 | |||
| 1186 | /* Initialize vb2 queue */ | ||
| 1187 | q = &common->buffer_queue; | ||
| 1188 | q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 1189 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; | ||
| 1190 | q->drv_priv = ch; | ||
| 1191 | q->ops = &video_qops; | ||
| 1192 | q->mem_ops = &vb2_dma_contig_memops; | ||
| 1193 | q->buf_struct_size = sizeof(struct vpif_disp_buffer); | ||
| 1194 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 1195 | q->min_buffers_needed = 1; | ||
| 1196 | q->lock = &common->lock; | ||
| 1197 | err = vb2_queue_init(q); | ||
| 1198 | if (err) { | ||
| 1199 | vpif_err("vpif_display: vb2_queue_init() failed\n"); | ||
| 1200 | goto probe_out; | ||
| 1201 | } | ||
| 1202 | |||
| 1203 | common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev); | ||
| 1204 | if (IS_ERR(common->alloc_ctx)) { | ||
| 1205 | vpif_err("Failed to get the context\n"); | ||
| 1206 | err = PTR_ERR(common->alloc_ctx); | ||
| 1207 | goto probe_out; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | INIT_LIST_HEAD(&common->dma_queue); | ||
| 1211 | |||
| 1690 | /* register video device */ | 1212 | /* register video device */ |
| 1691 | vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", | 1213 | vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", |
| 1692 | (int)ch, (int)&ch->video_dev); | 1214 | (int)ch, (int)&ch->video_dev); |
| 1693 | 1215 | ||
| 1694 | err = video_register_device(ch->video_dev, | 1216 | /* Initialize the video_device structure */ |
| 1695 | VFL_TYPE_GRABBER, (j ? 3 : 2)); | 1217 | vdev = ch->video_dev; |
| 1218 | strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); | ||
| 1219 | vdev->release = video_device_release; | ||
| 1220 | vdev->fops = &vpif_fops; | ||
| 1221 | vdev->ioctl_ops = &vpif_ioctl_ops; | ||
| 1222 | vdev->v4l2_dev = &vpif_obj.v4l2_dev; | ||
| 1223 | vdev->vfl_dir = VFL_DIR_TX; | ||
| 1224 | vdev->queue = q; | ||
| 1225 | vdev->lock = &common->lock; | ||
| 1226 | set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); | ||
| 1227 | video_set_drvdata(ch->video_dev, ch); | ||
| 1228 | err = video_register_device(vdev, VFL_TYPE_GRABBER, | ||
| 1229 | (j ? 3 : 2)); | ||
| 1696 | if (err < 0) | 1230 | if (err < 0) |
| 1697 | goto probe_out; | 1231 | goto probe_out; |
| 1698 | } | 1232 | } |
| @@ -1702,6 +1236,8 @@ static int vpif_probe_complete(void) | |||
| 1702 | probe_out: | 1236 | probe_out: |
| 1703 | for (k = 0; k < j; k++) { | 1237 | for (k = 0; k < j; k++) { |
| 1704 | ch = vpif_obj.dev[k]; | 1238 | ch = vpif_obj.dev[k]; |
| 1239 | common = &ch->common[k]; | ||
| 1240 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 1705 | video_unregister_device(ch->video_dev); | 1241 | video_unregister_device(ch->video_dev); |
| 1706 | video_device_release(ch->video_dev); | 1242 | video_device_release(ch->video_dev); |
| 1707 | ch->video_dev = NULL; | 1243 | ch->video_dev = NULL; |
| @@ -1728,7 +1264,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
| 1728 | struct video_device *vfd; | 1264 | struct video_device *vfd; |
| 1729 | struct resource *res; | 1265 | struct resource *res; |
| 1730 | int subdev_count; | 1266 | int subdev_count; |
| 1731 | size_t size; | ||
| 1732 | 1267 | ||
| 1733 | vpif_dev = &pdev->dev; | 1268 | vpif_dev = &pdev->dev; |
| 1734 | err = initialize_vpif(); | 1269 | err = initialize_vpif(); |
| @@ -1746,7 +1281,7 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
| 1746 | 1281 | ||
| 1747 | while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) { | 1282 | while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) { |
| 1748 | err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr, | 1283 | err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr, |
| 1749 | IRQF_SHARED, "VPIF_Display", | 1284 | IRQF_SHARED, VPIF_DRIVER_NAME, |
| 1750 | (void *)(&vpif_obj.dev[res_idx]-> | 1285 | (void *)(&vpif_obj.dev[res_idx]-> |
| 1751 | channel_id)); | 1286 | channel_id)); |
| 1752 | if (err) { | 1287 | if (err) { |
| @@ -1772,36 +1307,10 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
| 1772 | goto vpif_unregister; | 1307 | goto vpif_unregister; |
| 1773 | } | 1308 | } |
| 1774 | 1309 | ||
| 1775 | /* Initialize field of video device */ | ||
| 1776 | *vfd = vpif_video_template; | ||
| 1777 | vfd->v4l2_dev = &vpif_obj.v4l2_dev; | ||
| 1778 | vfd->release = video_device_release; | ||
| 1779 | vfd->vfl_dir = VFL_DIR_TX; | ||
| 1780 | snprintf(vfd->name, sizeof(vfd->name), | ||
| 1781 | "VPIF_Display_DRIVER_V%s", | ||
| 1782 | VPIF_DISPLAY_VERSION); | ||
| 1783 | |||
| 1784 | /* Set video_dev to the video device */ | 1310 | /* Set video_dev to the video device */ |
| 1785 | ch->video_dev = vfd; | 1311 | ch->video_dev = vfd; |
| 1786 | } | 1312 | } |
| 1787 | 1313 | ||
| 1788 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 1789 | if (res) { | ||
| 1790 | size = resource_size(res); | ||
| 1791 | /* The resources are divided into two equal memory and when | ||
| 1792 | * we have HD output we can add them together | ||
| 1793 | */ | ||
| 1794 | for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) { | ||
| 1795 | ch = vpif_obj.dev[j]; | ||
| 1796 | ch->channel_id = j; | ||
| 1797 | |||
| 1798 | /* only enabled if second resource exists */ | ||
| 1799 | config_params.video_limit[ch->channel_id] = 0; | ||
| 1800 | if (size) | ||
| 1801 | config_params.video_limit[ch->channel_id] = | ||
| 1802 | size/2; | ||
| 1803 | } | ||
| 1804 | } | ||
| 1805 | vpif_obj.config = pdev->dev.platform_data; | 1314 | vpif_obj.config = pdev->dev.platform_data; |
| 1806 | subdev_count = vpif_obj.config->subdev_count; | 1315 | subdev_count = vpif_obj.config->subdev_count; |
| 1807 | subdevdata = vpif_obj.config->subdevinfo; | 1316 | subdevdata = vpif_obj.config->subdevinfo; |
| @@ -1867,6 +1376,7 @@ vpif_unregister: | |||
| 1867 | */ | 1376 | */ |
| 1868 | static int vpif_remove(struct platform_device *device) | 1377 | static int vpif_remove(struct platform_device *device) |
| 1869 | { | 1378 | { |
| 1379 | struct common_obj *common; | ||
| 1870 | struct channel_obj *ch; | 1380 | struct channel_obj *ch; |
| 1871 | int i; | 1381 | int i; |
| 1872 | 1382 | ||
| @@ -1877,6 +1387,8 @@ static int vpif_remove(struct platform_device *device) | |||
| 1877 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { | 1387 | for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { |
| 1878 | /* Get the pointer to the channel object */ | 1388 | /* Get the pointer to the channel object */ |
| 1879 | ch = vpif_obj.dev[i]; | 1389 | ch = vpif_obj.dev[i]; |
| 1390 | common = &ch->common[i]; | ||
| 1391 | vb2_dma_contig_cleanup_ctx(common->alloc_ctx); | ||
| 1880 | /* Unregister video device */ | 1392 | /* Unregister video device */ |
| 1881 | video_unregister_device(ch->video_dev); | 1393 | video_unregister_device(ch->video_dev); |
| 1882 | 1394 | ||
| @@ -1887,7 +1399,7 @@ static int vpif_remove(struct platform_device *device) | |||
| 1887 | return 0; | 1399 | return 0; |
| 1888 | } | 1400 | } |
| 1889 | 1401 | ||
| 1890 | #ifdef CONFIG_PM | 1402 | #ifdef CONFIG_PM_SLEEP |
| 1891 | static int vpif_suspend(struct device *dev) | 1403 | static int vpif_suspend(struct device *dev) |
| 1892 | { | 1404 | { |
| 1893 | struct common_obj *common; | 1405 | struct common_obj *common; |
| @@ -1898,18 +1410,20 @@ static int vpif_suspend(struct device *dev) | |||
| 1898 | /* Get the pointer to the channel object */ | 1410 | /* Get the pointer to the channel object */ |
| 1899 | ch = vpif_obj.dev[i]; | 1411 | ch = vpif_obj.dev[i]; |
| 1900 | common = &ch->common[VPIF_VIDEO_INDEX]; | 1412 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1413 | |||
| 1414 | if (!vb2_is_streaming(&common->buffer_queue)) | ||
| 1415 | continue; | ||
| 1416 | |||
| 1901 | mutex_lock(&common->lock); | 1417 | mutex_lock(&common->lock); |
| 1902 | if (atomic_read(&ch->usrs) && common->io_usrs) { | 1418 | /* Disable channel */ |
| 1903 | /* Disable channel */ | 1419 | if (ch->channel_id == VPIF_CHANNEL2_VIDEO) { |
| 1904 | if (ch->channel_id == VPIF_CHANNEL2_VIDEO) { | 1420 | enable_channel2(0); |
| 1905 | enable_channel2(0); | 1421 | channel2_intr_enable(0); |
| 1906 | channel2_intr_enable(0); | 1422 | } |
| 1907 | } | 1423 | if (ch->channel_id == VPIF_CHANNEL3_VIDEO || |
| 1908 | if (ch->channel_id == VPIF_CHANNEL3_VIDEO || | 1424 | ycmux_mode == 2) { |
| 1909 | common->started == 2) { | 1425 | enable_channel3(0); |
| 1910 | enable_channel3(0); | 1426 | channel3_intr_enable(0); |
| 1911 | channel3_intr_enable(0); | ||
| 1912 | } | ||
| 1913 | } | 1427 | } |
| 1914 | mutex_unlock(&common->lock); | 1428 | mutex_unlock(&common->lock); |
| 1915 | } | 1429 | } |
| @@ -1928,18 +1442,20 @@ static int vpif_resume(struct device *dev) | |||
| 1928 | /* Get the pointer to the channel object */ | 1442 | /* Get the pointer to the channel object */ |
| 1929 | ch = vpif_obj.dev[i]; | 1443 | ch = vpif_obj.dev[i]; |
| 1930 | common = &ch->common[VPIF_VIDEO_INDEX]; | 1444 | common = &ch->common[VPIF_VIDEO_INDEX]; |
| 1445 | |||
| 1446 | if (!vb2_is_streaming(&common->buffer_queue)) | ||
| 1447 | continue; | ||
| 1448 | |||
| 1931 | mutex_lock(&common->lock); | 1449 | mutex_lock(&common->lock); |
| 1932 | if (atomic_read(&ch->usrs) && common->io_usrs) { | 1450 | /* Enable channel */ |
| 1933 | /* Enable channel */ | 1451 | if (ch->channel_id == VPIF_CHANNEL2_VIDEO) { |
| 1934 | if (ch->channel_id == VPIF_CHANNEL2_VIDEO) { | 1452 | enable_channel2(1); |
| 1935 | enable_channel2(1); | 1453 | channel2_intr_enable(1); |
| 1936 | channel2_intr_enable(1); | 1454 | } |
| 1937 | } | 1455 | if (ch->channel_id == VPIF_CHANNEL3_VIDEO || |
| 1938 | if (ch->channel_id == VPIF_CHANNEL3_VIDEO || | 1456 | ycmux_mode == 2) { |
| 1939 | common->started == 2) { | 1457 | enable_channel3(1); |
| 1940 | enable_channel3(1); | 1458 | channel3_intr_enable(1); |
| 1941 | channel3_intr_enable(1); | ||
| 1942 | } | ||
| 1943 | } | 1459 | } |
| 1944 | mutex_unlock(&common->lock); | 1460 | mutex_unlock(&common->lock); |
| 1945 | } | 1461 | } |
| @@ -1947,21 +1463,15 @@ static int vpif_resume(struct device *dev) | |||
| 1947 | return 0; | 1463 | return 0; |
| 1948 | } | 1464 | } |
| 1949 | 1465 | ||
| 1950 | static const struct dev_pm_ops vpif_pm = { | ||
| 1951 | .suspend = vpif_suspend, | ||
| 1952 | .resume = vpif_resume, | ||
| 1953 | }; | ||
| 1954 | |||
| 1955 | #define vpif_pm_ops (&vpif_pm) | ||
| 1956 | #else | ||
| 1957 | #define vpif_pm_ops NULL | ||
| 1958 | #endif | 1466 | #endif |
| 1959 | 1467 | ||
| 1468 | static SIMPLE_DEV_PM_OPS(vpif_pm_ops, vpif_suspend, vpif_resume); | ||
| 1469 | |||
| 1960 | static __refdata struct platform_driver vpif_driver = { | 1470 | static __refdata struct platform_driver vpif_driver = { |
| 1961 | .driver = { | 1471 | .driver = { |
| 1962 | .name = "vpif_display", | 1472 | .name = VPIF_DRIVER_NAME, |
| 1963 | .owner = THIS_MODULE, | 1473 | .owner = THIS_MODULE, |
| 1964 | .pm = vpif_pm_ops, | 1474 | .pm = &vpif_pm_ops, |
| 1965 | }, | 1475 | }, |
| 1966 | .probe = vpif_probe, | 1476 | .probe = vpif_probe, |
| 1967 | .remove = vpif_remove, | 1477 | .remove = vpif_remove, |
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h index 4d0485b99a80..7b21a7607674 100644 --- a/drivers/media/platform/davinci/vpif_display.h +++ b/drivers/media/platform/davinci/vpif_display.h | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #ifndef DAVINCIHD_DISPLAY_H | 16 | #ifndef VPIF_DISPLAY_H |
| 17 | #define DAVINCIHD_DISPLAY_H | 17 | #define VPIF_DISPLAY_H |
| 18 | 18 | ||
| 19 | /* Header files */ | 19 | /* Header files */ |
| 20 | #include <media/videobuf2-dma-contig.h> | 20 | #include <media/videobuf2-dma-contig.h> |
| @@ -67,17 +67,10 @@ struct vpif_disp_buffer { | |||
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | struct common_obj { | 69 | struct common_obj { |
| 70 | /* Buffer specific parameters */ | ||
| 71 | u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for | ||
| 72 | * storing frames */ | ||
| 73 | u32 numbuffers; /* number of buffers */ | ||
| 74 | struct vpif_disp_buffer *cur_frm; /* Pointer pointing to current | 70 | struct vpif_disp_buffer *cur_frm; /* Pointer pointing to current |
| 75 | * vb2_buffer */ | 71 | * vb2_buffer */ |
| 76 | struct vpif_disp_buffer *next_frm; /* Pointer pointing to next | 72 | struct vpif_disp_buffer *next_frm; /* Pointer pointing to next |
| 77 | * vb2_buffer */ | 73 | * vb2_buffer */ |
| 78 | enum v4l2_memory memory; /* This field keeps track of | ||
| 79 | * type of buffer exchange | ||
| 80 | * method user has selected */ | ||
| 81 | struct v4l2_format fmt; /* Used to store the format */ | 74 | struct v4l2_format fmt; /* Used to store the format */ |
| 82 | struct vb2_queue buffer_queue; /* Buffer queue used in | 75 | struct vb2_queue buffer_queue; /* Buffer queue used in |
| 83 | * video-buf */ | 76 | * video-buf */ |
| @@ -90,10 +83,6 @@ struct common_obj { | |||
| 90 | /* channel specific parameters */ | 83 | /* channel specific parameters */ |
| 91 | struct mutex lock; /* lock used to access this | 84 | struct mutex lock; /* lock used to access this |
| 92 | * structure */ | 85 | * structure */ |
| 93 | u32 io_usrs; /* number of users performing | ||
| 94 | * IO */ | ||
| 95 | u8 started; /* Indicates whether streaming | ||
| 96 | * started */ | ||
| 97 | u32 ytop_off; /* offset of Y top from the | 86 | u32 ytop_off; /* offset of Y top from the |
| 98 | * starting of the buffer */ | 87 | * starting of the buffer */ |
| 99 | u32 ybtm_off; /* offset of Y bottom from the | 88 | u32 ybtm_off; /* offset of Y bottom from the |
| @@ -103,7 +92,7 @@ struct common_obj { | |||
| 103 | u32 cbtm_off; /* offset of C bottom from the | 92 | u32 cbtm_off; /* offset of C bottom from the |
| 104 | * starting of the buffer */ | 93 | * starting of the buffer */ |
| 105 | /* Function pointer to set the addresses */ | 94 | /* Function pointer to set the addresses */ |
| 106 | void (*set_addr) (unsigned long, unsigned long, | 95 | void (*set_addr)(unsigned long, unsigned long, |
| 107 | unsigned long, unsigned long); | 96 | unsigned long, unsigned long); |
| 108 | u32 height; | 97 | u32 height; |
| 109 | u32 width; | 98 | u32 width; |
| @@ -113,10 +102,6 @@ struct channel_obj { | |||
| 113 | /* V4l2 specific parameters */ | 102 | /* V4l2 specific parameters */ |
| 114 | struct video_device *video_dev; /* Identifies video device for | 103 | struct video_device *video_dev; /* Identifies video device for |
| 115 | * this channel */ | 104 | * this channel */ |
| 116 | struct v4l2_prio_state prio; /* Used to keep track of state of | ||
| 117 | * the priority */ | ||
| 118 | atomic_t usrs; /* number of open instances of | ||
| 119 | * the channel */ | ||
| 120 | u32 field_id; /* Indicates id of the field | 105 | u32 field_id; /* Indicates id of the field |
| 121 | * which is being displayed */ | 106 | * which is being displayed */ |
| 122 | u8 initialized; /* flag to indicate whether | 107 | u8 initialized; /* flag to indicate whether |
| @@ -130,19 +115,6 @@ struct channel_obj { | |||
| 130 | struct video_obj video; | 115 | struct video_obj video; |
| 131 | }; | 116 | }; |
| 132 | 117 | ||
| 133 | /* File handle structure */ | ||
| 134 | struct vpif_fh { | ||
| 135 | struct channel_obj *channel; /* pointer to channel object for | ||
| 136 | * opened device */ | ||
| 137 | u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle | ||
| 138 | * is doing IO */ | ||
| 139 | enum v4l2_priority prio; /* Used to keep track priority of | ||
| 140 | * this instance */ | ||
| 141 | u8 initialized; /* Used to keep track of whether this | ||
| 142 | * file handle has initialized | ||
| 143 | * channel or not */ | ||
| 144 | }; | ||
| 145 | |||
| 146 | /* vpif device structure */ | 118 | /* vpif device structure */ |
| 147 | struct vpif_device { | 119 | struct vpif_device { |
| 148 | struct v4l2_device v4l2_dev; | 120 | struct v4l2_device v4l2_dev; |
| @@ -152,12 +124,4 @@ struct vpif_device { | |||
| 152 | struct vpif_display_config *config; | 124 | struct vpif_display_config *config; |
| 153 | }; | 125 | }; |
| 154 | 126 | ||
| 155 | struct vpif_config_params { | 127 | #endif /* VPIF_DISPLAY_H */ |
| 156 | u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS]; | ||
| 157 | u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS]; | ||
| 158 | u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS]; | ||
| 159 | u32 video_limit[VPIF_DISPLAY_NUM_CHANNELS]; | ||
| 160 | u8 min_numbuffers; | ||
| 161 | }; | ||
| 162 | |||
| 163 | #endif /* DAVINCIHD_DISPLAY_H */ | ||
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index d0ea94f58d6f..e434f1f03d7b 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c | |||
| @@ -66,15 +66,13 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 66 | return ret > 0 ? 0 : ret; | 66 | return ret > 0 ? 0 : ret; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static int gsc_m2m_stop_streaming(struct vb2_queue *q) | 69 | static void gsc_m2m_stop_streaming(struct vb2_queue *q) |
| 70 | { | 70 | { |
| 71 | struct gsc_ctx *ctx = q->drv_priv; | 71 | struct gsc_ctx *ctx = q->drv_priv; |
| 72 | 72 | ||
| 73 | __gsc_m2m_job_abort(ctx); | 73 | __gsc_m2m_job_abort(ctx); |
| 74 | 74 | ||
| 75 | pm_runtime_put(&ctx->gsc_dev->pdev->dev); | 75 | pm_runtime_put(&ctx->gsc_dev->pdev->dev); |
| 76 | |||
| 77 | return 0; | ||
| 78 | } | 76 | } |
| 79 | 77 | ||
| 80 | void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state) | 78 | void gsc_m2m_job_finish(struct gsc_ctx *ctx, int vb_state) |
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index e1b2ceba00c1..5dcaa0a80540 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig | |||
| @@ -3,6 +3,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS | |||
| 3 | bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" | 3 | bool "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver" |
| 4 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 4 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 5 | depends on (PLAT_S5P || ARCH_EXYNOS) | 5 | depends on (PLAT_S5P || ARCH_EXYNOS) |
| 6 | depends on OF && COMMON_CLK | ||
| 6 | help | 7 | help |
| 7 | Say Y here to enable camera host interface devices for | 8 | Say Y here to enable camera host interface devices for |
| 8 | Samsung S5P and EXYNOS SoC series. | 9 | Samsung S5P and EXYNOS SoC series. |
| @@ -17,7 +18,7 @@ config VIDEO_S5P_FIMC | |||
| 17 | depends on I2C | 18 | depends on I2C |
| 18 | select VIDEOBUF2_DMA_CONTIG | 19 | select VIDEOBUF2_DMA_CONTIG |
| 19 | select V4L2_MEM2MEM_DEV | 20 | select V4L2_MEM2MEM_DEV |
| 20 | select MFD_SYSCON if OF | 21 | select MFD_SYSCON |
| 21 | select VIDEO_EXYNOS4_IS_COMMON | 22 | select VIDEO_EXYNOS4_IS_COMMON |
| 22 | help | 23 | help |
| 23 | This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host | 24 | This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host |
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c index 0ec210b4da1d..0eb34ecb8ee4 100644 --- a/drivers/media/platform/exynos4-is/common.c +++ b/drivers/media/platform/exynos4-is/common.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <media/s5p_fimc.h> | 13 | #include <media/exynos-fimc.h> |
| 14 | #include "common.h" | 14 | #include "common.h" |
| 15 | 15 | ||
| 16 | /* Called with the media graph mutex held or entity->stream_count > 0. */ | 16 | /* Called with the media graph mutex held or entity->stream_count > 0. */ |
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 92ae812abce2..3d2babd5067a 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c | |||
| @@ -294,15 +294,15 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 294 | return 0; | 294 | return 0; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | static int stop_streaming(struct vb2_queue *q) | 297 | static void stop_streaming(struct vb2_queue *q) |
| 298 | { | 298 | { |
| 299 | struct fimc_ctx *ctx = q->drv_priv; | 299 | struct fimc_ctx *ctx = q->drv_priv; |
| 300 | struct fimc_dev *fimc = ctx->fimc_dev; | 300 | struct fimc_dev *fimc = ctx->fimc_dev; |
| 301 | 301 | ||
| 302 | if (!fimc_capture_active(fimc)) | 302 | if (!fimc_capture_active(fimc)) |
| 303 | return -EINVAL; | 303 | return; |
| 304 | 304 | ||
| 305 | return fimc_stop_capture(fimc, false); | 305 | fimc_stop_capture(fimc, false); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | int fimc_capture_suspend(struct fimc_dev *fimc) | 308 | int fimc_capture_suspend(struct fimc_dev *fimc) |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index 25dbf5b05a96..b70fd996d794 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c | |||
| @@ -56,8 +56,8 @@ static struct fimc_fmt fimc_formats[] = { | |||
| 56 | .colplanes = 1, | 56 | .colplanes = 1, |
| 57 | .flags = FMT_FLAGS_M2M, | 57 | .flags = FMT_FLAGS_M2M, |
| 58 | }, { | 58 | }, { |
| 59 | .name = "ARGB8888, 32 bpp", | 59 | .name = "BGRA8888, 32 bpp", |
| 60 | .fourcc = V4L2_PIX_FMT_RGB32, | 60 | .fourcc = V4L2_PIX_FMT_BGR32, |
| 61 | .depth = { 32 }, | 61 | .depth = { 32 }, |
| 62 | .color = FIMC_FMT_RGB888, | 62 | .color = FIMC_FMT_RGB888, |
| 63 | .memplanes = 1, | 63 | .memplanes = 1, |
| @@ -450,7 +450,7 @@ void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) | |||
| 450 | bool pix_hoff = ctx->fimc_dev->drv_data->dma_pix_hoff; | 450 | bool pix_hoff = ctx->fimc_dev->drv_data->dma_pix_hoff; |
| 451 | u32 i, depth = 0; | 451 | u32 i, depth = 0; |
| 452 | 452 | ||
| 453 | for (i = 0; i < f->fmt->colplanes; i++) | 453 | for (i = 0; i < f->fmt->memplanes; i++) |
| 454 | depth += f->fmt->depth[i]; | 454 | depth += f->fmt->depth[i]; |
| 455 | 455 | ||
| 456 | f->dma_offset.y_h = f->offs_h; | 456 | f->dma_offset.y_h = f->offs_h; |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h index 1790fb4e32ea..6c75c6ced1f7 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.h +++ b/drivers/media/platform/exynos4-is/fimc-core.h | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <media/v4l2-device.h> | 27 | #include <media/v4l2-device.h> |
| 28 | #include <media/v4l2-mem2mem.h> | 28 | #include <media/v4l2-mem2mem.h> |
| 29 | #include <media/v4l2-mediabus.h> | 29 | #include <media/v4l2-mediabus.h> |
| 30 | #include <media/s5p_fimc.h> | 30 | #include <media/exynos-fimc.h> |
| 31 | 31 | ||
| 32 | #define dbg(fmt, args...) \ | 32 | #define dbg(fmt, args...) \ |
| 33 | pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args) | 33 | pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args) |
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 128b73b6cce2..5476dce3ad29 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c | |||
| @@ -367,6 +367,9 @@ static void fimc_is_free_cpu_memory(struct fimc_is *is) | |||
| 367 | { | 367 | { |
| 368 | struct device *dev = &is->pdev->dev; | 368 | struct device *dev = &is->pdev->dev; |
| 369 | 369 | ||
| 370 | if (is->memory.vaddr == NULL) | ||
| 371 | return; | ||
| 372 | |||
| 370 | dma_free_coherent(dev, is->memory.size, is->memory.vaddr, | 373 | dma_free_coherent(dev, is->memory.size, is->memory.vaddr, |
| 371 | is->memory.paddr); | 374 | is->memory.paddr); |
| 372 | } | 375 | } |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index e92b4e115adb..93f9cf2ebcd6 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <media/v4l2-ioctl.h> | 30 | #include <media/v4l2-ioctl.h> |
| 31 | #include <media/videobuf2-core.h> | 31 | #include <media/videobuf2-core.h> |
| 32 | #include <media/videobuf2-dma-contig.h> | 32 | #include <media/videobuf2-dma-contig.h> |
| 33 | #include <media/s5p_fimc.h> | 33 | #include <media/exynos-fimc.h> |
| 34 | 34 | ||
| 35 | #include "common.h" | 35 | #include "common.h" |
| 36 | #include "media-dev.h" | 36 | #include "media-dev.h" |
| @@ -125,7 +125,7 @@ static int isp_video_capture_start_streaming(struct vb2_queue *q, | |||
| 125 | return ret; | 125 | return ret; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static int isp_video_capture_stop_streaming(struct vb2_queue *q) | 128 | static void isp_video_capture_stop_streaming(struct vb2_queue *q) |
| 129 | { | 129 | { |
| 130 | struct fimc_isp *isp = vb2_get_drv_priv(q); | 130 | struct fimc_isp *isp = vb2_get_drv_priv(q); |
| 131 | struct fimc_is *is = fimc_isp_to_is(isp); | 131 | struct fimc_is *is = fimc_isp_to_is(isp); |
| @@ -134,7 +134,7 @@ static int isp_video_capture_stop_streaming(struct vb2_queue *q) | |||
| 134 | 134 | ||
| 135 | ret = fimc_pipeline_call(&isp->video_capture.ve, set_stream, 0); | 135 | ret = fimc_pipeline_call(&isp->video_capture.ve, set_stream, 0); |
| 136 | if (ret < 0) | 136 | if (ret < 0) |
| 137 | return ret; | 137 | return; |
| 138 | 138 | ||
| 139 | dma->cmd = DMA_OUTPUT_COMMAND_DISABLE; | 139 | dma->cmd = DMA_OUTPUT_COMMAND_DISABLE; |
| 140 | dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE; | 140 | dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE; |
| @@ -155,7 +155,6 @@ static int isp_video_capture_stop_streaming(struct vb2_queue *q) | |||
| 155 | clear_bit(ST_ISP_VID_CAP_STREAMING, &isp->state); | 155 | clear_bit(ST_ISP_VID_CAP_STREAMING, &isp->state); |
| 156 | 156 | ||
| 157 | isp->video_capture.buf_count = 0; | 157 | isp->video_capture.buf_count = 0; |
| 158 | return 0; | ||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb) | 160 | static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb) |
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h index 4dc55a18d978..b99be09b49fc 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.h +++ b/drivers/media/platform/exynos4-is/fimc-isp.h | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include <media/videobuf2-core.h> | 24 | #include <media/videobuf2-core.h> |
| 25 | #include <media/v4l2-device.h> | 25 | #include <media/v4l2-device.h> |
| 26 | #include <media/v4l2-mediabus.h> | 26 | #include <media/v4l2-mediabus.h> |
| 27 | #include <media/s5p_fimc.h> | 27 | #include <media/exynos-fimc.h> |
| 28 | 28 | ||
| 29 | extern int fimc_isp_debug; | 29 | extern int fimc_isp_debug; |
| 30 | 30 | ||
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c index d0dc7ee04452..bc3ec7d25a32 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c +++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
| 13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| 15 | #include <media/s5p_fimc.h> | 15 | #include <media/exynos-fimc.h> |
| 16 | 16 | ||
| 17 | #include "fimc-lite-reg.h" | 17 | #include "fimc-lite-reg.h" |
| 18 | #include "fimc-lite.h" | 18 | #include "fimc-lite.h" |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 3ad660b55b6b..a97d2352f1d7 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | #include <media/v4l2-mem2mem.h> | 30 | #include <media/v4l2-mem2mem.h> |
| 31 | #include <media/videobuf2-core.h> | 31 | #include <media/videobuf2-core.h> |
| 32 | #include <media/videobuf2-dma-contig.h> | 32 | #include <media/videobuf2-dma-contig.h> |
| 33 | #include <media/s5p_fimc.h> | 33 | #include <media/exynos-fimc.h> |
| 34 | 34 | ||
| 35 | #include "common.h" | 35 | #include "common.h" |
| 36 | #include "fimc-core.h" | 36 | #include "fimc-core.h" |
| @@ -350,14 +350,14 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 350 | return 0; | 350 | return 0; |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | static int stop_streaming(struct vb2_queue *q) | 353 | static void stop_streaming(struct vb2_queue *q) |
| 354 | { | 354 | { |
| 355 | struct fimc_lite *fimc = q->drv_priv; | 355 | struct fimc_lite *fimc = q->drv_priv; |
| 356 | 356 | ||
| 357 | if (!fimc_lite_active(fimc)) | 357 | if (!fimc_lite_active(fimc)) |
| 358 | return -EINVAL; | 358 | return; |
| 359 | 359 | ||
| 360 | return fimc_lite_stop_capture(fimc, false); | 360 | fimc_lite_stop_capture(fimc, false); |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, | 363 | static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h index 7428b2d22b52..ea19dc7be63e 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.h +++ b/drivers/media/platform/exynos4-is/fimc-lite.h | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include <media/v4l2-ctrls.h> | 23 | #include <media/v4l2-ctrls.h> |
| 24 | #include <media/v4l2-device.h> | 24 | #include <media/v4l2-device.h> |
| 25 | #include <media/v4l2-mediabus.h> | 25 | #include <media/v4l2-mediabus.h> |
| 26 | #include <media/s5p_fimc.h> | 26 | #include <media/exynos-fimc.h> |
| 27 | 27 | ||
| 28 | #define FIMC_LITE_DRV_NAME "exynos-fimc-lite" | 28 | #define FIMC_LITE_DRV_NAME "exynos-fimc-lite" |
| 29 | #define FLITE_CLK_NAME "flite" | 29 | #define FLITE_CLK_NAME "flite" |
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 36971d915b53..0ad1b6f84a27 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c | |||
| @@ -85,7 +85,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 85 | return ret > 0 ? 0 : ret; | 85 | return ret > 0 ? 0 : ret; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | static int stop_streaming(struct vb2_queue *q) | 88 | static void stop_streaming(struct vb2_queue *q) |
| 89 | { | 89 | { |
| 90 | struct fimc_ctx *ctx = q->drv_priv; | 90 | struct fimc_ctx *ctx = q->drv_priv; |
| 91 | int ret; | 91 | int ret; |
| @@ -95,7 +95,6 @@ static int stop_streaming(struct vb2_queue *q) | |||
| 95 | fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); | 95 | fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); |
| 96 | 96 | ||
| 97 | pm_runtime_put(&ctx->fimc_dev->pdev->dev); | 97 | pm_runtime_put(&ctx->fimc_dev->pdev->dev); |
| 98 | return 0; | ||
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | static void fimc_device_run(void *priv) | 100 | static void fimc_device_run(void *priv) |
| @@ -197,7 +196,7 @@ static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
| 197 | 196 | ||
| 198 | *num_planes = f->fmt->memplanes; | 197 | *num_planes = f->fmt->memplanes; |
| 199 | for (i = 0; i < f->fmt->memplanes; i++) { | 198 | for (i = 0; i < f->fmt->memplanes; i++) { |
| 200 | sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8; | 199 | sizes[i] = f->payload[i]; |
| 201 | allocators[i] = ctx->fimc_dev->alloc_ctx; | 200 | allocators[i] = ctx->fimc_dev->alloc_ctx; |
| 202 | } | 201 | } |
| 203 | return 0; | 202 | return 0; |
| @@ -342,7 +341,7 @@ static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt, | |||
| 342 | { | 341 | { |
| 343 | int i; | 342 | int i; |
| 344 | 343 | ||
| 345 | for (i = 0; i < fmt->colplanes; i++) { | 344 | for (i = 0; i < fmt->memplanes; i++) { |
| 346 | frame->bytesperline[i] = pixm->plane_fmt[i].bytesperline; | 345 | frame->bytesperline[i] = pixm->plane_fmt[i].bytesperline; |
| 347 | frame->payload[i] = pixm->plane_fmt[i].sizeimage; | 346 | frame->payload[i] = pixm->plane_fmt[i].sizeimage; |
| 348 | } | 347 | } |
| @@ -461,7 +460,7 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) | |||
| 461 | else | 460 | else |
| 462 | halign = ffs(fimc->variant->min_vsize_align) - 1; | 461 | halign = ffs(fimc->variant->min_vsize_align) - 1; |
| 463 | 462 | ||
| 464 | for (i = 0; i < f->fmt->colplanes; i++) | 463 | for (i = 0; i < f->fmt->memplanes; i++) |
| 465 | depth += f->fmt->depth[i]; | 464 | depth += f->fmt->depth[i]; |
| 466 | 465 | ||
| 467 | v4l_bound_align_image(&cr->c.width, min_size, f->o_width, | 466 | v4l_bound_align_image(&cr->c.width, min_size, f->o_width, |
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c index 1db8cb4c46ef..2d77fd8f440a 100644 --- a/drivers/media/platform/exynos4-is/fimc-reg.c +++ b/drivers/media/platform/exynos4-is/fimc-reg.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
| 14 | #include <linux/regmap.h> | 14 | #include <linux/regmap.h> |
| 15 | 15 | ||
| 16 | #include <media/s5p_fimc.h> | 16 | #include <media/exynos-fimc.h> |
| 17 | #include "media-dev.h" | 17 | #include "media-dev.h" |
| 18 | 18 | ||
| 19 | #include "fimc-reg.h" | 19 | #include "fimc-reg.h" |
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index e62211a80f0e..344718df5c62 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <media/v4l2-ctrls.h> | 31 | #include <media/v4l2-ctrls.h> |
| 32 | #include <media/v4l2-of.h> | 32 | #include <media/v4l2-of.h> |
| 33 | #include <media/media-device.h> | 33 | #include <media/media-device.h> |
| 34 | #include <media/s5p_fimc.h> | 34 | #include <media/exynos-fimc.h> |
| 35 | 35 | ||
| 36 | #include "media-dev.h" | 36 | #include "media-dev.h" |
| 37 | #include "fimc-core.h" | 37 | #include "fimc-core.h" |
| @@ -39,10 +39,6 @@ | |||
| 39 | #include "fimc-lite.h" | 39 | #include "fimc-lite.h" |
| 40 | #include "mipi-csis.h" | 40 | #include "mipi-csis.h" |
| 41 | 41 | ||
| 42 | static int __fimc_md_set_camclk(struct fimc_md *fmd, | ||
| 43 | struct fimc_source_info *si, | ||
| 44 | bool on); | ||
| 45 | |||
| 46 | /* Set up image sensor subdev -> FIMC capture node notifications. */ | 42 | /* Set up image sensor subdev -> FIMC capture node notifications. */ |
| 47 | static void __setup_sensor_notification(struct fimc_md *fmd, | 43 | static void __setup_sensor_notification(struct fimc_md *fmd, |
| 48 | struct v4l2_subdev *sensor, | 44 | struct v4l2_subdev *sensor, |
| @@ -223,17 +219,10 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, | |||
| 223 | return ret; | 219 | return ret; |
| 224 | } | 220 | } |
| 225 | 221 | ||
| 226 | ret = fimc_md_set_camclk(sd, true); | ||
| 227 | if (ret < 0) | ||
| 228 | goto err_wbclk; | ||
| 229 | |||
| 230 | ret = fimc_pipeline_s_power(p, 1); | 222 | ret = fimc_pipeline_s_power(p, 1); |
| 231 | if (!ret) | 223 | if (!ret) |
| 232 | return 0; | 224 | return 0; |
| 233 | 225 | ||
| 234 | fimc_md_set_camclk(sd, false); | ||
| 235 | |||
| 236 | err_wbclk: | ||
| 237 | if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) | 226 | if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) |
| 238 | clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); | 227 | clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]); |
| 239 | 228 | ||
| @@ -259,7 +248,6 @@ static int __fimc_pipeline_close(struct exynos_media_pipeline *ep) | |||
| 259 | } | 248 | } |
| 260 | 249 | ||
| 261 | ret = fimc_pipeline_s_power(p, 0); | 250 | ret = fimc_pipeline_s_power(p, 0); |
| 262 | fimc_md_set_camclk(sd, false); | ||
| 263 | 251 | ||
| 264 | fmd = entity_to_fimc_mdev(&sd->entity); | 252 | fmd = entity_to_fimc_mdev(&sd->entity); |
| 265 | 253 | ||
| @@ -337,75 +325,14 @@ static void fimc_md_pipelines_free(struct fimc_md *fmd) | |||
| 337 | } | 325 | } |
| 338 | } | 326 | } |
| 339 | 327 | ||
| 340 | /* | ||
| 341 | * Sensor subdevice helper functions | ||
| 342 | */ | ||
| 343 | static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, | ||
| 344 | struct fimc_source_info *si) | ||
| 345 | { | ||
| 346 | struct i2c_adapter *adapter; | ||
| 347 | struct v4l2_subdev *sd = NULL; | ||
| 348 | |||
| 349 | if (!si || !fmd) | ||
| 350 | return NULL; | ||
| 351 | /* | ||
| 352 | * If FIMC bus type is not Writeback FIFO assume it is same | ||
| 353 | * as sensor_bus_type. | ||
| 354 | */ | ||
| 355 | si->fimc_bus_type = si->sensor_bus_type; | ||
| 356 | |||
| 357 | adapter = i2c_get_adapter(si->i2c_bus_num); | ||
| 358 | if (!adapter) { | ||
| 359 | v4l2_warn(&fmd->v4l2_dev, | ||
| 360 | "Failed to get I2C adapter %d, deferring probe\n", | ||
| 361 | si->i2c_bus_num); | ||
| 362 | return ERR_PTR(-EPROBE_DEFER); | ||
| 363 | } | ||
| 364 | sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, | ||
| 365 | si->board_info, NULL); | ||
| 366 | if (IS_ERR_OR_NULL(sd)) { | ||
| 367 | i2c_put_adapter(adapter); | ||
| 368 | v4l2_warn(&fmd->v4l2_dev, | ||
| 369 | "Failed to acquire subdev %s, deferring probe\n", | ||
| 370 | si->board_info->type); | ||
| 371 | return ERR_PTR(-EPROBE_DEFER); | ||
| 372 | } | ||
| 373 | v4l2_set_subdev_hostdata(sd, si); | ||
| 374 | sd->grp_id = GRP_ID_SENSOR; | ||
| 375 | |||
| 376 | v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n", | ||
| 377 | sd->name); | ||
| 378 | return sd; | ||
| 379 | } | ||
| 380 | |||
| 381 | static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) | ||
| 382 | { | ||
| 383 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
| 384 | struct i2c_adapter *adapter; | ||
| 385 | |||
| 386 | if (!client || client->dev.of_node) | ||
| 387 | return; | ||
| 388 | |||
| 389 | v4l2_device_unregister_subdev(sd); | ||
| 390 | |||
| 391 | adapter = client->adapter; | ||
| 392 | i2c_unregister_device(client); | ||
| 393 | if (adapter) | ||
| 394 | i2c_put_adapter(adapter); | ||
| 395 | } | ||
| 396 | |||
| 397 | #ifdef CONFIG_OF | ||
| 398 | /* Parse port node and register as a sub-device any sensor specified there. */ | 328 | /* Parse port node and register as a sub-device any sensor specified there. */ |
| 399 | static int fimc_md_parse_port_node(struct fimc_md *fmd, | 329 | static int fimc_md_parse_port_node(struct fimc_md *fmd, |
| 400 | struct device_node *port, | 330 | struct device_node *port, |
| 401 | unsigned int index) | 331 | unsigned int index) |
| 402 | { | 332 | { |
| 333 | struct fimc_source_info *pd = &fmd->sensor[index].pdata; | ||
| 403 | struct device_node *rem, *ep, *np; | 334 | struct device_node *rem, *ep, *np; |
| 404 | struct fimc_source_info *pd; | ||
| 405 | struct v4l2_of_endpoint endpoint; | 335 | struct v4l2_of_endpoint endpoint; |
| 406 | u32 val; | ||
| 407 | |||
| 408 | pd = &fmd->sensor[index].pdata; | ||
| 409 | 336 | ||
| 410 | /* Assume here a port node can have only one endpoint node. */ | 337 | /* Assume here a port node can have only one endpoint node. */ |
| 411 | ep = of_get_next_child(port, NULL); | 338 | ep = of_get_next_child(port, NULL); |
| @@ -425,20 +352,6 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, | |||
| 425 | ep->full_name); | 352 | ep->full_name); |
| 426 | return 0; | 353 | return 0; |
| 427 | } | 354 | } |
| 428 | if (!of_property_read_u32(rem, "samsung,camclk-out", &val)) | ||
| 429 | pd->clk_id = val; | ||
| 430 | |||
| 431 | if (!of_property_read_u32(rem, "clock-frequency", &val)) | ||
| 432 | pd->clk_frequency = val; | ||
| 433 | else | ||
| 434 | pd->clk_frequency = DEFAULT_SENSOR_CLK_FREQ; | ||
| 435 | |||
| 436 | if (pd->clk_frequency == 0) { | ||
| 437 | v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n", | ||
| 438 | rem->full_name); | ||
| 439 | of_node_put(rem); | ||
| 440 | return -EINVAL; | ||
| 441 | } | ||
| 442 | 355 | ||
| 443 | if (fimc_input_is_parallel(endpoint.base.port)) { | 356 | if (fimc_input_is_parallel(endpoint.base.port)) { |
| 444 | if (endpoint.bus_type == V4L2_MBUS_PARALLEL) | 357 | if (endpoint.bus_type == V4L2_MBUS_PARALLEL) |
| @@ -485,14 +398,26 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, | |||
| 485 | } | 398 | } |
| 486 | 399 | ||
| 487 | /* Register all SoC external sub-devices */ | 400 | /* Register all SoC external sub-devices */ |
| 488 | static int fimc_md_of_sensors_register(struct fimc_md *fmd, | 401 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) |
| 489 | struct device_node *np) | ||
| 490 | { | 402 | { |
| 491 | struct device_node *parent = fmd->pdev->dev.of_node; | 403 | struct device_node *parent = fmd->pdev->dev.of_node; |
| 492 | struct device_node *node, *ports; | 404 | struct device_node *node, *ports; |
| 493 | int index = 0; | 405 | int index = 0; |
| 494 | int ret; | 406 | int ret; |
| 495 | 407 | ||
| 408 | /* | ||
| 409 | * Runtime resume one of the FIMC entities to make sure | ||
| 410 | * the sclk_cam clocks are not globally disabled. | ||
| 411 | */ | ||
| 412 | if (!fmd->pmf) | ||
| 413 | return -ENXIO; | ||
| 414 | |||
| 415 | ret = pm_runtime_get_sync(fmd->pmf); | ||
| 416 | if (ret < 0) | ||
| 417 | return ret; | ||
| 418 | |||
| 419 | fmd->num_sensors = 0; | ||
| 420 | |||
| 496 | /* Attach sensors linked to MIPI CSI-2 receivers */ | 421 | /* Attach sensors linked to MIPI CSI-2 receivers */ |
| 497 | for_each_available_child_of_node(parent, node) { | 422 | for_each_available_child_of_node(parent, node) { |
| 498 | struct device_node *port; | 423 | struct device_node *port; |
| @@ -506,14 +431,14 @@ static int fimc_md_of_sensors_register(struct fimc_md *fmd, | |||
| 506 | 431 | ||
| 507 | ret = fimc_md_parse_port_node(fmd, port, index); | 432 | ret = fimc_md_parse_port_node(fmd, port, index); |
| 508 | if (ret < 0) | 433 | if (ret < 0) |
| 509 | return ret; | 434 | goto rpm_put; |
| 510 | index++; | 435 | index++; |
| 511 | } | 436 | } |
| 512 | 437 | ||
| 513 | /* Attach sensors listed in the parallel-ports node */ | 438 | /* Attach sensors listed in the parallel-ports node */ |
| 514 | ports = of_get_child_by_name(parent, "parallel-ports"); | 439 | ports = of_get_child_by_name(parent, "parallel-ports"); |
| 515 | if (!ports) | 440 | if (!ports) |
| 516 | return 0; | 441 | goto rpm_put; |
| 517 | 442 | ||
| 518 | for_each_child_of_node(ports, node) { | 443 | for_each_child_of_node(ports, node) { |
| 519 | ret = fimc_md_parse_port_node(fmd, node, index); | 444 | ret = fimc_md_parse_port_node(fmd, node, index); |
| @@ -521,8 +446,9 @@ static int fimc_md_of_sensors_register(struct fimc_md *fmd, | |||
| 521 | break; | 446 | break; |
| 522 | index++; | 447 | index++; |
| 523 | } | 448 | } |
| 524 | 449 | rpm_put: | |
| 525 | return 0; | 450 | pm_runtime_put(fmd->pmf); |
| 451 | return ret; | ||
| 526 | } | 452 | } |
| 527 | 453 | ||
| 528 | static int __of_get_csis_id(struct device_node *np) | 454 | static int __of_get_csis_id(struct device_node *np) |
| @@ -535,68 +461,10 @@ static int __of_get_csis_id(struct device_node *np) | |||
| 535 | of_property_read_u32(np, "reg", ®); | 461 | of_property_read_u32(np, "reg", ®); |
| 536 | return reg - FIMC_INPUT_MIPI_CSI2_0; | 462 | return reg - FIMC_INPUT_MIPI_CSI2_0; |
| 537 | } | 463 | } |
| 538 | #else | ||
| 539 | #define fimc_md_of_sensors_register(fmd, np) (-ENOSYS) | ||
| 540 | #define __of_get_csis_id(np) (-ENOSYS) | ||
| 541 | #endif | ||
| 542 | |||
| 543 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) | ||
| 544 | { | ||
| 545 | struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data; | ||
| 546 | struct device_node *of_node = fmd->pdev->dev.of_node; | ||
| 547 | int num_clients = 0; | ||
| 548 | int ret, i; | ||
| 549 | |||
| 550 | /* | ||
| 551 | * Runtime resume one of the FIMC entities to make sure | ||
| 552 | * the sclk_cam clocks are not globally disabled. | ||
| 553 | */ | ||
| 554 | if (!fmd->pmf) | ||
| 555 | return -ENXIO; | ||
| 556 | |||
| 557 | ret = pm_runtime_get_sync(fmd->pmf); | ||
| 558 | if (ret < 0) | ||
| 559 | return ret; | ||
| 560 | |||
| 561 | if (of_node) { | ||
| 562 | fmd->num_sensors = 0; | ||
| 563 | ret = fimc_md_of_sensors_register(fmd, of_node); | ||
| 564 | } else if (pdata) { | ||
| 565 | WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor)); | ||
| 566 | num_clients = min_t(u32, pdata->num_clients, | ||
| 567 | ARRAY_SIZE(fmd->sensor)); | ||
| 568 | fmd->num_sensors = num_clients; | ||
| 569 | |||
| 570 | for (i = 0; i < num_clients; i++) { | ||
| 571 | struct fimc_sensor_info *si = &fmd->sensor[i]; | ||
| 572 | struct v4l2_subdev *sd; | ||
| 573 | |||
| 574 | si->pdata = pdata->source_info[i]; | ||
| 575 | ret = __fimc_md_set_camclk(fmd, &si->pdata, true); | ||
| 576 | if (ret) | ||
| 577 | break; | ||
| 578 | sd = fimc_md_register_sensor(fmd, &si->pdata); | ||
| 579 | ret = __fimc_md_set_camclk(fmd, &si->pdata, false); | ||
| 580 | |||
| 581 | if (IS_ERR(sd)) { | ||
| 582 | si->subdev = NULL; | ||
| 583 | ret = PTR_ERR(sd); | ||
| 584 | break; | ||
| 585 | } | ||
| 586 | si->subdev = sd; | ||
| 587 | if (ret) | ||
| 588 | break; | ||
| 589 | } | ||
| 590 | } | ||
| 591 | |||
| 592 | pm_runtime_put(fmd->pmf); | ||
| 593 | return ret; | ||
| 594 | } | ||
| 595 | 464 | ||
| 596 | /* | 465 | /* |
| 597 | * MIPI-CSIS, FIMC and FIMC-LITE platform devices registration. | 466 | * MIPI-CSIS, FIMC and FIMC-LITE platform devices registration. |
| 598 | */ | 467 | */ |
| 599 | |||
| 600 | static int register_fimc_lite_entity(struct fimc_md *fmd, | 468 | static int register_fimc_lite_entity(struct fimc_md *fmd, |
| 601 | struct fimc_lite *fimc_lite) | 469 | struct fimc_lite *fimc_lite) |
| 602 | { | 470 | { |
| @@ -753,35 +621,9 @@ dev_unlock: | |||
| 753 | return ret; | 621 | return ret; |
| 754 | } | 622 | } |
| 755 | 623 | ||
| 756 | static int fimc_md_pdev_match(struct device *dev, void *data) | ||
| 757 | { | ||
| 758 | struct platform_device *pdev = to_platform_device(dev); | ||
| 759 | int plat_entity = -1; | ||
| 760 | int ret; | ||
| 761 | char *p; | ||
| 762 | |||
| 763 | if (!get_device(dev)) | ||
| 764 | return -ENODEV; | ||
| 765 | |||
| 766 | if (!strcmp(pdev->name, CSIS_DRIVER_NAME)) { | ||
| 767 | plat_entity = IDX_CSIS; | ||
| 768 | } else { | ||
| 769 | p = strstr(pdev->name, "fimc"); | ||
| 770 | if (p && *(p + 4) == 0) | ||
| 771 | plat_entity = IDX_FIMC; | ||
| 772 | } | ||
| 773 | |||
| 774 | if (plat_entity >= 0) | ||
| 775 | ret = fimc_md_register_platform_entity(data, pdev, | ||
| 776 | plat_entity); | ||
| 777 | put_device(dev); | ||
| 778 | return 0; | ||
| 779 | } | ||
| 780 | |||
| 781 | /* Register FIMC, FIMC-LITE and CSIS media entities */ | 624 | /* Register FIMC, FIMC-LITE and CSIS media entities */ |
| 782 | #ifdef CONFIG_OF | 625 | static int fimc_md_register_platform_entities(struct fimc_md *fmd, |
| 783 | static int fimc_md_register_of_platform_entities(struct fimc_md *fmd, | 626 | struct device_node *parent) |
| 784 | struct device_node *parent) | ||
| 785 | { | 627 | { |
| 786 | struct device_node *node; | 628 | struct device_node *node; |
| 787 | int ret = 0; | 629 | int ret = 0; |
| @@ -815,9 +657,6 @@ static int fimc_md_register_of_platform_entities(struct fimc_md *fmd, | |||
| 815 | 657 | ||
| 816 | return ret; | 658 | return ret; |
| 817 | } | 659 | } |
| 818 | #else | ||
| 819 | #define fimc_md_register_of_platform_entities(fmd, node) (-ENOSYS) | ||
| 820 | #endif | ||
| 821 | 660 | ||
| 822 | static void fimc_md_unregister_entities(struct fimc_md *fmd) | 661 | static void fimc_md_unregister_entities(struct fimc_md *fmd) |
| 823 | { | 662 | { |
| @@ -845,14 +684,6 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) | |||
| 845 | v4l2_device_unregister_subdev(fmd->csis[i].sd); | 684 | v4l2_device_unregister_subdev(fmd->csis[i].sd); |
| 846 | fmd->csis[i].sd = NULL; | 685 | fmd->csis[i].sd = NULL; |
| 847 | } | 686 | } |
| 848 | if (fmd->pdev->dev.of_node == NULL) { | ||
| 849 | for (i = 0; i < fmd->num_sensors; i++) { | ||
| 850 | if (fmd->sensor[i].subdev == NULL) | ||
| 851 | continue; | ||
| 852 | fimc_md_unregister_sensor(fmd->sensor[i].subdev); | ||
| 853 | fmd->sensor[i].subdev = NULL; | ||
| 854 | } | ||
| 855 | } | ||
| 856 | 687 | ||
| 857 | if (fmd->fimc_is) | 688 | if (fmd->fimc_is) |
| 858 | v4l2_device_unregister_subdev(&fmd->fimc_is->isp.subdev); | 689 | v4l2_device_unregister_subdev(&fmd->fimc_is->isp.subdev); |
| @@ -1137,7 +968,7 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) | |||
| 1137 | 968 | ||
| 1138 | static int fimc_md_get_clocks(struct fimc_md *fmd) | 969 | static int fimc_md_get_clocks(struct fimc_md *fmd) |
| 1139 | { | 970 | { |
| 1140 | struct device *dev = NULL; | 971 | struct device *dev = &fmd->pdev->dev; |
| 1141 | char clk_name[32]; | 972 | char clk_name[32]; |
| 1142 | struct clk *clock; | 973 | struct clk *clock; |
| 1143 | int i, ret = 0; | 974 | int i, ret = 0; |
| @@ -1145,16 +976,12 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) | |||
| 1145 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) | 976 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) |
| 1146 | fmd->camclk[i].clock = ERR_PTR(-EINVAL); | 977 | fmd->camclk[i].clock = ERR_PTR(-EINVAL); |
| 1147 | 978 | ||
| 1148 | if (fmd->pdev->dev.of_node) | ||
| 1149 | dev = &fmd->pdev->dev; | ||
| 1150 | |||
| 1151 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { | 979 | for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { |
| 1152 | snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i); | 980 | snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i); |
| 1153 | clock = clk_get(dev, clk_name); | 981 | clock = clk_get(dev, clk_name); |
| 1154 | 982 | ||
| 1155 | if (IS_ERR(clock)) { | 983 | if (IS_ERR(clock)) { |
| 1156 | dev_err(&fmd->pdev->dev, "Failed to get clock: %s\n", | 984 | dev_err(dev, "Failed to get clock: %s\n", clk_name); |
| 1157 | clk_name); | ||
| 1158 | ret = PTR_ERR(clock); | 985 | ret = PTR_ERR(clock); |
| 1159 | break; | 986 | break; |
| 1160 | } | 987 | } |
| @@ -1188,86 +1015,6 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) | |||
| 1188 | return ret; | 1015 | return ret; |
| 1189 | } | 1016 | } |
| 1190 | 1017 | ||
| 1191 | static int __fimc_md_set_camclk(struct fimc_md *fmd, | ||
| 1192 | struct fimc_source_info *si, | ||
| 1193 | bool on) | ||
| 1194 | { | ||
| 1195 | struct fimc_camclk_info *camclk; | ||
| 1196 | int ret = 0; | ||
| 1197 | |||
| 1198 | /* | ||
| 1199 | * When device tree is used the sensor drivers are supposed to | ||
| 1200 | * control the clock themselves. This whole function will be | ||
| 1201 | * removed once S5PV210 platform is converted to the device tree. | ||
| 1202 | */ | ||
| 1203 | if (fmd->pdev->dev.of_node) | ||
| 1204 | return 0; | ||
| 1205 | |||
| 1206 | if (WARN_ON(si->clk_id >= FIMC_MAX_CAMCLKS) || !fmd || !fmd->pmf) | ||
| 1207 | return -EINVAL; | ||
| 1208 | |||
| 1209 | camclk = &fmd->camclk[si->clk_id]; | ||
| 1210 | |||
| 1211 | dbg("camclk %d, f: %lu, use_count: %d, on: %d", | ||
| 1212 | si->clk_id, si->clk_frequency, camclk->use_count, on); | ||
| 1213 | |||
| 1214 | if (on) { | ||
| 1215 | if (camclk->use_count > 0 && | ||
| 1216 | camclk->frequency != si->clk_frequency) | ||
| 1217 | return -EINVAL; | ||
| 1218 | |||
| 1219 | if (camclk->use_count++ == 0) { | ||
| 1220 | clk_set_rate(camclk->clock, si->clk_frequency); | ||
| 1221 | camclk->frequency = si->clk_frequency; | ||
| 1222 | ret = pm_runtime_get_sync(fmd->pmf); | ||
| 1223 | if (ret < 0) | ||
| 1224 | return ret; | ||
| 1225 | ret = clk_prepare_enable(camclk->clock); | ||
| 1226 | dbg("Enabled camclk %d: f: %lu", si->clk_id, | ||
| 1227 | clk_get_rate(camclk->clock)); | ||
| 1228 | } | ||
| 1229 | return ret; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | if (WARN_ON(camclk->use_count == 0)) | ||
| 1233 | return 0; | ||
| 1234 | |||
| 1235 | if (--camclk->use_count == 0) { | ||
| 1236 | clk_disable_unprepare(camclk->clock); | ||
| 1237 | pm_runtime_put(fmd->pmf); | ||
| 1238 | dbg("Disabled camclk %d", si->clk_id); | ||
| 1239 | } | ||
| 1240 | return ret; | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | /** | ||
| 1244 | * fimc_md_set_camclk - peripheral sensor clock setup | ||
| 1245 | * @sd: sensor subdev to configure sclk_cam clock for | ||
| 1246 | * @on: 1 to enable or 0 to disable the clock | ||
| 1247 | * | ||
| 1248 | * There are 2 separate clock outputs available in the SoC for external | ||
| 1249 | * image processors. These clocks are shared between all registered FIMC | ||
| 1250 | * devices to which sensors can be attached, either directly or through | ||
| 1251 | * the MIPI CSI receiver. The clock is allowed here to be used by | ||
| 1252 | * multiple sensors concurrently if they use same frequency. | ||
| 1253 | * This function should only be called when the graph mutex is held. | ||
| 1254 | */ | ||
| 1255 | int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) | ||
| 1256 | { | ||
| 1257 | struct fimc_source_info *si = v4l2_get_subdev_hostdata(sd); | ||
| 1258 | struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity); | ||
| 1259 | |||
| 1260 | /* | ||
| 1261 | * If there is a clock provider registered the sensors will | ||
| 1262 | * handle their clock themselves, no need to control it on | ||
| 1263 | * the host interface side. | ||
| 1264 | */ | ||
| 1265 | if (fmd->clk_provider.num_clocks > 0) | ||
| 1266 | return 0; | ||
| 1267 | |||
| 1268 | return __fimc_md_set_camclk(fmd, si, on); | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) | 1018 | static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) |
| 1272 | { | 1019 | { |
| 1273 | struct exynos_video_entity *ve; | 1020 | struct exynos_video_entity *ve; |
| @@ -1426,7 +1173,6 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd) | |||
| 1426 | return 0; | 1173 | return 0; |
| 1427 | } | 1174 | } |
| 1428 | 1175 | ||
| 1429 | #ifdef CONFIG_OF | ||
| 1430 | static int cam_clk_prepare(struct clk_hw *hw) | 1176 | static int cam_clk_prepare(struct clk_hw *hw) |
| 1431 | { | 1177 | { |
| 1432 | struct cam_clk *camclk = to_cam_clk(hw); | 1178 | struct cam_clk *camclk = to_cam_clk(hw); |
| @@ -1518,10 +1264,6 @@ err: | |||
| 1518 | fimc_md_unregister_clk_provider(fmd); | 1264 | fimc_md_unregister_clk_provider(fmd); |
| 1519 | return ret; | 1265 | return ret; |
| 1520 | } | 1266 | } |
| 1521 | #else | ||
| 1522 | #define fimc_md_register_clk_provider(fmd) (0) | ||
| 1523 | #define fimc_md_unregister_clk_provider(fmd) (0) | ||
| 1524 | #endif | ||
| 1525 | 1267 | ||
| 1526 | static int subdev_notifier_bound(struct v4l2_async_notifier *notifier, | 1268 | static int subdev_notifier_bound(struct v4l2_async_notifier *notifier, |
| 1527 | struct v4l2_subdev *subdev, | 1269 | struct v4l2_subdev *subdev, |
| @@ -1585,8 +1327,8 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
| 1585 | return -ENOMEM; | 1327 | return -ENOMEM; |
| 1586 | 1328 | ||
| 1587 | spin_lock_init(&fmd->slock); | 1329 | spin_lock_init(&fmd->slock); |
| 1588 | fmd->pdev = pdev; | ||
| 1589 | INIT_LIST_HEAD(&fmd->pipelines); | 1330 | INIT_LIST_HEAD(&fmd->pipelines); |
| 1331 | fmd->pdev = pdev; | ||
| 1590 | 1332 | ||
| 1591 | strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", | 1333 | strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", |
| 1592 | sizeof(fmd->media_dev.model)); | 1334 | sizeof(fmd->media_dev.model)); |
| @@ -1599,6 +1341,7 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
| 1599 | strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); | 1341 | strlcpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name)); |
| 1600 | 1342 | ||
| 1601 | fmd->use_isp = fimc_md_is_isp_available(dev->of_node); | 1343 | fmd->use_isp = fimc_md_is_isp_available(dev->of_node); |
| 1344 | fmd->user_subdev_api = true; | ||
| 1602 | 1345 | ||
| 1603 | ret = v4l2_device_register(dev, &fmd->v4l2_dev); | 1346 | ret = v4l2_device_register(dev, &fmd->v4l2_dev); |
| 1604 | if (ret < 0) { | 1347 | if (ret < 0) { |
| @@ -1616,8 +1359,6 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
| 1616 | if (ret) | 1359 | if (ret) |
| 1617 | goto err_md; | 1360 | goto err_md; |
| 1618 | 1361 | ||
| 1619 | fmd->user_subdev_api = (dev->of_node != NULL); | ||
| 1620 | |||
| 1621 | ret = fimc_md_get_pinctrl(fmd); | 1362 | ret = fimc_md_get_pinctrl(fmd); |
| 1622 | if (ret < 0) { | 1363 | if (ret < 0) { |
| 1623 | if (ret != EPROBE_DEFER) | 1364 | if (ret != EPROBE_DEFER) |
| @@ -1630,22 +1371,16 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
| 1630 | /* Protect the media graph while we're registering entities */ | 1371 | /* Protect the media graph while we're registering entities */ |
| 1631 | mutex_lock(&fmd->media_dev.graph_mutex); | 1372 | mutex_lock(&fmd->media_dev.graph_mutex); |
| 1632 | 1373 | ||
| 1633 | if (dev->of_node) | 1374 | ret = fimc_md_register_platform_entities(fmd, dev->of_node); |
| 1634 | ret = fimc_md_register_of_platform_entities(fmd, dev->of_node); | ||
| 1635 | else | ||
| 1636 | ret = bus_for_each_dev(&platform_bus_type, NULL, fmd, | ||
| 1637 | fimc_md_pdev_match); | ||
| 1638 | if (ret) { | 1375 | if (ret) { |
| 1639 | mutex_unlock(&fmd->media_dev.graph_mutex); | 1376 | mutex_unlock(&fmd->media_dev.graph_mutex); |
| 1640 | goto err_clk; | 1377 | goto err_clk; |
| 1641 | } | 1378 | } |
| 1642 | 1379 | ||
| 1643 | if (dev->platform_data || dev->of_node) { | 1380 | ret = fimc_md_register_sensor_entities(fmd); |
| 1644 | ret = fimc_md_register_sensor_entities(fmd); | 1381 | if (ret) { |
| 1645 | if (ret) { | 1382 | mutex_unlock(&fmd->media_dev.graph_mutex); |
| 1646 | mutex_unlock(&fmd->media_dev.graph_mutex); | 1383 | goto err_m_ent; |
| 1647 | goto err_m_ent; | ||
| 1648 | } | ||
| 1649 | } | 1384 | } |
| 1650 | 1385 | ||
| 1651 | mutex_unlock(&fmd->media_dev.graph_mutex); | 1386 | mutex_unlock(&fmd->media_dev.graph_mutex); |
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index ee1e2519f728..03214541f149 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | #include <media/media-entity.h> | 19 | #include <media/media-entity.h> |
| 20 | #include <media/v4l2-device.h> | 20 | #include <media/v4l2-device.h> |
| 21 | #include <media/v4l2-subdev.h> | 21 | #include <media/v4l2-subdev.h> |
| 22 | #include <media/s5p_fimc.h> | 22 | #include <media/exynos-fimc.h> |
| 23 | 23 | ||
| 24 | #include "fimc-core.h" | 24 | #include "fimc-core.h" |
| 25 | #include "fimc-lite.h" | 25 | #include "fimc-lite.h" |
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 3678ba59725c..ae54ef5f535d 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c | |||
| @@ -22,14 +22,13 @@ | |||
| 22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
| 23 | #include <linux/of_graph.h> | 23 | #include <linux/of_graph.h> |
| 24 | #include <linux/phy/phy.h> | 24 | #include <linux/phy/phy.h> |
| 25 | #include <linux/platform_data/mipi-csis.h> | ||
| 26 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 27 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 28 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
| 29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 30 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
| 31 | #include <linux/videodev2.h> | 30 | #include <linux/videodev2.h> |
| 32 | #include <media/s5p_fimc.h> | 31 | #include <media/exynos-fimc.h> |
| 33 | #include <media/v4l2-of.h> | 32 | #include <media/v4l2-of.h> |
| 34 | #include <media/v4l2-subdev.h> | 33 | #include <media/v4l2-subdev.h> |
| 35 | 34 | ||
| @@ -730,26 +729,6 @@ static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id) | |||
| 730 | return IRQ_HANDLED; | 729 | return IRQ_HANDLED; |
| 731 | } | 730 | } |
| 732 | 731 | ||
| 733 | static int s5pcsis_get_platform_data(struct platform_device *pdev, | ||
| 734 | struct csis_state *state) | ||
| 735 | { | ||
| 736 | struct s5p_platform_mipi_csis *pdata = pdev->dev.platform_data; | ||
| 737 | |||
| 738 | if (pdata == NULL) { | ||
| 739 | dev_err(&pdev->dev, "Platform data not specified\n"); | ||
| 740 | return -EINVAL; | ||
| 741 | } | ||
| 742 | |||
| 743 | state->clk_frequency = pdata->clk_rate; | ||
| 744 | state->num_lanes = pdata->lanes; | ||
| 745 | state->hs_settle = pdata->hs_settle; | ||
| 746 | state->index = max(0, pdev->id); | ||
| 747 | state->max_num_lanes = state->index ? CSIS1_MAX_LANES : | ||
| 748 | CSIS0_MAX_LANES; | ||
| 749 | return 0; | ||
| 750 | } | ||
| 751 | |||
| 752 | #ifdef CONFIG_OF | ||
| 753 | static int s5pcsis_parse_dt(struct platform_device *pdev, | 732 | static int s5pcsis_parse_dt(struct platform_device *pdev, |
| 754 | struct csis_state *state) | 733 | struct csis_state *state) |
| 755 | { | 734 | { |
| @@ -787,9 +766,6 @@ static int s5pcsis_parse_dt(struct platform_device *pdev, | |||
| 787 | 766 | ||
| 788 | return 0; | 767 | return 0; |
| 789 | } | 768 | } |
| 790 | #else | ||
| 791 | #define s5pcsis_parse_dt(pdev, state) (-ENOSYS) | ||
| 792 | #endif | ||
| 793 | 769 | ||
| 794 | static int s5pcsis_pm_resume(struct device *dev, bool runtime); | 770 | static int s5pcsis_pm_resume(struct device *dev, bool runtime); |
| 795 | static const struct of_device_id s5pcsis_of_match[]; | 771 | static const struct of_device_id s5pcsis_of_match[]; |
| @@ -812,19 +788,14 @@ static int s5pcsis_probe(struct platform_device *pdev) | |||
| 812 | spin_lock_init(&state->slock); | 788 | spin_lock_init(&state->slock); |
| 813 | state->pdev = pdev; | 789 | state->pdev = pdev; |
| 814 | 790 | ||
| 815 | if (dev->of_node) { | 791 | of_id = of_match_node(s5pcsis_of_match, dev->of_node); |
| 816 | of_id = of_match_node(s5pcsis_of_match, dev->of_node); | 792 | if (WARN_ON(of_id == NULL)) |
| 817 | if (WARN_ON(of_id == NULL)) | 793 | return -EINVAL; |
| 818 | return -EINVAL; | ||
| 819 | |||
| 820 | drv_data = of_id->data; | ||
| 821 | state->interrupt_mask = drv_data->interrupt_mask; | ||
| 822 | 794 | ||
| 823 | ret = s5pcsis_parse_dt(pdev, state); | 795 | drv_data = of_id->data; |
| 824 | } else { | 796 | state->interrupt_mask = drv_data->interrupt_mask; |
| 825 | ret = s5pcsis_get_platform_data(pdev, state); | ||
| 826 | } | ||
| 827 | 797 | ||
| 798 | ret = s5pcsis_parse_dt(pdev, state); | ||
| 828 | if (ret < 0) | 799 | if (ret < 0) |
| 829 | return ret; | 800 | return ret; |
| 830 | 801 | ||
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index dbf0ce38a8e7..d5dc198502ef 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c | |||
| @@ -964,7 +964,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) | |||
| 964 | struct viu_fh *fh = priv; | 964 | struct viu_fh *fh = priv; |
| 965 | 965 | ||
| 966 | fh->dev->std = id; | 966 | fh->dev->std = id; |
| 967 | decoder_call(fh->dev, core, s_std, id); | 967 | decoder_call(fh->dev, video, s_std, id); |
| 968 | return 0; | 968 | return 0; |
| 969 | } | 969 | } |
| 970 | 970 | ||
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 8b34c485be79..be4b51212106 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c | |||
| @@ -1156,7 +1156,7 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 1156 | return mcam_read_setup(cam); | 1156 | return mcam_read_setup(cam); |
| 1157 | } | 1157 | } |
| 1158 | 1158 | ||
| 1159 | static int mcam_vb_stop_streaming(struct vb2_queue *vq) | 1159 | static void mcam_vb_stop_streaming(struct vb2_queue *vq) |
| 1160 | { | 1160 | { |
| 1161 | struct mcam_camera *cam = vb2_get_drv_priv(vq); | 1161 | struct mcam_camera *cam = vb2_get_drv_priv(vq); |
| 1162 | unsigned long flags; | 1162 | unsigned long flags; |
| @@ -1164,10 +1164,10 @@ static int mcam_vb_stop_streaming(struct vb2_queue *vq) | |||
| 1164 | if (cam->state == S_BUFWAIT) { | 1164 | if (cam->state == S_BUFWAIT) { |
| 1165 | /* They never gave us buffers */ | 1165 | /* They never gave us buffers */ |
| 1166 | cam->state = S_IDLE; | 1166 | cam->state = S_IDLE; |
| 1167 | return 0; | 1167 | return; |
| 1168 | } | 1168 | } |
| 1169 | if (cam->state != S_STREAMING) | 1169 | if (cam->state != S_STREAMING) |
| 1170 | return -EINVAL; | 1170 | return; |
| 1171 | mcam_ctlr_stop_dma(cam); | 1171 | mcam_ctlr_stop_dma(cam); |
| 1172 | /* | 1172 | /* |
| 1173 | * Reset the CCIC PHY after stopping streaming, | 1173 | * Reset the CCIC PHY after stopping streaming, |
| @@ -1182,7 +1182,6 @@ static int mcam_vb_stop_streaming(struct vb2_queue *vq) | |||
| 1182 | spin_lock_irqsave(&cam->dev_lock, flags); | 1182 | spin_lock_irqsave(&cam->dev_lock, flags); |
| 1183 | INIT_LIST_HEAD(&cam->buffers); | 1183 | INIT_LIST_HEAD(&cam->buffers); |
| 1184 | spin_unlock_irqrestore(&cam->dev_lock, flags); | 1184 | spin_unlock_irqrestore(&cam->dev_lock, flags); |
| 1185 | return 0; | ||
| 1186 | } | 1185 | } |
| 1187 | 1186 | ||
| 1188 | 1187 | ||
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c index 4f3096b17066..0714070ed7fa 100644 --- a/drivers/media/platform/mem2mem_testdev.c +++ b/drivers/media/platform/mem2mem_testdev.c | |||
| @@ -787,7 +787,7 @@ static int m2mtest_start_streaming(struct vb2_queue *q, unsigned count) | |||
| 787 | return 0; | 787 | return 0; |
| 788 | } | 788 | } |
| 789 | 789 | ||
| 790 | static int m2mtest_stop_streaming(struct vb2_queue *q) | 790 | static void m2mtest_stop_streaming(struct vb2_queue *q) |
| 791 | { | 791 | { |
| 792 | struct m2mtest_ctx *ctx = vb2_get_drv_priv(q); | 792 | struct m2mtest_ctx *ctx = vb2_get_drv_priv(q); |
| 793 | struct vb2_buffer *vb; | 793 | struct vb2_buffer *vb; |
| @@ -799,12 +799,11 @@ static int m2mtest_stop_streaming(struct vb2_queue *q) | |||
| 799 | else | 799 | else |
| 800 | vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); | 800 | vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); |
| 801 | if (vb == NULL) | 801 | if (vb == NULL) |
| 802 | return 0; | 802 | return; |
| 803 | spin_lock_irqsave(&ctx->dev->irqlock, flags); | 803 | spin_lock_irqsave(&ctx->dev->irqlock, flags); |
| 804 | v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); | 804 | v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); |
| 805 | spin_unlock_irqrestore(&ctx->dev->irqlock, flags); | 805 | spin_unlock_irqrestore(&ctx->dev->irqlock, flags); |
| 806 | } | 806 | } |
| 807 | return 0; | ||
| 808 | } | 807 | } |
| 809 | 808 | ||
| 810 | static struct vb2_ops m2mtest_qops = { | 809 | static struct vb2_ops m2mtest_qops = { |
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 0b7480e82142..fa8f7cabe364 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c | |||
| @@ -207,10 +207,8 @@ struct emmaprp_dev { | |||
| 207 | struct mutex dev_mutex; | 207 | struct mutex dev_mutex; |
| 208 | spinlock_t irqlock; | 208 | spinlock_t irqlock; |
| 209 | 209 | ||
| 210 | int irq_emma; | ||
| 211 | void __iomem *base_emma; | 210 | void __iomem *base_emma; |
| 212 | struct clk *clk_emma_ahb, *clk_emma_ipg; | 211 | struct clk *clk_emma_ahb, *clk_emma_ipg; |
| 213 | struct resource *res_emma; | ||
| 214 | 212 | ||
| 215 | struct v4l2_m2m_dev *m2m_dev; | 213 | struct v4l2_m2m_dev *m2m_dev; |
| 216 | struct vb2_alloc_ctx *alloc_ctx; | 214 | struct vb2_alloc_ctx *alloc_ctx; |
| @@ -901,9 +899,8 @@ static int emmaprp_probe(struct platform_device *pdev) | |||
| 901 | { | 899 | { |
| 902 | struct emmaprp_dev *pcdev; | 900 | struct emmaprp_dev *pcdev; |
| 903 | struct video_device *vfd; | 901 | struct video_device *vfd; |
| 904 | struct resource *res_emma; | 902 | struct resource *res; |
| 905 | int irq_emma; | 903 | int irq, ret; |
| 906 | int ret; | ||
| 907 | 904 | ||
| 908 | pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL); | 905 | pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL); |
| 909 | if (!pcdev) | 906 | if (!pcdev) |
| @@ -920,12 +917,10 @@ static int emmaprp_probe(struct platform_device *pdev) | |||
| 920 | if (IS_ERR(pcdev->clk_emma_ahb)) | 917 | if (IS_ERR(pcdev->clk_emma_ahb)) |
| 921 | return PTR_ERR(pcdev->clk_emma_ahb); | 918 | return PTR_ERR(pcdev->clk_emma_ahb); |
| 922 | 919 | ||
| 923 | irq_emma = platform_get_irq(pdev, 0); | 920 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 924 | res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 921 | pcdev->base_emma = devm_ioremap_resource(&pdev->dev, res); |
| 925 | if (irq_emma < 0 || res_emma == NULL) { | 922 | if (IS_ERR(pcdev->base_emma)) |
| 926 | dev_err(&pdev->dev, "Missing platform resources data\n"); | 923 | return PTR_ERR(pcdev->base_emma); |
| 927 | return -ENODEV; | ||
| 928 | } | ||
| 929 | 924 | ||
| 930 | ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev); | 925 | ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev); |
| 931 | if (ret) | 926 | if (ret) |
| @@ -952,20 +947,11 @@ static int emmaprp_probe(struct platform_device *pdev) | |||
| 952 | 947 | ||
| 953 | platform_set_drvdata(pdev, pcdev); | 948 | platform_set_drvdata(pdev, pcdev); |
| 954 | 949 | ||
| 955 | pcdev->base_emma = devm_ioremap_resource(&pdev->dev, res_emma); | 950 | irq = platform_get_irq(pdev, 0); |
| 956 | if (IS_ERR(pcdev->base_emma)) { | 951 | ret = devm_request_irq(&pdev->dev, irq, emmaprp_irq, 0, |
| 957 | ret = PTR_ERR(pcdev->base_emma); | 952 | dev_name(&pdev->dev), pcdev); |
| 958 | goto rel_vdev; | 953 | if (ret) |
| 959 | } | ||
| 960 | |||
| 961 | pcdev->irq_emma = irq_emma; | ||
| 962 | pcdev->res_emma = res_emma; | ||
| 963 | |||
| 964 | if (devm_request_irq(&pdev->dev, pcdev->irq_emma, emmaprp_irq, | ||
| 965 | 0, MEM2MEM_NAME, pcdev) < 0) { | ||
| 966 | ret = -ENODEV; | ||
| 967 | goto rel_vdev; | 954 | goto rel_vdev; |
| 968 | } | ||
| 969 | 955 | ||
| 970 | pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | 956 | pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); |
| 971 | if (IS_ERR(pcdev->alloc_ctx)) { | 957 | if (IS_ERR(pcdev->alloc_ctx)) { |
| @@ -999,6 +985,8 @@ rel_vdev: | |||
| 999 | unreg_dev: | 985 | unreg_dev: |
| 1000 | v4l2_device_unregister(&pcdev->v4l2_dev); | 986 | v4l2_device_unregister(&pcdev->v4l2_dev); |
| 1001 | 987 | ||
| 988 | mutex_destroy(&pcdev->dev_mutex); | ||
| 989 | |||
| 1002 | return ret; | 990 | return ret; |
| 1003 | } | 991 | } |
| 1004 | 992 | ||
| @@ -1012,6 +1000,7 @@ static int emmaprp_remove(struct platform_device *pdev) | |||
| 1012 | v4l2_m2m_release(pcdev->m2m_dev); | 1000 | v4l2_m2m_release(pcdev->m2m_dev); |
| 1013 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | 1001 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); |
| 1014 | v4l2_device_unregister(&pcdev->v4l2_dev); | 1002 | v4l2_device_unregister(&pcdev->v4l2_dev); |
| 1003 | mutex_destroy(&pcdev->dev_mutex); | ||
| 1015 | 1004 | ||
| 1016 | return 0; | 1005 | return 0; |
| 1017 | } | 1006 | } |
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 4e4d1631e042..deba425e3d8f 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c | |||
| @@ -435,10 +435,10 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 435 | return 0; | 435 | return 0; |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | static int stop_streaming(struct vb2_queue *vq) | 438 | static void stop_streaming(struct vb2_queue *vq) |
| 439 | { | 439 | { |
| 440 | struct camif_vp *vp = vb2_get_drv_priv(vq); | 440 | struct camif_vp *vp = vb2_get_drv_priv(vq); |
| 441 | return camif_stop_capture(vp); | 441 | camif_stop_capture(vp); |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, | 444 | static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 8a18972012f7..0dcb796ecad9 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c | |||
| @@ -192,8 +192,7 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
| 192 | .colplanes = 2, | 192 | .colplanes = 2, |
| 193 | .h_align = 4, | 193 | .h_align = 4, |
| 194 | .v_align = 4, | 194 | .v_align = 4, |
| 195 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | 195 | .flags = SJPEG_FMT_FLAG_DEC_CAPTURE | |
| 196 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
| 197 | SJPEG_FMT_FLAG_S5P | | 196 | SJPEG_FMT_FLAG_S5P | |
| 198 | SJPEG_FMT_NON_RGB, | 197 | SJPEG_FMT_NON_RGB, |
| 199 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | 198 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, |
| @@ -959,7 +958,7 @@ static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 959 | static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx, | 958 | static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx, |
| 960 | u32 pixelformat, unsigned int fmt_type) | 959 | u32 pixelformat, unsigned int fmt_type) |
| 961 | { | 960 | { |
| 962 | unsigned int k, fmt_flag, ver_flag; | 961 | unsigned int k, fmt_flag; |
| 963 | 962 | ||
| 964 | if (ctx->mode == S5P_JPEG_ENCODE) | 963 | if (ctx->mode == S5P_JPEG_ENCODE) |
| 965 | fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ? | 964 | fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ? |
| @@ -970,16 +969,11 @@ static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx, | |||
| 970 | SJPEG_FMT_FLAG_DEC_OUTPUT : | 969 | SJPEG_FMT_FLAG_DEC_OUTPUT : |
| 971 | SJPEG_FMT_FLAG_DEC_CAPTURE; | 970 | SJPEG_FMT_FLAG_DEC_CAPTURE; |
| 972 | 971 | ||
| 973 | if (ctx->jpeg->variant->version == SJPEG_S5P) | ||
| 974 | ver_flag = SJPEG_FMT_FLAG_S5P; | ||
| 975 | else | ||
| 976 | ver_flag = SJPEG_FMT_FLAG_EXYNOS4; | ||
| 977 | |||
| 978 | for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) { | 972 | for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) { |
| 979 | struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k]; | 973 | struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k]; |
| 980 | if (fmt->fourcc == pixelformat && | 974 | if (fmt->fourcc == pixelformat && |
| 981 | fmt->flags & fmt_flag && | 975 | fmt->flags & fmt_flag && |
| 982 | fmt->flags & ver_flag) { | 976 | fmt->flags & ctx->jpeg->variant->fmt_ver_flag) { |
| 983 | return fmt; | 977 | return fmt; |
| 984 | } | 978 | } |
| 985 | } | 979 | } |
| @@ -1069,15 +1063,17 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1069 | return -EINVAL; | 1063 | return -EINVAL; |
| 1070 | } | 1064 | } |
| 1071 | 1065 | ||
| 1066 | if ((ctx->jpeg->variant->version != SJPEG_EXYNOS4) || | ||
| 1067 | (ctx->mode != S5P_JPEG_DECODE)) | ||
| 1068 | goto exit; | ||
| 1069 | |||
| 1072 | /* | 1070 | /* |
| 1073 | * The exynos4x12 device requires resulting YUV image | 1071 | * The exynos4x12 device requires resulting YUV image |
| 1074 | * subsampling not to be lower than the input jpeg subsampling. | 1072 | * subsampling not to be lower than the input jpeg subsampling. |
| 1075 | * If this requirement is not met then downgrade the requested | 1073 | * If this requirement is not met then downgrade the requested |
| 1076 | * capture format to the one with subsampling equal to the input jpeg. | 1074 | * capture format to the one with subsampling equal to the input jpeg. |
| 1077 | */ | 1075 | */ |
| 1078 | if ((ctx->jpeg->variant->version != SJPEG_S5P) && | 1076 | if ((fmt->flags & SJPEG_FMT_NON_RGB) && |
| 1079 | (ctx->mode == S5P_JPEG_DECODE) && | ||
| 1080 | (fmt->flags & SJPEG_FMT_NON_RGB) && | ||
| 1081 | (fmt->subsampling < ctx->subsampling)) { | 1077 | (fmt->subsampling < ctx->subsampling)) { |
| 1082 | ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling, | 1078 | ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling, |
| 1083 | fmt->fourcc, | 1079 | fmt->fourcc, |
| @@ -1090,6 +1086,23 @@ static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1090 | FMT_TYPE_CAPTURE); | 1086 | FMT_TYPE_CAPTURE); |
| 1091 | } | 1087 | } |
| 1092 | 1088 | ||
| 1089 | /* | ||
| 1090 | * Decompression of a JPEG file with 4:2:0 subsampling and odd | ||
| 1091 | * width to the YUV 4:2:0 compliant formats produces a raw image | ||
| 1092 | * with broken luma component. Adjust capture format to RGB565 | ||
| 1093 | * in such a case. | ||
| 1094 | */ | ||
| 1095 | if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 && | ||
| 1096 | (ctx->out_q.w & 1) && | ||
| 1097 | (pix->pixelformat == V4L2_PIX_FMT_NV12 || | ||
| 1098 | pix->pixelformat == V4L2_PIX_FMT_NV21 || | ||
| 1099 | pix->pixelformat == V4L2_PIX_FMT_YUV420)) { | ||
| 1100 | pix->pixelformat = V4L2_PIX_FMT_RGB565; | ||
| 1101 | fmt = s5p_jpeg_find_format(ctx, pix->pixelformat, | ||
| 1102 | FMT_TYPE_CAPTURE); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | exit: | ||
| 1093 | return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE); | 1106 | return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE); |
| 1094 | } | 1107 | } |
| 1095 | 1108 | ||
| @@ -1111,6 +1124,32 @@ static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv, | |||
| 1111 | return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT); | 1124 | return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT); |
| 1112 | } | 1125 | } |
| 1113 | 1126 | ||
| 1127 | static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx, | ||
| 1128 | struct v4l2_format *f, | ||
| 1129 | int fmt_depth) | ||
| 1130 | { | ||
| 1131 | struct v4l2_pix_format *pix = &f->fmt.pix; | ||
| 1132 | u32 pix_fmt = f->fmt.pix.pixelformat; | ||
| 1133 | int w = pix->width, h = pix->height, wh_align; | ||
| 1134 | |||
| 1135 | if (pix_fmt == V4L2_PIX_FMT_RGB32 || | ||
| 1136 | pix_fmt == V4L2_PIX_FMT_NV24 || | ||
| 1137 | pix_fmt == V4L2_PIX_FMT_NV42 || | ||
| 1138 | pix_fmt == V4L2_PIX_FMT_NV12 || | ||
| 1139 | pix_fmt == V4L2_PIX_FMT_NV21 || | ||
| 1140 | pix_fmt == V4L2_PIX_FMT_YUV420) | ||
| 1141 | wh_align = 4; | ||
| 1142 | else | ||
| 1143 | wh_align = 1; | ||
| 1144 | |||
| 1145 | jpeg_bound_align_image(&w, S5P_JPEG_MIN_WIDTH, | ||
| 1146 | S5P_JPEG_MAX_WIDTH, wh_align, | ||
| 1147 | &h, S5P_JPEG_MIN_HEIGHT, | ||
| 1148 | S5P_JPEG_MAX_HEIGHT, wh_align); | ||
| 1149 | |||
| 1150 | return w * h * fmt_depth >> 3; | ||
| 1151 | } | ||
| 1152 | |||
| 1114 | static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) | 1153 | static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) |
| 1115 | { | 1154 | { |
| 1116 | struct vb2_queue *vq; | 1155 | struct vb2_queue *vq; |
| @@ -1137,10 +1176,24 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f) | |||
| 1137 | q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type); | 1176 | q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type); |
| 1138 | q_data->w = pix->width; | 1177 | q_data->w = pix->width; |
| 1139 | q_data->h = pix->height; | 1178 | q_data->h = pix->height; |
| 1140 | if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) | 1179 | if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) { |
| 1141 | q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3; | 1180 | /* |
| 1142 | else | 1181 | * During encoding Exynos4x12 SoCs access wider memory area |
| 1182 | * than it results from Image_x and Image_y values written to | ||
| 1183 | * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu | ||
| 1184 | * page fault calculate proper buffer size in such a case. | ||
| 1185 | */ | ||
| 1186 | if (ct->jpeg->variant->version == SJPEG_EXYNOS4 && | ||
| 1187 | f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE) | ||
| 1188 | q_data->size = exynos4_jpeg_get_output_buffer_size(ct, | ||
| 1189 | f, | ||
| 1190 | q_data->fmt->depth); | ||
| 1191 | else | ||
| 1192 | q_data->size = q_data->w * q_data->h * | ||
| 1193 | q_data->fmt->depth >> 3; | ||
| 1194 | } else { | ||
| 1143 | q_data->size = pix->sizeimage; | 1195 | q_data->size = pix->sizeimage; |
| 1196 | } | ||
| 1144 | 1197 | ||
| 1145 | if (f_type == FMT_TYPE_OUTPUT) { | 1198 | if (f_type == FMT_TYPE_OUTPUT) { |
| 1146 | ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler, | 1199 | ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler, |
| @@ -1182,8 +1235,7 @@ static int s5p_jpeg_g_selection(struct file *file, void *priv, | |||
| 1182 | struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); | 1235 | struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv); |
| 1183 | 1236 | ||
| 1184 | if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && | 1237 | if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && |
| 1185 | s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | 1238 | s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1186 | ctx->jpeg->variant->version != SJPEG_S5P) | ||
| 1187 | return -EINVAL; | 1239 | return -EINVAL; |
| 1188 | 1240 | ||
| 1189 | /* For JPEG blob active == default == bounds */ | 1241 | /* For JPEG blob active == default == bounds */ |
| @@ -1571,7 +1623,7 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = { | |||
| 1571 | .job_abort = s5p_jpeg_job_abort, | 1623 | .job_abort = s5p_jpeg_job_abort, |
| 1572 | } | 1624 | } |
| 1573 | ; | 1625 | ; |
| 1574 | static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = { | 1626 | static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = { |
| 1575 | .device_run = exynos4_jpeg_device_run, | 1627 | .device_run = exynos4_jpeg_device_run, |
| 1576 | .job_ready = s5p_jpeg_job_ready, | 1628 | .job_ready = s5p_jpeg_job_ready, |
| 1577 | .job_abort = s5p_jpeg_job_abort, | 1629 | .job_abort = s5p_jpeg_job_abort, |
| @@ -1670,13 +1722,11 @@ static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 1670 | return ret > 0 ? 0 : ret; | 1722 | return ret > 0 ? 0 : ret; |
| 1671 | } | 1723 | } |
| 1672 | 1724 | ||
| 1673 | static int s5p_jpeg_stop_streaming(struct vb2_queue *q) | 1725 | static void s5p_jpeg_stop_streaming(struct vb2_queue *q) |
| 1674 | { | 1726 | { |
| 1675 | struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); | 1727 | struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); |
| 1676 | 1728 | ||
| 1677 | pm_runtime_put(ctx->jpeg->dev); | 1729 | pm_runtime_put(ctx->jpeg->dev); |
| 1678 | |||
| 1679 | return 0; | ||
| 1680 | } | 1730 | } |
| 1681 | 1731 | ||
| 1682 | static struct vb2_ops s5p_jpeg_qops = { | 1732 | static struct vb2_ops s5p_jpeg_qops = { |
| @@ -1845,7 +1895,7 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv) | |||
| 1845 | return IRQ_HANDLED; | 1895 | return IRQ_HANDLED; |
| 1846 | } | 1896 | } |
| 1847 | 1897 | ||
| 1848 | static void *jpeg_get_drv_data(struct platform_device *pdev); | 1898 | static void *jpeg_get_drv_data(struct device *dev); |
| 1849 | 1899 | ||
| 1850 | /* | 1900 | /* |
| 1851 | * ============================================================================ | 1901 | * ============================================================================ |
| @@ -1857,18 +1907,14 @@ static int s5p_jpeg_probe(struct platform_device *pdev) | |||
| 1857 | { | 1907 | { |
| 1858 | struct s5p_jpeg *jpeg; | 1908 | struct s5p_jpeg *jpeg; |
| 1859 | struct resource *res; | 1909 | struct resource *res; |
| 1860 | struct v4l2_m2m_ops *samsung_jpeg_m2m_ops; | ||
| 1861 | int ret; | 1910 | int ret; |
| 1862 | 1911 | ||
| 1863 | if (!pdev->dev.of_node) | ||
| 1864 | return -ENODEV; | ||
| 1865 | |||
| 1866 | /* JPEG IP abstraction struct */ | 1912 | /* JPEG IP abstraction struct */ |
| 1867 | jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL); | 1913 | jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL); |
| 1868 | if (!jpeg) | 1914 | if (!jpeg) |
| 1869 | return -ENOMEM; | 1915 | return -ENOMEM; |
| 1870 | 1916 | ||
| 1871 | jpeg->variant = jpeg_get_drv_data(pdev); | 1917 | jpeg->variant = jpeg_get_drv_data(&pdev->dev); |
| 1872 | 1918 | ||
| 1873 | mutex_init(&jpeg->lock); | 1919 | mutex_init(&jpeg->lock); |
| 1874 | spin_lock_init(&jpeg->slock); | 1920 | spin_lock_init(&jpeg->slock); |
| @@ -1911,13 +1957,8 @@ static int s5p_jpeg_probe(struct platform_device *pdev) | |||
| 1911 | goto clk_get_rollback; | 1957 | goto clk_get_rollback; |
| 1912 | } | 1958 | } |
| 1913 | 1959 | ||
| 1914 | if (jpeg->variant->version == SJPEG_S5P) | ||
| 1915 | samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops; | ||
| 1916 | else | ||
| 1917 | samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops; | ||
| 1918 | |||
| 1919 | /* mem2mem device */ | 1960 | /* mem2mem device */ |
| 1920 | jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops); | 1961 | jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops); |
| 1921 | if (IS_ERR(jpeg->m2m_dev)) { | 1962 | if (IS_ERR(jpeg->m2m_dev)) { |
| 1922 | v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); | 1963 | v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); |
| 1923 | ret = PTR_ERR(jpeg->m2m_dev); | 1964 | ret = PTR_ERR(jpeg->m2m_dev); |
| @@ -2102,15 +2143,18 @@ static const struct dev_pm_ops s5p_jpeg_pm_ops = { | |||
| 2102 | SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL) | 2143 | SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL) |
| 2103 | }; | 2144 | }; |
| 2104 | 2145 | ||
| 2105 | #ifdef CONFIG_OF | ||
| 2106 | static struct s5p_jpeg_variant s5p_jpeg_drvdata = { | 2146 | static struct s5p_jpeg_variant s5p_jpeg_drvdata = { |
| 2107 | .version = SJPEG_S5P, | 2147 | .version = SJPEG_S5P, |
| 2108 | .jpeg_irq = s5p_jpeg_irq, | 2148 | .jpeg_irq = s5p_jpeg_irq, |
| 2149 | .m2m_ops = &s5p_jpeg_m2m_ops, | ||
| 2150 | .fmt_ver_flag = SJPEG_FMT_FLAG_S5P, | ||
| 2109 | }; | 2151 | }; |
| 2110 | 2152 | ||
| 2111 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { | 2153 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { |
| 2112 | .version = SJPEG_EXYNOS4, | 2154 | .version = SJPEG_EXYNOS4, |
| 2113 | .jpeg_irq = exynos4_jpeg_irq, | 2155 | .jpeg_irq = exynos4_jpeg_irq, |
| 2156 | .m2m_ops = &exynos4_jpeg_m2m_ops, | ||
| 2157 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, | ||
| 2114 | }; | 2158 | }; |
| 2115 | 2159 | ||
| 2116 | static const struct of_device_id samsung_jpeg_match[] = { | 2160 | static const struct of_device_id samsung_jpeg_match[] = { |
| @@ -2129,19 +2173,21 @@ static const struct of_device_id samsung_jpeg_match[] = { | |||
| 2129 | 2173 | ||
| 2130 | MODULE_DEVICE_TABLE(of, samsung_jpeg_match); | 2174 | MODULE_DEVICE_TABLE(of, samsung_jpeg_match); |
| 2131 | 2175 | ||
| 2132 | static void *jpeg_get_drv_data(struct platform_device *pdev) | 2176 | static void *jpeg_get_drv_data(struct device *dev) |
| 2133 | { | 2177 | { |
| 2134 | struct s5p_jpeg_variant *driver_data = NULL; | 2178 | struct s5p_jpeg_variant *driver_data = NULL; |
| 2135 | const struct of_device_id *match; | 2179 | const struct of_device_id *match; |
| 2136 | 2180 | ||
| 2137 | match = of_match_node(of_match_ptr(samsung_jpeg_match), | 2181 | if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) |
| 2138 | pdev->dev.of_node); | 2182 | return &s5p_jpeg_drvdata; |
| 2183 | |||
| 2184 | match = of_match_node(samsung_jpeg_match, dev->of_node); | ||
| 2185 | |||
| 2139 | if (match) | 2186 | if (match) |
| 2140 | driver_data = (struct s5p_jpeg_variant *)match->data; | 2187 | driver_data = (struct s5p_jpeg_variant *)match->data; |
| 2141 | 2188 | ||
| 2142 | return driver_data; | 2189 | return driver_data; |
| 2143 | } | 2190 | } |
| 2144 | #endif | ||
| 2145 | 2191 | ||
| 2146 | static struct platform_driver s5p_jpeg_driver = { | 2192 | static struct platform_driver s5p_jpeg_driver = { |
| 2147 | .probe = s5p_jpeg_probe, | 2193 | .probe = s5p_jpeg_probe, |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index f482dbf55d5f..3e4786329727 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h | |||
| @@ -117,8 +117,10 @@ struct s5p_jpeg { | |||
| 117 | }; | 117 | }; |
| 118 | 118 | ||
| 119 | struct s5p_jpeg_variant { | 119 | struct s5p_jpeg_variant { |
| 120 | unsigned int version; | 120 | unsigned int version; |
| 121 | irqreturn_t (*jpeg_irq)(int irq, void *priv); | 121 | unsigned int fmt_ver_flag; |
| 122 | struct v4l2_m2m_ops *m2m_ops; | ||
| 123 | irqreturn_t (*jpeg_irq)(int irq, void *priv); | ||
| 122 | }; | 124 | }; |
| 123 | 125 | ||
| 124 | /** | 126 | /** |
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h index 8d0b686d9adb..51cb2dd0e13a 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v6.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v6.h | |||
| @@ -141,6 +141,7 @@ | |||
| 141 | #define S5P_FIMV_D_SLICE_IF_ENABLE_V6 0xf4c4 | 141 | #define S5P_FIMV_D_SLICE_IF_ENABLE_V6 0xf4c4 |
| 142 | #define S5P_FIMV_D_PICTURE_TAG_V6 0xf4c8 | 142 | #define S5P_FIMV_D_PICTURE_TAG_V6 0xf4c8 |
| 143 | #define S5P_FIMV_D_STREAM_DATA_SIZE_V6 0xf4d0 | 143 | #define S5P_FIMV_D_STREAM_DATA_SIZE_V6 0xf4d0 |
| 144 | #define S5P_FIMV_D_INIT_BUFFER_OPTIONS_V6 0xf47c | ||
| 144 | 145 | ||
| 145 | /* Display information register */ | 146 | /* Display information register */ |
| 146 | #define S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6 0xf500 | 147 | #define S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6 0xf500 |
| @@ -381,8 +382,7 @@ | |||
| 381 | (DIV_ROUND_UP((mbw) * (mbh), 32) * 16)) | 382 | (DIV_ROUND_UP((mbw) * (mbh), 32) * 16)) |
| 382 | #define S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6(w, h) (((w) * 192) + 64) | 383 | #define S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6(w, h) (((w) * 192) + 64) |
| 383 | #define S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(w, h) \ | 384 | #define S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6(w, h) \ |
| 384 | ((w) * ((h) * 64 + 144) + (2048/16 * (h) * 64) + \ | 385 | ((w) * 144 + 8192 * (h) + 49216 + 1048576) |
| 385 | (2048/16 * 256 + 8320)) | ||
| 386 | #define S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(w, h) \ | 386 | #define S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6(w, h) \ |
| 387 | (2096 * ((w) + (h) + 1)) | 387 | (2096 * ((w) + (h) + 1)) |
| 388 | #define S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(w, h) ((w) * 400) | 388 | #define S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6(w, h) ((w) * 400) |
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v7.h b/drivers/media/platform/s5p-mfc/regs-mfc-v7.h index ea5ec2a711af..1a5c6fdf7846 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v7.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v7.h | |||
| @@ -18,8 +18,6 @@ | |||
| 18 | #define S5P_FIMV_CODEC_VP8_ENC_V7 25 | 18 | #define S5P_FIMV_CODEC_VP8_ENC_V7 25 |
| 19 | 19 | ||
| 20 | /* Additional registers for v7 */ | 20 | /* Additional registers for v7 */ |
| 21 | #define S5P_FIMV_D_INIT_BUFFER_OPTIONS_V7 0xf47c | ||
| 22 | |||
| 23 | #define S5P_FIMV_E_SOURCE_FIRST_ADDR_V7 0xf9e0 | 21 | #define S5P_FIMV_E_SOURCE_FIRST_ADDR_V7 0xf9e0 |
| 24 | #define S5P_FIMV_E_SOURCE_SECOND_ADDR_V7 0xf9e4 | 22 | #define S5P_FIMV_E_SOURCE_SECOND_ADDR_V7 0xf9e4 |
| 25 | #define S5P_FIMV_E_SOURCE_THIRD_ADDR_V7 0xf9e8 | 23 | #define S5P_FIMV_E_SOURCE_THIRD_ADDR_V7 0xf9e8 |
| @@ -56,6 +54,7 @@ | |||
| 56 | (SZ_1M + ((w) * 144) + (8192 * (h)) + 49216) | 54 | (SZ_1M + ((w) * 144) + (8192 * (h)) + 49216) |
| 57 | 55 | ||
| 58 | #define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V7(w, h) \ | 56 | #define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V7(w, h) \ |
| 59 | (((w) * 48) + (((w) + 1) / 2 * 128) + 144 + 8192) | 57 | (((w) * 48) + 8192 + ((((w) + 1) / 2) * 128) + 144 + \ |
| 58 | ((((((w) * 16) * ((h) * 16)) * 3) / 2) * 4)) | ||
| 60 | 59 | ||
| 61 | #endif /*_REGS_MFC_V7_H*/ | 60 | #endif /*_REGS_MFC_V7_H*/ |
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h new file mode 100644 index 000000000000..cc7cbec51b5e --- /dev/null +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /* | ||
| 2 | * Register definition file for Samsung MFC V8.x Interface (FIMV) driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
| 5 | * http://www.samsung.com/ | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _REGS_MFC_V8_H | ||
| 13 | #define _REGS_MFC_V8_H | ||
| 14 | |||
| 15 | #include <linux/sizes.h> | ||
| 16 | #include "regs-mfc-v7.h" | ||
| 17 | |||
| 18 | /* Additional registers for v8 */ | ||
| 19 | #define S5P_FIMV_D_MVC_NUM_VIEWS_V8 0xf104 | ||
| 20 | #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8 0xf144 | ||
| 21 | #define S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8 0xf148 | ||
| 22 | #define S5P_FIMV_D_MV_BUFFER_SIZE_V8 0xf150 | ||
| 23 | |||
| 24 | #define S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8 0xf138 | ||
| 25 | #define S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8 0xf13c | ||
| 26 | |||
| 27 | #define S5P_FIMV_D_FIRST_PLANE_DPB_V8 0xf160 | ||
| 28 | #define S5P_FIMV_D_SECOND_PLANE_DPB_V8 0xf260 | ||
| 29 | #define S5P_FIMV_D_MV_BUFFER_V8 0xf460 | ||
| 30 | |||
| 31 | #define S5P_FIMV_D_NUM_MV_V8 0xf134 | ||
| 32 | #define S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8 0xf154 | ||
| 33 | |||
| 34 | #define S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8 0xf560 | ||
| 35 | #define S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8 0xf564 | ||
| 36 | |||
| 37 | #define S5P_FIMV_D_CPB_BUFFER_ADDR_V8 0xf5b0 | ||
| 38 | #define S5P_FIMV_D_CPB_BUFFER_SIZE_V8 0xf5b4 | ||
| 39 | #define S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8 0xf5bc | ||
| 40 | #define S5P_FIMV_D_CPB_BUFFER_OFFSET_V8 0xf5c0 | ||
| 41 | #define S5P_FIMV_D_SLICE_IF_ENABLE_V8 0xf5c4 | ||
| 42 | #define S5P_FIMV_D_STREAM_DATA_SIZE_V8 0xf5d0 | ||
| 43 | |||
| 44 | /* Display information register */ | ||
| 45 | #define S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V8 0xf600 | ||
| 46 | #define S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V8 0xf604 | ||
| 47 | |||
| 48 | /* Display status */ | ||
| 49 | #define S5P_FIMV_D_DISPLAY_STATUS_V8 0xf608 | ||
| 50 | |||
| 51 | #define S5P_FIMV_D_DISPLAY_FIRST_PLANE_ADDR_V8 0xf60c | ||
| 52 | #define S5P_FIMV_D_DISPLAY_SECOND_PLANE_ADDR_V8 0xf610 | ||
| 53 | |||
| 54 | #define S5P_FIMV_D_DISPLAY_FRAME_TYPE_V8 0xf618 | ||
| 55 | #define S5P_FIMV_D_DISPLAY_CROP_INFO1_V8 0xf61c | ||
| 56 | #define S5P_FIMV_D_DISPLAY_CROP_INFO2_V8 0xf620 | ||
| 57 | #define S5P_FIMV_D_DISPLAY_PICTURE_PROFILE_V8 0xf624 | ||
| 58 | |||
| 59 | /* Decoded picture information register */ | ||
| 60 | #define S5P_FIMV_D_DECODED_STATUS_V8 0xf644 | ||
| 61 | #define S5P_FIMV_D_DECODED_FIRST_PLANE_ADDR_V8 0xf648 | ||
| 62 | #define S5P_FIMV_D_DECODED_SECOND_PLANE_ADDR_V8 0xf64c | ||
| 63 | #define S5P_FIMV_D_DECODED_THIRD_PLANE_ADDR_V8 0xf650 | ||
| 64 | #define S5P_FIMV_D_DECODED_FRAME_TYPE_V8 0xf654 | ||
| 65 | #define S5P_FIMV_D_DECODED_NAL_SIZE_V8 0xf664 | ||
| 66 | |||
| 67 | /* Returned value register for specific setting */ | ||
| 68 | #define S5P_FIMV_D_RET_PICTURE_TAG_TOP_V8 0xf674 | ||
| 69 | #define S5P_FIMV_D_RET_PICTURE_TAG_BOT_V8 0xf678 | ||
| 70 | #define S5P_FIMV_D_MVC_VIEW_ID_V8 0xf6d8 | ||
| 71 | |||
| 72 | /* SEI related information */ | ||
| 73 | #define S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V8 0xf6dc | ||
| 74 | |||
| 75 | /* Encoder Registers */ | ||
| 76 | #define S5P_FIMV_E_FIXED_PICTURE_QP_V8 0xf794 | ||
| 77 | #define S5P_FIMV_E_RC_CONFIG_V8 0xf798 | ||
| 78 | #define S5P_FIMV_E_RC_QP_BOUND_V8 0xf79c | ||
| 79 | #define S5P_FIMV_E_RC_RPARAM_V8 0xf7a4 | ||
| 80 | #define S5P_FIMV_E_MB_RC_CONFIG_V8 0xf7a8 | ||
| 81 | #define S5P_FIMV_E_PADDING_CTRL_V8 0xf7ac | ||
| 82 | #define S5P_FIMV_E_MV_HOR_RANGE_V8 0xf7b4 | ||
| 83 | #define S5P_FIMV_E_MV_VER_RANGE_V8 0xf7b8 | ||
| 84 | |||
| 85 | #define S5P_FIMV_E_VBV_BUFFER_SIZE_V8 0xf78c | ||
| 86 | #define S5P_FIMV_E_VBV_INIT_DELAY_V8 0xf790 | ||
| 87 | |||
| 88 | #define S5P_FIMV_E_ASPECT_RATIO_V8 0xfb4c | ||
| 89 | #define S5P_FIMV_E_EXTENDED_SAR_V8 0xfb50 | ||
| 90 | #define S5P_FIMV_E_H264_OPTIONS_V8 0xfb54 | ||
| 91 | |||
| 92 | /* MFCv8 Context buffer sizes */ | ||
| 93 | #define MFC_CTX_BUF_SIZE_V8 (30 * SZ_1K) /* 30KB */ | ||
| 94 | #define MFC_H264_DEC_CTX_BUF_SIZE_V8 (2 * SZ_1M) /* 2MB */ | ||
| 95 | #define MFC_OTHER_DEC_CTX_BUF_SIZE_V8 (20 * SZ_1K) /* 20KB */ | ||
| 96 | #define MFC_H264_ENC_CTX_BUF_SIZE_V8 (100 * SZ_1K) /* 100KB */ | ||
| 97 | #define MFC_OTHER_ENC_CTX_BUF_SIZE_V8 (10 * SZ_1K) /* 10KB */ | ||
| 98 | |||
| 99 | /* Buffer size defines */ | ||
| 100 | #define S5P_FIMV_TMV_BUFFER_SIZE_V8(w, h) (((w) + 1) * ((h) + 1) * 8) | ||
| 101 | |||
| 102 | #define S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V8(w, h) (((w) * 704) + 2176) | ||
| 103 | #define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V8(w, h) \ | ||
| 104 | (((w) * 576 + (h) * 128) + 4128) | ||
| 105 | |||
| 106 | #define S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V8(w, h) \ | ||
| 107 | (((w) * 592) + 2336) | ||
| 108 | #define S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V8(w, h) \ | ||
| 109 | (((w) * 576) + 10512 + \ | ||
| 110 | ((((((w) * 16) * ((h) * 16)) * 3) / 2) * 4)) | ||
| 111 | #define S5P_FIMV_ME_BUFFER_SIZE_V8(imw, imh, mbw, mbh) \ | ||
| 112 | ((DIV_ROUND_UP((mbw * 16), 64) * DIV_ROUND_UP((mbh * 16), 64) * 256) \ | ||
| 113 | + (DIV_ROUND_UP((mbw) * (mbh), 32) * 16)) | ||
| 114 | |||
| 115 | /* BUffer alignment defines */ | ||
| 116 | #define S5P_FIMV_D_ALIGN_PLANE_SIZE_V8 64 | ||
| 117 | |||
| 118 | /* MFCv8 variant defines */ | ||
| 119 | #define MAX_FW_SIZE_V8 (SZ_1M) /* 1MB */ | ||
| 120 | #define MAX_CPB_SIZE_V8 (3 * SZ_1M) /* 3MB */ | ||
| 121 | #define MFC_VERSION_V8 0x80 | ||
| 122 | #define MFC_NUM_PORTS_V8 1 | ||
| 123 | |||
| 124 | #endif /*_REGS_MFC_V8_H*/ | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 89356ae90238..41723180d10c 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
| @@ -309,12 +309,15 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
| 309 | { | 309 | { |
| 310 | struct s5p_mfc_dev *dev = ctx->dev; | 310 | struct s5p_mfc_dev *dev = ctx->dev; |
| 311 | unsigned int dst_frame_status; | 311 | unsigned int dst_frame_status; |
| 312 | unsigned int dec_frame_status; | ||
| 312 | struct s5p_mfc_buf *src_buf; | 313 | struct s5p_mfc_buf *src_buf; |
| 313 | unsigned long flags; | 314 | unsigned long flags; |
| 314 | unsigned int res_change; | 315 | unsigned int res_change; |
| 315 | 316 | ||
| 316 | dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) | 317 | dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) |
| 317 | & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; | 318 | & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; |
| 319 | dec_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dec_status, dev) | ||
| 320 | & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; | ||
| 318 | res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) | 321 | res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) |
| 319 | & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK) | 322 | & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK) |
| 320 | >> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT; | 323 | >> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT; |
| @@ -339,16 +342,23 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
| 339 | /* All frames remaining in the buffer have been extracted */ | 342 | /* All frames remaining in the buffer have been extracted */ |
| 340 | if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) { | 343 | if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) { |
| 341 | if (ctx->state == MFCINST_RES_CHANGE_FLUSH) { | 344 | if (ctx->state == MFCINST_RES_CHANGE_FLUSH) { |
| 345 | static const struct v4l2_event ev_src_ch = { | ||
| 346 | .type = V4L2_EVENT_SOURCE_CHANGE, | ||
| 347 | .u.src_change.changes = | ||
| 348 | V4L2_EVENT_SRC_CH_RESOLUTION, | ||
| 349 | }; | ||
| 350 | |||
| 342 | s5p_mfc_handle_frame_all_extracted(ctx); | 351 | s5p_mfc_handle_frame_all_extracted(ctx); |
| 343 | ctx->state = MFCINST_RES_CHANGE_END; | 352 | ctx->state = MFCINST_RES_CHANGE_END; |
| 353 | v4l2_event_queue_fh(&ctx->fh, &ev_src_ch); | ||
| 354 | |||
| 344 | goto leave_handle_frame; | 355 | goto leave_handle_frame; |
| 345 | } else { | 356 | } else { |
| 346 | s5p_mfc_handle_frame_all_extracted(ctx); | 357 | s5p_mfc_handle_frame_all_extracted(ctx); |
| 347 | } | 358 | } |
| 348 | } | 359 | } |
| 349 | 360 | ||
| 350 | if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY || | 361 | if (dec_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY) |
| 351 | dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY) | ||
| 352 | s5p_mfc_handle_frame_copy_time(ctx); | 362 | s5p_mfc_handle_frame_copy_time(ctx); |
| 353 | 363 | ||
| 354 | /* A frame has been decoded and is in the buffer */ | 364 | /* A frame has been decoded and is in the buffer */ |
| @@ -366,6 +376,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, | |||
| 366 | ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops, | 376 | ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops, |
| 367 | get_consumed_stream, dev); | 377 | get_consumed_stream, dev); |
| 368 | if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && | 378 | if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && |
| 379 | ctx->codec_mode != S5P_MFC_CODEC_VP8_DEC && | ||
| 369 | ctx->consumed_stream + STUFF_BYTE < | 380 | ctx->consumed_stream + STUFF_BYTE < |
| 370 | src_buf->b->v4l2_planes[0].bytesused) { | 381 | src_buf->b->v4l2_planes[0].bytesused) { |
| 371 | /* Run MFC again on the same buffer */ | 382 | /* Run MFC again on the same buffer */ |
| @@ -641,6 +652,7 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) | |||
| 641 | 652 | ||
| 642 | case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET: | 653 | case S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET: |
| 643 | clear_work_bit(ctx); | 654 | clear_work_bit(ctx); |
| 655 | ctx->inst_no = MFC_NO_INSTANCE_SET; | ||
| 644 | ctx->state = MFCINST_FREE; | 656 | ctx->state = MFCINST_FREE; |
| 645 | wake_up(&ctx->queue); | 657 | wake_up(&ctx->queue); |
| 646 | goto irq_cleanup_hw; | 658 | goto irq_cleanup_hw; |
| @@ -761,7 +773,7 @@ static int s5p_mfc_open(struct file *file) | |||
| 761 | goto err_bad_node; | 773 | goto err_bad_node; |
| 762 | } | 774 | } |
| 763 | ctx->fh.ctrl_handler = &ctx->ctrl_handler; | 775 | ctx->fh.ctrl_handler = &ctx->ctrl_handler; |
| 764 | ctx->inst_no = -1; | 776 | ctx->inst_no = MFC_NO_INSTANCE_SET; |
| 765 | /* Load firmware if this is the first instance */ | 777 | /* Load firmware if this is the first instance */ |
| 766 | if (dev->num_inst == 1) { | 778 | if (dev->num_inst == 1) { |
| 767 | dev->watchdog_timer.expires = jiffies + | 779 | dev->watchdog_timer.expires = jiffies + |
| @@ -871,29 +883,11 @@ static int s5p_mfc_release(struct file *file) | |||
| 871 | vb2_queue_release(&ctx->vq_dst); | 883 | vb2_queue_release(&ctx->vq_dst); |
| 872 | /* Mark context as idle */ | 884 | /* Mark context as idle */ |
| 873 | clear_work_bit_irqsave(ctx); | 885 | clear_work_bit_irqsave(ctx); |
| 874 | /* If instance was initialised then | 886 | /* If instance was initialised and not yet freed, |
| 875 | * return instance and free resources */ | 887 | * return instance and free resources */ |
| 876 | if (ctx->inst_no != MFC_NO_INSTANCE_SET) { | 888 | if (ctx->state != MFCINST_FREE && ctx->state != MFCINST_INIT) { |
| 877 | mfc_debug(2, "Has to free instance\n"); | 889 | mfc_debug(2, "Has to free instance\n"); |
| 878 | ctx->state = MFCINST_RETURN_INST; | 890 | s5p_mfc_close_mfc_inst(dev, ctx); |
| 879 | set_work_bit_irqsave(ctx); | ||
| 880 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
| 881 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | ||
| 882 | /* Wait until instance is returned or timeout occurred */ | ||
| 883 | if (s5p_mfc_wait_for_done_ctx | ||
| 884 | (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) { | ||
| 885 | s5p_mfc_clock_off(); | ||
| 886 | mfc_err("Err returning instance\n"); | ||
| 887 | } | ||
| 888 | mfc_debug(2, "After free instance\n"); | ||
| 889 | /* Free resources */ | ||
| 890 | s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx); | ||
| 891 | s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx); | ||
| 892 | if (ctx->type == MFCINST_DECODER) | ||
| 893 | s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, | ||
| 894 | ctx); | ||
| 895 | |||
| 896 | ctx->inst_no = MFC_NO_INSTANCE_SET; | ||
| 897 | } | 891 | } |
| 898 | /* hardware locking scheme */ | 892 | /* hardware locking scheme */ |
| 899 | if (dev->curr_ctx == ctx->num) | 893 | if (dev->curr_ctx == ctx->num) |
| @@ -1207,6 +1201,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) | |||
| 1207 | /* Initialize HW ops and commands based on MFC version */ | 1201 | /* Initialize HW ops and commands based on MFC version */ |
| 1208 | s5p_mfc_init_hw_ops(dev); | 1202 | s5p_mfc_init_hw_ops(dev); |
| 1209 | s5p_mfc_init_hw_cmds(dev); | 1203 | s5p_mfc_init_hw_cmds(dev); |
| 1204 | s5p_mfc_init_regs(dev); | ||
| 1210 | 1205 | ||
| 1211 | pr_debug("%s--\n", __func__); | 1206 | pr_debug("%s--\n", __func__); |
| 1212 | return 0; | 1207 | return 0; |
| @@ -1352,6 +1347,7 @@ struct s5p_mfc_buf_align mfc_buf_align_v5 = { | |||
| 1352 | 1347 | ||
| 1353 | static struct s5p_mfc_variant mfc_drvdata_v5 = { | 1348 | static struct s5p_mfc_variant mfc_drvdata_v5 = { |
| 1354 | .version = MFC_VERSION, | 1349 | .version = MFC_VERSION, |
| 1350 | .version_bit = MFC_V5_BIT, | ||
| 1355 | .port_num = MFC_NUM_PORTS, | 1351 | .port_num = MFC_NUM_PORTS, |
| 1356 | .buf_size = &buf_size_v5, | 1352 | .buf_size = &buf_size_v5, |
| 1357 | .buf_align = &mfc_buf_align_v5, | 1353 | .buf_align = &mfc_buf_align_v5, |
| @@ -1378,6 +1374,7 @@ struct s5p_mfc_buf_align mfc_buf_align_v6 = { | |||
| 1378 | 1374 | ||
| 1379 | static struct s5p_mfc_variant mfc_drvdata_v6 = { | 1375 | static struct s5p_mfc_variant mfc_drvdata_v6 = { |
| 1380 | .version = MFC_VERSION_V6, | 1376 | .version = MFC_VERSION_V6, |
| 1377 | .version_bit = MFC_V6_BIT, | ||
| 1381 | .port_num = MFC_NUM_PORTS_V6, | 1378 | .port_num = MFC_NUM_PORTS_V6, |
| 1382 | .buf_size = &buf_size_v6, | 1379 | .buf_size = &buf_size_v6, |
| 1383 | .buf_align = &mfc_buf_align_v6, | 1380 | .buf_align = &mfc_buf_align_v6, |
| @@ -1404,12 +1401,40 @@ struct s5p_mfc_buf_align mfc_buf_align_v7 = { | |||
| 1404 | 1401 | ||
| 1405 | static struct s5p_mfc_variant mfc_drvdata_v7 = { | 1402 | static struct s5p_mfc_variant mfc_drvdata_v7 = { |
| 1406 | .version = MFC_VERSION_V7, | 1403 | .version = MFC_VERSION_V7, |
| 1404 | .version_bit = MFC_V7_BIT, | ||
| 1407 | .port_num = MFC_NUM_PORTS_V7, | 1405 | .port_num = MFC_NUM_PORTS_V7, |
| 1408 | .buf_size = &buf_size_v7, | 1406 | .buf_size = &buf_size_v7, |
| 1409 | .buf_align = &mfc_buf_align_v7, | 1407 | .buf_align = &mfc_buf_align_v7, |
| 1410 | .fw_name = "s5p-mfc-v7.fw", | 1408 | .fw_name = "s5p-mfc-v7.fw", |
| 1411 | }; | 1409 | }; |
| 1412 | 1410 | ||
| 1411 | struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { | ||
| 1412 | .dev_ctx = MFC_CTX_BUF_SIZE_V8, | ||
| 1413 | .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V8, | ||
| 1414 | .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V8, | ||
| 1415 | .h264_enc_ctx = MFC_H264_ENC_CTX_BUF_SIZE_V8, | ||
| 1416 | .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V8, | ||
| 1417 | }; | ||
| 1418 | |||
| 1419 | struct s5p_mfc_buf_size buf_size_v8 = { | ||
| 1420 | .fw = MAX_FW_SIZE_V8, | ||
| 1421 | .cpb = MAX_CPB_SIZE_V8, | ||
| 1422 | .priv = &mfc_buf_size_v8, | ||
| 1423 | }; | ||
| 1424 | |||
| 1425 | struct s5p_mfc_buf_align mfc_buf_align_v8 = { | ||
| 1426 | .base = 0, | ||
| 1427 | }; | ||
| 1428 | |||
| 1429 | static struct s5p_mfc_variant mfc_drvdata_v8 = { | ||
| 1430 | .version = MFC_VERSION_V8, | ||
| 1431 | .version_bit = MFC_V8_BIT, | ||
| 1432 | .port_num = MFC_NUM_PORTS_V8, | ||
| 1433 | .buf_size = &buf_size_v8, | ||
| 1434 | .buf_align = &mfc_buf_align_v8, | ||
| 1435 | .fw_name = "s5p-mfc-v8.fw", | ||
| 1436 | }; | ||
| 1437 | |||
| 1413 | static struct platform_device_id mfc_driver_ids[] = { | 1438 | static struct platform_device_id mfc_driver_ids[] = { |
| 1414 | { | 1439 | { |
| 1415 | .name = "s5p-mfc", | 1440 | .name = "s5p-mfc", |
| @@ -1423,6 +1448,9 @@ static struct platform_device_id mfc_driver_ids[] = { | |||
| 1423 | }, { | 1448 | }, { |
| 1424 | .name = "s5p-mfc-v7", | 1449 | .name = "s5p-mfc-v7", |
| 1425 | .driver_data = (unsigned long)&mfc_drvdata_v7, | 1450 | .driver_data = (unsigned long)&mfc_drvdata_v7, |
| 1451 | }, { | ||
| 1452 | .name = "s5p-mfc-v8", | ||
| 1453 | .driver_data = (unsigned long)&mfc_drvdata_v8, | ||
| 1426 | }, | 1454 | }, |
| 1427 | {}, | 1455 | {}, |
| 1428 | }; | 1456 | }; |
| @@ -1438,6 +1466,9 @@ static const struct of_device_id exynos_mfc_match[] = { | |||
| 1438 | }, { | 1466 | }, { |
| 1439 | .compatible = "samsung,mfc-v7", | 1467 | .compatible = "samsung,mfc-v7", |
| 1440 | .data = &mfc_drvdata_v7, | 1468 | .data = &mfc_drvdata_v7, |
| 1469 | }, { | ||
| 1470 | .compatible = "samsung,mfc-v8", | ||
| 1471 | .data = &mfc_drvdata_v8, | ||
| 1441 | }, | 1472 | }, |
| 1442 | {}, | 1473 | {}, |
| 1443 | }; | 1474 | }; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 5c28cc3e699b..b04360cd34f0 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h | |||
| @@ -23,8 +23,7 @@ | |||
| 23 | #include <media/v4l2-ioctl.h> | 23 | #include <media/v4l2-ioctl.h> |
| 24 | #include <media/videobuf2-core.h> | 24 | #include <media/videobuf2-core.h> |
| 25 | #include "regs-mfc.h" | 25 | #include "regs-mfc.h" |
| 26 | #include "regs-mfc-v6.h" | 26 | #include "regs-mfc-v8.h" |
| 27 | #include "regs-mfc-v7.h" | ||
| 28 | 27 | ||
| 29 | /* Definitions related to MFC memory */ | 28 | /* Definitions related to MFC memory */ |
| 30 | 29 | ||
| @@ -223,6 +222,7 @@ struct s5p_mfc_buf_align { | |||
| 223 | struct s5p_mfc_variant { | 222 | struct s5p_mfc_variant { |
| 224 | unsigned int version; | 223 | unsigned int version; |
| 225 | unsigned int port_num; | 224 | unsigned int port_num; |
| 225 | u32 version_bit; | ||
| 226 | struct s5p_mfc_buf_size *buf_size; | 226 | struct s5p_mfc_buf_size *buf_size; |
| 227 | struct s5p_mfc_buf_align *buf_align; | 227 | struct s5p_mfc_buf_align *buf_align; |
| 228 | char *fw_name; | 228 | char *fw_name; |
| @@ -330,6 +330,7 @@ struct s5p_mfc_dev { | |||
| 330 | int warn_start; | 330 | int warn_start; |
| 331 | struct s5p_mfc_hw_ops *mfc_ops; | 331 | struct s5p_mfc_hw_ops *mfc_ops; |
| 332 | struct s5p_mfc_hw_cmds *mfc_cmds; | 332 | struct s5p_mfc_hw_cmds *mfc_cmds; |
| 333 | const struct s5p_mfc_regs *mfc_regs; | ||
| 333 | }; | 334 | }; |
| 334 | 335 | ||
| 335 | /** | 336 | /** |
| @@ -663,6 +664,7 @@ struct s5p_mfc_fmt { | |||
| 663 | u32 codec_mode; | 664 | u32 codec_mode; |
| 664 | enum s5p_mfc_fmt_type type; | 665 | enum s5p_mfc_fmt_type type; |
| 665 | u32 num_planes; | 666 | u32 num_planes; |
| 667 | u32 versions; | ||
| 666 | }; | 668 | }; |
| 667 | 669 | ||
| 668 | /** | 670 | /** |
| @@ -700,6 +702,13 @@ void set_work_bit_irqsave(struct s5p_mfc_ctx *ctx); | |||
| 700 | (dev->variant->port_num ? 1 : 0) : 0) : 0) | 702 | (dev->variant->port_num ? 1 : 0) : 0) : 0) |
| 701 | #define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0) | 703 | #define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0) |
| 702 | #define IS_MFCV6_PLUS(dev) (dev->variant->version >= 0x60 ? 1 : 0) | 704 | #define IS_MFCV6_PLUS(dev) (dev->variant->version >= 0x60 ? 1 : 0) |
| 703 | #define IS_MFCV7(dev) (dev->variant->version >= 0x70 ? 1 : 0) | 705 | #define IS_MFCV7_PLUS(dev) (dev->variant->version >= 0x70 ? 1 : 0) |
| 706 | #define IS_MFCV8(dev) (dev->variant->version >= 0x80 ? 1 : 0) | ||
| 707 | |||
| 708 | #define MFC_V5_BIT BIT(0) | ||
| 709 | #define MFC_V6_BIT BIT(1) | ||
| 710 | #define MFC_V7_BIT BIT(2) | ||
| 711 | #define MFC_V8_BIT BIT(3) | ||
| 712 | |||
| 704 | 713 | ||
| 705 | #endif /* S5P_MFC_COMMON_H_ */ | 714 | #endif /* S5P_MFC_COMMON_H_ */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index ee05f2dd439b..6c3f8f743900 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | |||
| @@ -400,3 +400,65 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | |||
| 400 | return 0; | 400 | return 0; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) | ||
| 404 | { | ||
| 405 | int ret = 0; | ||
| 406 | |||
| 407 | ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx); | ||
| 408 | if (ret) { | ||
| 409 | mfc_err("Failed allocating instance buffer\n"); | ||
| 410 | goto err; | ||
| 411 | } | ||
| 412 | |||
| 413 | if (ctx->type == MFCINST_DECODER) { | ||
| 414 | ret = s5p_mfc_hw_call(dev->mfc_ops, | ||
| 415 | alloc_dec_temp_buffers, ctx); | ||
| 416 | if (ret) { | ||
| 417 | mfc_err("Failed allocating temporary buffers\n"); | ||
| 418 | goto err_free_inst_buf; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | set_work_bit_irqsave(ctx); | ||
| 423 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
| 424 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | ||
| 425 | if (s5p_mfc_wait_for_done_ctx(ctx, | ||
| 426 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { | ||
| 427 | /* Error or timeout */ | ||
| 428 | mfc_err("Error getting instance from hardware\n"); | ||
| 429 | ret = -EIO; | ||
| 430 | goto err_free_desc_buf; | ||
| 431 | } | ||
| 432 | |||
| 433 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); | ||
| 434 | return ret; | ||
| 435 | |||
| 436 | err_free_desc_buf: | ||
| 437 | if (ctx->type == MFCINST_DECODER) | ||
| 438 | s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx); | ||
| 439 | err_free_inst_buf: | ||
| 440 | s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx); | ||
| 441 | err: | ||
| 442 | return ret; | ||
| 443 | } | ||
| 444 | |||
| 445 | void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx) | ||
| 446 | { | ||
| 447 | ctx->state = MFCINST_RETURN_INST; | ||
| 448 | set_work_bit_irqsave(ctx); | ||
| 449 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
| 450 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | ||
| 451 | /* Wait until instance is returned or timeout occurred */ | ||
| 452 | if (s5p_mfc_wait_for_done_ctx(ctx, | ||
| 453 | S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) | ||
| 454 | mfc_err("Err returning instance\n"); | ||
| 455 | |||
| 456 | /* Free resources */ | ||
| 457 | s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx); | ||
| 458 | s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx); | ||
| 459 | if (ctx->type == MFCINST_DECODER) | ||
| 460 | s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx); | ||
| 461 | |||
| 462 | ctx->inst_no = MFC_NO_INSTANCE_SET; | ||
| 463 | ctx->state = MFCINST_FREE; | ||
| 464 | } | ||
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h index 6a9b6f8606bb..8e5df041edf7 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.h | |||
| @@ -28,4 +28,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev); | |||
| 28 | 28 | ||
| 29 | int s5p_mfc_reset(struct s5p_mfc_dev *dev); | 29 | int s5p_mfc_reset(struct s5p_mfc_dev *dev); |
| 30 | 30 | ||
| 31 | int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx); | ||
| 32 | void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx); | ||
| 33 | |||
| 31 | #endif /* S5P_MFC_CTRL_H */ | 34 | #endif /* S5P_MFC_CTRL_H */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 8faf9691712d..4d93835dec9d 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
| @@ -25,15 +25,13 @@ | |||
| 25 | #include <media/v4l2-event.h> | 25 | #include <media/v4l2-event.h> |
| 26 | #include <media/videobuf2-core.h> | 26 | #include <media/videobuf2-core.h> |
| 27 | #include "s5p_mfc_common.h" | 27 | #include "s5p_mfc_common.h" |
| 28 | #include "s5p_mfc_ctrl.h" | ||
| 28 | #include "s5p_mfc_debug.h" | 29 | #include "s5p_mfc_debug.h" |
| 29 | #include "s5p_mfc_dec.h" | 30 | #include "s5p_mfc_dec.h" |
| 30 | #include "s5p_mfc_intr.h" | 31 | #include "s5p_mfc_intr.h" |
| 31 | #include "s5p_mfc_opr.h" | 32 | #include "s5p_mfc_opr.h" |
| 32 | #include "s5p_mfc_pm.h" | 33 | #include "s5p_mfc_pm.h" |
| 33 | 34 | ||
| 34 | #define DEF_SRC_FMT_DEC V4L2_PIX_FMT_H264 | ||
| 35 | #define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12MT_16X16 | ||
| 36 | |||
| 37 | static struct s5p_mfc_fmt formats[] = { | 35 | static struct s5p_mfc_fmt formats[] = { |
| 38 | { | 36 | { |
| 39 | .name = "4:2:0 2 Planes 16x16 Tiles", | 37 | .name = "4:2:0 2 Planes 16x16 Tiles", |
| @@ -41,6 +39,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 41 | .codec_mode = S5P_MFC_CODEC_NONE, | 39 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 42 | .type = MFC_FMT_RAW, | 40 | .type = MFC_FMT_RAW, |
| 43 | .num_planes = 2, | 41 | .num_planes = 2, |
| 42 | .versions = MFC_V6_BIT | MFC_V7_BIT, | ||
| 44 | }, | 43 | }, |
| 45 | { | 44 | { |
| 46 | .name = "4:2:0 2 Planes 64x32 Tiles", | 45 | .name = "4:2:0 2 Planes 64x32 Tiles", |
| @@ -48,6 +47,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 48 | .codec_mode = S5P_MFC_CODEC_NONE, | 47 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 49 | .type = MFC_FMT_RAW, | 48 | .type = MFC_FMT_RAW, |
| 50 | .num_planes = 2, | 49 | .num_planes = 2, |
| 50 | .versions = MFC_V5_BIT, | ||
| 51 | }, | 51 | }, |
| 52 | { | 52 | { |
| 53 | .name = "4:2:0 2 Planes Y/CbCr", | 53 | .name = "4:2:0 2 Planes Y/CbCr", |
| @@ -55,6 +55,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 55 | .codec_mode = S5P_MFC_CODEC_NONE, | 55 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 56 | .type = MFC_FMT_RAW, | 56 | .type = MFC_FMT_RAW, |
| 57 | .num_planes = 2, | 57 | .num_planes = 2, |
| 58 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | ||
| 58 | }, | 59 | }, |
| 59 | { | 60 | { |
| 60 | .name = "4:2:0 2 Planes Y/CrCb", | 61 | .name = "4:2:0 2 Planes Y/CrCb", |
| @@ -62,6 +63,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 62 | .codec_mode = S5P_MFC_CODEC_NONE, | 63 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 63 | .type = MFC_FMT_RAW, | 64 | .type = MFC_FMT_RAW, |
| 64 | .num_planes = 2, | 65 | .num_planes = 2, |
| 66 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | ||
| 65 | }, | 67 | }, |
| 66 | { | 68 | { |
| 67 | .name = "H264 Encoded Stream", | 69 | .name = "H264 Encoded Stream", |
| @@ -69,6 +71,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 69 | .codec_mode = S5P_MFC_CODEC_H264_DEC, | 71 | .codec_mode = S5P_MFC_CODEC_H264_DEC, |
| 70 | .type = MFC_FMT_DEC, | 72 | .type = MFC_FMT_DEC, |
| 71 | .num_planes = 1, | 73 | .num_planes = 1, |
| 74 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 75 | MFC_V8_BIT, | ||
| 72 | }, | 76 | }, |
| 73 | { | 77 | { |
| 74 | .name = "H264/MVC Encoded Stream", | 78 | .name = "H264/MVC Encoded Stream", |
| @@ -76,6 +80,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 76 | .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC, | 80 | .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC, |
| 77 | .type = MFC_FMT_DEC, | 81 | .type = MFC_FMT_DEC, |
| 78 | .num_planes = 1, | 82 | .num_planes = 1, |
| 83 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | ||
| 79 | }, | 84 | }, |
| 80 | { | 85 | { |
| 81 | .name = "H263 Encoded Stream", | 86 | .name = "H263 Encoded Stream", |
| @@ -83,6 +88,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 83 | .codec_mode = S5P_MFC_CODEC_H263_DEC, | 88 | .codec_mode = S5P_MFC_CODEC_H263_DEC, |
| 84 | .type = MFC_FMT_DEC, | 89 | .type = MFC_FMT_DEC, |
| 85 | .num_planes = 1, | 90 | .num_planes = 1, |
| 91 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 92 | MFC_V8_BIT, | ||
| 86 | }, | 93 | }, |
| 87 | { | 94 | { |
| 88 | .name = "MPEG1 Encoded Stream", | 95 | .name = "MPEG1 Encoded Stream", |
| @@ -90,6 +97,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 90 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, | 97 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, |
| 91 | .type = MFC_FMT_DEC, | 98 | .type = MFC_FMT_DEC, |
| 92 | .num_planes = 1, | 99 | .num_planes = 1, |
| 100 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 101 | MFC_V8_BIT, | ||
| 93 | }, | 102 | }, |
| 94 | { | 103 | { |
| 95 | .name = "MPEG2 Encoded Stream", | 104 | .name = "MPEG2 Encoded Stream", |
| @@ -97,6 +106,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 97 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, | 106 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, |
| 98 | .type = MFC_FMT_DEC, | 107 | .type = MFC_FMT_DEC, |
| 99 | .num_planes = 1, | 108 | .num_planes = 1, |
| 109 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 110 | MFC_V8_BIT, | ||
| 100 | }, | 111 | }, |
| 101 | { | 112 | { |
| 102 | .name = "MPEG4 Encoded Stream", | 113 | .name = "MPEG4 Encoded Stream", |
| @@ -104,6 +115,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 104 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, | 115 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, |
| 105 | .type = MFC_FMT_DEC, | 116 | .type = MFC_FMT_DEC, |
| 106 | .num_planes = 1, | 117 | .num_planes = 1, |
| 118 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 119 | MFC_V8_BIT, | ||
| 107 | }, | 120 | }, |
| 108 | { | 121 | { |
| 109 | .name = "XviD Encoded Stream", | 122 | .name = "XviD Encoded Stream", |
| @@ -111,6 +124,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 111 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, | 124 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, |
| 112 | .type = MFC_FMT_DEC, | 125 | .type = MFC_FMT_DEC, |
| 113 | .num_planes = 1, | 126 | .num_planes = 1, |
| 127 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 128 | MFC_V8_BIT, | ||
| 114 | }, | 129 | }, |
| 115 | { | 130 | { |
| 116 | .name = "VC1 Encoded Stream", | 131 | .name = "VC1 Encoded Stream", |
| @@ -118,6 +133,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 118 | .codec_mode = S5P_MFC_CODEC_VC1_DEC, | 133 | .codec_mode = S5P_MFC_CODEC_VC1_DEC, |
| 119 | .type = MFC_FMT_DEC, | 134 | .type = MFC_FMT_DEC, |
| 120 | .num_planes = 1, | 135 | .num_planes = 1, |
| 136 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 137 | MFC_V8_BIT, | ||
| 121 | }, | 138 | }, |
| 122 | { | 139 | { |
| 123 | .name = "VC1 RCV Encoded Stream", | 140 | .name = "VC1 RCV Encoded Stream", |
| @@ -125,6 +142,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 125 | .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC, | 142 | .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC, |
| 126 | .type = MFC_FMT_DEC, | 143 | .type = MFC_FMT_DEC, |
| 127 | .num_planes = 1, | 144 | .num_planes = 1, |
| 145 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 146 | MFC_V8_BIT, | ||
| 128 | }, | 147 | }, |
| 129 | { | 148 | { |
| 130 | .name = "VP8 Encoded Stream", | 149 | .name = "VP8 Encoded Stream", |
| @@ -132,6 +151,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 132 | .codec_mode = S5P_MFC_CODEC_VP8_DEC, | 151 | .codec_mode = S5P_MFC_CODEC_VP8_DEC, |
| 133 | .type = MFC_FMT_DEC, | 152 | .type = MFC_FMT_DEC, |
| 134 | .num_planes = 1, | 153 | .num_planes = 1, |
| 154 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | ||
| 135 | }, | 155 | }, |
| 136 | }; | 156 | }; |
| 137 | 157 | ||
| @@ -262,8 +282,10 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 262 | } | 282 | } |
| 263 | 283 | ||
| 264 | /* Enumerate format */ | 284 | /* Enumerate format */ |
| 265 | static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) | 285 | static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, |
| 286 | bool mplane, bool out) | ||
| 266 | { | 287 | { |
| 288 | struct s5p_mfc_dev *dev = video_drvdata(file); | ||
| 267 | struct s5p_mfc_fmt *fmt; | 289 | struct s5p_mfc_fmt *fmt; |
| 268 | int i, j = 0; | 290 | int i, j = 0; |
| 269 | 291 | ||
| @@ -276,6 +298,8 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) | |||
| 276 | continue; | 298 | continue; |
| 277 | else if (!out && formats[i].type != MFC_FMT_RAW) | 299 | else if (!out && formats[i].type != MFC_FMT_RAW) |
| 278 | continue; | 300 | continue; |
| 301 | else if ((dev->variant->version_bit & formats[i].versions) == 0) | ||
| 302 | continue; | ||
| 279 | 303 | ||
| 280 | if (j == f->index) | 304 | if (j == f->index) |
| 281 | break; | 305 | break; |
| @@ -292,25 +316,25 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) | |||
| 292 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, | 316 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, |
| 293 | struct v4l2_fmtdesc *f) | 317 | struct v4l2_fmtdesc *f) |
| 294 | { | 318 | { |
| 295 | return vidioc_enum_fmt(f, false, false); | 319 | return vidioc_enum_fmt(file, f, false, false); |
| 296 | } | 320 | } |
| 297 | 321 | ||
| 298 | static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, | 322 | static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, |
| 299 | struct v4l2_fmtdesc *f) | 323 | struct v4l2_fmtdesc *f) |
| 300 | { | 324 | { |
| 301 | return vidioc_enum_fmt(f, true, false); | 325 | return vidioc_enum_fmt(file, f, true, false); |
| 302 | } | 326 | } |
| 303 | 327 | ||
| 304 | static int vidioc_enum_fmt_vid_out(struct file *file, void *prov, | 328 | static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, |
| 305 | struct v4l2_fmtdesc *f) | 329 | struct v4l2_fmtdesc *f) |
| 306 | { | 330 | { |
| 307 | return vidioc_enum_fmt(f, false, true); | 331 | return vidioc_enum_fmt(file, f, false, true); |
| 308 | } | 332 | } |
| 309 | 333 | ||
| 310 | static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, | 334 | static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *priv, |
| 311 | struct v4l2_fmtdesc *f) | 335 | struct v4l2_fmtdesc *f) |
| 312 | { | 336 | { |
| 313 | return vidioc_enum_fmt(f, true, true); | 337 | return vidioc_enum_fmt(file, f, true, true); |
| 314 | } | 338 | } |
| 315 | 339 | ||
| 316 | /* Get format */ | 340 | /* Get format */ |
| @@ -386,11 +410,9 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 386 | mfc_err("Unknown codec\n"); | 410 | mfc_err("Unknown codec\n"); |
| 387 | return -EINVAL; | 411 | return -EINVAL; |
| 388 | } | 412 | } |
| 389 | if (!IS_MFCV6_PLUS(dev)) { | 413 | if ((dev->variant->version_bit & fmt->versions) == 0) { |
| 390 | if (fmt->fourcc == V4L2_PIX_FMT_VP8) { | 414 | mfc_err("Unsupported format by this MFC version.\n"); |
| 391 | mfc_err("Not supported format.\n"); | 415 | return -EINVAL; |
| 392 | return -EINVAL; | ||
| 393 | } | ||
| 394 | } | 416 | } |
| 395 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 417 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
| 396 | fmt = find_format(f, MFC_FMT_RAW); | 418 | fmt = find_format(f, MFC_FMT_RAW); |
| @@ -398,13 +420,8 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 398 | mfc_err("Unsupported format for destination.\n"); | 420 | mfc_err("Unsupported format for destination.\n"); |
| 399 | return -EINVAL; | 421 | return -EINVAL; |
| 400 | } | 422 | } |
| 401 | if (IS_MFCV6_PLUS(dev) && | 423 | if ((dev->variant->version_bit & fmt->versions) == 0) { |
| 402 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) { | 424 | mfc_err("Unsupported format by this MFC version.\n"); |
| 403 | mfc_err("Not supported format.\n"); | ||
| 404 | return -EINVAL; | ||
| 405 | } else if (!IS_MFCV6_PLUS(dev) && | ||
| 406 | (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) { | ||
| 407 | mfc_err("Not supported format.\n"); | ||
| 408 | return -EINVAL; | 425 | return -EINVAL; |
| 409 | } | 426 | } |
| 410 | } | 427 | } |
| @@ -462,104 +479,131 @@ out: | |||
| 462 | return ret; | 479 | return ret; |
| 463 | } | 480 | } |
| 464 | 481 | ||
| 465 | /* Reqeust buffers */ | 482 | static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, |
| 466 | static int vidioc_reqbufs(struct file *file, void *priv, | 483 | struct v4l2_requestbuffers *reqbufs) |
| 467 | struct v4l2_requestbuffers *reqbufs) | ||
| 468 | { | 484 | { |
| 469 | struct s5p_mfc_dev *dev = video_drvdata(file); | ||
| 470 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | ||
| 471 | int ret = 0; | 485 | int ret = 0; |
| 472 | 486 | ||
| 473 | if (reqbufs->memory != V4L2_MEMORY_MMAP) { | 487 | s5p_mfc_clock_on(); |
| 474 | mfc_err("Only V4L2_MEMORY_MAP is supported\n"); | 488 | |
| 475 | return -EINVAL; | 489 | if (reqbufs->count == 0) { |
| 476 | } | 490 | mfc_debug(2, "Freeing buffers\n"); |
| 477 | if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 491 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); |
| 478 | /* Can only request buffers after an instance has been opened.*/ | 492 | if (ret) |
| 479 | if (ctx->state == MFCINST_INIT) { | 493 | goto out; |
| 480 | ctx->src_bufs_cnt = 0; | 494 | s5p_mfc_close_mfc_inst(dev, ctx); |
| 481 | if (reqbufs->count == 0) { | 495 | ctx->src_bufs_cnt = 0; |
| 482 | mfc_debug(2, "Freeing buffers\n"); | 496 | ctx->output_state = QUEUE_FREE; |
| 483 | s5p_mfc_clock_on(); | 497 | } else if (ctx->output_state == QUEUE_FREE) { |
| 484 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); | 498 | /* Can only request buffers when we have a valid format set. */ |
| 485 | s5p_mfc_clock_off(); | 499 | WARN_ON(ctx->src_bufs_cnt != 0); |
| 486 | return ret; | 500 | if (ctx->state != MFCINST_INIT) { |
| 487 | } | 501 | mfc_err("Reqbufs called in an invalid state\n"); |
| 488 | /* Decoding */ | 502 | ret = -EINVAL; |
| 489 | if (ctx->output_state != QUEUE_FREE) { | 503 | goto out; |
| 490 | mfc_err("Bufs have already been requested\n"); | ||
| 491 | return -EINVAL; | ||
| 492 | } | ||
| 493 | s5p_mfc_clock_on(); | ||
| 494 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); | ||
| 495 | s5p_mfc_clock_off(); | ||
| 496 | if (ret) { | ||
| 497 | mfc_err("vb2_reqbufs on output failed\n"); | ||
| 498 | return ret; | ||
| 499 | } | ||
| 500 | mfc_debug(2, "vb2_reqbufs: %d\n", ret); | ||
| 501 | ctx->output_state = QUEUE_BUFS_REQUESTED; | ||
| 502 | } | ||
| 503 | } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | ||
| 504 | ctx->dst_bufs_cnt = 0; | ||
| 505 | if (reqbufs->count == 0) { | ||
| 506 | mfc_debug(2, "Freeing buffers\n"); | ||
| 507 | s5p_mfc_clock_on(); | ||
| 508 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | ||
| 509 | s5p_mfc_clock_off(); | ||
| 510 | return ret; | ||
| 511 | } | 504 | } |
| 512 | if (ctx->capture_state != QUEUE_FREE) { | 505 | |
| 513 | mfc_err("Bufs have already been requested\n"); | 506 | mfc_debug(2, "Allocating %d buffers for OUTPUT queue\n", |
| 514 | return -EINVAL; | 507 | reqbufs->count); |
| 515 | } | 508 | ret = vb2_reqbufs(&ctx->vq_src, reqbufs); |
| 516 | ctx->capture_state = QUEUE_BUFS_REQUESTED; | 509 | if (ret) |
| 517 | s5p_mfc_clock_on(); | 510 | goto out; |
| 518 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | 511 | |
| 519 | s5p_mfc_clock_off(); | 512 | ret = s5p_mfc_open_mfc_inst(dev, ctx); |
| 520 | if (ret) { | 513 | if (ret) { |
| 521 | mfc_err("vb2_reqbufs on capture failed\n"); | ||
| 522 | return ret; | ||
| 523 | } | ||
| 524 | if (reqbufs->count < ctx->pb_count) { | ||
| 525 | mfc_err("Not enough buffers allocated\n"); | ||
| 526 | reqbufs->count = 0; | 514 | reqbufs->count = 0; |
| 527 | s5p_mfc_clock_on(); | 515 | vb2_reqbufs(&ctx->vq_src, reqbufs); |
| 528 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | 516 | goto out; |
| 529 | s5p_mfc_clock_off(); | ||
| 530 | return -ENOMEM; | ||
| 531 | } | 517 | } |
| 518 | |||
| 519 | ctx->output_state = QUEUE_BUFS_REQUESTED; | ||
| 520 | } else { | ||
| 521 | mfc_err("Buffers have already been requested\n"); | ||
| 522 | ret = -EINVAL; | ||
| 523 | } | ||
| 524 | out: | ||
| 525 | s5p_mfc_clock_off(); | ||
| 526 | if (ret) | ||
| 527 | mfc_err("Failed allocating buffers for OUTPUT queue\n"); | ||
| 528 | return ret; | ||
| 529 | } | ||
| 530 | |||
| 531 | static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, | ||
| 532 | struct v4l2_requestbuffers *reqbufs) | ||
| 533 | { | ||
| 534 | int ret = 0; | ||
| 535 | |||
| 536 | s5p_mfc_clock_on(); | ||
| 537 | |||
| 538 | if (reqbufs->count == 0) { | ||
| 539 | mfc_debug(2, "Freeing buffers\n"); | ||
| 540 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | ||
| 541 | if (ret) | ||
| 542 | goto out; | ||
| 543 | s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx); | ||
| 544 | ctx->dst_bufs_cnt = 0; | ||
| 545 | } else if (ctx->capture_state == QUEUE_FREE) { | ||
| 546 | WARN_ON(ctx->dst_bufs_cnt != 0); | ||
| 547 | mfc_debug(2, "Allocating %d buffers for CAPTURE queue\n", | ||
| 548 | reqbufs->count); | ||
| 549 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | ||
| 550 | if (ret) | ||
| 551 | goto out; | ||
| 552 | |||
| 553 | ctx->capture_state = QUEUE_BUFS_REQUESTED; | ||
| 532 | ctx->total_dpb_count = reqbufs->count; | 554 | ctx->total_dpb_count = reqbufs->count; |
| 555 | |||
| 533 | ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx); | 556 | ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_codec_buffers, ctx); |
| 534 | if (ret) { | 557 | if (ret) { |
| 535 | mfc_err("Failed to allocate decoding buffers\n"); | 558 | mfc_err("Failed to allocate decoding buffers\n"); |
| 536 | reqbufs->count = 0; | 559 | reqbufs->count = 0; |
| 537 | s5p_mfc_clock_on(); | 560 | vb2_reqbufs(&ctx->vq_dst, reqbufs); |
| 538 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | 561 | ret = -ENOMEM; |
| 539 | s5p_mfc_clock_off(); | 562 | ctx->capture_state = QUEUE_FREE; |
| 540 | return -ENOMEM; | 563 | goto out; |
| 541 | } | ||
| 542 | if (ctx->dst_bufs_cnt == ctx->total_dpb_count) { | ||
| 543 | ctx->capture_state = QUEUE_BUFS_MMAPED; | ||
| 544 | } else { | ||
| 545 | mfc_err("Not all buffers passed to buf_init\n"); | ||
| 546 | reqbufs->count = 0; | ||
| 547 | s5p_mfc_clock_on(); | ||
| 548 | ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); | ||
| 549 | s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, | ||
| 550 | ctx); | ||
| 551 | s5p_mfc_clock_off(); | ||
| 552 | return -ENOMEM; | ||
| 553 | } | 564 | } |
| 565 | |||
| 566 | WARN_ON(ctx->dst_bufs_cnt != ctx->total_dpb_count); | ||
| 567 | ctx->capture_state = QUEUE_BUFS_MMAPED; | ||
| 568 | |||
| 554 | if (s5p_mfc_ctx_ready(ctx)) | 569 | if (s5p_mfc_ctx_ready(ctx)) |
| 555 | set_work_bit_irqsave(ctx); | 570 | set_work_bit_irqsave(ctx); |
| 556 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | 571 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); |
| 557 | s5p_mfc_wait_for_done_ctx(ctx, | 572 | s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, |
| 558 | S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0); | 573 | 0); |
| 574 | } else { | ||
| 575 | mfc_err("Buffers have already been requested\n"); | ||
| 576 | ret = -EINVAL; | ||
| 559 | } | 577 | } |
| 578 | out: | ||
| 579 | s5p_mfc_clock_off(); | ||
| 580 | if (ret) | ||
| 581 | mfc_err("Failed allocating buffers for CAPTURE queue\n"); | ||
| 560 | return ret; | 582 | return ret; |
| 561 | } | 583 | } |
| 562 | 584 | ||
| 585 | /* Reqeust buffers */ | ||
| 586 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
| 587 | struct v4l2_requestbuffers *reqbufs) | ||
| 588 | { | ||
| 589 | struct s5p_mfc_dev *dev = video_drvdata(file); | ||
| 590 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | ||
| 591 | |||
| 592 | if (reqbufs->memory != V4L2_MEMORY_MMAP) { | ||
| 593 | mfc_err("Only V4L2_MEMORY_MAP is supported\n"); | ||
| 594 | return -EINVAL; | ||
| 595 | } | ||
| 596 | |||
| 597 | if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | ||
| 598 | return reqbufs_output(dev, ctx, reqbufs); | ||
| 599 | } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | ||
| 600 | return reqbufs_capture(dev, ctx, reqbufs); | ||
| 601 | } else { | ||
| 602 | mfc_err("Invalid type requested\n"); | ||
| 603 | return -EINVAL; | ||
| 604 | } | ||
| 605 | } | ||
| 606 | |||
| 563 | /* Query buffer */ | 607 | /* Query buffer */ |
| 564 | static int vidioc_querybuf(struct file *file, void *priv, | 608 | static int vidioc_querybuf(struct file *file, void *priv, |
| 565 | struct v4l2_buffer *buf) | 609 | struct v4l2_buffer *buf) |
| @@ -573,7 +617,7 @@ static int vidioc_querybuf(struct file *file, void *priv, | |||
| 573 | return -EINVAL; | 617 | return -EINVAL; |
| 574 | } | 618 | } |
| 575 | mfc_debug(2, "State: %d, buf->type: %d\n", ctx->state, buf->type); | 619 | mfc_debug(2, "State: %d, buf->type: %d\n", ctx->state, buf->type); |
| 576 | if (ctx->state == MFCINST_INIT && | 620 | if (ctx->state == MFCINST_GOT_INST && |
| 577 | buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 621 | buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
| 578 | ret = vb2_querybuf(&ctx->vq_src, buf); | 622 | ret = vb2_querybuf(&ctx->vq_src, buf); |
| 579 | } else if (ctx->state == MFCINST_RUNNING && | 623 | } else if (ctx->state == MFCINST_RUNNING && |
| @@ -649,39 +693,11 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
| 649 | enum v4l2_buf_type type) | 693 | enum v4l2_buf_type type) |
| 650 | { | 694 | { |
| 651 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | 695 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); |
| 652 | struct s5p_mfc_dev *dev = ctx->dev; | ||
| 653 | int ret = -EINVAL; | 696 | int ret = -EINVAL; |
| 654 | 697 | ||
| 655 | mfc_debug_enter(); | 698 | mfc_debug_enter(); |
| 656 | if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 699 | if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
| 657 | |||
| 658 | if (ctx->state == MFCINST_INIT) { | ||
| 659 | ctx->dst_bufs_cnt = 0; | ||
| 660 | ctx->src_bufs_cnt = 0; | ||
| 661 | ctx->capture_state = QUEUE_FREE; | ||
| 662 | ctx->output_state = QUEUE_FREE; | ||
| 663 | s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, | ||
| 664 | ctx); | ||
| 665 | s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers, | ||
| 666 | ctx); | ||
| 667 | set_work_bit_irqsave(ctx); | ||
| 668 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
| 669 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | ||
| 670 | |||
| 671 | if (s5p_mfc_wait_for_done_ctx(ctx, | ||
| 672 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 0)) { | ||
| 673 | /* Error or timeout */ | ||
| 674 | mfc_err("Error getting instance from hardware\n"); | ||
| 675 | s5p_mfc_hw_call(dev->mfc_ops, | ||
| 676 | release_instance_buffer, ctx); | ||
| 677 | s5p_mfc_hw_call(dev->mfc_ops, | ||
| 678 | release_dec_desc_buffer, ctx); | ||
| 679 | return -EIO; | ||
| 680 | } | ||
| 681 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); | ||
| 682 | } | ||
| 683 | ret = vb2_streamon(&ctx->vq_src, type); | 700 | ret = vb2_streamon(&ctx->vq_src, type); |
| 684 | } | ||
| 685 | else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | 701 | else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
| 686 | ret = vb2_streamon(&ctx->vq_dst, type); | 702 | ret = vb2_streamon(&ctx->vq_dst, type); |
| 687 | mfc_debug_leave(); | 703 | mfc_debug_leave(); |
| @@ -851,6 +867,8 @@ static int vidioc_subscribe_event(struct v4l2_fh *fh, | |||
| 851 | switch (sub->type) { | 867 | switch (sub->type) { |
| 852 | case V4L2_EVENT_EOS: | 868 | case V4L2_EVENT_EOS: |
| 853 | return v4l2_event_subscribe(fh, sub, 2, NULL); | 869 | return v4l2_event_subscribe(fh, sub, 2, NULL); |
| 870 | case V4L2_EVENT_SOURCE_CHANGE: | ||
| 871 | return v4l2_src_change_event_subscribe(fh, sub); | ||
| 854 | default: | 872 | default: |
| 855 | return -EINVAL; | 873 | return -EINVAL; |
| 856 | } | 874 | } |
| @@ -1027,7 +1045,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 1027 | return 0; | 1045 | return 0; |
| 1028 | } | 1046 | } |
| 1029 | 1047 | ||
| 1030 | static int s5p_mfc_stop_streaming(struct vb2_queue *q) | 1048 | static void s5p_mfc_stop_streaming(struct vb2_queue *q) |
| 1031 | { | 1049 | { |
| 1032 | unsigned long flags; | 1050 | unsigned long flags; |
| 1033 | struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); | 1051 | struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); |
| @@ -1071,7 +1089,6 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q) | |||
| 1071 | } | 1089 | } |
| 1072 | if (aborted) | 1090 | if (aborted) |
| 1073 | ctx->state = MFCINST_RUNNING; | 1091 | ctx->state = MFCINST_RUNNING; |
| 1074 | return 0; | ||
| 1075 | } | 1092 | } |
| 1076 | 1093 | ||
| 1077 | 1094 | ||
| @@ -1191,9 +1208,14 @@ void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx) | |||
| 1191 | void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx) | 1208 | void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx) |
| 1192 | { | 1209 | { |
| 1193 | struct v4l2_format f; | 1210 | struct v4l2_format f; |
| 1194 | f.fmt.pix_mp.pixelformat = DEF_SRC_FMT_DEC; | 1211 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; |
| 1195 | ctx->src_fmt = find_format(&f, MFC_FMT_DEC); | 1212 | ctx->src_fmt = find_format(&f, MFC_FMT_DEC); |
| 1196 | f.fmt.pix_mp.pixelformat = DEF_DST_FMT_DEC; | 1213 | if (IS_MFCV8(ctx->dev)) |
| 1214 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; | ||
| 1215 | else if (IS_MFCV6_PLUS(ctx->dev)) | ||
| 1216 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; | ||
| 1217 | else | ||
| 1218 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT; | ||
| 1197 | ctx->dst_fmt = find_format(&f, MFC_FMT_RAW); | 1219 | ctx->dst_fmt = find_format(&f, MFC_FMT_RAW); |
| 1198 | mfc_debug(2, "Default src_fmt is %x, dest_fmt is %x\n", | 1220 | mfc_debug(2, "Default src_fmt is %x, dest_fmt is %x\n", |
| 1199 | (unsigned int)ctx->src_fmt, (unsigned int)ctx->dst_fmt); | 1221 | (unsigned int)ctx->src_fmt, (unsigned int)ctx->dst_fmt); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index df83cd157bab..d26b2484ca10 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <media/v4l2-ctrls.h> | 26 | #include <media/v4l2-ctrls.h> |
| 27 | #include <media/videobuf2-core.h> | 27 | #include <media/videobuf2-core.h> |
| 28 | #include "s5p_mfc_common.h" | 28 | #include "s5p_mfc_common.h" |
| 29 | #include "s5p_mfc_ctrl.h" | ||
| 29 | #include "s5p_mfc_debug.h" | 30 | #include "s5p_mfc_debug.h" |
| 30 | #include "s5p_mfc_enc.h" | 31 | #include "s5p_mfc_enc.h" |
| 31 | #include "s5p_mfc_intr.h" | 32 | #include "s5p_mfc_intr.h" |
| @@ -41,6 +42,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 41 | .codec_mode = S5P_MFC_CODEC_NONE, | 42 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 42 | .type = MFC_FMT_RAW, | 43 | .type = MFC_FMT_RAW, |
| 43 | .num_planes = 2, | 44 | .num_planes = 2, |
| 45 | .versions = MFC_V6_BIT | MFC_V7_BIT, | ||
| 44 | }, | 46 | }, |
| 45 | { | 47 | { |
| 46 | .name = "4:2:0 2 Planes 64x32 Tiles", | 48 | .name = "4:2:0 2 Planes 64x32 Tiles", |
| @@ -48,6 +50,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 48 | .codec_mode = S5P_MFC_CODEC_NONE, | 50 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 49 | .type = MFC_FMT_RAW, | 51 | .type = MFC_FMT_RAW, |
| 50 | .num_planes = 2, | 52 | .num_planes = 2, |
| 53 | .versions = MFC_V5_BIT, | ||
| 51 | }, | 54 | }, |
| 52 | { | 55 | { |
| 53 | .name = "4:2:0 2 Planes Y/CbCr", | 56 | .name = "4:2:0 2 Planes Y/CbCr", |
| @@ -55,6 +58,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 55 | .codec_mode = S5P_MFC_CODEC_NONE, | 58 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 56 | .type = MFC_FMT_RAW, | 59 | .type = MFC_FMT_RAW, |
| 57 | .num_planes = 2, | 60 | .num_planes = 2, |
| 61 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 62 | MFC_V8_BIT, | ||
| 58 | }, | 63 | }, |
| 59 | { | 64 | { |
| 60 | .name = "4:2:0 2 Planes Y/CrCb", | 65 | .name = "4:2:0 2 Planes Y/CrCb", |
| @@ -62,6 +67,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 62 | .codec_mode = S5P_MFC_CODEC_NONE, | 67 | .codec_mode = S5P_MFC_CODEC_NONE, |
| 63 | .type = MFC_FMT_RAW, | 68 | .type = MFC_FMT_RAW, |
| 64 | .num_planes = 2, | 69 | .num_planes = 2, |
| 70 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 71 | MFC_V8_BIT, | ||
| 65 | }, | 72 | }, |
| 66 | { | 73 | { |
| 67 | .name = "H264 Encoded Stream", | 74 | .name = "H264 Encoded Stream", |
| @@ -69,6 +76,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 69 | .codec_mode = S5P_MFC_CODEC_H264_ENC, | 76 | .codec_mode = S5P_MFC_CODEC_H264_ENC, |
| 70 | .type = MFC_FMT_ENC, | 77 | .type = MFC_FMT_ENC, |
| 71 | .num_planes = 1, | 78 | .num_planes = 1, |
| 79 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 80 | MFC_V8_BIT, | ||
| 72 | }, | 81 | }, |
| 73 | { | 82 | { |
| 74 | .name = "MPEG4 Encoded Stream", | 83 | .name = "MPEG4 Encoded Stream", |
| @@ -76,6 +85,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 76 | .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, | 85 | .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, |
| 77 | .type = MFC_FMT_ENC, | 86 | .type = MFC_FMT_ENC, |
| 78 | .num_planes = 1, | 87 | .num_planes = 1, |
| 88 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 89 | MFC_V8_BIT, | ||
| 79 | }, | 90 | }, |
| 80 | { | 91 | { |
| 81 | .name = "H263 Encoded Stream", | 92 | .name = "H263 Encoded Stream", |
| @@ -83,6 +94,8 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 83 | .codec_mode = S5P_MFC_CODEC_H263_ENC, | 94 | .codec_mode = S5P_MFC_CODEC_H263_ENC, |
| 84 | .type = MFC_FMT_ENC, | 95 | .type = MFC_FMT_ENC, |
| 85 | .num_planes = 1, | 96 | .num_planes = 1, |
| 97 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | ||
| 98 | MFC_V8_BIT, | ||
| 86 | }, | 99 | }, |
| 87 | { | 100 | { |
| 88 | .name = "VP8 Encoded Stream", | 101 | .name = "VP8 Encoded Stream", |
| @@ -90,6 +103,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
| 90 | .codec_mode = S5P_MFC_CODEC_VP8_ENC, | 103 | .codec_mode = S5P_MFC_CODEC_VP8_ENC, |
| 91 | .type = MFC_FMT_ENC, | 104 | .type = MFC_FMT_ENC, |
| 92 | .num_planes = 1, | 105 | .num_planes = 1, |
| 106 | .versions = MFC_V7_BIT | MFC_V8_BIT, | ||
| 93 | }, | 107 | }, |
| 94 | }; | 108 | }; |
| 95 | 109 | ||
| @@ -772,13 +786,16 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) | |||
| 772 | 786 | ||
| 773 | if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { | 787 | if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { |
| 774 | spin_lock_irqsave(&dev->irqlock, flags); | 788 | spin_lock_irqsave(&dev->irqlock, flags); |
| 775 | dst_mb = list_entry(ctx->dst_queue.next, | 789 | if (!list_empty(&ctx->dst_queue)) { |
| 776 | struct s5p_mfc_buf, list); | 790 | dst_mb = list_entry(ctx->dst_queue.next, |
| 777 | list_del(&dst_mb->list); | 791 | struct s5p_mfc_buf, list); |
| 778 | ctx->dst_queue_cnt--; | 792 | list_del(&dst_mb->list); |
| 779 | vb2_set_plane_payload(dst_mb->b, 0, | 793 | ctx->dst_queue_cnt--; |
| 780 | s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev)); | 794 | vb2_set_plane_payload(dst_mb->b, 0, |
| 781 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); | 795 | s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, |
| 796 | dev)); | ||
| 797 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); | ||
| 798 | } | ||
| 782 | spin_unlock_irqrestore(&dev->irqlock, flags); | 799 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 783 | } | 800 | } |
| 784 | 801 | ||
| @@ -883,8 +900,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) | |||
| 883 | mfc_debug(2, "enc src count: %d, enc ref count: %d\n", | 900 | mfc_debug(2, "enc src count: %d, enc ref count: %d\n", |
| 884 | ctx->src_queue_cnt, ctx->ref_queue_cnt); | 901 | ctx->src_queue_cnt, ctx->ref_queue_cnt); |
| 885 | } | 902 | } |
| 886 | if (strm_size > 0) { | 903 | if ((ctx->dst_queue_cnt > 0) && (strm_size > 0)) { |
| 887 | /* at least one more dest. buffers exist always */ | ||
| 888 | mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, | 904 | mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, |
| 889 | list); | 905 | list); |
| 890 | list_del(&mb_entry->list); | 906 | list_del(&mb_entry->list); |
| @@ -937,8 +953,10 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 937 | return 0; | 953 | return 0; |
| 938 | } | 954 | } |
| 939 | 955 | ||
| 940 | static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) | 956 | static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, |
| 957 | bool mplane, bool out) | ||
| 941 | { | 958 | { |
| 959 | struct s5p_mfc_dev *dev = video_drvdata(file); | ||
| 942 | struct s5p_mfc_fmt *fmt; | 960 | struct s5p_mfc_fmt *fmt; |
| 943 | int i, j = 0; | 961 | int i, j = 0; |
| 944 | 962 | ||
| @@ -951,6 +969,9 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) | |||
| 951 | continue; | 969 | continue; |
| 952 | else if (!out && formats[i].type != MFC_FMT_ENC) | 970 | else if (!out && formats[i].type != MFC_FMT_ENC) |
| 953 | continue; | 971 | continue; |
| 972 | else if ((dev->variant->version_bit & formats[i].versions) == 0) | ||
| 973 | continue; | ||
| 974 | |||
| 954 | if (j == f->index) { | 975 | if (j == f->index) { |
| 955 | fmt = &formats[i]; | 976 | fmt = &formats[i]; |
| 956 | strlcpy(f->description, fmt->name, | 977 | strlcpy(f->description, fmt->name, |
| @@ -966,25 +987,25 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) | |||
| 966 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, | 987 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, |
| 967 | struct v4l2_fmtdesc *f) | 988 | struct v4l2_fmtdesc *f) |
| 968 | { | 989 | { |
| 969 | return vidioc_enum_fmt(f, false, false); | 990 | return vidioc_enum_fmt(file, f, false, false); |
| 970 | } | 991 | } |
| 971 | 992 | ||
| 972 | static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, | 993 | static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, |
| 973 | struct v4l2_fmtdesc *f) | 994 | struct v4l2_fmtdesc *f) |
| 974 | { | 995 | { |
| 975 | return vidioc_enum_fmt(f, true, false); | 996 | return vidioc_enum_fmt(file, f, true, false); |
| 976 | } | 997 | } |
| 977 | 998 | ||
| 978 | static int vidioc_enum_fmt_vid_out(struct file *file, void *prov, | 999 | static int vidioc_enum_fmt_vid_out(struct file *file, void *prov, |
| 979 | struct v4l2_fmtdesc *f) | 1000 | struct v4l2_fmtdesc *f) |
| 980 | { | 1001 | { |
| 981 | return vidioc_enum_fmt(f, false, true); | 1002 | return vidioc_enum_fmt(file, f, false, true); |
| 982 | } | 1003 | } |
| 983 | 1004 | ||
| 984 | static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, | 1005 | static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, |
| 985 | struct v4l2_fmtdesc *f) | 1006 | struct v4l2_fmtdesc *f) |
| 986 | { | 1007 | { |
| 987 | return vidioc_enum_fmt(f, true, true); | 1008 | return vidioc_enum_fmt(file, f, true, true); |
| 988 | } | 1009 | } |
| 989 | 1010 | ||
| 990 | static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | 1011 | static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) |
| @@ -1035,16 +1056,14 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 1035 | mfc_err("failed to try output format\n"); | 1056 | mfc_err("failed to try output format\n"); |
| 1036 | return -EINVAL; | 1057 | return -EINVAL; |
| 1037 | } | 1058 | } |
| 1038 | |||
| 1039 | if (!IS_MFCV7(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | ||
| 1040 | mfc_err("VP8 is supported only in MFC v7\n"); | ||
| 1041 | return -EINVAL; | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { | 1059 | if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { |
| 1045 | mfc_err("must be set encoding output size\n"); | 1060 | mfc_err("must be set encoding output size\n"); |
| 1046 | return -EINVAL; | 1061 | return -EINVAL; |
| 1047 | } | 1062 | } |
| 1063 | if ((dev->variant->version_bit & fmt->versions) == 0) { | ||
| 1064 | mfc_err("Unsupported format by this MFC version.\n"); | ||
| 1065 | return -EINVAL; | ||
| 1066 | } | ||
| 1048 | 1067 | ||
| 1049 | pix_fmt_mp->plane_fmt[0].bytesperline = | 1068 | pix_fmt_mp->plane_fmt[0].bytesperline = |
| 1050 | pix_fmt_mp->plane_fmt[0].sizeimage; | 1069 | pix_fmt_mp->plane_fmt[0].sizeimage; |
| @@ -1055,22 +1074,15 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 1055 | return -EINVAL; | 1074 | return -EINVAL; |
| 1056 | } | 1075 | } |
| 1057 | 1076 | ||
| 1058 | if (!IS_MFCV6_PLUS(dev)) { | ||
| 1059 | if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { | ||
| 1060 | mfc_err("Not supported format.\n"); | ||
| 1061 | return -EINVAL; | ||
| 1062 | } | ||
| 1063 | } else if (IS_MFCV6_PLUS(dev)) { | ||
| 1064 | if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) { | ||
| 1065 | mfc_err("Not supported format.\n"); | ||
| 1066 | return -EINVAL; | ||
| 1067 | } | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | if (fmt->num_planes != pix_fmt_mp->num_planes) { | 1077 | if (fmt->num_planes != pix_fmt_mp->num_planes) { |
| 1071 | mfc_err("failed to try output format\n"); | 1078 | mfc_err("failed to try output format\n"); |
| 1072 | return -EINVAL; | 1079 | return -EINVAL; |
| 1073 | } | 1080 | } |
| 1081 | if ((dev->variant->version_bit & fmt->versions) == 0) { | ||
| 1082 | mfc_err("Unsupported format by this MFC version.\n"); | ||
| 1083 | return -EINVAL; | ||
| 1084 | } | ||
| 1085 | |||
| 1074 | v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, | 1086 | v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, |
| 1075 | &pix_fmt_mp->height, 4, 1080, 1, 0); | 1087 | &pix_fmt_mp->height, 4, 1080, 1, 0); |
| 1076 | } else { | 1088 | } else { |
| @@ -1104,20 +1116,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 1104 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; | 1116 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; |
| 1105 | ctx->dst_bufs_cnt = 0; | 1117 | ctx->dst_bufs_cnt = 0; |
| 1106 | ctx->capture_state = QUEUE_FREE; | 1118 | ctx->capture_state = QUEUE_FREE; |
| 1107 | s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx); | 1119 | ret = s5p_mfc_open_mfc_inst(dev, ctx); |
| 1108 | set_work_bit_irqsave(ctx); | ||
| 1109 | s5p_mfc_clean_ctx_int_flags(ctx); | ||
| 1110 | s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); | ||
| 1111 | if (s5p_mfc_wait_for_done_ctx(ctx, \ | ||
| 1112 | S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 1)) { | ||
| 1113 | /* Error or timeout */ | ||
| 1114 | mfc_err("Error getting instance from hardware\n"); | ||
| 1115 | s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, | ||
| 1116 | ctx); | ||
| 1117 | ret = -EIO; | ||
| 1118 | goto out; | ||
| 1119 | } | ||
| 1120 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); | ||
| 1121 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 1120 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
| 1122 | /* src_fmt is validated by call to vidioc_try_fmt */ | 1121 | /* src_fmt is validated by call to vidioc_try_fmt */ |
| 1123 | ctx->src_fmt = find_format(f, MFC_FMT_RAW); | 1122 | ctx->src_fmt = find_format(f, MFC_FMT_RAW); |
| @@ -1138,7 +1137,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 1138 | ctx->output_state = QUEUE_FREE; | 1137 | ctx->output_state = QUEUE_FREE; |
| 1139 | } else { | 1138 | } else { |
| 1140 | mfc_err("invalid buf type\n"); | 1139 | mfc_err("invalid buf type\n"); |
| 1141 | return -EINVAL; | 1140 | ret = -EINVAL; |
| 1142 | } | 1141 | } |
| 1143 | out: | 1142 | out: |
| 1144 | mfc_debug_leave(); | 1143 | mfc_debug_leave(); |
| @@ -1954,7 +1953,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 1954 | return 0; | 1953 | return 0; |
| 1955 | } | 1954 | } |
| 1956 | 1955 | ||
| 1957 | static int s5p_mfc_stop_streaming(struct vb2_queue *q) | 1956 | static void s5p_mfc_stop_streaming(struct vb2_queue *q) |
| 1958 | { | 1957 | { |
| 1959 | unsigned long flags; | 1958 | unsigned long flags; |
| 1960 | struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); | 1959 | struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); |
| @@ -1983,7 +1982,6 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q) | |||
| 1983 | ctx->src_queue_cnt = 0; | 1982 | ctx->src_queue_cnt = 0; |
| 1984 | } | 1983 | } |
| 1985 | spin_unlock_irqrestore(&dev->irqlock, flags); | 1984 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1986 | return 0; | ||
| 1987 | } | 1985 | } |
| 1988 | 1986 | ||
| 1989 | static void s5p_mfc_buf_queue(struct vb2_buffer *vb) | 1987 | static void s5p_mfc_buf_queue(struct vb2_buffer *vb) |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c index 3c01c339d696..c9a227428e6a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | |||
| @@ -31,6 +31,12 @@ void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev) | |||
| 31 | dev->mfc_ops = s5p_mfc_ops; | 31 | dev->mfc_ops = s5p_mfc_ops; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | void s5p_mfc_init_regs(struct s5p_mfc_dev *dev) | ||
| 35 | { | ||
| 36 | if (IS_MFCV6_PLUS(dev)) | ||
| 37 | dev->mfc_regs = s5p_mfc_init_regs_v6_plus(dev); | ||
| 38 | } | ||
| 39 | |||
| 34 | int s5p_mfc_alloc_priv_buf(struct device *dev, | 40 | int s5p_mfc_alloc_priv_buf(struct device *dev, |
| 35 | struct s5p_mfc_priv_buf *b) | 41 | struct s5p_mfc_priv_buf *b) |
| 36 | { | 42 | { |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h index 754c540e7a7e..7a7ad32ee608 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h | |||
| @@ -17,6 +17,259 @@ | |||
| 17 | 17 | ||
| 18 | #include "s5p_mfc_common.h" | 18 | #include "s5p_mfc_common.h" |
| 19 | 19 | ||
| 20 | struct s5p_mfc_regs { | ||
| 21 | |||
| 22 | /* codec common registers */ | ||
| 23 | void *risc_on; | ||
| 24 | void *risc2host_int; | ||
| 25 | void *host2risc_int; | ||
| 26 | void *risc_base_address; | ||
| 27 | void *mfc_reset; | ||
| 28 | void *host2risc_command; | ||
| 29 | void *risc2host_command; | ||
| 30 | void *mfc_bus_reset_ctrl; | ||
| 31 | void *firmware_version; | ||
| 32 | void *instance_id; | ||
| 33 | void *codec_type; | ||
| 34 | void *context_mem_addr; | ||
| 35 | void *context_mem_size; | ||
| 36 | void *pixel_format; | ||
| 37 | void *metadata_enable; | ||
| 38 | void *mfc_version; | ||
| 39 | void *dbg_info_enable; | ||
| 40 | void *dbg_buffer_addr; | ||
| 41 | void *dbg_buffer_size; | ||
| 42 | void *hed_control; | ||
| 43 | void *mfc_timeout_value; | ||
| 44 | void *hed_shared_mem_addr; | ||
| 45 | void *dis_shared_mem_addr;/* only v7 */ | ||
| 46 | void *ret_instance_id; | ||
| 47 | void *error_code; | ||
| 48 | void *dbg_buffer_output_size; | ||
| 49 | void *metadata_status; | ||
| 50 | void *metadata_addr_mb_info; | ||
| 51 | void *metadata_size_mb_info; | ||
| 52 | void *dbg_info_stage_counter; | ||
| 53 | |||
| 54 | /* decoder registers */ | ||
| 55 | void *d_crc_ctrl; | ||
| 56 | void *d_dec_options; | ||
| 57 | void *d_display_delay; | ||
| 58 | void *d_set_frame_width; | ||
| 59 | void *d_set_frame_height; | ||
| 60 | void *d_sei_enable; | ||
| 61 | void *d_min_num_dpb; | ||
| 62 | void *d_min_first_plane_dpb_size; | ||
| 63 | void *d_min_second_plane_dpb_size; | ||
| 64 | void *d_min_third_plane_dpb_size;/* only v8 */ | ||
| 65 | void *d_min_num_mv; | ||
| 66 | void *d_mvc_num_views; | ||
| 67 | void *d_min_num_dis;/* only v7 */ | ||
| 68 | void *d_min_first_dis_size;/* only v7 */ | ||
| 69 | void *d_min_second_dis_size;/* only v7 */ | ||
| 70 | void *d_min_third_dis_size;/* only v7 */ | ||
| 71 | void *d_post_filter_luma_dpb0;/* v7 and v8 */ | ||
| 72 | void *d_post_filter_luma_dpb1;/* v7 and v8 */ | ||
| 73 | void *d_post_filter_luma_dpb2;/* only v7 */ | ||
| 74 | void *d_post_filter_chroma_dpb0;/* v7 and v8 */ | ||
| 75 | void *d_post_filter_chroma_dpb1;/* v7 and v8 */ | ||
| 76 | void *d_post_filter_chroma_dpb2;/* only v7 */ | ||
| 77 | void *d_num_dpb; | ||
| 78 | void *d_num_mv; | ||
| 79 | void *d_init_buffer_options; | ||
| 80 | void *d_first_plane_dpb_stride_size;/* only v8 */ | ||
| 81 | void *d_second_plane_dpb_stride_size;/* only v8 */ | ||
| 82 | void *d_third_plane_dpb_stride_size;/* only v8 */ | ||
| 83 | void *d_first_plane_dpb_size; | ||
| 84 | void *d_second_plane_dpb_size; | ||
| 85 | void *d_third_plane_dpb_size;/* only v8 */ | ||
| 86 | void *d_mv_buffer_size; | ||
| 87 | void *d_first_plane_dpb; | ||
| 88 | void *d_second_plane_dpb; | ||
| 89 | void *d_third_plane_dpb; | ||
| 90 | void *d_mv_buffer; | ||
| 91 | void *d_scratch_buffer_addr; | ||
| 92 | void *d_scratch_buffer_size; | ||
| 93 | void *d_metadata_buffer_addr; | ||
| 94 | void *d_metadata_buffer_size; | ||
| 95 | void *d_nal_start_options;/* v7 and v8 */ | ||
| 96 | void *d_cpb_buffer_addr; | ||
| 97 | void *d_cpb_buffer_size; | ||
| 98 | void *d_available_dpb_flag_upper; | ||
| 99 | void *d_available_dpb_flag_lower; | ||
| 100 | void *d_cpb_buffer_offset; | ||
| 101 | void *d_slice_if_enable; | ||
| 102 | void *d_picture_tag; | ||
| 103 | void *d_stream_data_size; | ||
| 104 | void *d_dynamic_dpb_flag_upper;/* v7 and v8 */ | ||
| 105 | void *d_dynamic_dpb_flag_lower;/* v7 and v8 */ | ||
| 106 | void *d_display_frame_width; | ||
| 107 | void *d_display_frame_height; | ||
| 108 | void *d_display_status; | ||
| 109 | void *d_display_first_plane_addr; | ||
| 110 | void *d_display_second_plane_addr; | ||
| 111 | void *d_display_third_plane_addr;/* only v8 */ | ||
| 112 | void *d_display_frame_type; | ||
| 113 | void *d_display_crop_info1; | ||
| 114 | void *d_display_crop_info2; | ||
| 115 | void *d_display_picture_profile; | ||
| 116 | void *d_display_luma_crc;/* v7 and v8 */ | ||
| 117 | void *d_display_chroma0_crc;/* v7 and v8 */ | ||
| 118 | void *d_display_chroma1_crc;/* only v8 */ | ||
| 119 | void *d_display_luma_crc_top;/* only v6 */ | ||
| 120 | void *d_display_chroma_crc_top;/* only v6 */ | ||
| 121 | void *d_display_luma_crc_bot;/* only v6 */ | ||
| 122 | void *d_display_chroma_crc_bot;/* only v6 */ | ||
| 123 | void *d_display_aspect_ratio; | ||
| 124 | void *d_display_extended_ar; | ||
| 125 | void *d_decoded_frame_width; | ||
| 126 | void *d_decoded_frame_height; | ||
| 127 | void *d_decoded_status; | ||
| 128 | void *d_decoded_first_plane_addr; | ||
| 129 | void *d_decoded_second_plane_addr; | ||
| 130 | void *d_decoded_third_plane_addr;/* only v8 */ | ||
| 131 | void *d_decoded_frame_type; | ||
| 132 | void *d_decoded_crop_info1; | ||
| 133 | void *d_decoded_crop_info2; | ||
| 134 | void *d_decoded_picture_profile; | ||
| 135 | void *d_decoded_nal_size; | ||
| 136 | void *d_decoded_luma_crc; | ||
| 137 | void *d_decoded_chroma0_crc; | ||
| 138 | void *d_decoded_chroma1_crc;/* only v8 */ | ||
| 139 | void *d_ret_picture_tag_top; | ||
| 140 | void *d_ret_picture_tag_bot; | ||
| 141 | void *d_ret_picture_time_top; | ||
| 142 | void *d_ret_picture_time_bot; | ||
| 143 | void *d_chroma_format; | ||
| 144 | void *d_vc1_info;/* v7 and v8 */ | ||
| 145 | void *d_mpeg4_info; | ||
| 146 | void *d_h264_info; | ||
| 147 | void *d_metadata_addr_concealed_mb; | ||
| 148 | void *d_metadata_size_concealed_mb; | ||
| 149 | void *d_metadata_addr_vc1_param; | ||
| 150 | void *d_metadata_size_vc1_param; | ||
| 151 | void *d_metadata_addr_sei_nal; | ||
| 152 | void *d_metadata_size_sei_nal; | ||
| 153 | void *d_metadata_addr_vui; | ||
| 154 | void *d_metadata_size_vui; | ||
| 155 | void *d_metadata_addr_mvcvui;/* v7 and v8 */ | ||
| 156 | void *d_metadata_size_mvcvui;/* v7 and v8 */ | ||
| 157 | void *d_mvc_view_id; | ||
| 158 | void *d_frame_pack_sei_avail; | ||
| 159 | void *d_frame_pack_arrgment_id; | ||
| 160 | void *d_frame_pack_sei_info; | ||
| 161 | void *d_frame_pack_grid_pos; | ||
| 162 | void *d_display_recovery_sei_info;/* v7 and v8 */ | ||
| 163 | void *d_decoded_recovery_sei_info;/* v7 and v8 */ | ||
| 164 | void *d_display_first_addr;/* only v7 */ | ||
| 165 | void *d_display_second_addr;/* only v7 */ | ||
| 166 | void *d_display_third_addr;/* only v7 */ | ||
| 167 | void *d_decoded_first_addr;/* only v7 */ | ||
| 168 | void *d_decoded_second_addr;/* only v7 */ | ||
| 169 | void *d_decoded_third_addr;/* only v7 */ | ||
| 170 | void *d_used_dpb_flag_upper;/* v7 and v8 */ | ||
| 171 | void *d_used_dpb_flag_lower;/* v7 and v8 */ | ||
| 172 | |||
| 173 | /* encoder registers */ | ||
| 174 | void *e_frame_width; | ||
| 175 | void *e_frame_height; | ||
| 176 | void *e_cropped_frame_width; | ||
| 177 | void *e_cropped_frame_height; | ||
| 178 | void *e_frame_crop_offset; | ||
| 179 | void *e_enc_options; | ||
| 180 | void *e_picture_profile; | ||
| 181 | void *e_vbv_buffer_size; | ||
| 182 | void *e_vbv_init_delay; | ||
| 183 | void *e_fixed_picture_qp; | ||
| 184 | void *e_rc_config; | ||
| 185 | void *e_rc_qp_bound; | ||
| 186 | void *e_rc_qp_bound_pb;/* v7 and v8 */ | ||
| 187 | void *e_rc_mode; | ||
| 188 | void *e_mb_rc_config; | ||
| 189 | void *e_padding_ctrl; | ||
| 190 | void *e_air_threshold; | ||
| 191 | void *e_mv_hor_range; | ||
| 192 | void *e_mv_ver_range; | ||
| 193 | void *e_num_dpb; | ||
| 194 | void *e_luma_dpb; | ||
| 195 | void *e_chroma_dpb; | ||
| 196 | void *e_me_buffer; | ||
| 197 | void *e_scratch_buffer_addr; | ||
| 198 | void *e_scratch_buffer_size; | ||
| 199 | void *e_tmv_buffer0; | ||
| 200 | void *e_tmv_buffer1; | ||
| 201 | void *e_ir_buffer_addr;/* v7 and v8 */ | ||
| 202 | void *e_source_first_plane_addr; | ||
| 203 | void *e_source_second_plane_addr; | ||
| 204 | void *e_source_third_plane_addr;/* v7 and v8 */ | ||
| 205 | void *e_source_first_plane_stride;/* v7 and v8 */ | ||
| 206 | void *e_source_second_plane_stride;/* v7 and v8 */ | ||
| 207 | void *e_source_third_plane_stride;/* v7 and v8 */ | ||
| 208 | void *e_stream_buffer_addr; | ||
| 209 | void *e_stream_buffer_size; | ||
| 210 | void *e_roi_buffer_addr; | ||
| 211 | void *e_param_change; | ||
| 212 | void *e_ir_size; | ||
| 213 | void *e_gop_config; | ||
| 214 | void *e_mslice_mode; | ||
| 215 | void *e_mslice_size_mb; | ||
| 216 | void *e_mslice_size_bits; | ||
| 217 | void *e_frame_insertion; | ||
| 218 | void *e_rc_frame_rate; | ||
| 219 | void *e_rc_bit_rate; | ||
| 220 | void *e_rc_roi_ctrl; | ||
| 221 | void *e_picture_tag; | ||
| 222 | void *e_bit_count_enable; | ||
| 223 | void *e_max_bit_count; | ||
| 224 | void *e_min_bit_count; | ||
| 225 | void *e_metadata_buffer_addr; | ||
| 226 | void *e_metadata_buffer_size; | ||
| 227 | void *e_encoded_source_first_plane_addr; | ||
| 228 | void *e_encoded_source_second_plane_addr; | ||
| 229 | void *e_encoded_source_third_plane_addr;/* v7 and v8 */ | ||
| 230 | void *e_stream_size; | ||
| 231 | void *e_slice_type; | ||
| 232 | void *e_picture_count; | ||
| 233 | void *e_ret_picture_tag; | ||
| 234 | void *e_stream_buffer_write_pointer; /* only v6 */ | ||
| 235 | void *e_recon_luma_dpb_addr; | ||
| 236 | void *e_recon_chroma_dpb_addr; | ||
| 237 | void *e_metadata_addr_enc_slice; | ||
| 238 | void *e_metadata_size_enc_slice; | ||
| 239 | void *e_mpeg4_options; | ||
| 240 | void *e_mpeg4_hec_period; | ||
| 241 | void *e_aspect_ratio; | ||
| 242 | void *e_extended_sar; | ||
| 243 | void *e_h264_options; | ||
| 244 | void *e_h264_options_2;/* v7 and v8 */ | ||
| 245 | void *e_h264_lf_alpha_offset; | ||
| 246 | void *e_h264_lf_beta_offset; | ||
| 247 | void *e_h264_i_period; | ||
| 248 | void *e_h264_fmo_slice_grp_map_type; | ||
| 249 | void *e_h264_fmo_num_slice_grp_minus1; | ||
| 250 | void *e_h264_fmo_slice_grp_change_dir; | ||
| 251 | void *e_h264_fmo_slice_grp_change_rate_minus1; | ||
| 252 | void *e_h264_fmo_run_length_minus1_0; | ||
| 253 | void *e_h264_aso_slice_order_0; | ||
| 254 | void *e_h264_chroma_qp_offset; | ||
| 255 | void *e_h264_num_t_layer; | ||
| 256 | void *e_h264_hierarchical_qp_layer0; | ||
| 257 | void *e_h264_frame_packing_sei_info; | ||
| 258 | void *e_h264_nal_control;/* v7 and v8 */ | ||
| 259 | void *e_mvc_frame_qp_view1; | ||
| 260 | void *e_mvc_rc_bit_rate_view1; | ||
| 261 | void *e_mvc_rc_qbound_view1; | ||
| 262 | void *e_mvc_rc_mode_view1; | ||
| 263 | void *e_mvc_inter_view_prediction_on; | ||
| 264 | void *e_vp8_options;/* v7 and v8 */ | ||
| 265 | void *e_vp8_filter_options;/* v7 and v8 */ | ||
| 266 | void *e_vp8_golden_frame_option;/* v7 and v8 */ | ||
| 267 | void *e_vp8_num_t_layer;/* v7 and v8 */ | ||
| 268 | void *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */ | ||
| 269 | void *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */ | ||
| 270 | void *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */ | ||
| 271 | }; | ||
| 272 | |||
| 20 | struct s5p_mfc_hw_ops { | 273 | struct s5p_mfc_hw_ops { |
| 21 | int (*alloc_dec_temp_buffers)(struct s5p_mfc_ctx *ctx); | 274 | int (*alloc_dec_temp_buffers)(struct s5p_mfc_ctx *ctx); |
| 22 | void (*release_dec_desc_buffer)(struct s5p_mfc_ctx *ctx); | 275 | void (*release_dec_desc_buffer)(struct s5p_mfc_ctx *ctx); |
| @@ -80,6 +333,7 @@ struct s5p_mfc_hw_ops { | |||
| 80 | }; | 333 | }; |
| 81 | 334 | ||
| 82 | void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); | 335 | void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); |
| 336 | void s5p_mfc_init_regs(struct s5p_mfc_dev *dev); | ||
| 83 | int s5p_mfc_alloc_priv_buf(struct device *dev, | 337 | int s5p_mfc_alloc_priv_buf(struct device *dev, |
| 84 | struct s5p_mfc_priv_buf *b); | 338 | struct s5p_mfc_priv_buf *b); |
| 85 | void s5p_mfc_release_priv_buf(struct device *dev, | 339 | void s5p_mfc_release_priv_buf(struct device *dev, |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index f64621ae9b5a..4f5e0ead90c6 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | |||
| @@ -43,10 +43,10 @@ | |||
| 43 | } while (0) | 43 | } while (0) |
| 44 | #endif /* S5P_MFC_DEBUG_REGWRITE */ | 44 | #endif /* S5P_MFC_DEBUG_REGWRITE */ |
| 45 | 45 | ||
| 46 | #define READL(offset) readl(dev->regs_base + (offset)) | 46 | #define READL(reg) \ |
| 47 | #define WRITEL(data, offset) writel((data), dev->regs_base + (offset)) | 47 | (WARN_ON_ONCE(!(reg)) ? 0 : readl(reg)) |
| 48 | #define OFFSETA(x) (((x) - dev->port_a) >> S5P_FIMV_MEM_OFFSET) | 48 | #define WRITEL(data, reg) \ |
| 49 | #define OFFSETB(x) (((x) - dev->port_b) >> S5P_FIMV_MEM_OFFSET) | 49 | (WARN_ON_ONCE(!(reg)) ? 0 : writel((data), (reg))) |
| 50 | 50 | ||
| 51 | /* Allocate temporary buffers for decoding */ | 51 | /* Allocate temporary buffers for decoding */ |
| 52 | static int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) | 52 | static int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) |
| @@ -77,7 +77,12 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 77 | ctx->luma_size, ctx->chroma_size, ctx->mv_size); | 77 | ctx->luma_size, ctx->chroma_size, ctx->mv_size); |
| 78 | mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count); | 78 | mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count); |
| 79 | } else if (ctx->type == MFCINST_ENCODER) { | 79 | } else if (ctx->type == MFCINST_ENCODER) { |
| 80 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * | 80 | if (IS_MFCV8(dev)) |
| 81 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * | ||
| 82 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height), | ||
| 83 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); | ||
| 84 | else | ||
| 85 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * | ||
| 81 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height), | 86 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height), |
| 82 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); | 87 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); |
| 83 | 88 | ||
| @@ -87,10 +92,16 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 87 | ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * | 92 | ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * |
| 88 | S5P_FIMV_CHROMA_MB_TO_PIXEL_V6, | 93 | S5P_FIMV_CHROMA_MB_TO_PIXEL_V6, |
| 89 | S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6); | 94 | S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6); |
| 90 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V6( | 95 | if (IS_MFCV8(dev)) |
| 91 | ctx->img_width, ctx->img_height, | 96 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V8( |
| 92 | mb_width, mb_height), | 97 | ctx->img_width, ctx->img_height, |
| 93 | S5P_FIMV_ME_BUFFER_ALIGN_V6); | 98 | mb_width, mb_height), |
| 99 | S5P_FIMV_ME_BUFFER_ALIGN_V6); | ||
| 100 | else | ||
| 101 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V6( | ||
| 102 | ctx->img_width, ctx->img_height, | ||
| 103 | mb_width, mb_height), | ||
| 104 | S5P_FIMV_ME_BUFFER_ALIGN_V6); | ||
| 94 | 105 | ||
| 95 | mfc_debug(2, "recon luma size: %d chroma size: %d\n", | 106 | mfc_debug(2, "recon luma size: %d chroma size: %d\n", |
| 96 | ctx->luma_dpb_size, ctx->chroma_dpb_size); | 107 | ctx->luma_dpb_size, ctx->chroma_dpb_size); |
| @@ -102,8 +113,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 102 | switch (ctx->codec_mode) { | 113 | switch (ctx->codec_mode) { |
| 103 | case S5P_MFC_CODEC_H264_DEC: | 114 | case S5P_MFC_CODEC_H264_DEC: |
| 104 | case S5P_MFC_CODEC_H264_MVC_DEC: | 115 | case S5P_MFC_CODEC_H264_MVC_DEC: |
| 105 | ctx->scratch_buf_size = | 116 | if (IS_MFCV8(dev)) |
| 106 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6( | 117 | ctx->scratch_buf_size = |
| 118 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V8( | ||
| 119 | mb_width, | ||
| 120 | mb_height); | ||
| 121 | else | ||
| 122 | ctx->scratch_buf_size = | ||
| 123 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6( | ||
| 107 | mb_width, | 124 | mb_width, |
| 108 | mb_height); | 125 | mb_height); |
| 109 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 126 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| @@ -113,7 +130,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 113 | (ctx->mv_count * ctx->mv_size); | 130 | (ctx->mv_count * ctx->mv_size); |
| 114 | break; | 131 | break; |
| 115 | case S5P_MFC_CODEC_MPEG4_DEC: | 132 | case S5P_MFC_CODEC_MPEG4_DEC: |
| 116 | if (IS_MFCV7(dev)) { | 133 | if (IS_MFCV7_PLUS(dev)) { |
| 117 | ctx->scratch_buf_size = | 134 | ctx->scratch_buf_size = |
| 118 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V7( | 135 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V7( |
| 119 | mb_width, | 136 | mb_width, |
| @@ -153,19 +170,31 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 153 | ctx->bank1.size = ctx->scratch_buf_size; | 170 | ctx->bank1.size = ctx->scratch_buf_size; |
| 154 | break; | 171 | break; |
| 155 | case S5P_MFC_CODEC_VP8_DEC: | 172 | case S5P_MFC_CODEC_VP8_DEC: |
| 156 | ctx->scratch_buf_size = | 173 | if (IS_MFCV8(dev)) |
| 157 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6( | 174 | ctx->scratch_buf_size = |
| 158 | mb_width, | 175 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V8( |
| 159 | mb_height); | 176 | mb_width, |
| 177 | mb_height); | ||
| 178 | else | ||
| 179 | ctx->scratch_buf_size = | ||
| 180 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6( | ||
| 181 | mb_width, | ||
| 182 | mb_height); | ||
| 160 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 183 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 161 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 184 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
| 162 | ctx->bank1.size = ctx->scratch_buf_size; | 185 | ctx->bank1.size = ctx->scratch_buf_size; |
| 163 | break; | 186 | break; |
| 164 | case S5P_MFC_CODEC_H264_ENC: | 187 | case S5P_MFC_CODEC_H264_ENC: |
| 165 | ctx->scratch_buf_size = | 188 | if (IS_MFCV8(dev)) |
| 166 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6( | 189 | ctx->scratch_buf_size = |
| 190 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V8( | ||
| 167 | mb_width, | 191 | mb_width, |
| 168 | mb_height); | 192 | mb_height); |
| 193 | else | ||
| 194 | ctx->scratch_buf_size = | ||
| 195 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6( | ||
| 196 | mb_width, | ||
| 197 | mb_height); | ||
| 169 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 198 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 170 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 199 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
| 171 | ctx->bank1.size = | 200 | ctx->bank1.size = |
| @@ -189,10 +218,16 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
| 189 | ctx->bank2.size = 0; | 218 | ctx->bank2.size = 0; |
| 190 | break; | 219 | break; |
| 191 | case S5P_MFC_CODEC_VP8_ENC: | 220 | case S5P_MFC_CODEC_VP8_ENC: |
| 192 | ctx->scratch_buf_size = | 221 | if (IS_MFCV8(dev)) |
| 193 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V7( | 222 | ctx->scratch_buf_size = |
| 223 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V8( | ||
| 194 | mb_width, | 224 | mb_width, |
| 195 | mb_height); | 225 | mb_height); |
| 226 | else | ||
| 227 | ctx->scratch_buf_size = | ||
| 228 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V7( | ||
| 229 | mb_width, | ||
| 230 | mb_height); | ||
| 196 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 231 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 197 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 232 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
| 198 | ctx->bank1.size = | 233 | ctx->bank1.size = |
| @@ -332,6 +367,12 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) | |||
| 332 | 367 | ||
| 333 | ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height); | 368 | ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height); |
| 334 | ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1)); | 369 | ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1)); |
| 370 | if (IS_MFCV8(ctx->dev)) { | ||
| 371 | /* MFCv8 needs additional 64 bytes for luma,chroma dpb*/ | ||
| 372 | ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; | ||
| 373 | ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; | ||
| 374 | } | ||
| 375 | |||
| 335 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || | 376 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
| 336 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { | 377 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { |
| 337 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width, | 378 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width, |
| @@ -354,7 +395,7 @@ static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx) | |||
| 354 | ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256); | 395 | ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256); |
| 355 | 396 | ||
| 356 | /* MFCv7 needs pad bytes for Luma and Chroma */ | 397 | /* MFCv7 needs pad bytes for Luma and Chroma */ |
| 357 | if (IS_MFCV7(ctx->dev)) { | 398 | if (IS_MFCV7_PLUS(ctx->dev)) { |
| 358 | ctx->luma_size += MFC_LUMA_PAD_BYTES_V7; | 399 | ctx->luma_size += MFC_LUMA_PAD_BYTES_V7; |
| 359 | ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7; | 400 | ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7; |
| 360 | } | 401 | } |
| @@ -366,16 +407,17 @@ static int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 366 | unsigned int strm_size) | 407 | unsigned int strm_size) |
| 367 | { | 408 | { |
| 368 | struct s5p_mfc_dev *dev = ctx->dev; | 409 | struct s5p_mfc_dev *dev = ctx->dev; |
| 410 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 369 | struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; | 411 | struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; |
| 370 | 412 | ||
| 371 | mfc_debug_enter(); | 413 | mfc_debug_enter(); |
| 372 | mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n" | 414 | mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n" |
| 373 | "buf_size: 0x%08x (%d)\n", | 415 | "buf_size: 0x%08x (%d)\n", |
| 374 | ctx->inst_no, buf_addr, strm_size, strm_size); | 416 | ctx->inst_no, buf_addr, strm_size, strm_size); |
| 375 | WRITEL(strm_size, S5P_FIMV_D_STREAM_DATA_SIZE_V6); | 417 | WRITEL(strm_size, mfc_regs->d_stream_data_size); |
| 376 | WRITEL(buf_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V6); | 418 | WRITEL(buf_addr, mfc_regs->d_cpb_buffer_addr); |
| 377 | WRITEL(buf_size->cpb, S5P_FIMV_D_CPB_BUFFER_SIZE_V6); | 419 | WRITEL(buf_size->cpb, mfc_regs->d_cpb_buffer_size); |
| 378 | WRITEL(start_num_byte, S5P_FIMV_D_CPB_BUFFER_OFFSET_V6); | 420 | WRITEL(start_num_byte, mfc_regs->d_cpb_buffer_offset); |
| 379 | 421 | ||
| 380 | mfc_debug_leave(); | 422 | mfc_debug_leave(); |
| 381 | return 0; | 423 | return 0; |
| @@ -387,6 +429,7 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 387 | unsigned int frame_size, i; | 429 | unsigned int frame_size, i; |
| 388 | unsigned int frame_size_ch, frame_size_mv; | 430 | unsigned int frame_size_ch, frame_size_mv; |
| 389 | struct s5p_mfc_dev *dev = ctx->dev; | 431 | struct s5p_mfc_dev *dev = ctx->dev; |
| 432 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 390 | size_t buf_addr1; | 433 | size_t buf_addr1; |
| 391 | int buf_size1; | 434 | int buf_size1; |
| 392 | int align_gap; | 435 | int align_gap; |
| @@ -398,19 +441,27 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 398 | mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count); | 441 | mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count); |
| 399 | mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay); | 442 | mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay); |
| 400 | 443 | ||
| 401 | WRITEL(ctx->total_dpb_count, S5P_FIMV_D_NUM_DPB_V6); | 444 | WRITEL(ctx->total_dpb_count, mfc_regs->d_num_dpb); |
| 402 | WRITEL(ctx->luma_size, S5P_FIMV_D_LUMA_DPB_SIZE_V6); | 445 | WRITEL(ctx->luma_size, mfc_regs->d_first_plane_dpb_size); |
| 403 | WRITEL(ctx->chroma_size, S5P_FIMV_D_CHROMA_DPB_SIZE_V6); | 446 | WRITEL(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size); |
| 447 | |||
| 448 | WRITEL(buf_addr1, mfc_regs->d_scratch_buffer_addr); | ||
| 449 | WRITEL(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size); | ||
| 450 | |||
| 451 | if (IS_MFCV8(dev)) { | ||
| 452 | WRITEL(ctx->img_width, | ||
| 453 | mfc_regs->d_first_plane_dpb_stride_size); | ||
| 454 | WRITEL(ctx->img_width, | ||
| 455 | mfc_regs->d_second_plane_dpb_stride_size); | ||
| 456 | } | ||
| 404 | 457 | ||
| 405 | WRITEL(buf_addr1, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6); | ||
| 406 | WRITEL(ctx->scratch_buf_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6); | ||
| 407 | buf_addr1 += ctx->scratch_buf_size; | 458 | buf_addr1 += ctx->scratch_buf_size; |
| 408 | buf_size1 -= ctx->scratch_buf_size; | 459 | buf_size1 -= ctx->scratch_buf_size; |
| 409 | 460 | ||
| 410 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || | 461 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || |
| 411 | ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){ | 462 | ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){ |
| 412 | WRITEL(ctx->mv_size, S5P_FIMV_D_MV_BUFFER_SIZE_V6); | 463 | WRITEL(ctx->mv_size, mfc_regs->d_mv_buffer_size); |
| 413 | WRITEL(ctx->mv_count, S5P_FIMV_D_NUM_MV_V6); | 464 | WRITEL(ctx->mv_count, mfc_regs->d_num_mv); |
| 414 | } | 465 | } |
| 415 | 466 | ||
| 416 | frame_size = ctx->luma_size; | 467 | frame_size = ctx->luma_size; |
| @@ -424,11 +475,11 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 424 | mfc_debug(2, "Luma %d: %x\n", i, | 475 | mfc_debug(2, "Luma %d: %x\n", i, |
| 425 | ctx->dst_bufs[i].cookie.raw.luma); | 476 | ctx->dst_bufs[i].cookie.raw.luma); |
| 426 | WRITEL(ctx->dst_bufs[i].cookie.raw.luma, | 477 | WRITEL(ctx->dst_bufs[i].cookie.raw.luma, |
| 427 | S5P_FIMV_D_LUMA_DPB_V6 + i * 4); | 478 | mfc_regs->d_first_plane_dpb + i * 4); |
| 428 | mfc_debug(2, "\tChroma %d: %x\n", i, | 479 | mfc_debug(2, "\tChroma %d: %x\n", i, |
| 429 | ctx->dst_bufs[i].cookie.raw.chroma); | 480 | ctx->dst_bufs[i].cookie.raw.chroma); |
| 430 | WRITEL(ctx->dst_bufs[i].cookie.raw.chroma, | 481 | WRITEL(ctx->dst_bufs[i].cookie.raw.chroma, |
| 431 | S5P_FIMV_D_CHROMA_DPB_V6 + i * 4); | 482 | mfc_regs->d_second_plane_dpb + i * 4); |
| 432 | } | 483 | } |
| 433 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || | 484 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
| 434 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { | 485 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { |
| @@ -441,7 +492,7 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 441 | 492 | ||
| 442 | mfc_debug(2, "\tBuf1: %x, size: %d\n", | 493 | mfc_debug(2, "\tBuf1: %x, size: %d\n", |
| 443 | buf_addr1, buf_size1); | 494 | buf_addr1, buf_size1); |
| 444 | WRITEL(buf_addr1, S5P_FIMV_D_MV_BUFFER_V6 + i * 4); | 495 | WRITEL(buf_addr1, mfc_regs->d_mv_buffer + i * 4); |
| 445 | buf_addr1 += frame_size_mv; | 496 | buf_addr1 += frame_size_mv; |
| 446 | buf_size1 -= frame_size_mv; | 497 | buf_size1 -= frame_size_mv; |
| 447 | } | 498 | } |
| @@ -454,7 +505,7 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 454 | return -ENOMEM; | 505 | return -ENOMEM; |
| 455 | } | 506 | } |
| 456 | 507 | ||
| 457 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 508 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 458 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | 509 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
| 459 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); | 510 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); |
| 460 | 511 | ||
| @@ -467,9 +518,10 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 467 | unsigned long addr, unsigned int size) | 518 | unsigned long addr, unsigned int size) |
| 468 | { | 519 | { |
| 469 | struct s5p_mfc_dev *dev = ctx->dev; | 520 | struct s5p_mfc_dev *dev = ctx->dev; |
| 521 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 470 | 522 | ||
| 471 | WRITEL(addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); /* 16B align */ | 523 | WRITEL(addr, mfc_regs->e_stream_buffer_addr); /* 16B align */ |
| 472 | WRITEL(size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); | 524 | WRITEL(size, mfc_regs->e_stream_buffer_size); |
| 473 | 525 | ||
| 474 | mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n", | 526 | mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n", |
| 475 | addr, size); | 527 | addr, size); |
| @@ -481,14 +533,10 @@ static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 481 | unsigned long y_addr, unsigned long c_addr) | 533 | unsigned long y_addr, unsigned long c_addr) |
| 482 | { | 534 | { |
| 483 | struct s5p_mfc_dev *dev = ctx->dev; | 535 | struct s5p_mfc_dev *dev = ctx->dev; |
| 536 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 484 | 537 | ||
| 485 | if (IS_MFCV7(dev)) { | 538 | WRITEL(y_addr, mfc_regs->e_source_first_plane_addr); |
| 486 | WRITEL(y_addr, S5P_FIMV_E_SOURCE_FIRST_ADDR_V7); | 539 | WRITEL(c_addr, mfc_regs->e_source_second_plane_addr); |
| 487 | WRITEL(c_addr, S5P_FIMV_E_SOURCE_SECOND_ADDR_V7); | ||
| 488 | } else { | ||
| 489 | WRITEL(y_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); | ||
| 490 | WRITEL(c_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); | ||
| 491 | } | ||
| 492 | 540 | ||
| 493 | mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr); | 541 | mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr); |
| 494 | mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr); | 542 | mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr); |
| @@ -498,18 +546,14 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 498 | unsigned long *y_addr, unsigned long *c_addr) | 546 | unsigned long *y_addr, unsigned long *c_addr) |
| 499 | { | 547 | { |
| 500 | struct s5p_mfc_dev *dev = ctx->dev; | 548 | struct s5p_mfc_dev *dev = ctx->dev; |
| 549 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 501 | unsigned long enc_recon_y_addr, enc_recon_c_addr; | 550 | unsigned long enc_recon_y_addr, enc_recon_c_addr; |
| 502 | 551 | ||
| 503 | if (IS_MFCV7(dev)) { | 552 | *y_addr = READL(mfc_regs->e_encoded_source_first_plane_addr); |
| 504 | *y_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7); | 553 | *c_addr = READL(mfc_regs->e_encoded_source_second_plane_addr); |
| 505 | *c_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7); | ||
| 506 | } else { | ||
| 507 | *y_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6); | ||
| 508 | *c_addr = READL(S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6); | ||
| 509 | } | ||
| 510 | 554 | ||
| 511 | enc_recon_y_addr = READL(S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); | 555 | enc_recon_y_addr = READL(mfc_regs->e_recon_luma_dpb_addr); |
| 512 | enc_recon_c_addr = READL(S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); | 556 | enc_recon_c_addr = READL(mfc_regs->e_recon_chroma_dpb_addr); |
| 513 | 557 | ||
| 514 | mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr); | 558 | mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr); |
| 515 | mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr); | 559 | mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr); |
| @@ -519,6 +563,7 @@ static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, | |||
| 519 | static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | 563 | static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) |
| 520 | { | 564 | { |
| 521 | struct s5p_mfc_dev *dev = ctx->dev; | 565 | struct s5p_mfc_dev *dev = ctx->dev; |
| 566 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 522 | size_t buf_addr1; | 567 | size_t buf_addr1; |
| 523 | int i, buf_size1; | 568 | int i, buf_size1; |
| 524 | 569 | ||
| @@ -530,24 +575,24 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 530 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); | 575 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); |
| 531 | 576 | ||
| 532 | for (i = 0; i < ctx->pb_count; i++) { | 577 | for (i = 0; i < ctx->pb_count; i++) { |
| 533 | WRITEL(buf_addr1, S5P_FIMV_E_LUMA_DPB_V6 + (4 * i)); | 578 | WRITEL(buf_addr1, mfc_regs->e_luma_dpb + (4 * i)); |
| 534 | buf_addr1 += ctx->luma_dpb_size; | 579 | buf_addr1 += ctx->luma_dpb_size; |
| 535 | WRITEL(buf_addr1, S5P_FIMV_E_CHROMA_DPB_V6 + (4 * i)); | 580 | WRITEL(buf_addr1, mfc_regs->e_chroma_dpb + (4 * i)); |
| 536 | buf_addr1 += ctx->chroma_dpb_size; | 581 | buf_addr1 += ctx->chroma_dpb_size; |
| 537 | WRITEL(buf_addr1, S5P_FIMV_E_ME_BUFFER_V6 + (4 * i)); | 582 | WRITEL(buf_addr1, mfc_regs->e_me_buffer + (4 * i)); |
| 538 | buf_addr1 += ctx->me_buffer_size; | 583 | buf_addr1 += ctx->me_buffer_size; |
| 539 | buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size + | 584 | buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size + |
| 540 | ctx->me_buffer_size); | 585 | ctx->me_buffer_size); |
| 541 | } | 586 | } |
| 542 | 587 | ||
| 543 | WRITEL(buf_addr1, S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6); | 588 | WRITEL(buf_addr1, mfc_regs->e_scratch_buffer_addr); |
| 544 | WRITEL(ctx->scratch_buf_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6); | 589 | WRITEL(ctx->scratch_buf_size, mfc_regs->e_scratch_buffer_size); |
| 545 | buf_addr1 += ctx->scratch_buf_size; | 590 | buf_addr1 += ctx->scratch_buf_size; |
| 546 | buf_size1 -= ctx->scratch_buf_size; | 591 | buf_size1 -= ctx->scratch_buf_size; |
| 547 | 592 | ||
| 548 | WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER0_V6); | 593 | WRITEL(buf_addr1, mfc_regs->e_tmv_buffer0); |
| 549 | buf_addr1 += ctx->tmv_buffer_size >> 1; | 594 | buf_addr1 += ctx->tmv_buffer_size >> 1; |
| 550 | WRITEL(buf_addr1, S5P_FIMV_E_TMV_BUFFER1_V6); | 595 | WRITEL(buf_addr1, mfc_regs->e_tmv_buffer1); |
| 551 | buf_addr1 += ctx->tmv_buffer_size >> 1; | 596 | buf_addr1 += ctx->tmv_buffer_size >> 1; |
| 552 | buf_size1 -= ctx->tmv_buffer_size; | 597 | buf_size1 -= ctx->tmv_buffer_size; |
| 553 | 598 | ||
| @@ -558,7 +603,7 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 558 | return -ENOMEM; | 603 | return -ENOMEM; |
| 559 | } | 604 | } |
| 560 | 605 | ||
| 561 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 606 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 562 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | 607 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
| 563 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); | 608 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); |
| 564 | 609 | ||
| @@ -570,18 +615,19 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
| 570 | static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx) | 615 | static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx) |
| 571 | { | 616 | { |
| 572 | struct s5p_mfc_dev *dev = ctx->dev; | 617 | struct s5p_mfc_dev *dev = ctx->dev; |
| 618 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 573 | 619 | ||
| 574 | /* multi-slice control */ | 620 | /* multi-slice control */ |
| 575 | /* multi-slice MB number or bit size */ | 621 | /* multi-slice MB number or bit size */ |
| 576 | WRITEL(ctx->slice_mode, S5P_FIMV_E_MSLICE_MODE_V6); | 622 | WRITEL(ctx->slice_mode, mfc_regs->e_mslice_mode); |
| 577 | if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { | 623 | if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { |
| 578 | WRITEL(ctx->slice_size.mb, S5P_FIMV_E_MSLICE_SIZE_MB_V6); | 624 | WRITEL(ctx->slice_size.mb, mfc_regs->e_mslice_size_mb); |
| 579 | } else if (ctx->slice_mode == | 625 | } else if (ctx->slice_mode == |
| 580 | V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { | 626 | V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { |
| 581 | WRITEL(ctx->slice_size.bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6); | 627 | WRITEL(ctx->slice_size.bits, mfc_regs->e_mslice_size_bits); |
| 582 | } else { | 628 | } else { |
| 583 | WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_MB_V6); | 629 | WRITEL(0x0, mfc_regs->e_mslice_size_mb); |
| 584 | WRITEL(0x0, S5P_FIMV_E_MSLICE_SIZE_BITS_V6); | 630 | WRITEL(0x0, mfc_regs->e_mslice_size_bits); |
| 585 | } | 631 | } |
| 586 | 632 | ||
| 587 | return 0; | 633 | return 0; |
| @@ -590,27 +636,28 @@ static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx) | |||
| 590 | static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) | 636 | static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) |
| 591 | { | 637 | { |
| 592 | struct s5p_mfc_dev *dev = ctx->dev; | 638 | struct s5p_mfc_dev *dev = ctx->dev; |
| 639 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 593 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 640 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 594 | unsigned int reg = 0; | 641 | unsigned int reg = 0; |
| 595 | 642 | ||
| 596 | mfc_debug_enter(); | 643 | mfc_debug_enter(); |
| 597 | 644 | ||
| 598 | /* width */ | 645 | /* width */ |
| 599 | WRITEL(ctx->img_width, S5P_FIMV_E_FRAME_WIDTH_V6); /* 16 align */ | 646 | WRITEL(ctx->img_width, mfc_regs->e_frame_width); /* 16 align */ |
| 600 | /* height */ | 647 | /* height */ |
| 601 | WRITEL(ctx->img_height, S5P_FIMV_E_FRAME_HEIGHT_V6); /* 16 align */ | 648 | WRITEL(ctx->img_height, mfc_regs->e_frame_height); /* 16 align */ |
| 602 | 649 | ||
| 603 | /* cropped width */ | 650 | /* cropped width */ |
| 604 | WRITEL(ctx->img_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6); | 651 | WRITEL(ctx->img_width, mfc_regs->e_cropped_frame_width); |
| 605 | /* cropped height */ | 652 | /* cropped height */ |
| 606 | WRITEL(ctx->img_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6); | 653 | WRITEL(ctx->img_height, mfc_regs->e_cropped_frame_height); |
| 607 | /* cropped offset */ | 654 | /* cropped offset */ |
| 608 | WRITEL(0x0, S5P_FIMV_E_FRAME_CROP_OFFSET_V6); | 655 | WRITEL(0x0, mfc_regs->e_frame_crop_offset); |
| 609 | 656 | ||
| 610 | /* pictype : IDR period */ | 657 | /* pictype : IDR period */ |
| 611 | reg = 0; | 658 | reg = 0; |
| 612 | reg |= p->gop_size & 0xFFFF; | 659 | reg |= p->gop_size & 0xFFFF; |
| 613 | WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6); | 660 | WRITEL(reg, mfc_regs->e_gop_config); |
| 614 | 661 | ||
| 615 | /* multi-slice control */ | 662 | /* multi-slice control */ |
| 616 | /* multi-slice MB number or bit size */ | 663 | /* multi-slice MB number or bit size */ |
| @@ -618,65 +665,65 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) | |||
| 618 | reg = 0; | 665 | reg = 0; |
| 619 | if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { | 666 | if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { |
| 620 | reg |= (0x1 << 3); | 667 | reg |= (0x1 << 3); |
| 621 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 668 | WRITEL(reg, mfc_regs->e_enc_options); |
| 622 | ctx->slice_size.mb = p->slice_mb; | 669 | ctx->slice_size.mb = p->slice_mb; |
| 623 | } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { | 670 | } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { |
| 624 | reg |= (0x1 << 3); | 671 | reg |= (0x1 << 3); |
| 625 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 672 | WRITEL(reg, mfc_regs->e_enc_options); |
| 626 | ctx->slice_size.bits = p->slice_bit; | 673 | ctx->slice_size.bits = p->slice_bit; |
| 627 | } else { | 674 | } else { |
| 628 | reg &= ~(0x1 << 3); | 675 | reg &= ~(0x1 << 3); |
| 629 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 676 | WRITEL(reg, mfc_regs->e_enc_options); |
| 630 | } | 677 | } |
| 631 | 678 | ||
| 632 | s5p_mfc_set_slice_mode(ctx); | 679 | s5p_mfc_set_slice_mode(ctx); |
| 633 | 680 | ||
| 634 | /* cyclic intra refresh */ | 681 | /* cyclic intra refresh */ |
| 635 | WRITEL(p->intra_refresh_mb, S5P_FIMV_E_IR_SIZE_V6); | 682 | WRITEL(p->intra_refresh_mb, mfc_regs->e_ir_size); |
| 636 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 683 | reg = READL(mfc_regs->e_enc_options); |
| 637 | if (p->intra_refresh_mb == 0) | 684 | if (p->intra_refresh_mb == 0) |
| 638 | reg &= ~(0x1 << 4); | 685 | reg &= ~(0x1 << 4); |
| 639 | else | 686 | else |
| 640 | reg |= (0x1 << 4); | 687 | reg |= (0x1 << 4); |
| 641 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 688 | WRITEL(reg, mfc_regs->e_enc_options); |
| 642 | 689 | ||
| 643 | /* 'NON_REFERENCE_STORE_ENABLE' for debugging */ | 690 | /* 'NON_REFERENCE_STORE_ENABLE' for debugging */ |
| 644 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 691 | reg = READL(mfc_regs->e_enc_options); |
| 645 | reg &= ~(0x1 << 9); | 692 | reg &= ~(0x1 << 9); |
| 646 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 693 | WRITEL(reg, mfc_regs->e_enc_options); |
| 647 | 694 | ||
| 648 | /* memory structure cur. frame */ | 695 | /* memory structure cur. frame */ |
| 649 | if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { | 696 | if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { |
| 650 | /* 0: Linear, 1: 2D tiled*/ | 697 | /* 0: Linear, 1: 2D tiled*/ |
| 651 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 698 | reg = READL(mfc_regs->e_enc_options); |
| 652 | reg &= ~(0x1 << 7); | 699 | reg &= ~(0x1 << 7); |
| 653 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 700 | WRITEL(reg, mfc_regs->e_enc_options); |
| 654 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ | 701 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
| 655 | WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6); | 702 | WRITEL(0x0, mfc_regs->pixel_format); |
| 656 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) { | 703 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) { |
| 657 | /* 0: Linear, 1: 2D tiled*/ | 704 | /* 0: Linear, 1: 2D tiled*/ |
| 658 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 705 | reg = READL(mfc_regs->e_enc_options); |
| 659 | reg &= ~(0x1 << 7); | 706 | reg &= ~(0x1 << 7); |
| 660 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 707 | WRITEL(reg, mfc_regs->e_enc_options); |
| 661 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ | 708 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
| 662 | WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT_V6); | 709 | WRITEL(0x1, mfc_regs->pixel_format); |
| 663 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { | 710 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { |
| 664 | /* 0: Linear, 1: 2D tiled*/ | 711 | /* 0: Linear, 1: 2D tiled*/ |
| 665 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 712 | reg = READL(mfc_regs->e_enc_options); |
| 666 | reg |= (0x1 << 7); | 713 | reg |= (0x1 << 7); |
| 667 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 714 | WRITEL(reg, mfc_regs->e_enc_options); |
| 668 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ | 715 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
| 669 | WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6); | 716 | WRITEL(0x0, mfc_regs->pixel_format); |
| 670 | } | 717 | } |
| 671 | 718 | ||
| 672 | /* memory structure recon. frame */ | 719 | /* memory structure recon. frame */ |
| 673 | /* 0: Linear, 1: 2D tiled */ | 720 | /* 0: Linear, 1: 2D tiled */ |
| 674 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 721 | reg = READL(mfc_regs->e_enc_options); |
| 675 | reg |= (0x1 << 8); | 722 | reg |= (0x1 << 8); |
| 676 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 723 | WRITEL(reg, mfc_regs->e_enc_options); |
| 677 | 724 | ||
| 678 | /* padding control & value */ | 725 | /* padding control & value */ |
| 679 | WRITEL(0x0, S5P_FIMV_E_PADDING_CTRL_V6); | 726 | WRITEL(0x0, mfc_regs->e_padding_ctrl); |
| 680 | if (p->pad) { | 727 | if (p->pad) { |
| 681 | reg = 0; | 728 | reg = 0; |
| 682 | /** enable */ | 729 | /** enable */ |
| @@ -687,64 +734,64 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) | |||
| 687 | reg |= ((p->pad_cb & 0xFF) << 8); | 734 | reg |= ((p->pad_cb & 0xFF) << 8); |
| 688 | /** y value */ | 735 | /** y value */ |
| 689 | reg |= p->pad_luma & 0xFF; | 736 | reg |= p->pad_luma & 0xFF; |
| 690 | WRITEL(reg, S5P_FIMV_E_PADDING_CTRL_V6); | 737 | WRITEL(reg, mfc_regs->e_padding_ctrl); |
| 691 | } | 738 | } |
| 692 | 739 | ||
| 693 | /* rate control config. */ | 740 | /* rate control config. */ |
| 694 | reg = 0; | 741 | reg = 0; |
| 695 | /* frame-level rate control */ | 742 | /* frame-level rate control */ |
| 696 | reg |= ((p->rc_frame & 0x1) << 9); | 743 | reg |= ((p->rc_frame & 0x1) << 9); |
| 697 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 744 | WRITEL(reg, mfc_regs->e_rc_config); |
| 698 | 745 | ||
| 699 | /* bit rate */ | 746 | /* bit rate */ |
| 700 | if (p->rc_frame) | 747 | if (p->rc_frame) |
| 701 | WRITEL(p->rc_bitrate, | 748 | WRITEL(p->rc_bitrate, |
| 702 | S5P_FIMV_E_RC_BIT_RATE_V6); | 749 | mfc_regs->e_rc_bit_rate); |
| 703 | else | 750 | else |
| 704 | WRITEL(1, S5P_FIMV_E_RC_BIT_RATE_V6); | 751 | WRITEL(1, mfc_regs->e_rc_bit_rate); |
| 705 | 752 | ||
| 706 | /* reaction coefficient */ | 753 | /* reaction coefficient */ |
| 707 | if (p->rc_frame) { | 754 | if (p->rc_frame) { |
| 708 | if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */ | 755 | if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */ |
| 709 | WRITEL(1, S5P_FIMV_E_RC_RPARAM_V6); | 756 | WRITEL(1, mfc_regs->e_rc_mode); |
| 710 | else /* loose CBR */ | 757 | else /* loose CBR */ |
| 711 | WRITEL(2, S5P_FIMV_E_RC_RPARAM_V6); | 758 | WRITEL(2, mfc_regs->e_rc_mode); |
| 712 | } | 759 | } |
| 713 | 760 | ||
| 714 | /* seq header ctrl */ | 761 | /* seq header ctrl */ |
| 715 | reg = READL(S5P_FIMV_E_ENC_OPTIONS_V6); | 762 | reg = READL(mfc_regs->e_enc_options); |
| 716 | reg &= ~(0x1 << 2); | 763 | reg &= ~(0x1 << 2); |
| 717 | reg |= ((p->seq_hdr_mode & 0x1) << 2); | 764 | reg |= ((p->seq_hdr_mode & 0x1) << 2); |
| 718 | 765 | ||
| 719 | /* frame skip mode */ | 766 | /* frame skip mode */ |
| 720 | reg &= ~(0x3); | 767 | reg &= ~(0x3); |
| 721 | reg |= (p->frame_skip_mode & 0x3); | 768 | reg |= (p->frame_skip_mode & 0x3); |
| 722 | WRITEL(reg, S5P_FIMV_E_ENC_OPTIONS_V6); | 769 | WRITEL(reg, mfc_regs->e_enc_options); |
| 723 | 770 | ||
| 724 | /* 'DROP_CONTROL_ENABLE', disable */ | 771 | /* 'DROP_CONTROL_ENABLE', disable */ |
| 725 | reg = READL(S5P_FIMV_E_RC_CONFIG_V6); | 772 | reg = READL(mfc_regs->e_rc_config); |
| 726 | reg &= ~(0x1 << 10); | 773 | reg &= ~(0x1 << 10); |
| 727 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 774 | WRITEL(reg, mfc_regs->e_rc_config); |
| 728 | 775 | ||
| 729 | /* setting for MV range [16, 256] */ | 776 | /* setting for MV range [16, 256] */ |
| 730 | reg = (p->mv_h_range & S5P_FIMV_E_MV_RANGE_V6_MASK); | 777 | reg = (p->mv_h_range & S5P_FIMV_E_MV_RANGE_V6_MASK); |
| 731 | WRITEL(reg, S5P_FIMV_E_MV_HOR_RANGE_V6); | 778 | WRITEL(reg, mfc_regs->e_mv_hor_range); |
| 732 | 779 | ||
| 733 | reg = (p->mv_v_range & S5P_FIMV_E_MV_RANGE_V6_MASK); | 780 | reg = (p->mv_v_range & S5P_FIMV_E_MV_RANGE_V6_MASK); |
| 734 | WRITEL(reg, S5P_FIMV_E_MV_VER_RANGE_V6); | 781 | WRITEL(reg, mfc_regs->e_mv_ver_range); |
| 735 | 782 | ||
| 736 | WRITEL(0x0, S5P_FIMV_E_FRAME_INSERTION_V6); | 783 | WRITEL(0x0, mfc_regs->e_frame_insertion); |
| 737 | WRITEL(0x0, S5P_FIMV_E_ROI_BUFFER_ADDR_V6); | 784 | WRITEL(0x0, mfc_regs->e_roi_buffer_addr); |
| 738 | WRITEL(0x0, S5P_FIMV_E_PARAM_CHANGE_V6); | 785 | WRITEL(0x0, mfc_regs->e_param_change); |
| 739 | WRITEL(0x0, S5P_FIMV_E_RC_ROI_CTRL_V6); | 786 | WRITEL(0x0, mfc_regs->e_rc_roi_ctrl); |
| 740 | WRITEL(0x0, S5P_FIMV_E_PICTURE_TAG_V6); | 787 | WRITEL(0x0, mfc_regs->e_picture_tag); |
| 741 | 788 | ||
| 742 | WRITEL(0x0, S5P_FIMV_E_BIT_COUNT_ENABLE_V6); | 789 | WRITEL(0x0, mfc_regs->e_bit_count_enable); |
| 743 | WRITEL(0x0, S5P_FIMV_E_MAX_BIT_COUNT_V6); | 790 | WRITEL(0x0, mfc_regs->e_max_bit_count); |
| 744 | WRITEL(0x0, S5P_FIMV_E_MIN_BIT_COUNT_V6); | 791 | WRITEL(0x0, mfc_regs->e_min_bit_count); |
| 745 | 792 | ||
| 746 | WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_ADDR_V6); | 793 | WRITEL(0x0, mfc_regs->e_metadata_buffer_addr); |
| 747 | WRITEL(0x0, S5P_FIMV_E_METADATA_BUFFER_SIZE_V6); | 794 | WRITEL(0x0, mfc_regs->e_metadata_buffer_size); |
| 748 | 795 | ||
| 749 | mfc_debug_leave(); | 796 | mfc_debug_leave(); |
| 750 | 797 | ||
| @@ -754,6 +801,7 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) | |||
| 754 | static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | 801 | static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) |
| 755 | { | 802 | { |
| 756 | struct s5p_mfc_dev *dev = ctx->dev; | 803 | struct s5p_mfc_dev *dev = ctx->dev; |
| 804 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 757 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 805 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 758 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; | 806 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; |
| 759 | unsigned int reg = 0; | 807 | unsigned int reg = 0; |
| @@ -764,10 +812,10 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 764 | s5p_mfc_set_enc_params(ctx); | 812 | s5p_mfc_set_enc_params(ctx); |
| 765 | 813 | ||
| 766 | /* pictype : number of B */ | 814 | /* pictype : number of B */ |
| 767 | reg = READL(S5P_FIMV_E_GOP_CONFIG_V6); | 815 | reg = READL(mfc_regs->e_gop_config); |
| 768 | reg &= ~(0x3 << 16); | 816 | reg &= ~(0x3 << 16); |
| 769 | reg |= ((p->num_b_frame & 0x3) << 16); | 817 | reg |= ((p->num_b_frame & 0x3) << 16); |
| 770 | WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6); | 818 | WRITEL(reg, mfc_regs->e_gop_config); |
| 771 | 819 | ||
| 772 | /* profile & level */ | 820 | /* profile & level */ |
| 773 | reg = 0; | 821 | reg = 0; |
| @@ -775,18 +823,19 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 775 | reg |= ((p_h264->level & 0xFF) << 8); | 823 | reg |= ((p_h264->level & 0xFF) << 8); |
| 776 | /** profile - 0 ~ 3 */ | 824 | /** profile - 0 ~ 3 */ |
| 777 | reg |= p_h264->profile & 0x3F; | 825 | reg |= p_h264->profile & 0x3F; |
| 778 | WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6); | 826 | WRITEL(reg, mfc_regs->e_picture_profile); |
| 779 | 827 | ||
| 780 | /* rate control config. */ | 828 | /* rate control config. */ |
| 781 | reg = READL(S5P_FIMV_E_RC_CONFIG_V6); | 829 | reg = READL(mfc_regs->e_rc_config); |
| 782 | /** macroblock level rate control */ | 830 | /** macroblock level rate control */ |
| 783 | reg &= ~(0x1 << 8); | 831 | reg &= ~(0x1 << 8); |
| 784 | reg |= ((p->rc_mb & 0x1) << 8); | 832 | reg |= ((p->rc_mb & 0x1) << 8); |
| 785 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 833 | WRITEL(reg, mfc_regs->e_rc_config); |
| 834 | |||
| 786 | /** frame QP */ | 835 | /** frame QP */ |
| 787 | reg &= ~(0x3F); | 836 | reg &= ~(0x3F); |
| 788 | reg |= p_h264->rc_frame_qp & 0x3F; | 837 | reg |= p_h264->rc_frame_qp & 0x3F; |
| 789 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 838 | WRITEL(reg, mfc_regs->e_rc_config); |
| 790 | 839 | ||
| 791 | /* max & min value of QP */ | 840 | /* max & min value of QP */ |
| 792 | reg = 0; | 841 | reg = 0; |
| @@ -794,16 +843,16 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 794 | reg |= ((p_h264->rc_max_qp & 0x3F) << 8); | 843 | reg |= ((p_h264->rc_max_qp & 0x3F) << 8); |
| 795 | /** min QP */ | 844 | /** min QP */ |
| 796 | reg |= p_h264->rc_min_qp & 0x3F; | 845 | reg |= p_h264->rc_min_qp & 0x3F; |
| 797 | WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6); | 846 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
| 798 | 847 | ||
| 799 | /* other QPs */ | 848 | /* other QPs */ |
| 800 | WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 849 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
| 801 | if (!p->rc_frame && !p->rc_mb) { | 850 | if (!p->rc_frame && !p->rc_mb) { |
| 802 | reg = 0; | 851 | reg = 0; |
| 803 | reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16); | 852 | reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16); |
| 804 | reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8); | 853 | reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8); |
| 805 | reg |= p_h264->rc_frame_qp & 0x3F; | 854 | reg |= p_h264->rc_frame_qp & 0x3F; |
| 806 | WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 855 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
| 807 | } | 856 | } |
| 808 | 857 | ||
| 809 | /* frame rate */ | 858 | /* frame rate */ |
| @@ -811,38 +860,38 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 811 | reg = 0; | 860 | reg = 0; |
| 812 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | 861 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 813 | reg |= p->rc_framerate_denom & 0xFFFF; | 862 | reg |= p->rc_framerate_denom & 0xFFFF; |
| 814 | WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6); | 863 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
| 815 | } | 864 | } |
| 816 | 865 | ||
| 817 | /* vbv buffer size */ | 866 | /* vbv buffer size */ |
| 818 | if (p->frame_skip_mode == | 867 | if (p->frame_skip_mode == |
| 819 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | 868 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
| 820 | WRITEL(p_h264->cpb_size & 0xFFFF, | 869 | WRITEL(p_h264->cpb_size & 0xFFFF, |
| 821 | S5P_FIMV_E_VBV_BUFFER_SIZE_V6); | 870 | mfc_regs->e_vbv_buffer_size); |
| 822 | 871 | ||
| 823 | if (p->rc_frame) | 872 | if (p->rc_frame) |
| 824 | WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); | 873 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
| 825 | } | 874 | } |
| 826 | 875 | ||
| 827 | /* interlace */ | 876 | /* interlace */ |
| 828 | reg = 0; | 877 | reg = 0; |
| 829 | reg |= ((p_h264->interlace & 0x1) << 3); | 878 | reg |= ((p_h264->interlace & 0x1) << 3); |
| 830 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 879 | WRITEL(reg, mfc_regs->e_h264_options); |
| 831 | 880 | ||
| 832 | /* height */ | 881 | /* height */ |
| 833 | if (p_h264->interlace) { | 882 | if (p_h264->interlace) { |
| 834 | WRITEL(ctx->img_height >> 1, | 883 | WRITEL(ctx->img_height >> 1, |
| 835 | S5P_FIMV_E_FRAME_HEIGHT_V6); /* 32 align */ | 884 | mfc_regs->e_frame_height); /* 32 align */ |
| 836 | /* cropped height */ | 885 | /* cropped height */ |
| 837 | WRITEL(ctx->img_height >> 1, | 886 | WRITEL(ctx->img_height >> 1, |
| 838 | S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6); | 887 | mfc_regs->e_cropped_frame_height); |
| 839 | } | 888 | } |
| 840 | 889 | ||
| 841 | /* loop filter ctrl */ | 890 | /* loop filter ctrl */ |
| 842 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 891 | reg = READL(mfc_regs->e_h264_options); |
| 843 | reg &= ~(0x3 << 1); | 892 | reg &= ~(0x3 << 1); |
| 844 | reg |= ((p_h264->loop_filter_mode & 0x3) << 1); | 893 | reg |= ((p_h264->loop_filter_mode & 0x3) << 1); |
| 845 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 894 | WRITEL(reg, mfc_regs->e_h264_options); |
| 846 | 895 | ||
| 847 | /* loopfilter alpha offset */ | 896 | /* loopfilter alpha offset */ |
| 848 | if (p_h264->loop_filter_alpha < 0) { | 897 | if (p_h264->loop_filter_alpha < 0) { |
| @@ -852,7 +901,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 852 | reg = 0x00; | 901 | reg = 0x00; |
| 853 | reg |= (p_h264->loop_filter_alpha & 0xF); | 902 | reg |= (p_h264->loop_filter_alpha & 0xF); |
| 854 | } | 903 | } |
| 855 | WRITEL(reg, S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6); | 904 | WRITEL(reg, mfc_regs->e_h264_lf_alpha_offset); |
| 856 | 905 | ||
| 857 | /* loopfilter beta offset */ | 906 | /* loopfilter beta offset */ |
| 858 | if (p_h264->loop_filter_beta < 0) { | 907 | if (p_h264->loop_filter_beta < 0) { |
| @@ -862,28 +911,28 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 862 | reg = 0x00; | 911 | reg = 0x00; |
| 863 | reg |= (p_h264->loop_filter_beta & 0xF); | 912 | reg |= (p_h264->loop_filter_beta & 0xF); |
| 864 | } | 913 | } |
| 865 | WRITEL(reg, S5P_FIMV_E_H264_LF_BETA_OFFSET_V6); | 914 | WRITEL(reg, mfc_regs->e_h264_lf_beta_offset); |
| 866 | 915 | ||
| 867 | /* entropy coding mode */ | 916 | /* entropy coding mode */ |
| 868 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 917 | reg = READL(mfc_regs->e_h264_options); |
| 869 | reg &= ~(0x1); | 918 | reg &= ~(0x1); |
| 870 | reg |= p_h264->entropy_mode & 0x1; | 919 | reg |= p_h264->entropy_mode & 0x1; |
| 871 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 920 | WRITEL(reg, mfc_regs->e_h264_options); |
| 872 | 921 | ||
| 873 | /* number of ref. picture */ | 922 | /* number of ref. picture */ |
| 874 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 923 | reg = READL(mfc_regs->e_h264_options); |
| 875 | reg &= ~(0x1 << 7); | 924 | reg &= ~(0x1 << 7); |
| 876 | reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7); | 925 | reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7); |
| 877 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 926 | WRITEL(reg, mfc_regs->e_h264_options); |
| 878 | 927 | ||
| 879 | /* 8x8 transform enable */ | 928 | /* 8x8 transform enable */ |
| 880 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 929 | reg = READL(mfc_regs->e_h264_options); |
| 881 | reg &= ~(0x3 << 12); | 930 | reg &= ~(0x3 << 12); |
| 882 | reg |= ((p_h264->_8x8_transform & 0x3) << 12); | 931 | reg |= ((p_h264->_8x8_transform & 0x3) << 12); |
| 883 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 932 | WRITEL(reg, mfc_regs->e_h264_options); |
| 884 | 933 | ||
| 885 | /* macroblock adaptive scaling features */ | 934 | /* macroblock adaptive scaling features */ |
| 886 | WRITEL(0x0, S5P_FIMV_E_MB_RC_CONFIG_V6); | 935 | WRITEL(0x0, mfc_regs->e_mb_rc_config); |
| 887 | if (p->rc_mb) { | 936 | if (p->rc_mb) { |
| 888 | reg = 0; | 937 | reg = 0; |
| 889 | /** dark region */ | 938 | /** dark region */ |
| @@ -894,92 +943,95 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 894 | reg |= ((p_h264->rc_mb_static & 0x1) << 1); | 943 | reg |= ((p_h264->rc_mb_static & 0x1) << 1); |
| 895 | /** high activity region */ | 944 | /** high activity region */ |
| 896 | reg |= p_h264->rc_mb_activity & 0x1; | 945 | reg |= p_h264->rc_mb_activity & 0x1; |
| 897 | WRITEL(reg, S5P_FIMV_E_MB_RC_CONFIG_V6); | 946 | WRITEL(reg, mfc_regs->e_mb_rc_config); |
| 898 | } | 947 | } |
| 899 | 948 | ||
| 900 | /* aspect ratio VUI */ | 949 | /* aspect ratio VUI */ |
| 901 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 950 | READL(mfc_regs->e_h264_options); |
| 902 | reg &= ~(0x1 << 5); | 951 | reg &= ~(0x1 << 5); |
| 903 | reg |= ((p_h264->vui_sar & 0x1) << 5); | 952 | reg |= ((p_h264->vui_sar & 0x1) << 5); |
| 904 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 953 | WRITEL(reg, mfc_regs->e_h264_options); |
| 905 | 954 | ||
| 906 | WRITEL(0x0, S5P_FIMV_E_ASPECT_RATIO_V6); | 955 | WRITEL(0x0, mfc_regs->e_aspect_ratio); |
| 907 | WRITEL(0x0, S5P_FIMV_E_EXTENDED_SAR_V6); | 956 | WRITEL(0x0, mfc_regs->e_extended_sar); |
| 908 | if (p_h264->vui_sar) { | 957 | if (p_h264->vui_sar) { |
| 909 | /* aspect ration IDC */ | 958 | /* aspect ration IDC */ |
| 910 | reg = 0; | 959 | reg = 0; |
| 911 | reg |= p_h264->vui_sar_idc & 0xFF; | 960 | reg |= p_h264->vui_sar_idc & 0xFF; |
| 912 | WRITEL(reg, S5P_FIMV_E_ASPECT_RATIO_V6); | 961 | WRITEL(reg, mfc_regs->e_aspect_ratio); |
| 913 | if (p_h264->vui_sar_idc == 0xFF) { | 962 | if (p_h264->vui_sar_idc == 0xFF) { |
| 914 | /* extended SAR */ | 963 | /* extended SAR */ |
| 915 | reg = 0; | 964 | reg = 0; |
| 916 | reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16; | 965 | reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16; |
| 917 | reg |= p_h264->vui_ext_sar_height & 0xFFFF; | 966 | reg |= p_h264->vui_ext_sar_height & 0xFFFF; |
| 918 | WRITEL(reg, S5P_FIMV_E_EXTENDED_SAR_V6); | 967 | WRITEL(reg, mfc_regs->e_extended_sar); |
| 919 | } | 968 | } |
| 920 | } | 969 | } |
| 921 | 970 | ||
| 922 | /* intra picture period for H.264 open GOP */ | 971 | /* intra picture period for H.264 open GOP */ |
| 923 | /* control */ | 972 | /* control */ |
| 924 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 973 | READL(mfc_regs->e_h264_options); |
| 925 | reg &= ~(0x1 << 4); | 974 | reg &= ~(0x1 << 4); |
| 926 | reg |= ((p_h264->open_gop & 0x1) << 4); | 975 | reg |= ((p_h264->open_gop & 0x1) << 4); |
| 927 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 976 | WRITEL(reg, mfc_regs->e_h264_options); |
| 977 | |||
| 928 | /* value */ | 978 | /* value */ |
| 929 | WRITEL(0x0, S5P_FIMV_E_H264_I_PERIOD_V6); | 979 | WRITEL(0x0, mfc_regs->e_h264_i_period); |
| 930 | if (p_h264->open_gop) { | 980 | if (p_h264->open_gop) { |
| 931 | reg = 0; | 981 | reg = 0; |
| 932 | reg |= p_h264->open_gop_size & 0xFFFF; | 982 | reg |= p_h264->open_gop_size & 0xFFFF; |
| 933 | WRITEL(reg, S5P_FIMV_E_H264_I_PERIOD_V6); | 983 | WRITEL(reg, mfc_regs->e_h264_i_period); |
| 934 | } | 984 | } |
| 935 | 985 | ||
| 936 | /* 'WEIGHTED_BI_PREDICTION' for B is disable */ | 986 | /* 'WEIGHTED_BI_PREDICTION' for B is disable */ |
| 937 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 987 | READL(mfc_regs->e_h264_options); |
| 938 | reg &= ~(0x3 << 9); | 988 | reg &= ~(0x3 << 9); |
| 939 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 989 | WRITEL(reg, mfc_regs->e_h264_options); |
| 940 | 990 | ||
| 941 | /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */ | 991 | /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */ |
| 942 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 992 | READL(mfc_regs->e_h264_options); |
| 943 | reg &= ~(0x1 << 14); | 993 | reg &= ~(0x1 << 14); |
| 944 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 994 | WRITEL(reg, mfc_regs->e_h264_options); |
| 945 | 995 | ||
| 946 | /* ASO */ | 996 | /* ASO */ |
| 947 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 997 | READL(mfc_regs->e_h264_options); |
| 948 | reg &= ~(0x1 << 6); | 998 | reg &= ~(0x1 << 6); |
| 949 | reg |= ((p_h264->aso & 0x1) << 6); | 999 | reg |= ((p_h264->aso & 0x1) << 6); |
| 950 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 1000 | WRITEL(reg, mfc_regs->e_h264_options); |
| 951 | 1001 | ||
| 952 | /* hier qp enable */ | 1002 | /* hier qp enable */ |
| 953 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 1003 | READL(mfc_regs->e_h264_options); |
| 954 | reg &= ~(0x1 << 8); | 1004 | reg &= ~(0x1 << 8); |
| 955 | reg |= ((p_h264->open_gop & 0x1) << 8); | 1005 | reg |= ((p_h264->open_gop & 0x1) << 8); |
| 956 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 1006 | WRITEL(reg, mfc_regs->e_h264_options); |
| 957 | reg = 0; | 1007 | reg = 0; |
| 958 | if (p_h264->hier_qp && p_h264->hier_qp_layer) { | 1008 | if (p_h264->hier_qp && p_h264->hier_qp_layer) { |
| 959 | reg |= (p_h264->hier_qp_type & 0x1) << 0x3; | 1009 | reg |= (p_h264->hier_qp_type & 0x1) << 0x3; |
| 960 | reg |= p_h264->hier_qp_layer & 0x7; | 1010 | reg |= p_h264->hier_qp_layer & 0x7; |
| 961 | WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER_V6); | 1011 | WRITEL(reg, mfc_regs->e_h264_num_t_layer); |
| 962 | /* QP value for each layer */ | 1012 | /* QP value for each layer */ |
| 963 | for (i = 0; i < (p_h264->hier_qp_layer & 0x7); i++) | 1013 | for (i = 0; i < p_h264->hier_qp_layer && |
| 1014 | i < ARRAY_SIZE(p_h264->hier_qp_layer_qp); i++) { | ||
| 964 | WRITEL(p_h264->hier_qp_layer_qp[i], | 1015 | WRITEL(p_h264->hier_qp_layer_qp[i], |
| 965 | S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6 + | 1016 | mfc_regs->e_h264_hierarchical_qp_layer0 |
| 966 | i * 4); | 1017 | + i * 4); |
| 1018 | } | ||
| 967 | } | 1019 | } |
| 968 | /* number of coding layer should be zero when hierarchical is disable */ | 1020 | /* number of coding layer should be zero when hierarchical is disable */ |
| 969 | WRITEL(reg, S5P_FIMV_E_H264_NUM_T_LAYER_V6); | 1021 | WRITEL(reg, mfc_regs->e_h264_num_t_layer); |
| 970 | 1022 | ||
| 971 | /* frame packing SEI generation */ | 1023 | /* frame packing SEI generation */ |
| 972 | reg = READL(S5P_FIMV_E_H264_OPTIONS_V6); | 1024 | READL(mfc_regs->e_h264_options); |
| 973 | reg &= ~(0x1 << 25); | 1025 | reg &= ~(0x1 << 25); |
| 974 | reg |= ((p_h264->sei_frame_packing & 0x1) << 25); | 1026 | reg |= ((p_h264->sei_frame_packing & 0x1) << 25); |
| 975 | WRITEL(reg, S5P_FIMV_E_H264_OPTIONS_V6); | 1027 | WRITEL(reg, mfc_regs->e_h264_options); |
| 976 | if (p_h264->sei_frame_packing) { | 1028 | if (p_h264->sei_frame_packing) { |
| 977 | reg = 0; | 1029 | reg = 0; |
| 978 | /** current frame0 flag */ | 1030 | /** current frame0 flag */ |
| 979 | reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2); | 1031 | reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2); |
| 980 | /** arrangement type */ | 1032 | /** arrangement type */ |
| 981 | reg |= p_h264->sei_fp_arrangement_type & 0x3; | 1033 | reg |= p_h264->sei_fp_arrangement_type & 0x3; |
| 982 | WRITEL(reg, S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6); | 1034 | WRITEL(reg, mfc_regs->e_h264_frame_packing_sei_info); |
| 983 | } | 1035 | } |
| 984 | 1036 | ||
| 985 | if (p_h264->fmo) { | 1037 | if (p_h264->fmo) { |
| @@ -989,8 +1041,8 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 989 | p_h264->fmo_slice_grp = 4; | 1041 | p_h264->fmo_slice_grp = 4; |
| 990 | for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++) | 1042 | for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++) |
| 991 | WRITEL(p_h264->fmo_run_len[i] - 1, | 1043 | WRITEL(p_h264->fmo_run_len[i] - 1, |
| 992 | S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6 + | 1044 | mfc_regs->e_h264_fmo_run_length_minus1_0 |
| 993 | i * 4); | 1045 | + i * 4); |
| 994 | break; | 1046 | break; |
| 995 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES: | 1047 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES: |
| 996 | if (p_h264->fmo_slice_grp > 4) | 1048 | if (p_h264->fmo_slice_grp > 4) |
| @@ -1001,10 +1053,10 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 1001 | if (p_h264->fmo_slice_grp > 2) | 1053 | if (p_h264->fmo_slice_grp > 2) |
| 1002 | p_h264->fmo_slice_grp = 2; | 1054 | p_h264->fmo_slice_grp = 2; |
| 1003 | WRITEL(p_h264->fmo_chg_dir & 0x1, | 1055 | WRITEL(p_h264->fmo_chg_dir & 0x1, |
| 1004 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6); | 1056 | mfc_regs->e_h264_fmo_slice_grp_change_dir); |
| 1005 | /* the valid range is 0 ~ number of macroblocks -1 */ | 1057 | /* the valid range is 0 ~ number of macroblocks -1 */ |
| 1006 | WRITEL(p_h264->fmo_chg_rate, | 1058 | WRITEL(p_h264->fmo_chg_rate, |
| 1007 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6); | 1059 | mfc_regs->e_h264_fmo_slice_grp_change_rate_minus1); |
| 1008 | break; | 1060 | break; |
| 1009 | default: | 1061 | default: |
| 1010 | mfc_err("Unsupported map type for FMO: %d\n", | 1062 | mfc_err("Unsupported map type for FMO: %d\n", |
| @@ -1015,11 +1067,11 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 1015 | } | 1067 | } |
| 1016 | 1068 | ||
| 1017 | WRITEL(p_h264->fmo_map_type, | 1069 | WRITEL(p_h264->fmo_map_type, |
| 1018 | S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6); | 1070 | mfc_regs->e_h264_fmo_slice_grp_map_type); |
| 1019 | WRITEL(p_h264->fmo_slice_grp - 1, | 1071 | WRITEL(p_h264->fmo_slice_grp - 1, |
| 1020 | S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6); | 1072 | mfc_regs->e_h264_fmo_num_slice_grp_minus1); |
| 1021 | } else { | 1073 | } else { |
| 1022 | WRITEL(0, S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6); | 1074 | WRITEL(0, mfc_regs->e_h264_fmo_num_slice_grp_minus1); |
| 1023 | } | 1075 | } |
| 1024 | 1076 | ||
| 1025 | mfc_debug_leave(); | 1077 | mfc_debug_leave(); |
| @@ -1030,6 +1082,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |||
| 1030 | static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | 1082 | static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) |
| 1031 | { | 1083 | { |
| 1032 | struct s5p_mfc_dev *dev = ctx->dev; | 1084 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1085 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1033 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 1086 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1034 | struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; | 1087 | struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; |
| 1035 | unsigned int reg = 0; | 1088 | unsigned int reg = 0; |
| @@ -1039,10 +1092,10 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | |||
| 1039 | s5p_mfc_set_enc_params(ctx); | 1092 | s5p_mfc_set_enc_params(ctx); |
| 1040 | 1093 | ||
| 1041 | /* pictype : number of B */ | 1094 | /* pictype : number of B */ |
| 1042 | reg = READL(S5P_FIMV_E_GOP_CONFIG_V6); | 1095 | reg = READL(mfc_regs->e_gop_config); |
| 1043 | reg &= ~(0x3 << 16); | 1096 | reg &= ~(0x3 << 16); |
| 1044 | reg |= ((p->num_b_frame & 0x3) << 16); | 1097 | reg |= ((p->num_b_frame & 0x3) << 16); |
| 1045 | WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6); | 1098 | WRITEL(reg, mfc_regs->e_gop_config); |
| 1046 | 1099 | ||
| 1047 | /* profile & level */ | 1100 | /* profile & level */ |
| 1048 | reg = 0; | 1101 | reg = 0; |
| @@ -1050,18 +1103,19 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | |||
| 1050 | reg |= ((p_mpeg4->level & 0xFF) << 8); | 1103 | reg |= ((p_mpeg4->level & 0xFF) << 8); |
| 1051 | /** profile - 0 ~ 1 */ | 1104 | /** profile - 0 ~ 1 */ |
| 1052 | reg |= p_mpeg4->profile & 0x3F; | 1105 | reg |= p_mpeg4->profile & 0x3F; |
| 1053 | WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6); | 1106 | WRITEL(reg, mfc_regs->e_picture_profile); |
| 1054 | 1107 | ||
| 1055 | /* rate control config. */ | 1108 | /* rate control config. */ |
| 1056 | reg = READL(S5P_FIMV_E_RC_CONFIG_V6); | 1109 | reg = READL(mfc_regs->e_rc_config); |
| 1057 | /** macroblock level rate control */ | 1110 | /** macroblock level rate control */ |
| 1058 | reg &= ~(0x1 << 8); | 1111 | reg &= ~(0x1 << 8); |
| 1059 | reg |= ((p->rc_mb & 0x1) << 8); | 1112 | reg |= ((p->rc_mb & 0x1) << 8); |
| 1060 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 1113 | WRITEL(reg, mfc_regs->e_rc_config); |
| 1114 | |||
| 1061 | /** frame QP */ | 1115 | /** frame QP */ |
| 1062 | reg &= ~(0x3F); | 1116 | reg &= ~(0x3F); |
| 1063 | reg |= p_mpeg4->rc_frame_qp & 0x3F; | 1117 | reg |= p_mpeg4->rc_frame_qp & 0x3F; |
| 1064 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 1118 | WRITEL(reg, mfc_regs->e_rc_config); |
| 1065 | 1119 | ||
| 1066 | /* max & min value of QP */ | 1120 | /* max & min value of QP */ |
| 1067 | reg = 0; | 1121 | reg = 0; |
| @@ -1069,16 +1123,16 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | |||
| 1069 | reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8); | 1123 | reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8); |
| 1070 | /** min QP */ | 1124 | /** min QP */ |
| 1071 | reg |= p_mpeg4->rc_min_qp & 0x3F; | 1125 | reg |= p_mpeg4->rc_min_qp & 0x3F; |
| 1072 | WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6); | 1126 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
| 1073 | 1127 | ||
| 1074 | /* other QPs */ | 1128 | /* other QPs */ |
| 1075 | WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 1129 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
| 1076 | if (!p->rc_frame && !p->rc_mb) { | 1130 | if (!p->rc_frame && !p->rc_mb) { |
| 1077 | reg = 0; | 1131 | reg = 0; |
| 1078 | reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16); | 1132 | reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16); |
| 1079 | reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8); | 1133 | reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8); |
| 1080 | reg |= p_mpeg4->rc_frame_qp & 0x3F; | 1134 | reg |= p_mpeg4->rc_frame_qp & 0x3F; |
| 1081 | WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 1135 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
| 1082 | } | 1136 | } |
| 1083 | 1137 | ||
| 1084 | /* frame rate */ | 1138 | /* frame rate */ |
| @@ -1086,21 +1140,21 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | |||
| 1086 | reg = 0; | 1140 | reg = 0; |
| 1087 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | 1141 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 1088 | reg |= p->rc_framerate_denom & 0xFFFF; | 1142 | reg |= p->rc_framerate_denom & 0xFFFF; |
| 1089 | WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6); | 1143 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
| 1090 | } | 1144 | } |
| 1091 | 1145 | ||
| 1092 | /* vbv buffer size */ | 1146 | /* vbv buffer size */ |
| 1093 | if (p->frame_skip_mode == | 1147 | if (p->frame_skip_mode == |
| 1094 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | 1148 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
| 1095 | WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6); | 1149 | WRITEL(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
| 1096 | 1150 | ||
| 1097 | if (p->rc_frame) | 1151 | if (p->rc_frame) |
| 1098 | WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); | 1152 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
| 1099 | } | 1153 | } |
| 1100 | 1154 | ||
| 1101 | /* Disable HEC */ | 1155 | /* Disable HEC */ |
| 1102 | WRITEL(0x0, S5P_FIMV_E_MPEG4_OPTIONS_V6); | 1156 | WRITEL(0x0, mfc_regs->e_mpeg4_options); |
| 1103 | WRITEL(0x0, S5P_FIMV_E_MPEG4_HEC_PERIOD_V6); | 1157 | WRITEL(0x0, mfc_regs->e_mpeg4_hec_period); |
| 1104 | 1158 | ||
| 1105 | mfc_debug_leave(); | 1159 | mfc_debug_leave(); |
| 1106 | 1160 | ||
| @@ -1110,6 +1164,7 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | |||
| 1110 | static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | 1164 | static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) |
| 1111 | { | 1165 | { |
| 1112 | struct s5p_mfc_dev *dev = ctx->dev; | 1166 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1167 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1113 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 1168 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1114 | struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; | 1169 | struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; |
| 1115 | unsigned int reg = 0; | 1170 | unsigned int reg = 0; |
| @@ -1122,18 +1177,19 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | |||
| 1122 | reg = 0; | 1177 | reg = 0; |
| 1123 | /** profile */ | 1178 | /** profile */ |
| 1124 | reg |= (0x1 << 4); | 1179 | reg |= (0x1 << 4); |
| 1125 | WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6); | 1180 | WRITEL(reg, mfc_regs->e_picture_profile); |
| 1126 | 1181 | ||
| 1127 | /* rate control config. */ | 1182 | /* rate control config. */ |
| 1128 | reg = READL(S5P_FIMV_E_RC_CONFIG_V6); | 1183 | reg = READL(mfc_regs->e_rc_config); |
| 1129 | /** macroblock level rate control */ | 1184 | /** macroblock level rate control */ |
| 1130 | reg &= ~(0x1 << 8); | 1185 | reg &= ~(0x1 << 8); |
| 1131 | reg |= ((p->rc_mb & 0x1) << 8); | 1186 | reg |= ((p->rc_mb & 0x1) << 8); |
| 1132 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 1187 | WRITEL(reg, mfc_regs->e_rc_config); |
| 1188 | |||
| 1133 | /** frame QP */ | 1189 | /** frame QP */ |
| 1134 | reg &= ~(0x3F); | 1190 | reg &= ~(0x3F); |
| 1135 | reg |= p_h263->rc_frame_qp & 0x3F; | 1191 | reg |= p_h263->rc_frame_qp & 0x3F; |
| 1136 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 1192 | WRITEL(reg, mfc_regs->e_rc_config); |
| 1137 | 1193 | ||
| 1138 | /* max & min value of QP */ | 1194 | /* max & min value of QP */ |
| 1139 | reg = 0; | 1195 | reg = 0; |
| @@ -1141,16 +1197,16 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | |||
| 1141 | reg |= ((p_h263->rc_max_qp & 0x3F) << 8); | 1197 | reg |= ((p_h263->rc_max_qp & 0x3F) << 8); |
| 1142 | /** min QP */ | 1198 | /** min QP */ |
| 1143 | reg |= p_h263->rc_min_qp & 0x3F; | 1199 | reg |= p_h263->rc_min_qp & 0x3F; |
| 1144 | WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6); | 1200 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
| 1145 | 1201 | ||
| 1146 | /* other QPs */ | 1202 | /* other QPs */ |
| 1147 | WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 1203 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
| 1148 | if (!p->rc_frame && !p->rc_mb) { | 1204 | if (!p->rc_frame && !p->rc_mb) { |
| 1149 | reg = 0; | 1205 | reg = 0; |
| 1150 | reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16); | 1206 | reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16); |
| 1151 | reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8); | 1207 | reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8); |
| 1152 | reg |= p_h263->rc_frame_qp & 0x3F; | 1208 | reg |= p_h263->rc_frame_qp & 0x3F; |
| 1153 | WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 1209 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
| 1154 | } | 1210 | } |
| 1155 | 1211 | ||
| 1156 | /* frame rate */ | 1212 | /* frame rate */ |
| @@ -1158,16 +1214,16 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | |||
| 1158 | reg = 0; | 1214 | reg = 0; |
| 1159 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | 1215 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 1160 | reg |= p->rc_framerate_denom & 0xFFFF; | 1216 | reg |= p->rc_framerate_denom & 0xFFFF; |
| 1161 | WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6); | 1217 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
| 1162 | } | 1218 | } |
| 1163 | 1219 | ||
| 1164 | /* vbv buffer size */ | 1220 | /* vbv buffer size */ |
| 1165 | if (p->frame_skip_mode == | 1221 | if (p->frame_skip_mode == |
| 1166 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | 1222 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
| 1167 | WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6); | 1223 | WRITEL(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
| 1168 | 1224 | ||
| 1169 | if (p->rc_frame) | 1225 | if (p->rc_frame) |
| 1170 | WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); | 1226 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
| 1171 | } | 1227 | } |
| 1172 | 1228 | ||
| 1173 | mfc_debug_leave(); | 1229 | mfc_debug_leave(); |
| @@ -1178,6 +1234,7 @@ static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | |||
| 1178 | static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) | 1234 | static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) |
| 1179 | { | 1235 | { |
| 1180 | struct s5p_mfc_dev *dev = ctx->dev; | 1236 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1237 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1181 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 1238 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1182 | struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8; | 1239 | struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8; |
| 1183 | unsigned int reg = 0; | 1240 | unsigned int reg = 0; |
| @@ -1188,57 +1245,57 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) | |||
| 1188 | s5p_mfc_set_enc_params(ctx); | 1245 | s5p_mfc_set_enc_params(ctx); |
| 1189 | 1246 | ||
| 1190 | /* pictype : number of B */ | 1247 | /* pictype : number of B */ |
| 1191 | reg = READL(S5P_FIMV_E_GOP_CONFIG_V6); | 1248 | reg = READL(mfc_regs->e_gop_config); |
| 1192 | reg &= ~(0x3 << 16); | 1249 | reg &= ~(0x3 << 16); |
| 1193 | reg |= ((p->num_b_frame & 0x3) << 16); | 1250 | reg |= ((p->num_b_frame & 0x3) << 16); |
| 1194 | WRITEL(reg, S5P_FIMV_E_GOP_CONFIG_V6); | 1251 | WRITEL(reg, mfc_regs->e_gop_config); |
| 1195 | 1252 | ||
| 1196 | /* profile - 0 ~ 3 */ | 1253 | /* profile - 0 ~ 3 */ |
| 1197 | reg = p_vp8->profile & 0x3; | 1254 | reg = p_vp8->profile & 0x3; |
| 1198 | WRITEL(reg, S5P_FIMV_E_PICTURE_PROFILE_V6); | 1255 | WRITEL(reg, mfc_regs->e_picture_profile); |
| 1199 | 1256 | ||
| 1200 | /* rate control config. */ | 1257 | /* rate control config. */ |
| 1201 | reg = READL(S5P_FIMV_E_RC_CONFIG_V6); | 1258 | reg = READL(mfc_regs->e_rc_config); |
| 1202 | /** macroblock level rate control */ | 1259 | /** macroblock level rate control */ |
| 1203 | reg &= ~(0x1 << 8); | 1260 | reg &= ~(0x1 << 8); |
| 1204 | reg |= ((p->rc_mb & 0x1) << 8); | 1261 | reg |= ((p->rc_mb & 0x1) << 8); |
| 1205 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 1262 | WRITEL(reg, mfc_regs->e_rc_config); |
| 1206 | 1263 | ||
| 1207 | /* frame rate */ | 1264 | /* frame rate */ |
| 1208 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { | 1265 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { |
| 1209 | reg = 0; | 1266 | reg = 0; |
| 1210 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | 1267 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 1211 | reg |= p->rc_framerate_denom & 0xFFFF; | 1268 | reg |= p->rc_framerate_denom & 0xFFFF; |
| 1212 | WRITEL(reg, S5P_FIMV_E_RC_FRAME_RATE_V6); | 1269 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
| 1213 | } | 1270 | } |
| 1214 | 1271 | ||
| 1215 | /* frame QP */ | 1272 | /* frame QP */ |
| 1216 | reg &= ~(0x7F); | 1273 | reg &= ~(0x7F); |
| 1217 | reg |= p_vp8->rc_frame_qp & 0x7F; | 1274 | reg |= p_vp8->rc_frame_qp & 0x7F; |
| 1218 | WRITEL(reg, S5P_FIMV_E_RC_CONFIG_V6); | 1275 | WRITEL(reg, mfc_regs->e_rc_config); |
| 1219 | 1276 | ||
| 1220 | /* other QPs */ | 1277 | /* other QPs */ |
| 1221 | WRITEL(0x0, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 1278 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
| 1222 | if (!p->rc_frame && !p->rc_mb) { | 1279 | if (!p->rc_frame && !p->rc_mb) { |
| 1223 | reg = 0; | 1280 | reg = 0; |
| 1224 | reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8); | 1281 | reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8); |
| 1225 | reg |= p_vp8->rc_frame_qp & 0x7F; | 1282 | reg |= p_vp8->rc_frame_qp & 0x7F; |
| 1226 | WRITEL(reg, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | 1283 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
| 1227 | } | 1284 | } |
| 1228 | 1285 | ||
| 1229 | /* max QP */ | 1286 | /* max QP */ |
| 1230 | reg = ((p_vp8->rc_max_qp & 0x7F) << 8); | 1287 | reg = ((p_vp8->rc_max_qp & 0x7F) << 8); |
| 1231 | /* min QP */ | 1288 | /* min QP */ |
| 1232 | reg |= p_vp8->rc_min_qp & 0x7F; | 1289 | reg |= p_vp8->rc_min_qp & 0x7F; |
| 1233 | WRITEL(reg, S5P_FIMV_E_RC_QP_BOUND_V6); | 1290 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
| 1234 | 1291 | ||
| 1235 | /* vbv buffer size */ | 1292 | /* vbv buffer size */ |
| 1236 | if (p->frame_skip_mode == | 1293 | if (p->frame_skip_mode == |
| 1237 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | 1294 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
| 1238 | WRITEL(p->vbv_size & 0xFFFF, S5P_FIMV_E_VBV_BUFFER_SIZE_V6); | 1295 | WRITEL(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
| 1239 | 1296 | ||
| 1240 | if (p->rc_frame) | 1297 | if (p->rc_frame) |
| 1241 | WRITEL(p->vbv_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); | 1298 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
| 1242 | } | 1299 | } |
| 1243 | 1300 | ||
| 1244 | /* VP8 specific params */ | 1301 | /* VP8 specific params */ |
| @@ -1260,7 +1317,7 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) | |||
| 1260 | } | 1317 | } |
| 1261 | reg |= (val & 0xF) << 3; | 1318 | reg |= (val & 0xF) << 3; |
| 1262 | reg |= (p_vp8->num_ref & 0x2); | 1319 | reg |= (p_vp8->num_ref & 0x2); |
| 1263 | WRITEL(reg, S5P_FIMV_E_VP8_OPTIONS_V7); | 1320 | WRITEL(reg, mfc_regs->e_vp8_options); |
| 1264 | 1321 | ||
| 1265 | mfc_debug_leave(); | 1322 | mfc_debug_leave(); |
| 1266 | 1323 | ||
| @@ -1271,6 +1328,7 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) | |||
| 1271 | static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) | 1328 | static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) |
| 1272 | { | 1329 | { |
| 1273 | struct s5p_mfc_dev *dev = ctx->dev; | 1330 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1331 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1274 | unsigned int reg = 0; | 1332 | unsigned int reg = 0; |
| 1275 | int fmo_aso_ctrl = 0; | 1333 | int fmo_aso_ctrl = 0; |
| 1276 | 1334 | ||
| @@ -1278,9 +1336,9 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) | |||
| 1278 | mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, | 1336 | mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, |
| 1279 | S5P_FIMV_CH_SEQ_HEADER_V6); | 1337 | S5P_FIMV_CH_SEQ_HEADER_V6); |
| 1280 | mfc_debug(2, "BUFs: %08x %08x %08x\n", | 1338 | mfc_debug(2, "BUFs: %08x %08x %08x\n", |
| 1281 | READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6), | 1339 | READL(mfc_regs->d_cpb_buffer_addr), |
| 1282 | READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6), | 1340 | READL(mfc_regs->d_cpb_buffer_addr), |
| 1283 | READL(S5P_FIMV_D_CPB_BUFFER_ADDR_V6)); | 1341 | READL(mfc_regs->d_cpb_buffer_addr)); |
| 1284 | 1342 | ||
| 1285 | /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ | 1343 | /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ |
| 1286 | reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6); | 1344 | reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6); |
| @@ -1291,11 +1349,11 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) | |||
| 1291 | * set to negative value. */ | 1349 | * set to negative value. */ |
| 1292 | if (ctx->display_delay >= 0) { | 1350 | if (ctx->display_delay >= 0) { |
| 1293 | reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6); | 1351 | reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6); |
| 1294 | WRITEL(ctx->display_delay, S5P_FIMV_D_DISPLAY_DELAY_V6); | 1352 | WRITEL(ctx->display_delay, mfc_regs->d_display_delay); |
| 1295 | } | 1353 | } |
| 1296 | 1354 | ||
| 1297 | if (IS_MFCV7(dev)) { | 1355 | if (IS_MFCV7_PLUS(dev)) { |
| 1298 | WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS_V6); | 1356 | WRITEL(reg, mfc_regs->d_dec_options); |
| 1299 | reg = 0; | 1357 | reg = 0; |
| 1300 | } | 1358 | } |
| 1301 | 1359 | ||
| @@ -1309,22 +1367,22 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) | |||
| 1309 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) | 1367 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) |
| 1310 | reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6); | 1368 | reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6); |
| 1311 | 1369 | ||
| 1312 | if (IS_MFCV7(dev)) | 1370 | if (IS_MFCV7_PLUS(dev)) |
| 1313 | WRITEL(reg, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V7); | 1371 | WRITEL(reg, mfc_regs->d_init_buffer_options); |
| 1314 | else | 1372 | else |
| 1315 | WRITEL(reg, S5P_FIMV_D_DEC_OPTIONS_V6); | 1373 | WRITEL(reg, mfc_regs->d_dec_options); |
| 1316 | 1374 | ||
| 1317 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ | 1375 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
| 1318 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M) | 1376 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M) |
| 1319 | WRITEL(0x1, S5P_FIMV_PIXEL_FORMAT_V6); | 1377 | WRITEL(0x1, mfc_regs->pixel_format); |
| 1320 | else | 1378 | else |
| 1321 | WRITEL(0x0, S5P_FIMV_PIXEL_FORMAT_V6); | 1379 | WRITEL(0x0, mfc_regs->pixel_format); |
| 1322 | 1380 | ||
| 1323 | 1381 | ||
| 1324 | /* sei parse */ | 1382 | /* sei parse */ |
| 1325 | WRITEL(ctx->sei_fp_parse & 0x1, S5P_FIMV_D_SEI_ENABLE_V6); | 1383 | WRITEL(ctx->sei_fp_parse & 0x1, mfc_regs->d_sei_enable); |
| 1326 | 1384 | ||
| 1327 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 1385 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 1328 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | 1386 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
| 1329 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); | 1387 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); |
| 1330 | 1388 | ||
| @@ -1335,11 +1393,12 @@ static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) | |||
| 1335 | static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) | 1393 | static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) |
| 1336 | { | 1394 | { |
| 1337 | struct s5p_mfc_dev *dev = ctx->dev; | 1395 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1396 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1338 | 1397 | ||
| 1339 | if (flush) { | 1398 | if (flush) { |
| 1340 | dev->curr_ctx = ctx->num; | 1399 | dev->curr_ctx = ctx->num; |
| 1341 | s5p_mfc_clean_ctx_int_flags(ctx); | 1400 | s5p_mfc_clean_ctx_int_flags(ctx); |
| 1342 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 1401 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 1343 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | 1402 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
| 1344 | S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); | 1403 | S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); |
| 1345 | } | 1404 | } |
| @@ -1350,11 +1409,12 @@ static int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, | |||
| 1350 | enum s5p_mfc_decode_arg last_frame) | 1409 | enum s5p_mfc_decode_arg last_frame) |
| 1351 | { | 1410 | { |
| 1352 | struct s5p_mfc_dev *dev = ctx->dev; | 1411 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1412 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1353 | 1413 | ||
| 1354 | WRITEL(ctx->dec_dst_flag, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6); | 1414 | WRITEL(ctx->dec_dst_flag, mfc_regs->d_available_dpb_flag_lower); |
| 1355 | WRITEL(ctx->slice_interface & 0x1, S5P_FIMV_D_SLICE_IF_ENABLE_V6); | 1415 | WRITEL(ctx->slice_interface & 0x1, mfc_regs->d_slice_if_enable); |
| 1356 | 1416 | ||
| 1357 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 1417 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 1358 | /* Issue different commands to instance basing on whether it | 1418 | /* Issue different commands to instance basing on whether it |
| 1359 | * is the last frame or not. */ | 1419 | * is the last frame or not. */ |
| 1360 | switch (last_frame) { | 1420 | switch (last_frame) { |
| @@ -1378,6 +1438,7 @@ static int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, | |||
| 1378 | static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) | 1438 | static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) |
| 1379 | { | 1439 | { |
| 1380 | struct s5p_mfc_dev *dev = ctx->dev; | 1440 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1441 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1381 | 1442 | ||
| 1382 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) | 1443 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) |
| 1383 | s5p_mfc_set_enc_params_h264(ctx); | 1444 | s5p_mfc_set_enc_params_h264(ctx); |
| @@ -1393,13 +1454,13 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) | |||
| 1393 | return -EINVAL; | 1454 | return -EINVAL; |
| 1394 | } | 1455 | } |
| 1395 | 1456 | ||
| 1396 | /* Set stride lengths */ | 1457 | /* Set stride lengths for v7 & above */ |
| 1397 | if (IS_MFCV7(dev)) { | 1458 | if (IS_MFCV7_PLUS(dev)) { |
| 1398 | WRITEL(ctx->img_width, S5P_FIMV_E_SOURCE_FIRST_STRIDE_V7); | 1459 | WRITEL(ctx->img_width, mfc_regs->e_source_first_plane_stride); |
| 1399 | WRITEL(ctx->img_width, S5P_FIMV_E_SOURCE_SECOND_STRIDE_V7); | 1460 | WRITEL(ctx->img_width, mfc_regs->e_source_second_plane_stride); |
| 1400 | } | 1461 | } |
| 1401 | 1462 | ||
| 1402 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 1463 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 1403 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | 1464 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
| 1404 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); | 1465 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); |
| 1405 | 1466 | ||
| @@ -1409,14 +1470,16 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) | |||
| 1409 | static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) | 1470 | static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) |
| 1410 | { | 1471 | { |
| 1411 | struct s5p_mfc_dev *dev = ctx->dev; | 1472 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1473 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1412 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | 1474 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1413 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; | 1475 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; |
| 1414 | int i; | 1476 | int i; |
| 1415 | 1477 | ||
| 1416 | if (p_h264->aso) { | 1478 | if (p_h264->aso) { |
| 1417 | for (i = 0; i < 8; i++) | 1479 | for (i = 0; i < ARRAY_SIZE(p_h264->aso_slice_order); i++) { |
| 1418 | WRITEL(p_h264->aso_slice_order[i], | 1480 | WRITEL(p_h264->aso_slice_order[i], |
| 1419 | S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6 + i * 4); | 1481 | mfc_regs->e_h264_aso_slice_order_0 + i * 4); |
| 1482 | } | ||
| 1420 | } | 1483 | } |
| 1421 | return 0; | 1484 | return 0; |
| 1422 | } | 1485 | } |
| @@ -1425,6 +1488,7 @@ static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) | |||
| 1425 | static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) | 1488 | static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) |
| 1426 | { | 1489 | { |
| 1427 | struct s5p_mfc_dev *dev = ctx->dev; | 1490 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1491 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
| 1428 | 1492 | ||
| 1429 | mfc_debug(2, "++\n"); | 1493 | mfc_debug(2, "++\n"); |
| 1430 | 1494 | ||
| @@ -1435,7 +1499,7 @@ static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) | |||
| 1435 | 1499 | ||
| 1436 | s5p_mfc_set_slice_mode(ctx); | 1500 | s5p_mfc_set_slice_mode(ctx); |
| 1437 | 1501 | ||
| 1438 | WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6); | 1502 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
| 1439 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | 1503 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
| 1440 | S5P_FIMV_CH_FRAME_START_V6, NULL); | 1504 | S5P_FIMV_CH_FRAME_START_V6, NULL); |
| 1441 | 1505 | ||
| @@ -1810,28 +1874,26 @@ static void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq) | |||
| 1810 | 1874 | ||
| 1811 | static void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev) | 1875 | static void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev) |
| 1812 | { | 1876 | { |
| 1813 | mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD_V6); | 1877 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
| 1814 | mfc_write(dev, 0, S5P_FIMV_RISC2HOST_INT_V6); | 1878 | WRITEL(0, mfc_regs->risc2host_command); |
| 1879 | WRITEL(0, mfc_regs->risc2host_int); | ||
| 1815 | } | 1880 | } |
| 1816 | 1881 | ||
| 1817 | static void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, | 1882 | static void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, |
| 1818 | unsigned int ofs) | 1883 | unsigned int ofs) |
| 1819 | { | 1884 | { |
| 1820 | struct s5p_mfc_dev *dev = ctx->dev; | ||
| 1821 | |||
| 1822 | s5p_mfc_clock_on(); | 1885 | s5p_mfc_clock_on(); |
| 1823 | WRITEL(data, ofs); | 1886 | WRITEL(data, (void *)ofs); |
| 1824 | s5p_mfc_clock_off(); | 1887 | s5p_mfc_clock_off(); |
| 1825 | } | 1888 | } |
| 1826 | 1889 | ||
| 1827 | static unsigned int | 1890 | static unsigned int |
| 1828 | s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) | 1891 | s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) |
| 1829 | { | 1892 | { |
| 1830 | struct s5p_mfc_dev *dev = ctx->dev; | ||
| 1831 | int ret; | 1893 | int ret; |
| 1832 | 1894 | ||
| 1833 | s5p_mfc_clock_on(); | 1895 | s5p_mfc_clock_on(); |
| 1834 | ret = READL(ofs); | 1896 | ret = READL((void *)ofs); |
| 1835 | s5p_mfc_clock_off(); | 1897 | s5p_mfc_clock_off(); |
| 1836 | 1898 | ||
| 1837 | return ret; | 1899 | return ret; |
| @@ -1839,50 +1901,51 @@ s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) | |||
| 1839 | 1901 | ||
| 1840 | static int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) | 1902 | static int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) |
| 1841 | { | 1903 | { |
| 1842 | return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); | 1904 | return READL(dev->mfc_regs->d_display_first_plane_addr); |
| 1843 | } | 1905 | } |
| 1844 | 1906 | ||
| 1845 | static int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) | 1907 | static int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) |
| 1846 | { | 1908 | { |
| 1847 | return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); | 1909 | return READL(dev->mfc_regs->d_decoded_first_plane_addr); |
| 1848 | } | 1910 | } |
| 1849 | 1911 | ||
| 1850 | static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) | 1912 | static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) |
| 1851 | { | 1913 | { |
| 1852 | return mfc_read(dev, S5P_FIMV_D_DISPLAY_STATUS_V6); | 1914 | return READL(dev->mfc_regs->d_display_status); |
| 1853 | } | 1915 | } |
| 1854 | 1916 | ||
| 1855 | static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) | 1917 | static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) |
| 1856 | { | 1918 | { |
| 1857 | return mfc_read(dev, S5P_FIMV_D_DECODED_STATUS_V6); | 1919 | return READL(dev->mfc_regs->d_decoded_status); |
| 1858 | } | 1920 | } |
| 1859 | 1921 | ||
| 1860 | static int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev) | 1922 | static int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev) |
| 1861 | { | 1923 | { |
| 1862 | return mfc_read(dev, S5P_FIMV_D_DECODED_FRAME_TYPE_V6) & | 1924 | return READL(dev->mfc_regs->d_decoded_frame_type) & |
| 1863 | S5P_FIMV_DECODE_FRAME_MASK_V6; | 1925 | S5P_FIMV_DECODE_FRAME_MASK_V6; |
| 1864 | } | 1926 | } |
| 1865 | 1927 | ||
| 1866 | static int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx) | 1928 | static int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx) |
| 1867 | { | 1929 | { |
| 1868 | return mfc_read(ctx->dev, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6) & | 1930 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1931 | return READL(dev->mfc_regs->d_display_frame_type) & | ||
| 1869 | S5P_FIMV_DECODE_FRAME_MASK_V6; | 1932 | S5P_FIMV_DECODE_FRAME_MASK_V6; |
| 1870 | } | 1933 | } |
| 1871 | 1934 | ||
| 1872 | static int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev) | 1935 | static int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev) |
| 1873 | { | 1936 | { |
| 1874 | return mfc_read(dev, S5P_FIMV_D_DECODED_NAL_SIZE_V6); | 1937 | return READL(dev->mfc_regs->d_decoded_nal_size); |
| 1875 | } | 1938 | } |
| 1876 | 1939 | ||
| 1877 | static int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev) | 1940 | static int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev) |
| 1878 | { | 1941 | { |
| 1879 | return mfc_read(dev, S5P_FIMV_RISC2HOST_CMD_V6) & | 1942 | return READL(dev->mfc_regs->risc2host_command) & |
| 1880 | S5P_FIMV_RISC2HOST_CMD_MASK; | 1943 | S5P_FIMV_RISC2HOST_CMD_MASK; |
| 1881 | } | 1944 | } |
| 1882 | 1945 | ||
| 1883 | static int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev) | 1946 | static int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev) |
| 1884 | { | 1947 | { |
| 1885 | return mfc_read(dev, S5P_FIMV_ERROR_CODE_V6); | 1948 | return READL(dev->mfc_regs->error_code); |
| 1886 | } | 1949 | } |
| 1887 | 1950 | ||
| 1888 | static int s5p_mfc_err_dec_v6(unsigned int err) | 1951 | static int s5p_mfc_err_dec_v6(unsigned int err) |
| @@ -1897,82 +1960,323 @@ static int s5p_mfc_err_dspl_v6(unsigned int err) | |||
| 1897 | 1960 | ||
| 1898 | static int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev) | 1961 | static int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev) |
| 1899 | { | 1962 | { |
| 1900 | return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6); | 1963 | return READL(dev->mfc_regs->d_display_frame_width); |
| 1901 | } | 1964 | } |
| 1902 | 1965 | ||
| 1903 | static int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev) | 1966 | static int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev) |
| 1904 | { | 1967 | { |
| 1905 | return mfc_read(dev, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6); | 1968 | return READL(dev->mfc_regs->d_display_frame_height); |
| 1906 | } | 1969 | } |
| 1907 | 1970 | ||
| 1908 | static int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev) | 1971 | static int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev) |
| 1909 | { | 1972 | { |
| 1910 | return mfc_read(dev, S5P_FIMV_D_MIN_NUM_DPB_V6); | 1973 | return READL(dev->mfc_regs->d_min_num_dpb); |
| 1911 | } | 1974 | } |
| 1912 | 1975 | ||
| 1913 | static int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) | 1976 | static int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) |
| 1914 | { | 1977 | { |
| 1915 | return mfc_read(dev, S5P_FIMV_D_MIN_NUM_MV_V6); | 1978 | return READL(dev->mfc_regs->d_min_num_mv); |
| 1916 | } | 1979 | } |
| 1917 | 1980 | ||
| 1918 | static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) | 1981 | static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) |
| 1919 | { | 1982 | { |
| 1920 | return mfc_read(dev, S5P_FIMV_RET_INSTANCE_ID_V6); | 1983 | return READL(dev->mfc_regs->ret_instance_id); |
| 1921 | } | 1984 | } |
| 1922 | 1985 | ||
| 1923 | static int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev) | 1986 | static int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev) |
| 1924 | { | 1987 | { |
| 1925 | return mfc_read(dev, S5P_FIMV_E_NUM_DPB_V6); | 1988 | return READL(dev->mfc_regs->e_num_dpb); |
| 1926 | } | 1989 | } |
| 1927 | 1990 | ||
| 1928 | static int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev) | 1991 | static int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev) |
| 1929 | { | 1992 | { |
| 1930 | return mfc_read(dev, S5P_FIMV_E_STREAM_SIZE_V6); | 1993 | return READL(dev->mfc_regs->e_stream_size); |
| 1931 | } | 1994 | } |
| 1932 | 1995 | ||
| 1933 | static int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev) | 1996 | static int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev) |
| 1934 | { | 1997 | { |
| 1935 | return mfc_read(dev, S5P_FIMV_E_SLICE_TYPE_V6); | 1998 | return READL(dev->mfc_regs->e_slice_type); |
| 1936 | } | 1999 | } |
| 1937 | 2000 | ||
| 1938 | static int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev) | 2001 | static int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev) |
| 1939 | { | 2002 | { |
| 1940 | return mfc_read(dev, S5P_FIMV_E_PICTURE_COUNT_V6); | 2003 | return READL(dev->mfc_regs->e_picture_count); |
| 1941 | } | 2004 | } |
| 1942 | 2005 | ||
| 1943 | static int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx) | 2006 | static int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx) |
| 1944 | { | 2007 | { |
| 1945 | return mfc_read(ctx->dev, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6); | 2008 | struct s5p_mfc_dev *dev = ctx->dev; |
| 2009 | return READL(dev->mfc_regs->d_frame_pack_sei_avail); | ||
| 1946 | } | 2010 | } |
| 1947 | 2011 | ||
| 1948 | static int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev) | 2012 | static int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev) |
| 1949 | { | 2013 | { |
| 1950 | return mfc_read(dev, S5P_FIMV_D_MVC_NUM_VIEWS_V6); | 2014 | return READL(dev->mfc_regs->d_mvc_num_views); |
| 1951 | } | 2015 | } |
| 1952 | 2016 | ||
| 1953 | static int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev) | 2017 | static int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev) |
| 1954 | { | 2018 | { |
| 1955 | return mfc_read(dev, S5P_FIMV_D_MVC_VIEW_ID_V6); | 2019 | return READL(dev->mfc_regs->d_mvc_view_id); |
| 1956 | } | 2020 | } |
| 1957 | 2021 | ||
| 1958 | static unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx) | 2022 | static unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx) |
| 1959 | { | 2023 | { |
| 1960 | return s5p_mfc_read_info_v6(ctx, PIC_TIME_TOP_V6); | 2024 | return s5p_mfc_read_info_v6(ctx, |
| 2025 | (unsigned int) ctx->dev->mfc_regs->d_ret_picture_tag_top); | ||
| 1961 | } | 2026 | } |
| 1962 | 2027 | ||
| 1963 | static unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx) | 2028 | static unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx) |
| 1964 | { | 2029 | { |
| 1965 | return s5p_mfc_read_info_v6(ctx, PIC_TIME_BOT_V6); | 2030 | return s5p_mfc_read_info_v6(ctx, |
| 2031 | (unsigned int) ctx->dev->mfc_regs->d_ret_picture_tag_bot); | ||
| 1966 | } | 2032 | } |
| 1967 | 2033 | ||
| 1968 | static unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx) | 2034 | static unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx) |
| 1969 | { | 2035 | { |
| 1970 | return s5p_mfc_read_info_v6(ctx, CROP_INFO_H_V6); | 2036 | return s5p_mfc_read_info_v6(ctx, |
| 2037 | (unsigned int) ctx->dev->mfc_regs->d_display_crop_info1); | ||
| 1971 | } | 2038 | } |
| 1972 | 2039 | ||
| 1973 | static unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx) | 2040 | static unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx) |
| 1974 | { | 2041 | { |
| 1975 | return s5p_mfc_read_info_v6(ctx, CROP_INFO_V_V6); | 2042 | return s5p_mfc_read_info_v6(ctx, |
| 2043 | (unsigned int) ctx->dev->mfc_regs->d_display_crop_info2); | ||
| 2044 | } | ||
| 2045 | |||
| 2046 | static struct s5p_mfc_regs mfc_regs; | ||
| 2047 | |||
| 2048 | /* Initialize registers for MFC v6 onwards */ | ||
| 2049 | const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) | ||
| 2050 | { | ||
| 2051 | memset(&mfc_regs, 0, sizeof(mfc_regs)); | ||
| 2052 | |||
| 2053 | #define S5P_MFC_REG_ADDR(dev, reg) ((dev)->regs_base + (reg)) | ||
| 2054 | #define R(m, r) mfc_regs.m = S5P_MFC_REG_ADDR(dev, r) | ||
| 2055 | /* codec common registers */ | ||
| 2056 | R(risc_on, S5P_FIMV_RISC_ON_V6); | ||
| 2057 | R(risc2host_int, S5P_FIMV_RISC2HOST_INT_V6); | ||
| 2058 | R(host2risc_int, S5P_FIMV_HOST2RISC_INT_V6); | ||
| 2059 | R(risc_base_address, S5P_FIMV_RISC_BASE_ADDRESS_V6); | ||
| 2060 | R(mfc_reset, S5P_FIMV_MFC_RESET_V6); | ||
| 2061 | R(host2risc_command, S5P_FIMV_HOST2RISC_CMD_V6); | ||
| 2062 | R(risc2host_command, S5P_FIMV_RISC2HOST_CMD_V6); | ||
| 2063 | R(firmware_version, S5P_FIMV_FW_VERSION_V6); | ||
| 2064 | R(instance_id, S5P_FIMV_INSTANCE_ID_V6); | ||
| 2065 | R(codec_type, S5P_FIMV_CODEC_TYPE_V6); | ||
| 2066 | R(context_mem_addr, S5P_FIMV_CONTEXT_MEM_ADDR_V6); | ||
| 2067 | R(context_mem_size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); | ||
| 2068 | R(pixel_format, S5P_FIMV_PIXEL_FORMAT_V6); | ||
| 2069 | R(ret_instance_id, S5P_FIMV_RET_INSTANCE_ID_V6); | ||
| 2070 | R(error_code, S5P_FIMV_ERROR_CODE_V6); | ||
| 2071 | |||
| 2072 | /* decoder registers */ | ||
| 2073 | R(d_crc_ctrl, S5P_FIMV_D_CRC_CTRL_V6); | ||
| 2074 | R(d_dec_options, S5P_FIMV_D_DEC_OPTIONS_V6); | ||
| 2075 | R(d_display_delay, S5P_FIMV_D_DISPLAY_DELAY_V6); | ||
| 2076 | R(d_sei_enable, S5P_FIMV_D_SEI_ENABLE_V6); | ||
| 2077 | R(d_min_num_dpb, S5P_FIMV_D_MIN_NUM_DPB_V6); | ||
| 2078 | R(d_min_num_mv, S5P_FIMV_D_MIN_NUM_MV_V6); | ||
| 2079 | R(d_mvc_num_views, S5P_FIMV_D_MVC_NUM_VIEWS_V6); | ||
| 2080 | R(d_num_dpb, S5P_FIMV_D_NUM_DPB_V6); | ||
| 2081 | R(d_num_mv, S5P_FIMV_D_NUM_MV_V6); | ||
| 2082 | R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V6); | ||
| 2083 | R(d_first_plane_dpb_size, S5P_FIMV_D_LUMA_DPB_SIZE_V6); | ||
| 2084 | R(d_second_plane_dpb_size, S5P_FIMV_D_CHROMA_DPB_SIZE_V6); | ||
| 2085 | R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V6); | ||
| 2086 | R(d_first_plane_dpb, S5P_FIMV_D_LUMA_DPB_V6); | ||
| 2087 | R(d_second_plane_dpb, S5P_FIMV_D_CHROMA_DPB_V6); | ||
| 2088 | R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V6); | ||
| 2089 | R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6); | ||
| 2090 | R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6); | ||
| 2091 | R(d_cpb_buffer_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V6); | ||
| 2092 | R(d_cpb_buffer_size, S5P_FIMV_D_CPB_BUFFER_SIZE_V6); | ||
| 2093 | R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6); | ||
| 2094 | R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V6); | ||
| 2095 | R(d_slice_if_enable, S5P_FIMV_D_SLICE_IF_ENABLE_V6); | ||
| 2096 | R(d_stream_data_size, S5P_FIMV_D_STREAM_DATA_SIZE_V6); | ||
| 2097 | R(d_display_frame_width, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6); | ||
| 2098 | R(d_display_frame_height, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6); | ||
| 2099 | R(d_display_status, S5P_FIMV_D_DISPLAY_STATUS_V6); | ||
| 2100 | R(d_display_first_plane_addr, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); | ||
| 2101 | R(d_display_second_plane_addr, S5P_FIMV_D_DISPLAY_CHROMA_ADDR_V6); | ||
| 2102 | R(d_display_frame_type, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6); | ||
| 2103 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V6); | ||
| 2104 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V6); | ||
| 2105 | R(d_display_aspect_ratio, S5P_FIMV_D_DISPLAY_ASPECT_RATIO_V6); | ||
| 2106 | R(d_display_extended_ar, S5P_FIMV_D_DISPLAY_EXTENDED_AR_V6); | ||
| 2107 | R(d_decoded_status, S5P_FIMV_D_DECODED_STATUS_V6); | ||
| 2108 | R(d_decoded_first_plane_addr, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); | ||
| 2109 | R(d_decoded_second_plane_addr, S5P_FIMV_D_DECODED_CHROMA_ADDR_V6); | ||
| 2110 | R(d_decoded_frame_type, S5P_FIMV_D_DECODED_FRAME_TYPE_V6); | ||
| 2111 | R(d_decoded_nal_size, S5P_FIMV_D_DECODED_NAL_SIZE_V6); | ||
| 2112 | R(d_ret_picture_tag_top, S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6); | ||
| 2113 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6); | ||
| 2114 | R(d_h264_info, S5P_FIMV_D_H264_INFO_V6); | ||
| 2115 | R(d_mvc_view_id, S5P_FIMV_D_MVC_VIEW_ID_V6); | ||
| 2116 | R(d_frame_pack_sei_avail, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6); | ||
| 2117 | |||
| 2118 | /* encoder registers */ | ||
| 2119 | R(e_frame_width, S5P_FIMV_E_FRAME_WIDTH_V6); | ||
| 2120 | R(e_frame_height, S5P_FIMV_E_FRAME_HEIGHT_V6); | ||
| 2121 | R(e_cropped_frame_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6); | ||
| 2122 | R(e_cropped_frame_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6); | ||
| 2123 | R(e_frame_crop_offset, S5P_FIMV_E_FRAME_CROP_OFFSET_V6); | ||
| 2124 | R(e_enc_options, S5P_FIMV_E_ENC_OPTIONS_V6); | ||
| 2125 | R(e_picture_profile, S5P_FIMV_E_PICTURE_PROFILE_V6); | ||
| 2126 | R(e_vbv_buffer_size, S5P_FIMV_E_VBV_BUFFER_SIZE_V6); | ||
| 2127 | R(e_vbv_init_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); | ||
| 2128 | R(e_fixed_picture_qp, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | ||
| 2129 | R(e_rc_config, S5P_FIMV_E_RC_CONFIG_V6); | ||
| 2130 | R(e_rc_qp_bound, S5P_FIMV_E_RC_QP_BOUND_V6); | ||
| 2131 | R(e_rc_mode, S5P_FIMV_E_RC_RPARAM_V6); | ||
| 2132 | R(e_mb_rc_config, S5P_FIMV_E_MB_RC_CONFIG_V6); | ||
| 2133 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V6); | ||
| 2134 | R(e_mv_hor_range, S5P_FIMV_E_MV_HOR_RANGE_V6); | ||
| 2135 | R(e_mv_ver_range, S5P_FIMV_E_MV_VER_RANGE_V6); | ||
| 2136 | R(e_num_dpb, S5P_FIMV_E_NUM_DPB_V6); | ||
| 2137 | R(e_luma_dpb, S5P_FIMV_E_LUMA_DPB_V6); | ||
| 2138 | R(e_chroma_dpb, S5P_FIMV_E_CHROMA_DPB_V6); | ||
| 2139 | R(e_me_buffer, S5P_FIMV_E_ME_BUFFER_V6); | ||
| 2140 | R(e_scratch_buffer_addr, S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6); | ||
| 2141 | R(e_scratch_buffer_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6); | ||
| 2142 | R(e_tmv_buffer0, S5P_FIMV_E_TMV_BUFFER0_V6); | ||
| 2143 | R(e_tmv_buffer1, S5P_FIMV_E_TMV_BUFFER1_V6); | ||
| 2144 | R(e_source_first_plane_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); | ||
| 2145 | R(e_source_second_plane_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); | ||
| 2146 | R(e_stream_buffer_addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); | ||
| 2147 | R(e_stream_buffer_size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); | ||
| 2148 | R(e_roi_buffer_addr, S5P_FIMV_E_ROI_BUFFER_ADDR_V6); | ||
| 2149 | R(e_param_change, S5P_FIMV_E_PARAM_CHANGE_V6); | ||
| 2150 | R(e_ir_size, S5P_FIMV_E_IR_SIZE_V6); | ||
| 2151 | R(e_gop_config, S5P_FIMV_E_GOP_CONFIG_V6); | ||
| 2152 | R(e_mslice_mode, S5P_FIMV_E_MSLICE_MODE_V6); | ||
| 2153 | R(e_mslice_size_mb, S5P_FIMV_E_MSLICE_SIZE_MB_V6); | ||
| 2154 | R(e_mslice_size_bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6); | ||
| 2155 | R(e_frame_insertion, S5P_FIMV_E_FRAME_INSERTION_V6); | ||
| 2156 | R(e_rc_frame_rate, S5P_FIMV_E_RC_FRAME_RATE_V6); | ||
| 2157 | R(e_rc_bit_rate, S5P_FIMV_E_RC_BIT_RATE_V6); | ||
| 2158 | R(e_rc_roi_ctrl, S5P_FIMV_E_RC_ROI_CTRL_V6); | ||
| 2159 | R(e_picture_tag, S5P_FIMV_E_PICTURE_TAG_V6); | ||
| 2160 | R(e_bit_count_enable, S5P_FIMV_E_BIT_COUNT_ENABLE_V6); | ||
| 2161 | R(e_max_bit_count, S5P_FIMV_E_MAX_BIT_COUNT_V6); | ||
| 2162 | R(e_min_bit_count, S5P_FIMV_E_MIN_BIT_COUNT_V6); | ||
| 2163 | R(e_metadata_buffer_addr, S5P_FIMV_E_METADATA_BUFFER_ADDR_V6); | ||
| 2164 | R(e_metadata_buffer_size, S5P_FIMV_E_METADATA_BUFFER_SIZE_V6); | ||
| 2165 | R(e_encoded_source_first_plane_addr, | ||
| 2166 | S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6); | ||
| 2167 | R(e_encoded_source_second_plane_addr, | ||
| 2168 | S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6); | ||
| 2169 | R(e_stream_size, S5P_FIMV_E_STREAM_SIZE_V6); | ||
| 2170 | R(e_slice_type, S5P_FIMV_E_SLICE_TYPE_V6); | ||
| 2171 | R(e_picture_count, S5P_FIMV_E_PICTURE_COUNT_V6); | ||
| 2172 | R(e_ret_picture_tag, S5P_FIMV_E_RET_PICTURE_TAG_V6); | ||
| 2173 | R(e_recon_luma_dpb_addr, S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); | ||
| 2174 | R(e_recon_chroma_dpb_addr, S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); | ||
| 2175 | R(e_mpeg4_options, S5P_FIMV_E_MPEG4_OPTIONS_V6); | ||
| 2176 | R(e_mpeg4_hec_period, S5P_FIMV_E_MPEG4_HEC_PERIOD_V6); | ||
| 2177 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V6); | ||
| 2178 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V6); | ||
| 2179 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V6); | ||
| 2180 | R(e_h264_lf_alpha_offset, S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6); | ||
| 2181 | R(e_h264_lf_beta_offset, S5P_FIMV_E_H264_LF_BETA_OFFSET_V6); | ||
| 2182 | R(e_h264_i_period, S5P_FIMV_E_H264_I_PERIOD_V6); | ||
| 2183 | R(e_h264_fmo_slice_grp_map_type, | ||
| 2184 | S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6); | ||
| 2185 | R(e_h264_fmo_num_slice_grp_minus1, | ||
| 2186 | S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6); | ||
| 2187 | R(e_h264_fmo_slice_grp_change_dir, | ||
| 2188 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6); | ||
| 2189 | R(e_h264_fmo_slice_grp_change_rate_minus1, | ||
| 2190 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6); | ||
| 2191 | R(e_h264_fmo_run_length_minus1_0, | ||
| 2192 | S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6); | ||
| 2193 | R(e_h264_aso_slice_order_0, S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6); | ||
| 2194 | R(e_h264_num_t_layer, S5P_FIMV_E_H264_NUM_T_LAYER_V6); | ||
| 2195 | R(e_h264_hierarchical_qp_layer0, | ||
| 2196 | S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6); | ||
| 2197 | R(e_h264_frame_packing_sei_info, | ||
| 2198 | S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6); | ||
| 2199 | |||
| 2200 | if (!IS_MFCV7_PLUS(dev)) | ||
| 2201 | goto done; | ||
| 2202 | |||
| 2203 | /* Initialize registers used in MFC v7+ */ | ||
| 2204 | R(e_source_first_plane_addr, S5P_FIMV_E_SOURCE_FIRST_ADDR_V7); | ||
| 2205 | R(e_source_second_plane_addr, S5P_FIMV_E_SOURCE_SECOND_ADDR_V7); | ||
| 2206 | R(e_source_third_plane_addr, S5P_FIMV_E_SOURCE_THIRD_ADDR_V7); | ||
| 2207 | R(e_source_first_plane_stride, S5P_FIMV_E_SOURCE_FIRST_STRIDE_V7); | ||
| 2208 | R(e_source_second_plane_stride, S5P_FIMV_E_SOURCE_SECOND_STRIDE_V7); | ||
| 2209 | R(e_source_third_plane_stride, S5P_FIMV_E_SOURCE_THIRD_STRIDE_V7); | ||
| 2210 | R(e_encoded_source_first_plane_addr, | ||
| 2211 | S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7); | ||
| 2212 | R(e_encoded_source_second_plane_addr, | ||
| 2213 | S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7); | ||
| 2214 | R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7); | ||
| 2215 | |||
| 2216 | if (!IS_MFCV8(dev)) | ||
| 2217 | goto done; | ||
| 2218 | |||
| 2219 | /* Initialize registers used in MFC v8 only. | ||
| 2220 | * Also, over-write the registers which have | ||
| 2221 | * a different offset for MFC v8. */ | ||
| 2222 | R(d_stream_data_size, S5P_FIMV_D_STREAM_DATA_SIZE_V8); | ||
| 2223 | R(d_cpb_buffer_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V8); | ||
| 2224 | R(d_cpb_buffer_size, S5P_FIMV_D_CPB_BUFFER_SIZE_V8); | ||
| 2225 | R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8); | ||
| 2226 | R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8); | ||
| 2227 | R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8); | ||
| 2228 | R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8); | ||
| 2229 | R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8); | ||
| 2230 | R(d_first_plane_dpb_stride_size, | ||
| 2231 | S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8); | ||
| 2232 | R(d_second_plane_dpb_stride_size, | ||
| 2233 | S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8); | ||
| 2234 | R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8); | ||
| 2235 | R(d_num_mv, S5P_FIMV_D_NUM_MV_V8); | ||
| 2236 | R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8); | ||
| 2237 | R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8); | ||
| 2238 | R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8); | ||
| 2239 | R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8); | ||
| 2240 | R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8); | ||
| 2241 | R(d_slice_if_enable, S5P_FIMV_D_SLICE_IF_ENABLE_V8); | ||
| 2242 | R(d_display_first_plane_addr, S5P_FIMV_D_DISPLAY_FIRST_PLANE_ADDR_V8); | ||
| 2243 | R(d_display_second_plane_addr, S5P_FIMV_D_DISPLAY_SECOND_PLANE_ADDR_V8); | ||
| 2244 | R(d_decoded_first_plane_addr, S5P_FIMV_D_DECODED_FIRST_PLANE_ADDR_V8); | ||
| 2245 | R(d_decoded_second_plane_addr, S5P_FIMV_D_DECODED_SECOND_PLANE_ADDR_V8); | ||
| 2246 | R(d_display_status, S5P_FIMV_D_DISPLAY_STATUS_V8); | ||
| 2247 | R(d_decoded_status, S5P_FIMV_D_DECODED_STATUS_V8); | ||
| 2248 | R(d_decoded_frame_type, S5P_FIMV_D_DECODED_FRAME_TYPE_V8); | ||
| 2249 | R(d_display_frame_type, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V8); | ||
| 2250 | R(d_decoded_nal_size, S5P_FIMV_D_DECODED_NAL_SIZE_V8); | ||
| 2251 | R(d_display_frame_width, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V8); | ||
| 2252 | R(d_display_frame_height, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V8); | ||
| 2253 | R(d_frame_pack_sei_avail, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V8); | ||
| 2254 | R(d_mvc_num_views, S5P_FIMV_D_MVC_NUM_VIEWS_V8); | ||
| 2255 | R(d_mvc_view_id, S5P_FIMV_D_MVC_VIEW_ID_V8); | ||
| 2256 | R(d_ret_picture_tag_top, S5P_FIMV_D_RET_PICTURE_TAG_TOP_V8); | ||
| 2257 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V8); | ||
| 2258 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V8); | ||
| 2259 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V8); | ||
| 2260 | |||
| 2261 | /* encoder registers */ | ||
| 2262 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V8); | ||
| 2263 | R(e_rc_config, S5P_FIMV_E_RC_CONFIG_V8); | ||
| 2264 | R(e_rc_mode, S5P_FIMV_E_RC_RPARAM_V8); | ||
| 2265 | R(e_mv_hor_range, S5P_FIMV_E_MV_HOR_RANGE_V8); | ||
| 2266 | R(e_mv_ver_range, S5P_FIMV_E_MV_VER_RANGE_V8); | ||
| 2267 | R(e_rc_qp_bound, S5P_FIMV_E_RC_QP_BOUND_V8); | ||
| 2268 | R(e_fixed_picture_qp, S5P_FIMV_E_FIXED_PICTURE_QP_V8); | ||
| 2269 | R(e_vbv_buffer_size, S5P_FIMV_E_VBV_BUFFER_SIZE_V8); | ||
| 2270 | R(e_vbv_init_delay, S5P_FIMV_E_VBV_INIT_DELAY_V8); | ||
| 2271 | R(e_mb_rc_config, S5P_FIMV_E_MB_RC_CONFIG_V8); | ||
| 2272 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V8); | ||
| 2273 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V8); | ||
| 2274 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8); | ||
| 2275 | |||
| 2276 | done: | ||
| 2277 | return &mfc_regs; | ||
| 2278 | #undef S5P_MFC_REG_ADDR | ||
| 2279 | #undef R | ||
| 1976 | } | 2280 | } |
| 1977 | 2281 | ||
| 1978 | /* Initialize opr function pointers for MFC v6 */ | 2282 | /* Initialize opr function pointers for MFC v6 */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h index ab164efa127e..80558484bb40 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h | |||
| @@ -40,11 +40,6 @@ | |||
| 40 | #define FRAME_DELTA_H264_H263 1 | 40 | #define FRAME_DELTA_H264_H263 1 |
| 41 | #define TIGHT_CBR_MAX 10 | 41 | #define TIGHT_CBR_MAX 10 |
| 42 | 42 | ||
| 43 | /* Definitions for shared memory compatibility */ | ||
| 44 | #define PIC_TIME_TOP_V6 S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6 | ||
| 45 | #define PIC_TIME_BOT_V6 S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6 | ||
| 46 | #define CROP_INFO_H_V6 S5P_FIMV_D_DISPLAY_CROP_INFO1_V6 | ||
| 47 | #define CROP_INFO_V_V6 S5P_FIMV_D_DISPLAY_CROP_INFO2_V6 | ||
| 48 | |||
| 49 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void); | 43 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void); |
| 44 | const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev); | ||
| 50 | #endif /* S5P_MFC_OPR_V6_H_ */ | 45 | #endif /* S5P_MFC_OPR_V6_H_ */ |
diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c index 534722c04ec5..754740f4b671 100644 --- a/drivers/media/platform/s5p-tv/hdmi_drv.c +++ b/drivers/media/platform/s5p-tv/hdmi_drv.c | |||
| @@ -674,6 +674,8 @@ static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd, | |||
| 674 | static int hdmi_enum_dv_timings(struct v4l2_subdev *sd, | 674 | static int hdmi_enum_dv_timings(struct v4l2_subdev *sd, |
| 675 | struct v4l2_enum_dv_timings *timings) | 675 | struct v4l2_enum_dv_timings *timings) |
| 676 | { | 676 | { |
| 677 | if (timings->pad != 0) | ||
| 678 | return -EINVAL; | ||
| 677 | if (timings->index >= ARRAY_SIZE(hdmi_timings)) | 679 | if (timings->index >= ARRAY_SIZE(hdmi_timings)) |
| 678 | return -EINVAL; | 680 | return -EINVAL; |
| 679 | timings->timings = hdmi_timings[timings->index].dv_timings; | 681 | timings->timings = hdmi_timings[timings->index].dv_timings; |
| @@ -687,8 +689,11 @@ static int hdmi_dv_timings_cap(struct v4l2_subdev *sd, | |||
| 687 | { | 689 | { |
| 688 | struct hdmi_device *hdev = sd_to_hdmi_dev(sd); | 690 | struct hdmi_device *hdev = sd_to_hdmi_dev(sd); |
| 689 | 691 | ||
| 692 | if (cap->pad != 0) | ||
| 693 | return -EINVAL; | ||
| 694 | |||
| 690 | /* Let the phy fill in the pixelclock range */ | 695 | /* Let the phy fill in the pixelclock range */ |
| 691 | v4l2_subdev_call(hdev->phy_sd, video, dv_timings_cap, cap); | 696 | v4l2_subdev_call(hdev->phy_sd, pad, dv_timings_cap, cap); |
| 692 | cap->type = V4L2_DV_BT_656_1120; | 697 | cap->type = V4L2_DV_BT_656_1120; |
| 693 | cap->bt.min_width = 720; | 698 | cap->bt.min_width = 720; |
| 694 | cap->bt.max_width = 1920; | 699 | cap->bt.max_width = 1920; |
| @@ -707,12 +712,15 @@ static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = { | |||
| 707 | static const struct v4l2_subdev_video_ops hdmi_sd_video_ops = { | 712 | static const struct v4l2_subdev_video_ops hdmi_sd_video_ops = { |
| 708 | .s_dv_timings = hdmi_s_dv_timings, | 713 | .s_dv_timings = hdmi_s_dv_timings, |
| 709 | .g_dv_timings = hdmi_g_dv_timings, | 714 | .g_dv_timings = hdmi_g_dv_timings, |
| 710 | .enum_dv_timings = hdmi_enum_dv_timings, | ||
| 711 | .dv_timings_cap = hdmi_dv_timings_cap, | ||
| 712 | .g_mbus_fmt = hdmi_g_mbus_fmt, | 715 | .g_mbus_fmt = hdmi_g_mbus_fmt, |
| 713 | .s_stream = hdmi_s_stream, | 716 | .s_stream = hdmi_s_stream, |
| 714 | }; | 717 | }; |
| 715 | 718 | ||
| 719 | static const struct v4l2_subdev_pad_ops hdmi_sd_pad_ops = { | ||
| 720 | .enum_dv_timings = hdmi_enum_dv_timings, | ||
| 721 | .dv_timings_cap = hdmi_dv_timings_cap, | ||
| 722 | }; | ||
| 723 | |||
| 716 | static const struct v4l2_subdev_ops hdmi_sd_ops = { | 724 | static const struct v4l2_subdev_ops hdmi_sd_ops = { |
| 717 | .core = &hdmi_sd_core_ops, | 725 | .core = &hdmi_sd_core_ops, |
| 718 | .video = &hdmi_sd_video_ops, | 726 | .video = &hdmi_sd_video_ops, |
diff --git a/drivers/media/platform/s5p-tv/hdmiphy_drv.c b/drivers/media/platform/s5p-tv/hdmiphy_drv.c index e19a0af1ea4f..c2f2e35642f2 100644 --- a/drivers/media/platform/s5p-tv/hdmiphy_drv.c +++ b/drivers/media/platform/s5p-tv/hdmiphy_drv.c | |||
| @@ -225,6 +225,9 @@ static int hdmiphy_s_dv_timings(struct v4l2_subdev *sd, | |||
| 225 | static int hdmiphy_dv_timings_cap(struct v4l2_subdev *sd, | 225 | static int hdmiphy_dv_timings_cap(struct v4l2_subdev *sd, |
| 226 | struct v4l2_dv_timings_cap *cap) | 226 | struct v4l2_dv_timings_cap *cap) |
| 227 | { | 227 | { |
| 228 | if (cap->pad != 0) | ||
| 229 | return -EINVAL; | ||
| 230 | |||
| 228 | cap->type = V4L2_DV_BT_656_1120; | 231 | cap->type = V4L2_DV_BT_656_1120; |
| 229 | /* The phy only determines the pixelclock, leave the other values | 232 | /* The phy only determines the pixelclock, leave the other values |
| 230 | * at 0 to signify that we have no information for them. */ | 233 | * at 0 to signify that we have no information for them. */ |
| @@ -259,13 +262,17 @@ static const struct v4l2_subdev_core_ops hdmiphy_core_ops = { | |||
| 259 | 262 | ||
| 260 | static const struct v4l2_subdev_video_ops hdmiphy_video_ops = { | 263 | static const struct v4l2_subdev_video_ops hdmiphy_video_ops = { |
| 261 | .s_dv_timings = hdmiphy_s_dv_timings, | 264 | .s_dv_timings = hdmiphy_s_dv_timings, |
| 262 | .dv_timings_cap = hdmiphy_dv_timings_cap, | ||
| 263 | .s_stream = hdmiphy_s_stream, | 265 | .s_stream = hdmiphy_s_stream, |
| 264 | }; | 266 | }; |
| 265 | 267 | ||
| 268 | static const struct v4l2_subdev_pad_ops hdmiphy_pad_ops = { | ||
| 269 | .dv_timings_cap = hdmiphy_dv_timings_cap, | ||
| 270 | }; | ||
| 271 | |||
| 266 | static const struct v4l2_subdev_ops hdmiphy_ops = { | 272 | static const struct v4l2_subdev_ops hdmiphy_ops = { |
| 267 | .core = &hdmiphy_core_ops, | 273 | .core = &hdmiphy_core_ops, |
| 268 | .video = &hdmiphy_video_ops, | 274 | .video = &hdmiphy_video_ops, |
| 275 | .pad = &hdmiphy_pad_ops, | ||
| 269 | }; | 276 | }; |
| 270 | 277 | ||
| 271 | static int hdmiphy_probe(struct i2c_client *client, | 278 | static int hdmiphy_probe(struct i2c_client *client, |
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c index a1ce55fd30f3..8a8dbc8fdfde 100644 --- a/drivers/media/platform/s5p-tv/mixer_video.c +++ b/drivers/media/platform/s5p-tv/mixer_video.c | |||
| @@ -509,9 +509,11 @@ static int mxr_enum_dv_timings(struct file *file, void *fh, | |||
| 509 | struct mxr_device *mdev = layer->mdev; | 509 | struct mxr_device *mdev = layer->mdev; |
| 510 | int ret; | 510 | int ret; |
| 511 | 511 | ||
| 512 | timings->pad = 0; | ||
| 513 | |||
| 512 | /* lock protects from changing sd_out */ | 514 | /* lock protects from changing sd_out */ |
| 513 | mutex_lock(&mdev->mutex); | 515 | mutex_lock(&mdev->mutex); |
| 514 | ret = v4l2_subdev_call(to_outsd(mdev), video, enum_dv_timings, timings); | 516 | ret = v4l2_subdev_call(to_outsd(mdev), pad, enum_dv_timings, timings); |
| 515 | mutex_unlock(&mdev->mutex); | 517 | mutex_unlock(&mdev->mutex); |
| 516 | 518 | ||
| 517 | return ret ? -EINVAL : 0; | 519 | return ret ? -EINVAL : 0; |
| @@ -567,9 +569,11 @@ static int mxr_dv_timings_cap(struct file *file, void *fh, | |||
| 567 | struct mxr_device *mdev = layer->mdev; | 569 | struct mxr_device *mdev = layer->mdev; |
| 568 | int ret; | 570 | int ret; |
| 569 | 571 | ||
| 572 | cap->pad = 0; | ||
| 573 | |||
| 570 | /* lock protects from changing sd_out */ | 574 | /* lock protects from changing sd_out */ |
| 571 | mutex_lock(&mdev->mutex); | 575 | mutex_lock(&mdev->mutex); |
| 572 | ret = v4l2_subdev_call(to_outsd(mdev), video, dv_timings_cap, cap); | 576 | ret = v4l2_subdev_call(to_outsd(mdev), pad, dv_timings_cap, cap); |
| 573 | mutex_unlock(&mdev->mutex); | 577 | mutex_unlock(&mdev->mutex); |
| 574 | 578 | ||
| 575 | return ret ? -EINVAL : 0; | 579 | return ret ? -EINVAL : 0; |
| @@ -985,7 +989,7 @@ static void mxr_watchdog(unsigned long arg) | |||
| 985 | spin_unlock_irqrestore(&layer->enq_slock, flags); | 989 | spin_unlock_irqrestore(&layer->enq_slock, flags); |
| 986 | } | 990 | } |
| 987 | 991 | ||
| 988 | static int stop_streaming(struct vb2_queue *vq) | 992 | static void stop_streaming(struct vb2_queue *vq) |
| 989 | { | 993 | { |
| 990 | struct mxr_layer *layer = vb2_get_drv_priv(vq); | 994 | struct mxr_layer *layer = vb2_get_drv_priv(vq); |
| 991 | struct mxr_device *mdev = layer->mdev; | 995 | struct mxr_device *mdev = layer->mdev; |
| @@ -1031,7 +1035,6 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 1031 | mxr_streamer_put(mdev); | 1035 | mxr_streamer_put(mdev); |
| 1032 | /* allow changes in output configuration */ | 1036 | /* allow changes in output configuration */ |
| 1033 | mxr_output_put(mdev); | 1037 | mxr_output_put(mdev); |
| 1034 | return 0; | ||
| 1035 | } | 1038 | } |
| 1036 | 1039 | ||
| 1037 | static struct vb2_ops mxr_video_qops = { | 1040 | static struct vb2_ops mxr_video_qops = { |
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index f0b6c900034d..38c723aca438 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c | |||
| @@ -406,7 +406,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | /* abort streaming and wait for last buffer */ | 408 | /* abort streaming and wait for last buffer */ |
| 409 | static int stop_streaming(struct vb2_queue *vq) | 409 | static void stop_streaming(struct vb2_queue *vq) |
| 410 | { | 410 | { |
| 411 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); | 411 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); |
| 412 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 412 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| @@ -433,7 +433,7 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 433 | if (time_after(jiffies, timeout)) { | 433 | if (time_after(jiffies, timeout)) { |
| 434 | dev_err(icd->parent, | 434 | dev_err(icd->parent, |
| 435 | "Timeout waiting for finishing codec request\n"); | 435 | "Timeout waiting for finishing codec request\n"); |
| 436 | return -ETIMEDOUT; | 436 | return; |
| 437 | } | 437 | } |
| 438 | 438 | ||
| 439 | /* Disable interrupts */ | 439 | /* Disable interrupts */ |
| @@ -444,8 +444,6 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 444 | ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); | 444 | ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); |
| 445 | if (ret < 0) | 445 | if (ret < 0) |
| 446 | dev_err(icd->parent, "Disable ISI timed out\n"); | 446 | dev_err(icd->parent, "Disable ISI timed out\n"); |
| 447 | |||
| 448 | return ret; | ||
| 449 | } | 447 | } |
| 450 | 448 | ||
| 451 | static struct vb2_ops isi_video_qops = { | 449 | static struct vb2_ops isi_video_qops = { |
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index 3e844803bdca..b40bc2e5ba47 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c | |||
| @@ -741,7 +741,7 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 741 | return 0; | 741 | return 0; |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | static int mx2_stop_streaming(struct vb2_queue *q) | 744 | static void mx2_stop_streaming(struct vb2_queue *q) |
| 745 | { | 745 | { |
| 746 | struct soc_camera_device *icd = soc_camera_from_vb2q(q); | 746 | struct soc_camera_device *icd = soc_camera_from_vb2q(q); |
| 747 | struct soc_camera_host *ici = | 747 | struct soc_camera_host *ici = |
| @@ -773,8 +773,6 @@ static int mx2_stop_streaming(struct vb2_queue *q) | |||
| 773 | 773 | ||
| 774 | dma_free_coherent(ici->v4l2_dev.dev, | 774 | dma_free_coherent(ici->v4l2_dev.dev, |
| 775 | pcdev->discard_size, b, pcdev->discard_buffer_dma); | 775 | pcdev->discard_size, b, pcdev->discard_buffer_dma); |
| 776 | |||
| 777 | return 0; | ||
| 778 | } | 776 | } |
| 779 | 777 | ||
| 780 | static struct vb2_ops mx2_videobuf_ops = { | 778 | static struct vb2_ops mx2_videobuf_ops = { |
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index 9ed81ac6881c..83315dfeef62 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c | |||
| @@ -406,7 +406,7 @@ static int mx3_videobuf_init(struct vb2_buffer *vb) | |||
| 406 | return 0; | 406 | return 0; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | static int mx3_stop_streaming(struct vb2_queue *q) | 409 | static void mx3_stop_streaming(struct vb2_queue *q) |
| 410 | { | 410 | { |
| 411 | struct soc_camera_device *icd = soc_camera_from_vb2q(q); | 411 | struct soc_camera_device *icd = soc_camera_from_vb2q(q); |
| 412 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 412 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| @@ -430,8 +430,6 @@ static int mx3_stop_streaming(struct vb2_queue *q) | |||
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | spin_unlock_irqrestore(&mx3_cam->lock, flags); | 432 | spin_unlock_irqrestore(&mx3_cam->lock, flags); |
| 433 | |||
| 434 | return 0; | ||
| 435 | } | 433 | } |
| 436 | 434 | ||
| 437 | static struct vb2_ops mx3_videobuf_ops = { | 435 | static struct vb2_ops mx3_videobuf_ops = { |
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 704eee766487..e594230e84d3 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c | |||
| @@ -513,7 +513,7 @@ static int rcar_vin_videobuf_init(struct vb2_buffer *vb) | |||
| 513 | return 0; | 513 | return 0; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | static int rcar_vin_stop_streaming(struct vb2_queue *vq) | 516 | static void rcar_vin_stop_streaming(struct vb2_queue *vq) |
| 517 | { | 517 | { |
| 518 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); | 518 | struct soc_camera_device *icd = soc_camera_from_vb2q(vq); |
| 519 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 519 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| @@ -524,8 +524,6 @@ static int rcar_vin_stop_streaming(struct vb2_queue *vq) | |||
| 524 | list_for_each_safe(buf_head, tmp, &priv->capture) | 524 | list_for_each_safe(buf_head, tmp, &priv->capture) |
| 525 | list_del_init(buf_head); | 525 | list_del_init(buf_head); |
| 526 | spin_unlock_irq(&priv->lock); | 526 | spin_unlock_irq(&priv->lock); |
| 527 | |||
| 528 | return 0; | ||
| 529 | } | 527 | } |
| 530 | 528 | ||
| 531 | static struct vb2_ops rcar_vin_vb2_ops = { | 529 | static struct vb2_ops rcar_vin_vb2_ops = { |
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 3e75a469cd49..20ad4a571d37 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
| @@ -471,7 +471,7 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb) | |||
| 471 | return 0; | 471 | return 0; |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q) | 474 | static void sh_mobile_ceu_stop_streaming(struct vb2_queue *q) |
| 475 | { | 475 | { |
| 476 | struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq); | 476 | struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq); |
| 477 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 477 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| @@ -487,7 +487,7 @@ static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q) | |||
| 487 | 487 | ||
| 488 | spin_unlock_irq(&pcdev->lock); | 488 | spin_unlock_irq(&pcdev->lock); |
| 489 | 489 | ||
| 490 | return sh_mobile_ceu_soft_reset(pcdev); | 490 | sh_mobile_ceu_soft_reset(pcdev); |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | static struct vb2_ops sh_mobile_ceu_videobuf_ops = { | 493 | static struct vb2_ops sh_mobile_ceu_videobuf_ops = { |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 4b8c024fc487..7fec8cdaf095 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
| @@ -314,7 +314,7 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a) | |||
| 314 | struct soc_camera_device *icd = file->private_data; | 314 | struct soc_camera_device *icd = file->private_data; |
| 315 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 315 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 316 | 316 | ||
| 317 | return v4l2_subdev_call(sd, core, s_std, a); | 317 | return v4l2_subdev_call(sd, video, s_std, a); |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) | 320 | static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) |
| @@ -322,7 +322,7 @@ static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) | |||
| 322 | struct soc_camera_device *icd = file->private_data; | 322 | struct soc_camera_device *icd = file->private_data; |
| 323 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 323 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 324 | 324 | ||
| 325 | return v4l2_subdev_call(sd, core, g_std, a); | 325 | return v4l2_subdev_call(sd, video, g_std, a); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static int soc_camera_enum_framesizes(struct file *file, void *fh, | 328 | static int soc_camera_enum_framesizes(struct file *file, void *fh, |
| @@ -1277,6 +1277,8 @@ static int soc_camera_probe_finish(struct soc_camera_device *icd) | |||
| 1277 | sd->grp_id = soc_camera_grp_id(icd); | 1277 | sd->grp_id = soc_camera_grp_id(icd); |
| 1278 | v4l2_set_subdev_hostdata(sd, icd); | 1278 | v4l2_set_subdev_hostdata(sd, icd); |
| 1279 | 1279 | ||
| 1280 | v4l2_subdev_call(sd, video, g_tvnorms, &icd->vdev->tvnorms); | ||
| 1281 | |||
| 1280 | ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL); | 1282 | ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL); |
| 1281 | if (ret < 0) | 1283 | if (ret < 0) |
| 1282 | return ret; | 1284 | return ret; |
| @@ -1997,6 +1999,12 @@ static int soc_camera_video_start(struct soc_camera_device *icd) | |||
| 1997 | return -ENODEV; | 1999 | return -ENODEV; |
| 1998 | 2000 | ||
| 1999 | video_set_drvdata(icd->vdev, icd); | 2001 | video_set_drvdata(icd->vdev, icd); |
| 2002 | if (icd->vdev->tvnorms == 0) { | ||
| 2003 | /* disable the STD API if there are no tvnorms defined */ | ||
| 2004 | v4l2_disable_ioctl(icd->vdev, VIDIOC_G_STD); | ||
| 2005 | v4l2_disable_ioctl(icd->vdev, VIDIOC_S_STD); | ||
| 2006 | v4l2_disable_ioctl(icd->vdev, VIDIOC_ENUMSTD); | ||
| 2007 | } | ||
| 2000 | ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); | 2008 | ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); |
| 2001 | if (ret < 0) { | 2009 | if (ret < 0) { |
| 2002 | dev_err(icd->pdev, "video_register_device failed: %d\n", ret); | 2010 | dev_err(icd->pdev, "video_register_device failed: %d\n", ret); |
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c index acfea500710e..940df4000c42 100644 --- a/drivers/media/platform/ti-vpe/csc.c +++ b/drivers/media/platform/ti-vpe/csc.c | |||
| @@ -180,16 +180,16 @@ struct csc_data *csc_create(struct platform_device *pdev) | |||
| 180 | csc->pdev = pdev; | 180 | csc->pdev = pdev; |
| 181 | 181 | ||
| 182 | csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 182 | csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
| 183 | "vpe_csc"); | 183 | "csc"); |
| 184 | if (csc->res == NULL) { | 184 | if (csc->res == NULL) { |
| 185 | dev_err(&pdev->dev, "missing platform resources data\n"); | 185 | dev_err(&pdev->dev, "missing platform resources data\n"); |
| 186 | return ERR_PTR(-ENODEV); | 186 | return ERR_PTR(-ENODEV); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | csc->base = devm_ioremap_resource(&pdev->dev, csc->res); | 189 | csc->base = devm_ioremap_resource(&pdev->dev, csc->res); |
| 190 | if (!csc->base) { | 190 | if (IS_ERR(csc->base)) { |
| 191 | dev_err(&pdev->dev, "failed to ioremap\n"); | 191 | dev_err(&pdev->dev, "failed to ioremap\n"); |
| 192 | return ERR_PTR(-ENOMEM); | 192 | return csc->base; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | return csc; | 195 | return csc; |
diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c index 93f0af546b76..6314171ffe9b 100644 --- a/drivers/media/platform/ti-vpe/sc.c +++ b/drivers/media/platform/ti-vpe/sc.c | |||
| @@ -302,9 +302,9 @@ struct sc_data *sc_create(struct platform_device *pdev) | |||
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | sc->base = devm_ioremap_resource(&pdev->dev, sc->res); | 304 | sc->base = devm_ioremap_resource(&pdev->dev, sc->res); |
| 305 | if (!sc->base) { | 305 | if (IS_ERR(sc->base)) { |
| 306 | dev_err(&pdev->dev, "failed to ioremap\n"); | 306 | dev_err(&pdev->dev, "failed to ioremap\n"); |
| 307 | return ERR_PTR(-ENOMEM); | 307 | return sc->base; |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | return sc; | 310 | return sc; |
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index e8175e7938ed..a51a01359805 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c | |||
| @@ -614,8 +614,17 @@ static void dump_dtd(struct vpdma_dtd *dtd) | |||
| 614 | /* | 614 | /* |
| 615 | * append an outbound data transfer descriptor to the given descriptor list, | 615 | * append an outbound data transfer descriptor to the given descriptor list, |
| 616 | * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel | 616 | * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel |
| 617 | * | ||
| 618 | * @list: vpdma desc list to which we add this decriptor | ||
| 619 | * @width: width of the image in pixels in memory | ||
| 620 | * @c_rect: compose params of output image | ||
| 621 | * @fmt: vpdma data format of the buffer | ||
| 622 | * dma_addr: dma address as seen by VPDMA | ||
| 623 | * chan: VPDMA channel | ||
| 624 | * flags: VPDMA flags to configure some descriptor fileds | ||
| 617 | */ | 625 | */ |
| 618 | void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | 626 | void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, |
| 627 | const struct v4l2_rect *c_rect, | ||
| 619 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | 628 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, |
| 620 | enum vpdma_channel chan, u32 flags) | 629 | enum vpdma_channel chan, u32 flags) |
| 621 | { | 630 | { |
| @@ -623,6 +632,7 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | |||
| 623 | int field = 0; | 632 | int field = 0; |
| 624 | int notify = 1; | 633 | int notify = 1; |
| 625 | int channel, next_chan; | 634 | int channel, next_chan; |
| 635 | struct v4l2_rect rect = *c_rect; | ||
| 626 | int depth = fmt->depth; | 636 | int depth = fmt->depth; |
| 627 | int stride; | 637 | int stride; |
| 628 | struct vpdma_dtd *dtd; | 638 | struct vpdma_dtd *dtd; |
| @@ -630,11 +640,15 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | |||
| 630 | channel = next_chan = chan_info[chan].num; | 640 | channel = next_chan = chan_info[chan].num; |
| 631 | 641 | ||
| 632 | if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && | 642 | if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && |
| 633 | fmt->data_type == DATA_TYPE_C420) | 643 | fmt->data_type == DATA_TYPE_C420) { |
| 644 | rect.height >>= 1; | ||
| 645 | rect.top >>= 1; | ||
| 634 | depth = 8; | 646 | depth = 8; |
| 647 | } | ||
| 635 | 648 | ||
| 636 | stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN); | 649 | stride = ALIGN((depth * width) >> 3, VPDMA_STRIDE_ALIGN); |
| 637 | dma_addr += (c_rect->left * depth) >> 3; | 650 | |
| 651 | dma_addr += rect.top * stride + (rect.left * depth >> 3); | ||
| 638 | 652 | ||
| 639 | dtd = list->next; | 653 | dtd = list->next; |
| 640 | WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); | 654 | WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); |
| @@ -664,31 +678,48 @@ void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | |||
| 664 | /* | 678 | /* |
| 665 | * append an inbound data transfer descriptor to the given descriptor list, | 679 | * append an inbound data transfer descriptor to the given descriptor list, |
| 666 | * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel | 680 | * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel |
| 681 | * | ||
| 682 | * @list: vpdma desc list to which we add this decriptor | ||
| 683 | * @width: width of the image in pixels in memory(not the cropped width) | ||
| 684 | * @c_rect: crop params of input image | ||
| 685 | * @fmt: vpdma data format of the buffer | ||
| 686 | * dma_addr: dma address as seen by VPDMA | ||
| 687 | * chan: VPDMA channel | ||
| 688 | * field: top or bottom field info of the input image | ||
| 689 | * flags: VPDMA flags to configure some descriptor fileds | ||
| 690 | * frame_width/height: the complete width/height of the image presented to the | ||
| 691 | * client (this makes sense when multiple channels are | ||
| 692 | * connected to the same client, forming a larger frame) | ||
| 693 | * start_h, start_v: position where the given channel starts providing pixel | ||
| 694 | * data to the client (makes sense when multiple channels | ||
| 695 | * contribute to the client) | ||
| 667 | */ | 696 | */ |
| 668 | void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, | 697 | void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, |
| 669 | int frame_height, struct v4l2_rect *c_rect, | 698 | const struct v4l2_rect *c_rect, |
| 670 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | 699 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, |
| 671 | enum vpdma_channel chan, int field, u32 flags) | 700 | enum vpdma_channel chan, int field, u32 flags, int frame_width, |
| 701 | int frame_height, int start_h, int start_v) | ||
| 672 | { | 702 | { |
| 673 | int priority = 0; | 703 | int priority = 0; |
| 674 | int notify = 1; | 704 | int notify = 1; |
| 675 | int depth = fmt->depth; | 705 | int depth = fmt->depth; |
| 676 | int channel, next_chan; | 706 | int channel, next_chan; |
| 707 | struct v4l2_rect rect = *c_rect; | ||
| 677 | int stride; | 708 | int stride; |
| 678 | int height = c_rect->height; | ||
| 679 | struct vpdma_dtd *dtd; | 709 | struct vpdma_dtd *dtd; |
| 680 | 710 | ||
| 681 | channel = next_chan = chan_info[chan].num; | 711 | channel = next_chan = chan_info[chan].num; |
| 682 | 712 | ||
| 683 | if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && | 713 | if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV && |
| 684 | fmt->data_type == DATA_TYPE_C420) { | 714 | fmt->data_type == DATA_TYPE_C420) { |
| 685 | height >>= 1; | 715 | rect.height >>= 1; |
| 686 | frame_height >>= 1; | 716 | rect.top >>= 1; |
| 687 | depth = 8; | 717 | depth = 8; |
| 688 | } | 718 | } |
| 689 | 719 | ||
| 690 | stride = ALIGN((depth * c_rect->width) >> 3, VPDMA_STRIDE_ALIGN); | 720 | stride = ALIGN((depth * width) >> 3, VPDMA_STRIDE_ALIGN); |
| 691 | dma_addr += (c_rect->left * depth) >> 3; | 721 | |
| 722 | dma_addr += rect.top * stride + (rect.left * depth >> 3); | ||
| 692 | 723 | ||
| 693 | dtd = list->next; | 724 | dtd = list->next; |
| 694 | WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); | 725 | WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); |
| @@ -701,13 +732,14 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, | |||
| 701 | !!(flags & VPDMA_DATA_ODD_LINE_SKIP), | 732 | !!(flags & VPDMA_DATA_ODD_LINE_SKIP), |
| 702 | stride); | 733 | stride); |
| 703 | 734 | ||
| 704 | dtd->xfer_length_height = dtd_xfer_length_height(c_rect->width, height); | 735 | dtd->xfer_length_height = dtd_xfer_length_height(rect.width, |
| 736 | rect.height); | ||
| 705 | dtd->start_addr = (u32) dma_addr; | 737 | dtd->start_addr = (u32) dma_addr; |
| 706 | dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), | 738 | dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED), |
| 707 | DTD_DIR_IN, channel, priority, next_chan); | 739 | DTD_DIR_IN, channel, priority, next_chan); |
| 708 | dtd->frame_width_height = dtd_frame_width_height(frame_width, | 740 | dtd->frame_width_height = dtd_frame_width_height(frame_width, |
| 709 | frame_height); | 741 | frame_height); |
| 710 | dtd->start_h_v = dtd_start_h_v(c_rect->left, c_rect->top); | 742 | dtd->start_h_v = dtd_start_h_v(start_h, start_v); |
| 711 | dtd->client_attr0 = 0; | 743 | dtd->client_attr0 = 0; |
| 712 | dtd->client_attr1 = 0; | 744 | dtd->client_attr1 = 0; |
| 713 | 745 | ||
| @@ -781,7 +813,7 @@ static void vpdma_firmware_cb(const struct firmware *f, void *context) | |||
| 781 | /* already initialized */ | 813 | /* already initialized */ |
| 782 | if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK, | 814 | if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK, |
| 783 | VPDMA_LIST_RDY_SHFT)) { | 815 | VPDMA_LIST_RDY_SHFT)) { |
| 784 | vpdma->ready = true; | 816 | vpdma->cb(vpdma->pdev); |
| 785 | return; | 817 | return; |
| 786 | } | 818 | } |
| 787 | 819 | ||
| @@ -811,7 +843,7 @@ static void vpdma_firmware_cb(const struct firmware *f, void *context) | |||
| 811 | goto free_buf; | 843 | goto free_buf; |
| 812 | } | 844 | } |
| 813 | 845 | ||
| 814 | vpdma->ready = true; | 846 | vpdma->cb(vpdma->pdev); |
| 815 | 847 | ||
| 816 | free_buf: | 848 | free_buf: |
| 817 | vpdma_unmap_desc_buf(vpdma, &fw_dma_buf); | 849 | vpdma_unmap_desc_buf(vpdma, &fw_dma_buf); |
| @@ -839,7 +871,8 @@ static int vpdma_load_firmware(struct vpdma_data *vpdma) | |||
| 839 | return 0; | 871 | return 0; |
| 840 | } | 872 | } |
| 841 | 873 | ||
| 842 | struct vpdma_data *vpdma_create(struct platform_device *pdev) | 874 | struct vpdma_data *vpdma_create(struct platform_device *pdev, |
| 875 | void (*cb)(struct platform_device *pdev)) | ||
| 843 | { | 876 | { |
| 844 | struct resource *res; | 877 | struct resource *res; |
| 845 | struct vpdma_data *vpdma; | 878 | struct vpdma_data *vpdma; |
| @@ -854,6 +887,7 @@ struct vpdma_data *vpdma_create(struct platform_device *pdev) | |||
| 854 | } | 887 | } |
| 855 | 888 | ||
| 856 | vpdma->pdev = pdev; | 889 | vpdma->pdev = pdev; |
| 890 | vpdma->cb = cb; | ||
| 857 | 891 | ||
| 858 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma"); | 892 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma"); |
| 859 | if (res == NULL) { | 893 | if (res == NULL) { |
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h index cf40f11b3c8f..2bd8fb050381 100644 --- a/drivers/media/platform/ti-vpe/vpdma.h +++ b/drivers/media/platform/ti-vpe/vpdma.h | |||
| @@ -35,8 +35,8 @@ struct vpdma_data { | |||
| 35 | 35 | ||
| 36 | struct platform_device *pdev; | 36 | struct platform_device *pdev; |
| 37 | 37 | ||
| 38 | /* tells whether vpdma firmware is loaded or not */ | 38 | /* callback to VPE driver when the firmware is loaded */ |
| 39 | bool ready; | 39 | void (*cb)(struct platform_device *pdev); |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | enum vpdma_data_format_type { | 42 | enum vpdma_data_format_type { |
| @@ -186,13 +186,15 @@ void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client, | |||
| 186 | struct vpdma_buf *adb); | 186 | struct vpdma_buf *adb); |
| 187 | void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, | 187 | void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list, |
| 188 | enum vpdma_channel chan); | 188 | enum vpdma_channel chan); |
| 189 | void vpdma_add_out_dtd(struct vpdma_desc_list *list, struct v4l2_rect *c_rect, | 189 | void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, |
| 190 | const struct v4l2_rect *c_rect, | ||
| 190 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | 191 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, |
| 191 | enum vpdma_channel chan, u32 flags); | 192 | enum vpdma_channel chan, u32 flags); |
| 192 | void vpdma_add_in_dtd(struct vpdma_desc_list *list, int frame_width, | 193 | void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, |
| 193 | int frame_height, struct v4l2_rect *c_rect, | 194 | const struct v4l2_rect *c_rect, |
| 194 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, | 195 | const struct vpdma_data_format *fmt, dma_addr_t dma_addr, |
| 195 | enum vpdma_channel chan, int field, u32 flags); | 196 | enum vpdma_channel chan, int field, u32 flags, int frame_width, |
| 197 | int frame_height, int start_h, int start_v); | ||
| 196 | 198 | ||
| 197 | /* vpdma list interrupt management */ | 199 | /* vpdma list interrupt management */ |
| 198 | void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, | 200 | void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int list_num, |
| @@ -208,6 +210,7 @@ void vpdma_set_frame_start_event(struct vpdma_data *vpdma, | |||
| 208 | void vpdma_dump_regs(struct vpdma_data *vpdma); | 210 | void vpdma_dump_regs(struct vpdma_data *vpdma); |
| 209 | 211 | ||
| 210 | /* initialize vpdma, passed with VPE's platform device pointer */ | 212 | /* initialize vpdma, passed with VPE's platform device pointer */ |
| 211 | struct vpdma_data *vpdma_create(struct platform_device *pdev); | 213 | struct vpdma_data *vpdma_create(struct platform_device *pdev, |
| 214 | void (*cb)(struct platform_device *pdev)); | ||
| 212 | 215 | ||
| 213 | #endif | 216 | #endif |
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 5c421886d97c..972f43f69206 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c | |||
| @@ -410,8 +410,10 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx, | |||
| 410 | { | 410 | { |
| 411 | switch (type) { | 411 | switch (type) { |
| 412 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 412 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| 413 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | ||
| 413 | return &ctx->q_data[Q_DATA_SRC]; | 414 | return &ctx->q_data[Q_DATA_SRC]; |
| 414 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 415 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| 416 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
| 415 | return &ctx->q_data[Q_DATA_DST]; | 417 | return &ctx->q_data[Q_DATA_DST]; |
| 416 | default: | 418 | default: |
| 417 | BUG(); | 419 | BUG(); |
| @@ -986,7 +988,6 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port) | |||
| 986 | struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST]; | 988 | struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST]; |
| 987 | const struct vpe_port_data *p_data = &port_data[port]; | 989 | const struct vpe_port_data *p_data = &port_data[port]; |
| 988 | struct vb2_buffer *vb = ctx->dst_vb; | 990 | struct vb2_buffer *vb = ctx->dst_vb; |
| 989 | struct v4l2_rect *c_rect = &q_data->c_rect; | ||
| 990 | struct vpe_fmt *fmt = q_data->fmt; | 991 | struct vpe_fmt *fmt = q_data->fmt; |
| 991 | const struct vpdma_data_format *vpdma_fmt; | 992 | const struct vpdma_data_format *vpdma_fmt; |
| 992 | int mv_buf_selector = !ctx->src_mv_buf_selector; | 993 | int mv_buf_selector = !ctx->src_mv_buf_selector; |
| @@ -1015,8 +1016,8 @@ static void add_out_dtd(struct vpe_ctx *ctx, int port) | |||
| 1015 | if (q_data->flags & Q_DATA_MODE_TILED) | 1016 | if (q_data->flags & Q_DATA_MODE_TILED) |
| 1016 | flags |= VPDMA_DATA_MODE_TILED; | 1017 | flags |= VPDMA_DATA_MODE_TILED; |
| 1017 | 1018 | ||
| 1018 | vpdma_add_out_dtd(&ctx->desc_list, c_rect, vpdma_fmt, dma_addr, | 1019 | vpdma_add_out_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect, |
| 1019 | p_data->channel, flags); | 1020 | vpdma_fmt, dma_addr, p_data->channel, flags); |
| 1020 | } | 1021 | } |
| 1021 | 1022 | ||
| 1022 | static void add_in_dtd(struct vpe_ctx *ctx, int port) | 1023 | static void add_in_dtd(struct vpe_ctx *ctx, int port) |
| @@ -1024,11 +1025,11 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port) | |||
| 1024 | struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC]; | 1025 | struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC]; |
| 1025 | const struct vpe_port_data *p_data = &port_data[port]; | 1026 | const struct vpe_port_data *p_data = &port_data[port]; |
| 1026 | struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index]; | 1027 | struct vb2_buffer *vb = ctx->src_vbs[p_data->vb_index]; |
| 1027 | struct v4l2_rect *c_rect = &q_data->c_rect; | ||
| 1028 | struct vpe_fmt *fmt = q_data->fmt; | 1028 | struct vpe_fmt *fmt = q_data->fmt; |
| 1029 | const struct vpdma_data_format *vpdma_fmt; | 1029 | const struct vpdma_data_format *vpdma_fmt; |
| 1030 | int mv_buf_selector = ctx->src_mv_buf_selector; | 1030 | int mv_buf_selector = ctx->src_mv_buf_selector; |
| 1031 | int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM; | 1031 | int field = vb->v4l2_buf.field == V4L2_FIELD_BOTTOM; |
| 1032 | int frame_width, frame_height; | ||
| 1032 | dma_addr_t dma_addr; | 1033 | dma_addr_t dma_addr; |
| 1033 | u32 flags = 0; | 1034 | u32 flags = 0; |
| 1034 | 1035 | ||
| @@ -1055,8 +1056,15 @@ static void add_in_dtd(struct vpe_ctx *ctx, int port) | |||
| 1055 | if (q_data->flags & Q_DATA_MODE_TILED) | 1056 | if (q_data->flags & Q_DATA_MODE_TILED) |
| 1056 | flags |= VPDMA_DATA_MODE_TILED; | 1057 | flags |= VPDMA_DATA_MODE_TILED; |
| 1057 | 1058 | ||
| 1058 | vpdma_add_in_dtd(&ctx->desc_list, q_data->width, q_data->height, | 1059 | frame_width = q_data->c_rect.width; |
| 1059 | c_rect, vpdma_fmt, dma_addr, p_data->channel, field, flags); | 1060 | frame_height = q_data->c_rect.height; |
| 1061 | |||
| 1062 | if (p_data->vb_part && fmt->fourcc == V4L2_PIX_FMT_NV12) | ||
| 1063 | frame_height /= 2; | ||
| 1064 | |||
| 1065 | vpdma_add_in_dtd(&ctx->desc_list, q_data->width, &q_data->c_rect, | ||
| 1066 | vpdma_fmt, dma_addr, p_data->channel, field, flags, frame_width, | ||
| 1067 | frame_height, 0, 0); | ||
| 1060 | } | 1068 | } |
| 1061 | 1069 | ||
| 1062 | /* | 1070 | /* |
| @@ -1585,6 +1593,151 @@ static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
| 1585 | return set_srcdst_params(ctx); | 1593 | return set_srcdst_params(ctx); |
| 1586 | } | 1594 | } |
| 1587 | 1595 | ||
| 1596 | static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s) | ||
| 1597 | { | ||
| 1598 | struct vpe_q_data *q_data; | ||
| 1599 | |||
| 1600 | if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
| 1601 | (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)) | ||
| 1602 | return -EINVAL; | ||
| 1603 | |||
| 1604 | q_data = get_q_data(ctx, s->type); | ||
| 1605 | if (!q_data) | ||
| 1606 | return -EINVAL; | ||
| 1607 | |||
| 1608 | switch (s->target) { | ||
| 1609 | case V4L2_SEL_TGT_COMPOSE: | ||
| 1610 | /* | ||
| 1611 | * COMPOSE target is only valid for capture buffer type, return | ||
| 1612 | * error for output buffer type | ||
| 1613 | */ | ||
| 1614 | if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
| 1615 | return -EINVAL; | ||
| 1616 | break; | ||
| 1617 | case V4L2_SEL_TGT_CROP: | ||
| 1618 | /* | ||
| 1619 | * CROP target is only valid for output buffer type, return | ||
| 1620 | * error for capture buffer type | ||
| 1621 | */ | ||
| 1622 | if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1623 | return -EINVAL; | ||
| 1624 | break; | ||
| 1625 | /* | ||
| 1626 | * bound and default crop/compose targets are invalid targets to | ||
| 1627 | * try/set | ||
| 1628 | */ | ||
| 1629 | default: | ||
| 1630 | return -EINVAL; | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | if (s->r.top < 0 || s->r.left < 0) { | ||
| 1634 | vpe_err(ctx->dev, "negative values for top and left\n"); | ||
| 1635 | s->r.top = s->r.left = 0; | ||
| 1636 | } | ||
| 1637 | |||
| 1638 | v4l_bound_align_image(&s->r.width, MIN_W, q_data->width, 1, | ||
| 1639 | &s->r.height, MIN_H, q_data->height, H_ALIGN, S_ALIGN); | ||
| 1640 | |||
| 1641 | /* adjust left/top if cropping rectangle is out of bounds */ | ||
| 1642 | if (s->r.left + s->r.width > q_data->width) | ||
| 1643 | s->r.left = q_data->width - s->r.width; | ||
| 1644 | if (s->r.top + s->r.height > q_data->height) | ||
| 1645 | s->r.top = q_data->height - s->r.height; | ||
| 1646 | |||
| 1647 | return 0; | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | static int vpe_g_selection(struct file *file, void *fh, | ||
| 1651 | struct v4l2_selection *s) | ||
| 1652 | { | ||
| 1653 | struct vpe_ctx *ctx = file2ctx(file); | ||
| 1654 | struct vpe_q_data *q_data; | ||
| 1655 | bool use_c_rect = false; | ||
| 1656 | |||
| 1657 | if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
| 1658 | (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)) | ||
| 1659 | return -EINVAL; | ||
| 1660 | |||
| 1661 | q_data = get_q_data(ctx, s->type); | ||
| 1662 | if (!q_data) | ||
| 1663 | return -EINVAL; | ||
| 1664 | |||
| 1665 | switch (s->target) { | ||
| 1666 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
| 1667 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
| 1668 | if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
| 1669 | return -EINVAL; | ||
| 1670 | break; | ||
| 1671 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
| 1672 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
| 1673 | if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1674 | return -EINVAL; | ||
| 1675 | break; | ||
| 1676 | case V4L2_SEL_TGT_COMPOSE: | ||
| 1677 | if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
| 1678 | return -EINVAL; | ||
| 1679 | use_c_rect = true; | ||
| 1680 | break; | ||
| 1681 | case V4L2_SEL_TGT_CROP: | ||
| 1682 | if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 1683 | return -EINVAL; | ||
| 1684 | use_c_rect = true; | ||
| 1685 | break; | ||
| 1686 | default: | ||
| 1687 | return -EINVAL; | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | if (use_c_rect) { | ||
| 1691 | /* | ||
| 1692 | * for CROP/COMPOSE target type, return c_rect params from the | ||
| 1693 | * respective buffer type | ||
| 1694 | */ | ||
| 1695 | s->r = q_data->c_rect; | ||
| 1696 | } else { | ||
| 1697 | /* | ||
| 1698 | * for DEFAULT/BOUNDS target type, return width and height from | ||
| 1699 | * S_FMT of the respective buffer type | ||
| 1700 | */ | ||
| 1701 | s->r.left = 0; | ||
| 1702 | s->r.top = 0; | ||
| 1703 | s->r.width = q_data->width; | ||
| 1704 | s->r.height = q_data->height; | ||
| 1705 | } | ||
| 1706 | |||
| 1707 | return 0; | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | |||
| 1711 | static int vpe_s_selection(struct file *file, void *fh, | ||
| 1712 | struct v4l2_selection *s) | ||
| 1713 | { | ||
| 1714 | struct vpe_ctx *ctx = file2ctx(file); | ||
| 1715 | struct vpe_q_data *q_data; | ||
| 1716 | struct v4l2_selection sel = *s; | ||
| 1717 | int ret; | ||
| 1718 | |||
| 1719 | ret = __vpe_try_selection(ctx, &sel); | ||
| 1720 | if (ret) | ||
| 1721 | return ret; | ||
| 1722 | |||
| 1723 | q_data = get_q_data(ctx, sel.type); | ||
| 1724 | if (!q_data) | ||
| 1725 | return -EINVAL; | ||
| 1726 | |||
| 1727 | if ((q_data->c_rect.left == sel.r.left) && | ||
| 1728 | (q_data->c_rect.top == sel.r.top) && | ||
| 1729 | (q_data->c_rect.width == sel.r.width) && | ||
| 1730 | (q_data->c_rect.height == sel.r.height)) { | ||
| 1731 | vpe_dbg(ctx->dev, | ||
| 1732 | "requested crop/compose values are already set\n"); | ||
| 1733 | return 0; | ||
| 1734 | } | ||
| 1735 | |||
| 1736 | q_data->c_rect = sel.r; | ||
| 1737 | |||
| 1738 | return set_srcdst_params(ctx); | ||
| 1739 | } | ||
| 1740 | |||
| 1588 | static int vpe_reqbufs(struct file *file, void *priv, | 1741 | static int vpe_reqbufs(struct file *file, void *priv, |
| 1589 | struct v4l2_requestbuffers *reqbufs) | 1742 | struct v4l2_requestbuffers *reqbufs) |
| 1590 | { | 1743 | { |
| @@ -1672,6 +1825,9 @@ static const struct v4l2_ioctl_ops vpe_ioctl_ops = { | |||
| 1672 | .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt, | 1825 | .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt, |
| 1673 | .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt, | 1826 | .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt, |
| 1674 | 1827 | ||
| 1828 | .vidioc_g_selection = vpe_g_selection, | ||
| 1829 | .vidioc_s_selection = vpe_s_selection, | ||
| 1830 | |||
| 1675 | .vidioc_reqbufs = vpe_reqbufs, | 1831 | .vidioc_reqbufs = vpe_reqbufs, |
| 1676 | .vidioc_querybuf = vpe_querybuf, | 1832 | .vidioc_querybuf = vpe_querybuf, |
| 1677 | 1833 | ||
| @@ -1784,7 +1940,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, | |||
| 1784 | 1940 | ||
| 1785 | memset(src_vq, 0, sizeof(*src_vq)); | 1941 | memset(src_vq, 0, sizeof(*src_vq)); |
| 1786 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | 1942 | src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
| 1787 | src_vq->io_modes = VB2_MMAP; | 1943 | src_vq->io_modes = VB2_MMAP | VB2_DMABUF; |
| 1788 | src_vq->drv_priv = ctx; | 1944 | src_vq->drv_priv = ctx; |
| 1789 | src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | 1945 | src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); |
| 1790 | src_vq->ops = &vpe_qops; | 1946 | src_vq->ops = &vpe_qops; |
| @@ -1797,7 +1953,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, | |||
| 1797 | 1953 | ||
| 1798 | memset(dst_vq, 0, sizeof(*dst_vq)); | 1954 | memset(dst_vq, 0, sizeof(*dst_vq)); |
| 1799 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | 1955 | dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
| 1800 | dst_vq->io_modes = VB2_MMAP; | 1956 | dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; |
| 1801 | dst_vq->drv_priv = ctx; | 1957 | dst_vq->drv_priv = ctx; |
| 1802 | dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); | 1958 | dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); |
| 1803 | dst_vq->ops = &vpe_qops; | 1959 | dst_vq->ops = &vpe_qops; |
| @@ -1831,11 +1987,6 @@ static int vpe_open(struct file *file) | |||
| 1831 | 1987 | ||
| 1832 | vpe_dbg(dev, "vpe_open\n"); | 1988 | vpe_dbg(dev, "vpe_open\n"); |
| 1833 | 1989 | ||
| 1834 | if (!dev->vpdma->ready) { | ||
| 1835 | vpe_err(dev, "vpdma firmware not loaded\n"); | ||
| 1836 | return -ENODEV; | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 1990 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
| 1840 | if (!ctx) | 1991 | if (!ctx) |
| 1841 | return -ENOMEM; | 1992 | return -ENOMEM; |
| @@ -2055,10 +2206,40 @@ static void vpe_runtime_put(struct platform_device *pdev) | |||
| 2055 | WARN_ON(r < 0 && r != -ENOSYS); | 2206 | WARN_ON(r < 0 && r != -ENOSYS); |
| 2056 | } | 2207 | } |
| 2057 | 2208 | ||
| 2209 | static void vpe_fw_cb(struct platform_device *pdev) | ||
| 2210 | { | ||
| 2211 | struct vpe_dev *dev = platform_get_drvdata(pdev); | ||
| 2212 | struct video_device *vfd; | ||
| 2213 | int ret; | ||
| 2214 | |||
| 2215 | vfd = &dev->vfd; | ||
| 2216 | *vfd = vpe_videodev; | ||
| 2217 | vfd->lock = &dev->dev_mutex; | ||
| 2218 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
| 2219 | |||
| 2220 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
| 2221 | if (ret) { | ||
| 2222 | vpe_err(dev, "Failed to register video device\n"); | ||
| 2223 | |||
| 2224 | vpe_set_clock_enable(dev, 0); | ||
| 2225 | vpe_runtime_put(pdev); | ||
| 2226 | pm_runtime_disable(&pdev->dev); | ||
| 2227 | v4l2_m2m_release(dev->m2m_dev); | ||
| 2228 | vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); | ||
| 2229 | v4l2_device_unregister(&dev->v4l2_dev); | ||
| 2230 | |||
| 2231 | return; | ||
| 2232 | } | ||
| 2233 | |||
| 2234 | video_set_drvdata(vfd, dev); | ||
| 2235 | snprintf(vfd->name, sizeof(vfd->name), "%s", vpe_videodev.name); | ||
| 2236 | dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n", | ||
| 2237 | vfd->num); | ||
| 2238 | } | ||
| 2239 | |||
| 2058 | static int vpe_probe(struct platform_device *pdev) | 2240 | static int vpe_probe(struct platform_device *pdev) |
| 2059 | { | 2241 | { |
| 2060 | struct vpe_dev *dev; | 2242 | struct vpe_dev *dev; |
| 2061 | struct video_device *vfd; | ||
| 2062 | int ret, irq, func; | 2243 | int ret, irq, func; |
| 2063 | 2244 | ||
| 2064 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | 2245 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
| @@ -2139,28 +2320,12 @@ static int vpe_probe(struct platform_device *pdev) | |||
| 2139 | goto runtime_put; | 2320 | goto runtime_put; |
| 2140 | } | 2321 | } |
| 2141 | 2322 | ||
| 2142 | dev->vpdma = vpdma_create(pdev); | 2323 | dev->vpdma = vpdma_create(pdev, vpe_fw_cb); |
| 2143 | if (IS_ERR(dev->vpdma)) { | 2324 | if (IS_ERR(dev->vpdma)) { |
| 2144 | ret = PTR_ERR(dev->vpdma); | 2325 | ret = PTR_ERR(dev->vpdma); |
| 2145 | goto runtime_put; | 2326 | goto runtime_put; |
| 2146 | } | 2327 | } |
| 2147 | 2328 | ||
| 2148 | vfd = &dev->vfd; | ||
| 2149 | *vfd = vpe_videodev; | ||
| 2150 | vfd->lock = &dev->dev_mutex; | ||
| 2151 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
| 2152 | |||
| 2153 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
| 2154 | if (ret) { | ||
| 2155 | vpe_err(dev, "Failed to register video device\n"); | ||
| 2156 | goto runtime_put; | ||
| 2157 | } | ||
| 2158 | |||
| 2159 | video_set_drvdata(vfd, dev); | ||
| 2160 | snprintf(vfd->name, sizeof(vfd->name), "%s", vpe_videodev.name); | ||
| 2161 | dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n", | ||
| 2162 | vfd->num); | ||
| 2163 | |||
| 2164 | return 0; | 2329 | return 0; |
| 2165 | 2330 | ||
| 2166 | runtime_put: | 2331 | runtime_put: |
diff --git a/drivers/media/platform/timblogiw.c b/drivers/media/platform/timblogiw.c index ccdadd623a3a..3cb2f3564873 100644 --- a/drivers/media/platform/timblogiw.c +++ b/drivers/media/platform/timblogiw.c | |||
| @@ -347,7 +347,7 @@ static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id std) | |||
| 347 | mutex_lock(&lw->lock); | 347 | mutex_lock(&lw->lock); |
| 348 | 348 | ||
| 349 | if (TIMBLOGIW_HAS_DECODER(lw)) | 349 | if (TIMBLOGIW_HAS_DECODER(lw)) |
| 350 | err = v4l2_subdev_call(lw->sd_enc, core, s_std, std); | 350 | err = v4l2_subdev_call(lw->sd_enc, video, s_std, std); |
| 351 | 351 | ||
| 352 | if (!err) | 352 | if (!err) |
| 353 | fh->cur_norm = timblogiw_get_norm(std); | 353 | fh->cur_norm = timblogiw_get_norm(std); |
| @@ -800,7 +800,7 @@ static int timblogiw_probe(struct platform_device *pdev) | |||
| 800 | if (!pdata->encoder.module_name) | 800 | if (!pdata->encoder.module_name) |
| 801 | dev_info(&pdev->dev, "Running without decoder\n"); | 801 | dev_info(&pdev->dev, "Running without decoder\n"); |
| 802 | 802 | ||
| 803 | lw = kzalloc(sizeof(*lw), GFP_KERNEL); | 803 | lw = devm_kzalloc(&pdev->dev, sizeof(*lw), GFP_KERNEL); |
| 804 | if (!lw) { | 804 | if (!lw) { |
| 805 | err = -ENOMEM; | 805 | err = -ENOMEM; |
| 806 | goto err; | 806 | goto err; |
| @@ -820,7 +820,7 @@ static int timblogiw_probe(struct platform_device *pdev) | |||
| 820 | strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name)); | 820 | strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name)); |
| 821 | err = v4l2_device_register(NULL, &lw->v4l2_dev); | 821 | err = v4l2_device_register(NULL, &lw->v4l2_dev); |
| 822 | if (err) | 822 | if (err) |
| 823 | goto err_register; | 823 | goto err; |
| 824 | 824 | ||
| 825 | lw->video_dev.v4l2_dev = &lw->v4l2_dev; | 825 | lw->video_dev.v4l2_dev = &lw->v4l2_dev; |
| 826 | 826 | ||
| @@ -837,8 +837,6 @@ static int timblogiw_probe(struct platform_device *pdev) | |||
| 837 | 837 | ||
| 838 | err_request: | 838 | err_request: |
| 839 | v4l2_device_unregister(&lw->v4l2_dev); | 839 | v4l2_device_unregister(&lw->v4l2_dev); |
| 840 | err_register: | ||
| 841 | kfree(lw); | ||
| 842 | err: | 840 | err: |
| 843 | dev_err(&pdev->dev, "Failed to register: %d\n", err); | 841 | dev_err(&pdev->dev, "Failed to register: %d\n", err); |
| 844 | 842 | ||
| @@ -853,8 +851,6 @@ static int timblogiw_remove(struct platform_device *pdev) | |||
| 853 | 851 | ||
| 854 | v4l2_device_unregister(&lw->v4l2_dev); | 852 | v4l2_device_unregister(&lw->v4l2_dev); |
| 855 | 853 | ||
| 856 | kfree(lw); | ||
| 857 | |||
| 858 | return 0; | 854 | return 0; |
| 859 | } | 855 | } |
| 860 | 856 | ||
diff --git a/drivers/media/platform/vino.c b/drivers/media/platform/vino.c index c6af974c5b45..470d35336119 100644 --- a/drivers/media/platform/vino.c +++ b/drivers/media/platform/vino.c | |||
| @@ -2586,7 +2586,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) | |||
| 2586 | } | 2586 | } |
| 2587 | if (data_norm == 3) | 2587 | if (data_norm == 3) |
| 2588 | data_norm = VINO_DATA_NORM_PAL; | 2588 | data_norm = VINO_DATA_NORM_PAL; |
| 2589 | ret = decoder_call(core, s_std, norm); | 2589 | ret = decoder_call(video, s_std, norm); |
| 2590 | } | 2590 | } |
| 2591 | 2591 | ||
| 2592 | spin_lock_irqsave(&vino_drvdata->input_lock, flags); | 2592 | spin_lock_irqsave(&vino_drvdata->input_lock, flags); |
| @@ -2675,7 +2675,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) | |||
| 2675 | } | 2675 | } |
| 2676 | if (data_norm == 3) | 2676 | if (data_norm == 3) |
| 2677 | data_norm = VINO_DATA_NORM_PAL; | 2677 | data_norm = VINO_DATA_NORM_PAL; |
| 2678 | ret = decoder_call(core, s_std, norm); | 2678 | ret = decoder_call(video, s_std, norm); |
| 2679 | } | 2679 | } |
| 2680 | 2680 | ||
| 2681 | spin_lock_irqsave(&vino_drvdata->input_lock, flags); | 2681 | spin_lock_irqsave(&vino_drvdata->input_lock, flags); |
| @@ -2809,7 +2809,7 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs, | |||
| 2809 | * as it may take a while... */ | 2809 | * as it may take a while... */ |
| 2810 | 2810 | ||
| 2811 | norm = vino_data_norms[data_norm].std; | 2811 | norm = vino_data_norms[data_norm].std; |
| 2812 | err = decoder_call(core, s_std, norm); | 2812 | err = decoder_call(video, s_std, norm); |
| 2813 | 2813 | ||
| 2814 | spin_lock_irqsave(&vino_drvdata->input_lock, *flags); | 2814 | spin_lock_irqsave(&vino_drvdata->input_lock, *flags); |
| 2815 | 2815 | ||
diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c index 3890f4f42a78..d00bf3df0f8a 100644 --- a/drivers/media/platform/vivi.c +++ b/drivers/media/platform/vivi.c | |||
| @@ -906,12 +906,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 906 | } | 906 | } |
| 907 | 907 | ||
| 908 | /* abort streaming and wait for last buffer */ | 908 | /* abort streaming and wait for last buffer */ |
| 909 | static int stop_streaming(struct vb2_queue *vq) | 909 | static void stop_streaming(struct vb2_queue *vq) |
| 910 | { | 910 | { |
| 911 | struct vivi_dev *dev = vb2_get_drv_priv(vq); | 911 | struct vivi_dev *dev = vb2_get_drv_priv(vq); |
| 912 | dprintk(dev, 1, "%s\n", __func__); | 912 | dprintk(dev, 1, "%s\n", __func__); |
| 913 | vivi_stop_generating(dev); | 913 | vivi_stop_generating(dev); |
| 914 | return 0; | ||
| 915 | } | 914 | } |
| 916 | 915 | ||
| 917 | static void vivi_lock(struct vb2_queue *vq) | 916 | static void vivi_lock(struct vb2_queue *vq) |
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index b48f135ffc01..a0595c17700f 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c | |||
| @@ -720,7 +720,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 720 | return 0; | 720 | return 0; |
| 721 | } | 721 | } |
| 722 | 722 | ||
| 723 | static int vsp1_video_stop_streaming(struct vb2_queue *vq) | 723 | static void vsp1_video_stop_streaming(struct vb2_queue *vq) |
| 724 | { | 724 | { |
| 725 | struct vsp1_video *video = vb2_get_drv_priv(vq); | 725 | struct vsp1_video *video = vb2_get_drv_priv(vq); |
| 726 | struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity); | 726 | struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity); |
| @@ -743,8 +743,6 @@ static int vsp1_video_stop_streaming(struct vb2_queue *vq) | |||
| 743 | spin_lock_irqsave(&video->irqlock, flags); | 743 | spin_lock_irqsave(&video->irqlock, flags); |
| 744 | INIT_LIST_HEAD(&video->irqqueue); | 744 | INIT_LIST_HEAD(&video->irqqueue); |
| 745 | spin_unlock_irqrestore(&video->irqlock, flags); | 745 | spin_unlock_irqrestore(&video->irqlock, flags); |
| 746 | |||
| 747 | return 0; | ||
| 748 | } | 746 | } |
| 749 | 747 | ||
| 750 | static struct vb2_ops vsp1_video_queue_qops = { | 748 | static struct vb2_ops vsp1_video_queue_qops = { |
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 5d8f3d40d820..d5c1df3c9db1 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c | |||
| @@ -747,11 +747,19 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, | |||
| 747 | } | 747 | } |
| 748 | 748 | ||
| 749 | /* outbound data */ | 749 | /* outbound data */ |
| 750 | pipe = usb_sndintpipe(ir->usbdev, | 750 | if (usb_endpoint_xfer_int(ir->usb_ep_out)) { |
| 751 | ir->usb_ep_out->bEndpointAddress); | 751 | pipe = usb_sndintpipe(ir->usbdev, |
| 752 | usb_fill_int_urb(async_urb, ir->usbdev, pipe, | 752 | ir->usb_ep_out->bEndpointAddress); |
| 753 | async_buf, size, mce_async_callback, | 753 | usb_fill_int_urb(async_urb, ir->usbdev, pipe, async_buf, |
| 754 | ir, ir->usb_ep_out->bInterval); | 754 | size, mce_async_callback, ir, |
| 755 | ir->usb_ep_out->bInterval); | ||
| 756 | } else { | ||
| 757 | pipe = usb_sndbulkpipe(ir->usbdev, | ||
| 758 | ir->usb_ep_out->bEndpointAddress); | ||
| 759 | usb_fill_bulk_urb(async_urb, ir->usbdev, pipe, | ||
| 760 | async_buf, size, mce_async_callback, | ||
| 761 | ir); | ||
| 762 | } | ||
| 755 | memcpy(async_buf, data, size); | 763 | memcpy(async_buf, data, size); |
| 756 | 764 | ||
| 757 | } else if (urb_type == MCEUSB_RX) { | 765 | } else if (urb_type == MCEUSB_RX) { |
| @@ -1269,32 +1277,26 @@ static int mceusb_dev_probe(struct usb_interface *intf, | |||
| 1269 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { | 1277 | for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { |
| 1270 | ep = &idesc->endpoint[i].desc; | 1278 | ep = &idesc->endpoint[i].desc; |
| 1271 | 1279 | ||
| 1272 | if ((ep_in == NULL) | 1280 | if (ep_in == NULL) { |
| 1273 | && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 1281 | if (usb_endpoint_is_bulk_in(ep)) { |
| 1274 | == USB_DIR_IN) | 1282 | ep_in = ep; |
| 1275 | && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1283 | dev_dbg(&intf->dev, "acceptable bulk inbound endpoint found\n"); |
| 1276 | == USB_ENDPOINT_XFER_BULK) | 1284 | } else if (usb_endpoint_is_int_in(ep)) { |
| 1277 | || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1285 | ep_in = ep; |
| 1278 | == USB_ENDPOINT_XFER_INT))) { | 1286 | ep_in->bInterval = 1; |
| 1279 | 1287 | dev_dbg(&intf->dev, "acceptable interrupt inbound endpoint found\n"); | |
| 1280 | ep_in = ep; | 1288 | } |
| 1281 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; | ||
| 1282 | ep_in->bInterval = 1; | ||
| 1283 | dev_dbg(&intf->dev, "acceptable inbound endpoint found"); | ||
| 1284 | } | 1289 | } |
| 1285 | 1290 | ||
| 1286 | if ((ep_out == NULL) | 1291 | if (ep_out == NULL) { |
| 1287 | && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 1292 | if (usb_endpoint_is_bulk_out(ep)) { |
| 1288 | == USB_DIR_OUT) | 1293 | ep_out = ep; |
| 1289 | && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1294 | dev_dbg(&intf->dev, "acceptable bulk outbound endpoint found\n"); |
| 1290 | == USB_ENDPOINT_XFER_BULK) | 1295 | } else if (usb_endpoint_is_int_out(ep)) { |
| 1291 | || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1296 | ep_out = ep; |
| 1292 | == USB_ENDPOINT_XFER_INT))) { | 1297 | ep_out->bInterval = 1; |
| 1293 | 1298 | dev_dbg(&intf->dev, "acceptable interrupt outbound endpoint found\n"); | |
| 1294 | ep_out = ep; | 1299 | } |
| 1295 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; | ||
| 1296 | ep_out->bInterval = 1; | ||
| 1297 | dev_dbg(&intf->dev, "acceptable outbound endpoint found"); | ||
| 1298 | } | 1300 | } |
| 1299 | } | 1301 | } |
| 1300 | if (ep_in == NULL) { | 1302 | if (ep_in == NULL) { |
| @@ -1302,7 +1304,10 @@ static int mceusb_dev_probe(struct usb_interface *intf, | |||
| 1302 | return -ENODEV; | 1304 | return -ENODEV; |
| 1303 | } | 1305 | } |
| 1304 | 1306 | ||
| 1305 | pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); | 1307 | if (usb_endpoint_xfer_int(ep_in)) |
| 1308 | pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); | ||
| 1309 | else | ||
| 1310 | pipe = usb_rcvbulkpipe(dev, ep_in->bEndpointAddress); | ||
| 1306 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 1311 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
| 1307 | 1312 | ||
| 1308 | ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); | 1313 | ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); |
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig index a1284889cd15..22b6b8bb1d93 100644 --- a/drivers/media/tuners/Kconfig +++ b/drivers/media/tuners/Kconfig | |||
| @@ -230,6 +230,13 @@ config MEDIA_TUNER_TUA9001 | |||
| 230 | help | 230 | help |
| 231 | Infineon TUA 9001 silicon tuner driver. | 231 | Infineon TUA 9001 silicon tuner driver. |
| 232 | 232 | ||
| 233 | config MEDIA_TUNER_SI2157 | ||
| 234 | tristate "Silicon Labs Si2157 silicon tuner" | ||
| 235 | depends on MEDIA_SUPPORT && I2C | ||
| 236 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
| 237 | help | ||
| 238 | Silicon Labs Si2157 silicon tuner driver. | ||
| 239 | |||
| 233 | config MEDIA_TUNER_IT913X | 240 | config MEDIA_TUNER_IT913X |
| 234 | tristate "ITE Tech IT913x silicon tuner" | 241 | tristate "ITE Tech IT913x silicon tuner" |
| 235 | depends on MEDIA_SUPPORT && I2C | 242 | depends on MEDIA_SUPPORT && I2C |
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile index efe82a904b12..a6ff0c628dfa 100644 --- a/drivers/media/tuners/Makefile +++ b/drivers/media/tuners/Makefile | |||
| @@ -31,6 +31,7 @@ obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o | |||
| 31 | obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o | 31 | obj-$(CONFIG_MEDIA_TUNER_E4000) += e4000.o |
| 32 | obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o | 32 | obj-$(CONFIG_MEDIA_TUNER_FC2580) += fc2580.o |
| 33 | obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o | 33 | obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o |
| 34 | obj-$(CONFIG_MEDIA_TUNER_SI2157) += si2157.o | ||
| 34 | obj-$(CONFIG_MEDIA_TUNER_M88TS2022) += m88ts2022.o | 35 | obj-$(CONFIG_MEDIA_TUNER_M88TS2022) += m88ts2022.o |
| 35 | obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o | 36 | obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o |
| 36 | obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o | 37 | obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o |
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c new file mode 100644 index 000000000000..271a752cee54 --- /dev/null +++ b/drivers/media/tuners/si2157.c | |||
| @@ -0,0 +1,260 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs Si2157 silicon tuner driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "si2157_priv.h" | ||
| 18 | |||
| 19 | /* execute firmware command */ | ||
| 20 | static int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd) | ||
| 21 | { | ||
| 22 | int ret; | ||
| 23 | u8 buf[1]; | ||
| 24 | unsigned long timeout; | ||
| 25 | |||
| 26 | mutex_lock(&s->i2c_mutex); | ||
| 27 | |||
| 28 | if (cmd->len) { | ||
| 29 | /* write cmd and args for firmware */ | ||
| 30 | ret = i2c_master_send(s->client, cmd->args, cmd->len); | ||
| 31 | if (ret < 0) { | ||
| 32 | goto err_mutex_unlock; | ||
| 33 | } else if (ret != cmd->len) { | ||
| 34 | ret = -EREMOTEIO; | ||
| 35 | goto err_mutex_unlock; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | /* wait cmd execution terminate */ | ||
| 40 | #define TIMEOUT 80 | ||
| 41 | timeout = jiffies + msecs_to_jiffies(TIMEOUT); | ||
| 42 | while (!time_after(jiffies, timeout)) { | ||
| 43 | ret = i2c_master_recv(s->client, buf, 1); | ||
| 44 | if (ret < 0) { | ||
| 45 | goto err_mutex_unlock; | ||
| 46 | } else if (ret != 1) { | ||
| 47 | ret = -EREMOTEIO; | ||
| 48 | goto err_mutex_unlock; | ||
| 49 | } | ||
| 50 | |||
| 51 | /* firmware ready? */ | ||
| 52 | if ((buf[0] >> 7) & 0x01) | ||
| 53 | break; | ||
| 54 | } | ||
| 55 | |||
| 56 | dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", __func__, | ||
| 57 | jiffies_to_msecs(jiffies) - | ||
| 58 | (jiffies_to_msecs(timeout) - TIMEOUT)); | ||
| 59 | |||
| 60 | if (!(buf[0] >> 7) & 0x01) { | ||
| 61 | ret = -ETIMEDOUT; | ||
| 62 | goto err_mutex_unlock; | ||
| 63 | } else { | ||
| 64 | ret = 0; | ||
| 65 | } | ||
| 66 | |||
| 67 | err_mutex_unlock: | ||
| 68 | mutex_unlock(&s->i2c_mutex); | ||
| 69 | if (ret) | ||
| 70 | goto err; | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | err: | ||
| 74 | dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 75 | return ret; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int si2157_init(struct dvb_frontend *fe) | ||
| 79 | { | ||
| 80 | struct si2157 *s = fe->tuner_priv; | ||
| 81 | |||
| 82 | dev_dbg(&s->client->dev, "%s:\n", __func__); | ||
| 83 | |||
| 84 | s->active = true; | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int si2157_sleep(struct dvb_frontend *fe) | ||
| 90 | { | ||
| 91 | struct si2157 *s = fe->tuner_priv; | ||
| 92 | |||
| 93 | dev_dbg(&s->client->dev, "%s:\n", __func__); | ||
| 94 | |||
| 95 | s->active = false; | ||
| 96 | |||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int si2157_set_params(struct dvb_frontend *fe) | ||
| 101 | { | ||
| 102 | struct si2157 *s = fe->tuner_priv; | ||
| 103 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
| 104 | int ret; | ||
| 105 | struct si2157_cmd cmd; | ||
| 106 | |||
| 107 | dev_dbg(&s->client->dev, | ||
| 108 | "%s: delivery_system=%d frequency=%u bandwidth_hz=%u\n", | ||
| 109 | __func__, c->delivery_system, c->frequency, | ||
| 110 | c->bandwidth_hz); | ||
| 111 | |||
| 112 | if (!s->active) { | ||
| 113 | ret = -EAGAIN; | ||
| 114 | goto err; | ||
| 115 | } | ||
| 116 | |||
| 117 | /* configure? */ | ||
| 118 | cmd.args[0] = 0xc0; | ||
| 119 | cmd.args[1] = 0x00; | ||
| 120 | cmd.args[2] = 0x0c; | ||
| 121 | cmd.args[3] = 0x00; | ||
| 122 | cmd.args[4] = 0x00; | ||
| 123 | cmd.args[5] = 0x01; | ||
| 124 | cmd.args[6] = 0x01; | ||
| 125 | cmd.args[7] = 0x01; | ||
| 126 | cmd.args[8] = 0x01; | ||
| 127 | cmd.args[9] = 0x01; | ||
| 128 | cmd.args[10] = 0x01; | ||
| 129 | cmd.args[11] = 0x02; | ||
| 130 | cmd.args[12] = 0x00; | ||
| 131 | cmd.args[13] = 0x00; | ||
| 132 | cmd.args[14] = 0x01; | ||
| 133 | cmd.len = 15; | ||
| 134 | ret = si2157_cmd_execute(s, &cmd); | ||
| 135 | if (ret) | ||
| 136 | goto err; | ||
| 137 | |||
| 138 | cmd.args[0] = 0x02; | ||
| 139 | cmd.len = 1; | ||
| 140 | ret = si2157_cmd_execute(s, &cmd); | ||
| 141 | if (ret) | ||
| 142 | goto err; | ||
| 143 | |||
| 144 | cmd.args[0] = 0x01; | ||
| 145 | cmd.args[1] = 0x01; | ||
| 146 | cmd.len = 2; | ||
| 147 | ret = si2157_cmd_execute(s, &cmd); | ||
| 148 | if (ret) | ||
| 149 | goto err; | ||
| 150 | |||
| 151 | /* set frequency */ | ||
| 152 | cmd.args[0] = 0x41; | ||
| 153 | cmd.args[1] = 0x00; | ||
| 154 | cmd.args[2] = 0x00; | ||
| 155 | cmd.args[3] = 0x00; | ||
| 156 | cmd.args[4] = (c->frequency >> 0) & 0xff; | ||
| 157 | cmd.args[5] = (c->frequency >> 8) & 0xff; | ||
| 158 | cmd.args[6] = (c->frequency >> 16) & 0xff; | ||
| 159 | cmd.args[7] = (c->frequency >> 24) & 0xff; | ||
| 160 | cmd.len = 8; | ||
| 161 | ret = si2157_cmd_execute(s, &cmd); | ||
| 162 | if (ret) | ||
| 163 | goto err; | ||
| 164 | |||
| 165 | return 0; | ||
| 166 | err: | ||
| 167 | dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | static const struct dvb_tuner_ops si2157_tuner_ops = { | ||
| 172 | .info = { | ||
| 173 | .name = "Silicon Labs Si2157", | ||
| 174 | .frequency_min = 110000000, | ||
| 175 | .frequency_max = 862000000, | ||
| 176 | }, | ||
| 177 | |||
| 178 | .init = si2157_init, | ||
| 179 | .sleep = si2157_sleep, | ||
| 180 | .set_params = si2157_set_params, | ||
| 181 | }; | ||
| 182 | |||
| 183 | static int si2157_probe(struct i2c_client *client, | ||
| 184 | const struct i2c_device_id *id) | ||
| 185 | { | ||
| 186 | struct si2157_config *cfg = client->dev.platform_data; | ||
| 187 | struct dvb_frontend *fe = cfg->fe; | ||
| 188 | struct si2157 *s; | ||
| 189 | struct si2157_cmd cmd; | ||
| 190 | int ret; | ||
| 191 | |||
| 192 | s = kzalloc(sizeof(struct si2157), GFP_KERNEL); | ||
| 193 | if (!s) { | ||
| 194 | ret = -ENOMEM; | ||
| 195 | dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); | ||
| 196 | goto err; | ||
| 197 | } | ||
| 198 | |||
| 199 | s->client = client; | ||
| 200 | s->fe = cfg->fe; | ||
| 201 | mutex_init(&s->i2c_mutex); | ||
| 202 | |||
| 203 | /* check if the tuner is there */ | ||
| 204 | cmd.len = 0; | ||
| 205 | ret = si2157_cmd_execute(s, &cmd); | ||
| 206 | if (ret) | ||
| 207 | goto err; | ||
| 208 | |||
| 209 | fe->tuner_priv = s; | ||
| 210 | memcpy(&fe->ops.tuner_ops, &si2157_tuner_ops, | ||
| 211 | sizeof(struct dvb_tuner_ops)); | ||
| 212 | |||
| 213 | i2c_set_clientdata(client, s); | ||
| 214 | |||
| 215 | dev_info(&s->client->dev, | ||
| 216 | "%s: Silicon Labs Si2157 successfully attached\n", | ||
| 217 | KBUILD_MODNAME); | ||
| 218 | return 0; | ||
| 219 | err: | ||
| 220 | dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); | ||
| 221 | kfree(s); | ||
| 222 | |||
| 223 | return ret; | ||
| 224 | } | ||
| 225 | |||
| 226 | static int si2157_remove(struct i2c_client *client) | ||
| 227 | { | ||
| 228 | struct si2157 *s = i2c_get_clientdata(client); | ||
| 229 | struct dvb_frontend *fe = s->fe; | ||
| 230 | |||
| 231 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
| 232 | |||
| 233 | memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); | ||
| 234 | fe->tuner_priv = NULL; | ||
| 235 | kfree(s); | ||
| 236 | |||
| 237 | return 0; | ||
| 238 | } | ||
| 239 | |||
| 240 | static const struct i2c_device_id si2157_id[] = { | ||
| 241 | {"si2157", 0}, | ||
| 242 | {} | ||
| 243 | }; | ||
| 244 | MODULE_DEVICE_TABLE(i2c, si2157_id); | ||
| 245 | |||
| 246 | static struct i2c_driver si2157_driver = { | ||
| 247 | .driver = { | ||
| 248 | .owner = THIS_MODULE, | ||
| 249 | .name = "si2157", | ||
| 250 | }, | ||
| 251 | .probe = si2157_probe, | ||
| 252 | .remove = si2157_remove, | ||
| 253 | .id_table = si2157_id, | ||
| 254 | }; | ||
| 255 | |||
| 256 | module_i2c_driver(si2157_driver); | ||
| 257 | |||
| 258 | MODULE_DESCRIPTION("Silicon Labs Si2157 silicon tuner driver"); | ||
| 259 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
| 260 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h new file mode 100644 index 000000000000..f469a092b66b --- /dev/null +++ b/drivers/media/tuners/si2157.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs Si2157 silicon tuner driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef SI2157_H | ||
| 18 | #define SI2157_H | ||
| 19 | |||
| 20 | #include <linux/kconfig.h> | ||
| 21 | #include "dvb_frontend.h" | ||
| 22 | |||
| 23 | /* | ||
| 24 | * I2C address | ||
| 25 | * 0x60 | ||
| 26 | */ | ||
| 27 | struct si2157_config { | ||
| 28 | /* | ||
| 29 | * frontend | ||
| 30 | */ | ||
| 31 | struct dvb_frontend *fe; | ||
| 32 | }; | ||
| 33 | |||
| 34 | #endif | ||
diff --git a/drivers/media/tuners/si2157_priv.h b/drivers/media/tuners/si2157_priv.h new file mode 100644 index 000000000000..6cc6c6fdab7a --- /dev/null +++ b/drivers/media/tuners/si2157_priv.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | /* | ||
| 2 | * Silicon Labs Si2157 silicon tuner driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef SI2157_PRIV_H | ||
| 18 | #define SI2157_PRIV_H | ||
| 19 | |||
| 20 | #include "si2157.h" | ||
| 21 | |||
| 22 | /* state struct */ | ||
| 23 | struct si2157 { | ||
| 24 | struct mutex i2c_mutex; | ||
| 25 | struct i2c_client *client; | ||
| 26 | struct dvb_frontend *fe; | ||
| 27 | bool active; | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* firmare command struct */ | ||
| 31 | #define SI2157_ARGLEN 30 | ||
| 32 | struct si2157_cmd { | ||
| 33 | u8 args[SI2157_ARGLEN]; | ||
| 34 | unsigned len; | ||
| 35 | }; | ||
| 36 | |||
| 37 | #endif | ||
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 5cd09a681b6a..2b3d514be672 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
| 26 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
| 27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 28 | #include <linux/workqueue.h> | ||
| 28 | #include <linux/dvb/frontend.h> | 29 | #include <linux/dvb/frontend.h> |
| 29 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
| 30 | 31 | ||
| @@ -65,26 +66,25 @@ struct xc5000_priv { | |||
| 65 | u16 pll_register_no; | 66 | u16 pll_register_no; |
| 66 | u8 init_status_supported; | 67 | u8 init_status_supported; |
| 67 | u8 fw_checksum_supported; | 68 | u8 fw_checksum_supported; |
| 69 | |||
| 70 | struct dvb_frontend *fe; | ||
| 71 | struct delayed_work timer_sleep; | ||
| 68 | }; | 72 | }; |
| 69 | 73 | ||
| 70 | /* Misc Defines */ | 74 | /* Misc Defines */ |
| 71 | #define MAX_TV_STANDARD 24 | 75 | #define MAX_TV_STANDARD 24 |
| 72 | #define XC_MAX_I2C_WRITE_LENGTH 64 | 76 | #define XC_MAX_I2C_WRITE_LENGTH 64 |
| 73 | 77 | ||
| 78 | /* Time to suspend after the .sleep callback is called */ | ||
| 79 | #define XC5000_SLEEP_TIME 5000 /* ms */ | ||
| 80 | |||
| 74 | /* Signal Types */ | 81 | /* Signal Types */ |
| 75 | #define XC_RF_MODE_AIR 0 | 82 | #define XC_RF_MODE_AIR 0 |
| 76 | #define XC_RF_MODE_CABLE 1 | 83 | #define XC_RF_MODE_CABLE 1 |
| 77 | 84 | ||
| 78 | /* Result codes */ | ||
| 79 | #define XC_RESULT_SUCCESS 0 | ||
| 80 | #define XC_RESULT_RESET_FAILURE 1 | ||
| 81 | #define XC_RESULT_I2C_WRITE_FAILURE 2 | ||
| 82 | #define XC_RESULT_I2C_READ_FAILURE 3 | ||
| 83 | #define XC_RESULT_OUT_OF_RANGE 5 | ||
| 84 | |||
| 85 | /* Product id */ | 85 | /* Product id */ |
| 86 | #define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000 | 86 | #define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000 |
| 87 | #define XC_PRODUCT_ID_FW_LOADED 0x1388 | 87 | #define XC_PRODUCT_ID_FW_LOADED 0x1388 |
| 88 | 88 | ||
| 89 | /* Registers */ | 89 | /* Registers */ |
| 90 | #define XREG_INIT 0x00 | 90 | #define XREG_INIT 0x00 |
| @@ -152,16 +152,16 @@ struct xc5000_priv { | |||
| 152 | 152 | ||
| 153 | */ | 153 | */ |
| 154 | struct XC_TV_STANDARD { | 154 | struct XC_TV_STANDARD { |
| 155 | char *Name; | 155 | char *name; |
| 156 | u16 AudioMode; | 156 | u16 audio_mode; |
| 157 | u16 VideoMode; | 157 | u16 video_mode; |
| 158 | }; | 158 | }; |
| 159 | 159 | ||
| 160 | /* Tuner standards */ | 160 | /* Tuner standards */ |
| 161 | #define MN_NTSC_PAL_BTSC 0 | 161 | #define MN_NTSC_PAL_BTSC 0 |
| 162 | #define MN_NTSC_PAL_A2 1 | 162 | #define MN_NTSC_PAL_A2 1 |
| 163 | #define MN_NTSC_PAL_EIAJ 2 | 163 | #define MN_NTSC_PAL_EIAJ 2 |
| 164 | #define MN_NTSC_PAL_Mono 3 | 164 | #define MN_NTSC_PAL_MONO 3 |
| 165 | #define BG_PAL_A2 4 | 165 | #define BG_PAL_A2 4 |
| 166 | #define BG_PAL_NICAM 5 | 166 | #define BG_PAL_NICAM 5 |
| 167 | #define BG_PAL_MONO 6 | 167 | #define BG_PAL_MONO 6 |
| @@ -171,19 +171,19 @@ struct XC_TV_STANDARD { | |||
| 171 | #define DK_PAL_NICAM 10 | 171 | #define DK_PAL_NICAM 10 |
| 172 | #define DK_PAL_MONO 11 | 172 | #define DK_PAL_MONO 11 |
| 173 | #define DK_SECAM_A2DK1 12 | 173 | #define DK_SECAM_A2DK1 12 |
| 174 | #define DK_SECAM_A2LDK3 13 | 174 | #define DK_SECAM_A2LDK3 13 |
| 175 | #define DK_SECAM_A2MONO 14 | 175 | #define DK_SECAM_A2MONO 14 |
| 176 | #define L_SECAM_NICAM 15 | 176 | #define L_SECAM_NICAM 15 |
| 177 | #define LC_SECAM_NICAM 16 | 177 | #define LC_SECAM_NICAM 16 |
| 178 | #define DTV6 17 | 178 | #define DTV6 17 |
| 179 | #define DTV8 18 | 179 | #define DTV8 18 |
| 180 | #define DTV7_8 19 | 180 | #define DTV7_8 19 |
| 181 | #define DTV7 20 | 181 | #define DTV7 20 |
| 182 | #define FM_Radio_INPUT2 21 | 182 | #define FM_RADIO_INPUT2 21 |
| 183 | #define FM_Radio_INPUT1 22 | 183 | #define FM_RADIO_INPUT1 22 |
| 184 | #define FM_Radio_INPUT1_MONO 23 | 184 | #define FM_RADIO_INPUT1_MONO 23 |
| 185 | 185 | ||
| 186 | static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | 186 | static struct XC_TV_STANDARD xc5000_standard[MAX_TV_STANDARD] = { |
| 187 | {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, | 187 | {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, |
| 188 | {"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, | 188 | {"M/N-NTSC/PAL-A2", 0x0600, 0x8020}, |
| 189 | {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, | 189 | {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020}, |
| @@ -249,7 +249,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) | |||
| 249 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force); | 249 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force); |
| 250 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); | 250 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); |
| 251 | static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); | 251 | static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); |
| 252 | static int xc5000_TunerReset(struct dvb_frontend *fe); | 252 | static int xc5000_tuner_reset(struct dvb_frontend *fe); |
| 253 | 253 | ||
| 254 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 254 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
| 255 | { | 255 | { |
| @@ -258,9 +258,9 @@ static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | |||
| 258 | 258 | ||
| 259 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | 259 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { |
| 260 | printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len); | 260 | printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len); |
| 261 | return XC_RESULT_I2C_WRITE_FAILURE; | 261 | return -EREMOTEIO; |
| 262 | } | 262 | } |
| 263 | return XC_RESULT_SUCCESS; | 263 | return 0; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | #if 0 | 266 | #if 0 |
| @@ -297,15 +297,10 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) | |||
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | *val = (bval[0] << 8) | bval[1]; | 299 | *val = (bval[0] << 8) | bval[1]; |
| 300 | return XC_RESULT_SUCCESS; | 300 | return 0; |
| 301 | } | ||
| 302 | |||
| 303 | static void xc_wait(int wait_ms) | ||
| 304 | { | ||
| 305 | msleep(wait_ms); | ||
| 306 | } | 301 | } |
| 307 | 302 | ||
| 308 | static int xc5000_TunerReset(struct dvb_frontend *fe) | 303 | static int xc5000_tuner_reset(struct dvb_frontend *fe) |
| 309 | { | 304 | { |
| 310 | struct xc5000_priv *priv = fe->tuner_priv; | 305 | struct xc5000_priv *priv = fe->tuner_priv; |
| 311 | int ret; | 306 | int ret; |
| @@ -320,43 +315,43 @@ static int xc5000_TunerReset(struct dvb_frontend *fe) | |||
| 320 | XC5000_TUNER_RESET, 0); | 315 | XC5000_TUNER_RESET, 0); |
| 321 | if (ret) { | 316 | if (ret) { |
| 322 | printk(KERN_ERR "xc5000: reset failed\n"); | 317 | printk(KERN_ERR "xc5000: reset failed\n"); |
| 323 | return XC_RESULT_RESET_FAILURE; | 318 | return ret; |
| 324 | } | 319 | } |
| 325 | } else { | 320 | } else { |
| 326 | printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); | 321 | printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); |
| 327 | return XC_RESULT_RESET_FAILURE; | 322 | return -EINVAL; |
| 328 | } | 323 | } |
| 329 | return XC_RESULT_SUCCESS; | 324 | return 0; |
| 330 | } | 325 | } |
| 331 | 326 | ||
| 332 | static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | 327 | static int xc_write_reg(struct xc5000_priv *priv, u16 reg_addr, u16 i2c_data) |
| 333 | { | 328 | { |
| 334 | u8 buf[4]; | 329 | u8 buf[4]; |
| 335 | int WatchDogTimer = 100; | 330 | int watch_dog_timer = 100; |
| 336 | int result; | 331 | int result; |
| 337 | 332 | ||
| 338 | buf[0] = (regAddr >> 8) & 0xFF; | 333 | buf[0] = (reg_addr >> 8) & 0xFF; |
| 339 | buf[1] = regAddr & 0xFF; | 334 | buf[1] = reg_addr & 0xFF; |
| 340 | buf[2] = (i2cData >> 8) & 0xFF; | 335 | buf[2] = (i2c_data >> 8) & 0xFF; |
| 341 | buf[3] = i2cData & 0xFF; | 336 | buf[3] = i2c_data & 0xFF; |
| 342 | result = xc_send_i2c_data(priv, buf, 4); | 337 | result = xc_send_i2c_data(priv, buf, 4); |
| 343 | if (result == XC_RESULT_SUCCESS) { | 338 | if (result == 0) { |
| 344 | /* wait for busy flag to clear */ | 339 | /* wait for busy flag to clear */ |
| 345 | while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) { | 340 | while ((watch_dog_timer > 0) && (result == 0)) { |
| 346 | result = xc5000_readreg(priv, XREG_BUSY, (u16 *)buf); | 341 | result = xc5000_readreg(priv, XREG_BUSY, (u16 *)buf); |
| 347 | if (result == XC_RESULT_SUCCESS) { | 342 | if (result == 0) { |
| 348 | if ((buf[0] == 0) && (buf[1] == 0)) { | 343 | if ((buf[0] == 0) && (buf[1] == 0)) { |
| 349 | /* busy flag cleared */ | 344 | /* busy flag cleared */ |
| 350 | break; | 345 | break; |
| 351 | } else { | 346 | } else { |
| 352 | xc_wait(5); /* wait 5 ms */ | 347 | msleep(5); /* wait 5 ms */ |
| 353 | WatchDogTimer--; | 348 | watch_dog_timer--; |
| 354 | } | 349 | } |
| 355 | } | 350 | } |
| 356 | } | 351 | } |
| 357 | } | 352 | } |
| 358 | if (WatchDogTimer <= 0) | 353 | if (watch_dog_timer <= 0) |
| 359 | result = XC_RESULT_I2C_WRITE_FAILURE; | 354 | result = -EREMOTEIO; |
| 360 | 355 | ||
| 361 | return result; | 356 | return result; |
| 362 | } | 357 | } |
| @@ -375,13 +370,13 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
| 375 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; | 370 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; |
| 376 | if (len == 0x0000) { | 371 | if (len == 0x0000) { |
| 377 | /* RESET command */ | 372 | /* RESET command */ |
| 378 | result = xc5000_TunerReset(fe); | 373 | result = xc5000_tuner_reset(fe); |
| 379 | index += 2; | 374 | index += 2; |
| 380 | if (result != XC_RESULT_SUCCESS) | 375 | if (result != 0) |
| 381 | return result; | 376 | return result; |
| 382 | } else if (len & 0x8000) { | 377 | } else if (len & 0x8000) { |
| 383 | /* WAIT command */ | 378 | /* WAIT command */ |
| 384 | xc_wait(len & 0x7FFF); | 379 | msleep(len & 0x7FFF); |
| 385 | index += 2; | 380 | index += 2; |
| 386 | } else { | 381 | } else { |
| 387 | /* Send i2c data whilst ensuring individual transactions | 382 | /* Send i2c data whilst ensuring individual transactions |
| @@ -404,7 +399,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
| 404 | result = xc_send_i2c_data(priv, buf, | 399 | result = xc_send_i2c_data(priv, buf, |
| 405 | nbytes_to_send); | 400 | nbytes_to_send); |
| 406 | 401 | ||
| 407 | if (result != XC_RESULT_SUCCESS) | 402 | if (result != 0) |
| 408 | return result; | 403 | return result; |
| 409 | 404 | ||
| 410 | pos += nbytes_to_send - 2; | 405 | pos += nbytes_to_send - 2; |
| @@ -412,7 +407,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
| 412 | index += len; | 407 | index += len; |
| 413 | } | 408 | } |
| 414 | } | 409 | } |
| 415 | return XC_RESULT_SUCCESS; | 410 | return 0; |
| 416 | } | 411 | } |
| 417 | 412 | ||
| 418 | static int xc_initialize(struct xc5000_priv *priv) | 413 | static int xc_initialize(struct xc5000_priv *priv) |
| @@ -421,29 +416,29 @@ static int xc_initialize(struct xc5000_priv *priv) | |||
| 421 | return xc_write_reg(priv, XREG_INIT, 0); | 416 | return xc_write_reg(priv, XREG_INIT, 0); |
| 422 | } | 417 | } |
| 423 | 418 | ||
| 424 | static int xc_SetTVStandard(struct xc5000_priv *priv, | 419 | static int xc_set_tv_standard(struct xc5000_priv *priv, |
| 425 | u16 VideoMode, u16 AudioMode, u8 RadioMode) | 420 | u16 video_mode, u16 audio_mode, u8 radio_mode) |
| 426 | { | 421 | { |
| 427 | int ret; | 422 | int ret; |
| 428 | dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode); | 423 | dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, video_mode, audio_mode); |
| 429 | if (RadioMode) { | 424 | if (radio_mode) { |
| 430 | dprintk(1, "%s() Standard = %s\n", | 425 | dprintk(1, "%s() Standard = %s\n", |
| 431 | __func__, | 426 | __func__, |
| 432 | XC5000_Standard[RadioMode].Name); | 427 | xc5000_standard[radio_mode].name); |
| 433 | } else { | 428 | } else { |
| 434 | dprintk(1, "%s() Standard = %s\n", | 429 | dprintk(1, "%s() Standard = %s\n", |
| 435 | __func__, | 430 | __func__, |
| 436 | XC5000_Standard[priv->video_standard].Name); | 431 | xc5000_standard[priv->video_standard].name); |
| 437 | } | 432 | } |
| 438 | 433 | ||
| 439 | ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode); | 434 | ret = xc_write_reg(priv, XREG_VIDEO_MODE, video_mode); |
| 440 | if (ret == XC_RESULT_SUCCESS) | 435 | if (ret == 0) |
| 441 | ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode); | 436 | ret = xc_write_reg(priv, XREG_AUDIO_MODE, audio_mode); |
| 442 | 437 | ||
| 443 | return ret; | 438 | return ret; |
| 444 | } | 439 | } |
| 445 | 440 | ||
| 446 | static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) | 441 | static int xc_set_signal_source(struct xc5000_priv *priv, u16 rf_mode) |
| 447 | { | 442 | { |
| 448 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, | 443 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, |
| 449 | rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE"); | 444 | rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE"); |
| @@ -459,7 +454,7 @@ static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) | |||
| 459 | 454 | ||
| 460 | static const struct dvb_tuner_ops xc5000_tuner_ops; | 455 | static const struct dvb_tuner_ops xc5000_tuner_ops; |
| 461 | 456 | ||
| 462 | static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) | 457 | static int xc_set_rf_frequency(struct xc5000_priv *priv, u32 freq_hz) |
| 463 | { | 458 | { |
| 464 | u16 freq_code; | 459 | u16 freq_code; |
| 465 | 460 | ||
| @@ -467,7 +462,7 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) | |||
| 467 | 462 | ||
| 468 | if ((freq_hz > xc5000_tuner_ops.info.frequency_max) || | 463 | if ((freq_hz > xc5000_tuner_ops.info.frequency_max) || |
| 469 | (freq_hz < xc5000_tuner_ops.info.frequency_min)) | 464 | (freq_hz < xc5000_tuner_ops.info.frequency_min)) |
| 470 | return XC_RESULT_OUT_OF_RANGE; | 465 | return -EINVAL; |
| 471 | 466 | ||
| 472 | freq_code = (u16)(freq_hz / 15625); | 467 | freq_code = (u16)(freq_hz / 15625); |
| 473 | 468 | ||
| @@ -488,7 +483,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz) | |||
| 488 | } | 483 | } |
| 489 | 484 | ||
| 490 | 485 | ||
| 491 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) | 486 | static int xc_get_adc_envelope(struct xc5000_priv *priv, u16 *adc_envelope) |
| 492 | { | 487 | { |
| 493 | return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope); | 488 | return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope); |
| 494 | } | 489 | } |
| @@ -496,14 +491,14 @@ static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) | |||
| 496 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | 491 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) |
| 497 | { | 492 | { |
| 498 | int result; | 493 | int result; |
| 499 | u16 regData; | 494 | u16 reg_data; |
| 500 | u32 tmp; | 495 | u32 tmp; |
| 501 | 496 | ||
| 502 | result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®Data); | 497 | result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®_data); |
| 503 | if (result != XC_RESULT_SUCCESS) | 498 | if (result != 0) |
| 504 | return result; | 499 | return result; |
| 505 | 500 | ||
| 506 | tmp = (u32)regData; | 501 | tmp = (u32)reg_data; |
| 507 | (*freq_error_hz) = (tmp * 15625) / 1000; | 502 | (*freq_error_hz) = (tmp * 15625) / 1000; |
| 508 | return result; | 503 | return result; |
| 509 | } | 504 | } |
| @@ -521,7 +516,7 @@ static int xc_get_version(struct xc5000_priv *priv, | |||
| 521 | int result; | 516 | int result; |
| 522 | 517 | ||
| 523 | result = xc5000_readreg(priv, XREG_VERSION, &data); | 518 | result = xc5000_readreg(priv, XREG_VERSION, &data); |
| 524 | if (result != XC_RESULT_SUCCESS) | 519 | if (result != 0) |
| 525 | return result; | 520 | return result; |
| 526 | 521 | ||
| 527 | (*hw_majorversion) = (data >> 12) & 0x0F; | 522 | (*hw_majorversion) = (data >> 12) & 0x0F; |
| @@ -539,14 +534,14 @@ static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev) | |||
| 539 | 534 | ||
| 540 | static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | 535 | static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) |
| 541 | { | 536 | { |
| 542 | u16 regData; | 537 | u16 reg_data; |
| 543 | int result; | 538 | int result; |
| 544 | 539 | ||
| 545 | result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®Data); | 540 | result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®_data); |
| 546 | if (result != XC_RESULT_SUCCESS) | 541 | if (result != 0) |
| 547 | return result; | 542 | return result; |
| 548 | 543 | ||
| 549 | (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; | 544 | (*hsync_freq_hz) = ((reg_data & 0x0fff) * 763)/100; |
| 550 | return result; | 545 | return result; |
| 551 | } | 546 | } |
| 552 | 547 | ||
| @@ -570,19 +565,19 @@ static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain) | |||
| 570 | return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain); | 565 | return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain); |
| 571 | } | 566 | } |
| 572 | 567 | ||
| 573 | static u16 WaitForLock(struct xc5000_priv *priv) | 568 | static u16 wait_for_lock(struct xc5000_priv *priv) |
| 574 | { | 569 | { |
| 575 | u16 lockState = 0; | 570 | u16 lock_state = 0; |
| 576 | int watchDogCount = 40; | 571 | int watch_dog_count = 40; |
| 577 | 572 | ||
| 578 | while ((lockState == 0) && (watchDogCount > 0)) { | 573 | while ((lock_state == 0) && (watch_dog_count > 0)) { |
| 579 | xc_get_lock_status(priv, &lockState); | 574 | xc_get_lock_status(priv, &lock_state); |
| 580 | if (lockState != 1) { | 575 | if (lock_state != 1) { |
| 581 | xc_wait(5); | 576 | msleep(5); |
| 582 | watchDogCount--; | 577 | watch_dog_count--; |
| 583 | } | 578 | } |
| 584 | } | 579 | } |
| 585 | return lockState; | 580 | return lock_state; |
| 586 | } | 581 | } |
| 587 | 582 | ||
| 588 | #define XC_TUNE_ANALOG 0 | 583 | #define XC_TUNE_ANALOG 0 |
| @@ -593,11 +588,11 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) | |||
| 593 | 588 | ||
| 594 | dprintk(1, "%s(%u)\n", __func__, freq_hz); | 589 | dprintk(1, "%s(%u)\n", __func__, freq_hz); |
| 595 | 590 | ||
| 596 | if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) | 591 | if (xc_set_rf_frequency(priv, freq_hz) != 0) |
| 597 | return 0; | 592 | return 0; |
| 598 | 593 | ||
| 599 | if (mode == XC_TUNE_ANALOG) { | 594 | if (mode == XC_TUNE_ANALOG) { |
| 600 | if (WaitForLock(priv) == 1) | 595 | if (wait_for_lock(priv) == 1) |
| 601 | found = 1; | 596 | found = 1; |
| 602 | } | 597 | } |
| 603 | 598 | ||
| @@ -607,7 +602,7 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) | |||
| 607 | static int xc_set_xtal(struct dvb_frontend *fe) | 602 | static int xc_set_xtal(struct dvb_frontend *fe) |
| 608 | { | 603 | { |
| 609 | struct xc5000_priv *priv = fe->tuner_priv; | 604 | struct xc5000_priv *priv = fe->tuner_priv; |
| 610 | int ret = XC_RESULT_SUCCESS; | 605 | int ret = 0; |
| 611 | 606 | ||
| 612 | switch (priv->chip_id) { | 607 | switch (priv->chip_id) { |
| 613 | default: | 608 | default: |
| @@ -649,23 +644,22 @@ static int xc5000_fwupload(struct dvb_frontend *fe) | |||
| 649 | priv->i2c_props.adap->dev.parent); | 644 | priv->i2c_props.adap->dev.parent); |
| 650 | if (ret) { | 645 | if (ret) { |
| 651 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | 646 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); |
| 652 | ret = XC_RESULT_RESET_FAILURE; | ||
| 653 | goto out; | 647 | goto out; |
| 654 | } else { | 648 | } else { |
| 655 | printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n", | 649 | printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n", |
| 656 | fw->size); | 650 | fw->size); |
| 657 | ret = XC_RESULT_SUCCESS; | 651 | ret = 0; |
| 658 | } | 652 | } |
| 659 | 653 | ||
| 660 | if (fw->size != desired_fw->size) { | 654 | if (fw->size != desired_fw->size) { |
| 661 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); | 655 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); |
| 662 | ret = XC_RESULT_RESET_FAILURE; | 656 | ret = -EINVAL; |
| 663 | } else { | 657 | } else { |
| 664 | printk(KERN_INFO "xc5000: firmware uploading...\n"); | 658 | printk(KERN_INFO "xc5000: firmware uploading...\n"); |
| 665 | ret = xc_load_i2c_sequence(fe, fw->data); | 659 | ret = xc_load_i2c_sequence(fe, fw->data); |
| 666 | if (XC_RESULT_SUCCESS == ret) | 660 | if (0 == ret) |
| 667 | ret = xc_set_xtal(fe); | 661 | ret = xc_set_xtal(fe); |
| 668 | if (XC_RESULT_SUCCESS == ret) | 662 | if (0 == ret) |
| 669 | printk(KERN_INFO "xc5000: firmware upload complete...\n"); | 663 | printk(KERN_INFO "xc5000: firmware upload complete...\n"); |
| 670 | else | 664 | else |
| 671 | printk(KERN_ERR "xc5000: firmware upload failed...\n"); | 665 | printk(KERN_ERR "xc5000: firmware upload failed...\n"); |
| @@ -695,9 +689,9 @@ static void xc_debug_dump(struct xc5000_priv *priv) | |||
| 695 | * Frame Lines needs two frame times after initial lock | 689 | * Frame Lines needs two frame times after initial lock |
| 696 | * before it is valid. | 690 | * before it is valid. |
| 697 | */ | 691 | */ |
| 698 | xc_wait(100); | 692 | msleep(100); |
| 699 | 693 | ||
| 700 | xc_get_ADC_Envelope(priv, &adc_envelope); | 694 | xc_get_adc_envelope(priv, &adc_envelope); |
| 701 | dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope); | 695 | dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope); |
| 702 | 696 | ||
| 703 | xc_get_frequency_error(priv, &freq_error_hz); | 697 | xc_get_frequency_error(priv, &freq_error_hz); |
| @@ -744,7 +738,7 @@ static int xc5000_set_params(struct dvb_frontend *fe) | |||
| 744 | u32 freq = fe->dtv_property_cache.frequency; | 738 | u32 freq = fe->dtv_property_cache.frequency; |
| 745 | u32 delsys = fe->dtv_property_cache.delivery_system; | 739 | u32 delsys = fe->dtv_property_cache.delivery_system; |
| 746 | 740 | ||
| 747 | if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) { | 741 | if (xc_load_fw_and_init_tuner(fe, 0) != 0) { |
| 748 | dprintk(1, "Unable to load firmware and init tuner\n"); | 742 | dprintk(1, "Unable to load firmware and init tuner\n"); |
| 749 | return -EINVAL; | 743 | return -EINVAL; |
| 750 | } | 744 | } |
| @@ -820,24 +814,24 @@ static int xc5000_set_params(struct dvb_frontend *fe) | |||
| 820 | dprintk(1, "%s() frequency=%d (compensated to %d)\n", | 814 | dprintk(1, "%s() frequency=%d (compensated to %d)\n", |
| 821 | __func__, freq, priv->freq_hz); | 815 | __func__, freq, priv->freq_hz); |
| 822 | 816 | ||
| 823 | ret = xc_SetSignalSource(priv, priv->rf_mode); | 817 | ret = xc_set_signal_source(priv, priv->rf_mode); |
| 824 | if (ret != XC_RESULT_SUCCESS) { | 818 | if (ret != 0) { |
| 825 | printk(KERN_ERR | 819 | printk(KERN_ERR |
| 826 | "xc5000: xc_SetSignalSource(%d) failed\n", | 820 | "xc5000: xc_set_signal_source(%d) failed\n", |
| 827 | priv->rf_mode); | 821 | priv->rf_mode); |
| 828 | return -EREMOTEIO; | 822 | return -EREMOTEIO; |
| 829 | } | 823 | } |
| 830 | 824 | ||
| 831 | ret = xc_SetTVStandard(priv, | 825 | ret = xc_set_tv_standard(priv, |
| 832 | XC5000_Standard[priv->video_standard].VideoMode, | 826 | xc5000_standard[priv->video_standard].video_mode, |
| 833 | XC5000_Standard[priv->video_standard].AudioMode, 0); | 827 | xc5000_standard[priv->video_standard].audio_mode, 0); |
| 834 | if (ret != XC_RESULT_SUCCESS) { | 828 | if (ret != 0) { |
| 835 | printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n"); | 829 | printk(KERN_ERR "xc5000: xc_set_tv_standard failed\n"); |
| 836 | return -EREMOTEIO; | 830 | return -EREMOTEIO; |
| 837 | } | 831 | } |
| 838 | 832 | ||
| 839 | ret = xc_set_IF_frequency(priv, priv->if_khz); | 833 | ret = xc_set_IF_frequency(priv, priv->if_khz); |
| 840 | if (ret != XC_RESULT_SUCCESS) { | 834 | if (ret != 0) { |
| 841 | printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n", | 835 | printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n", |
| 842 | priv->if_khz); | 836 | priv->if_khz); |
| 843 | return -EIO; | 837 | return -EIO; |
| @@ -862,15 +856,15 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) | |||
| 862 | u16 id; | 856 | u16 id; |
| 863 | 857 | ||
| 864 | ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id); | 858 | ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id); |
| 865 | if (ret == XC_RESULT_SUCCESS) { | 859 | if (ret == 0) { |
| 866 | if (id == XC_PRODUCT_ID_FW_NOT_LOADED) | 860 | if (id == XC_PRODUCT_ID_FW_NOT_LOADED) |
| 867 | ret = XC_RESULT_RESET_FAILURE; | 861 | ret = -ENOENT; |
| 868 | else | 862 | else |
| 869 | ret = XC_RESULT_SUCCESS; | 863 | ret = 0; |
| 870 | } | 864 | } |
| 871 | 865 | ||
| 872 | dprintk(1, "%s() returns %s id = 0x%x\n", __func__, | 866 | dprintk(1, "%s() returns %s id = 0x%x\n", __func__, |
| 873 | ret == XC_RESULT_SUCCESS ? "True" : "False", id); | 867 | ret == 0 ? "True" : "False", id); |
| 874 | return ret; | 868 | return ret; |
| 875 | } | 869 | } |
| 876 | 870 | ||
| @@ -936,19 +930,19 @@ static int xc5000_set_tv_freq(struct dvb_frontend *fe, | |||
| 936 | } | 930 | } |
| 937 | 931 | ||
| 938 | tune_channel: | 932 | tune_channel: |
| 939 | ret = xc_SetSignalSource(priv, priv->rf_mode); | 933 | ret = xc_set_signal_source(priv, priv->rf_mode); |
| 940 | if (ret != XC_RESULT_SUCCESS) { | 934 | if (ret != 0) { |
| 941 | printk(KERN_ERR | 935 | printk(KERN_ERR |
| 942 | "xc5000: xc_SetSignalSource(%d) failed\n", | 936 | "xc5000: xc_set_signal_source(%d) failed\n", |
| 943 | priv->rf_mode); | 937 | priv->rf_mode); |
| 944 | return -EREMOTEIO; | 938 | return -EREMOTEIO; |
| 945 | } | 939 | } |
| 946 | 940 | ||
| 947 | ret = xc_SetTVStandard(priv, | 941 | ret = xc_set_tv_standard(priv, |
| 948 | XC5000_Standard[priv->video_standard].VideoMode, | 942 | xc5000_standard[priv->video_standard].video_mode, |
| 949 | XC5000_Standard[priv->video_standard].AudioMode, 0); | 943 | xc5000_standard[priv->video_standard].audio_mode, 0); |
| 950 | if (ret != XC_RESULT_SUCCESS) { | 944 | if (ret != 0) { |
| 951 | printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n"); | 945 | printk(KERN_ERR "xc5000: xc_set_tv_standard failed\n"); |
| 952 | return -EREMOTEIO; | 946 | return -EREMOTEIO; |
| 953 | } | 947 | } |
| 954 | 948 | ||
| @@ -966,7 +960,7 @@ tune_channel: | |||
| 966 | /* PLL is unlocked, force reload of the firmware */ | 960 | /* PLL is unlocked, force reload of the firmware */ |
| 967 | dprintk(1, "xc5000: PLL not locked (0x%x). Reloading...\n", | 961 | dprintk(1, "xc5000: PLL not locked (0x%x). Reloading...\n", |
| 968 | pll_lock_status); | 962 | pll_lock_status); |
| 969 | if (xc_load_fw_and_init_tuner(fe, 1) != XC_RESULT_SUCCESS) { | 963 | if (xc_load_fw_and_init_tuner(fe, 1) != 0) { |
| 970 | printk(KERN_ERR "xc5000: Unable to reload fw\n"); | 964 | printk(KERN_ERR "xc5000: Unable to reload fw\n"); |
| 971 | return -EREMOTEIO; | 965 | return -EREMOTEIO; |
| 972 | } | 966 | } |
| @@ -993,11 +987,11 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe, | |||
| 993 | } | 987 | } |
| 994 | 988 | ||
| 995 | if (priv->radio_input == XC5000_RADIO_FM1) | 989 | if (priv->radio_input == XC5000_RADIO_FM1) |
| 996 | radio_input = FM_Radio_INPUT1; | 990 | radio_input = FM_RADIO_INPUT1; |
| 997 | else if (priv->radio_input == XC5000_RADIO_FM2) | 991 | else if (priv->radio_input == XC5000_RADIO_FM2) |
| 998 | radio_input = FM_Radio_INPUT2; | 992 | radio_input = FM_RADIO_INPUT2; |
| 999 | else if (priv->radio_input == XC5000_RADIO_FM1_MONO) | 993 | else if (priv->radio_input == XC5000_RADIO_FM1_MONO) |
| 1000 | radio_input = FM_Radio_INPUT1_MONO; | 994 | radio_input = FM_RADIO_INPUT1_MONO; |
| 1001 | else { | 995 | else { |
| 1002 | dprintk(1, "%s() unknown radio input %d\n", __func__, | 996 | dprintk(1, "%s() unknown radio input %d\n", __func__, |
| 1003 | priv->radio_input); | 997 | priv->radio_input); |
| @@ -1008,18 +1002,18 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe, | |||
| 1008 | 1002 | ||
| 1009 | priv->rf_mode = XC_RF_MODE_AIR; | 1003 | priv->rf_mode = XC_RF_MODE_AIR; |
| 1010 | 1004 | ||
| 1011 | ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode, | 1005 | ret = xc_set_tv_standard(priv, xc5000_standard[radio_input].video_mode, |
| 1012 | XC5000_Standard[radio_input].AudioMode, radio_input); | 1006 | xc5000_standard[radio_input].audio_mode, radio_input); |
| 1013 | 1007 | ||
| 1014 | if (ret != XC_RESULT_SUCCESS) { | 1008 | if (ret != 0) { |
| 1015 | printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n"); | 1009 | printk(KERN_ERR "xc5000: xc_set_tv_standard failed\n"); |
| 1016 | return -EREMOTEIO; | 1010 | return -EREMOTEIO; |
| 1017 | } | 1011 | } |
| 1018 | 1012 | ||
| 1019 | ret = xc_SetSignalSource(priv, priv->rf_mode); | 1013 | ret = xc_set_signal_source(priv, priv->rf_mode); |
| 1020 | if (ret != XC_RESULT_SUCCESS) { | 1014 | if (ret != 0) { |
| 1021 | printk(KERN_ERR | 1015 | printk(KERN_ERR |
| 1022 | "xc5000: xc_SetSignalSource(%d) failed\n", | 1016 | "xc5000: xc_set_signal_source(%d) failed\n", |
| 1023 | priv->rf_mode); | 1017 | priv->rf_mode); |
| 1024 | return -EREMOTEIO; | 1018 | return -EREMOTEIO; |
| 1025 | } | 1019 | } |
| @@ -1044,7 +1038,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, | |||
| 1044 | if (priv->i2c_props.adap == NULL) | 1038 | if (priv->i2c_props.adap == NULL) |
| 1045 | return -EINVAL; | 1039 | return -EINVAL; |
| 1046 | 1040 | ||
| 1047 | if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) { | 1041 | if (xc_load_fw_and_init_tuner(fe, 0) != 0) { |
| 1048 | dprintk(1, "Unable to load firmware and init tuner\n"); | 1042 | dprintk(1, "Unable to load firmware and init tuner\n"); |
| 1049 | return -EINVAL; | 1043 | return -EINVAL; |
| 1050 | } | 1044 | } |
| @@ -1105,23 +1099,25 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status) | |||
| 1105 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) | 1099 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) |
| 1106 | { | 1100 | { |
| 1107 | struct xc5000_priv *priv = fe->tuner_priv; | 1101 | struct xc5000_priv *priv = fe->tuner_priv; |
| 1108 | int ret = XC_RESULT_SUCCESS; | 1102 | int ret = 0; |
| 1109 | u16 pll_lock_status; | 1103 | u16 pll_lock_status; |
| 1110 | u16 fw_ck; | 1104 | u16 fw_ck; |
| 1111 | 1105 | ||
| 1112 | if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { | 1106 | cancel_delayed_work(&priv->timer_sleep); |
| 1107 | |||
| 1108 | if (force || xc5000_is_firmware_loaded(fe) != 0) { | ||
| 1113 | 1109 | ||
| 1114 | fw_retry: | 1110 | fw_retry: |
| 1115 | 1111 | ||
| 1116 | ret = xc5000_fwupload(fe); | 1112 | ret = xc5000_fwupload(fe); |
| 1117 | if (ret != XC_RESULT_SUCCESS) | 1113 | if (ret != 0) |
| 1118 | return ret; | 1114 | return ret; |
| 1119 | 1115 | ||
| 1120 | msleep(20); | 1116 | msleep(20); |
| 1121 | 1117 | ||
| 1122 | if (priv->fw_checksum_supported) { | 1118 | if (priv->fw_checksum_supported) { |
| 1123 | if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck) | 1119 | if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck) |
| 1124 | != XC_RESULT_SUCCESS) { | 1120 | != 0) { |
| 1125 | dprintk(1, "%s() FW checksum reading failed.\n", | 1121 | dprintk(1, "%s() FW checksum reading failed.\n", |
| 1126 | __func__); | 1122 | __func__); |
| 1127 | goto fw_retry; | 1123 | goto fw_retry; |
| @@ -1137,7 +1133,7 @@ fw_retry: | |||
| 1137 | /* Start the tuner self-calibration process */ | 1133 | /* Start the tuner self-calibration process */ |
| 1138 | ret |= xc_initialize(priv); | 1134 | ret |= xc_initialize(priv); |
| 1139 | 1135 | ||
| 1140 | if (ret != XC_RESULT_SUCCESS) | 1136 | if (ret != 0) |
| 1141 | goto fw_retry; | 1137 | goto fw_retry; |
| 1142 | 1138 | ||
| 1143 | /* Wait for calibration to complete. | 1139 | /* Wait for calibration to complete. |
| @@ -1145,10 +1141,10 @@ fw_retry: | |||
| 1145 | * I2C transactions until calibration is complete. This way we | 1141 | * I2C transactions until calibration is complete. This way we |
| 1146 | * don't have to rely on clock stretching working. | 1142 | * don't have to rely on clock stretching working. |
| 1147 | */ | 1143 | */ |
| 1148 | xc_wait(100); | 1144 | msleep(100); |
| 1149 | 1145 | ||
| 1150 | if (priv->init_status_supported) { | 1146 | if (priv->init_status_supported) { |
| 1151 | if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != XC_RESULT_SUCCESS) { | 1147 | if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != 0) { |
| 1152 | dprintk(1, "%s() FW failed reading init status.\n", | 1148 | dprintk(1, "%s() FW failed reading init status.\n", |
| 1153 | __func__); | 1149 | __func__); |
| 1154 | goto fw_retry; | 1150 | goto fw_retry; |
| @@ -1177,27 +1173,39 @@ fw_retry: | |||
| 1177 | return ret; | 1173 | return ret; |
| 1178 | } | 1174 | } |
| 1179 | 1175 | ||
| 1180 | static int xc5000_sleep(struct dvb_frontend *fe) | 1176 | static void xc5000_do_timer_sleep(struct work_struct *timer_sleep) |
| 1181 | { | 1177 | { |
| 1178 | struct xc5000_priv *priv =container_of(timer_sleep, struct xc5000_priv, | ||
| 1179 | timer_sleep.work); | ||
| 1180 | struct dvb_frontend *fe = priv->fe; | ||
| 1182 | int ret; | 1181 | int ret; |
| 1183 | 1182 | ||
| 1184 | dprintk(1, "%s()\n", __func__); | 1183 | dprintk(1, "%s()\n", __func__); |
| 1185 | 1184 | ||
| 1186 | /* Avoid firmware reload on slow devices */ | ||
| 1187 | if (no_poweroff) | ||
| 1188 | return 0; | ||
| 1189 | |||
| 1190 | /* According to Xceive technical support, the "powerdown" register | 1185 | /* According to Xceive technical support, the "powerdown" register |
| 1191 | was removed in newer versions of the firmware. The "supported" | 1186 | was removed in newer versions of the firmware. The "supported" |
| 1192 | way to sleep the tuner is to pull the reset pin low for 10ms */ | 1187 | way to sleep the tuner is to pull the reset pin low for 10ms */ |
| 1193 | ret = xc5000_TunerReset(fe); | 1188 | ret = xc5000_tuner_reset(fe); |
| 1194 | if (ret != XC_RESULT_SUCCESS) { | 1189 | if (ret != 0) |
| 1195 | printk(KERN_ERR | 1190 | printk(KERN_ERR |
| 1196 | "xc5000: %s() unable to shutdown tuner\n", | 1191 | "xc5000: %s() unable to shutdown tuner\n", |
| 1197 | __func__); | 1192 | __func__); |
| 1198 | return -EREMOTEIO; | 1193 | } |
| 1199 | } else | 1194 | |
| 1200 | return XC_RESULT_SUCCESS; | 1195 | static int xc5000_sleep(struct dvb_frontend *fe) |
| 1196 | { | ||
| 1197 | struct xc5000_priv *priv = fe->tuner_priv; | ||
| 1198 | |||
| 1199 | dprintk(1, "%s()\n", __func__); | ||
| 1200 | |||
| 1201 | /* Avoid firmware reload on slow devices */ | ||
| 1202 | if (no_poweroff) | ||
| 1203 | return 0; | ||
| 1204 | |||
| 1205 | schedule_delayed_work(&priv->timer_sleep, | ||
| 1206 | msecs_to_jiffies(XC5000_SLEEP_TIME)); | ||
| 1207 | |||
| 1208 | return 0; | ||
| 1201 | } | 1209 | } |
| 1202 | 1210 | ||
| 1203 | static int xc5000_init(struct dvb_frontend *fe) | 1211 | static int xc5000_init(struct dvb_frontend *fe) |
| @@ -1205,7 +1213,7 @@ static int xc5000_init(struct dvb_frontend *fe) | |||
| 1205 | struct xc5000_priv *priv = fe->tuner_priv; | 1213 | struct xc5000_priv *priv = fe->tuner_priv; |
| 1206 | dprintk(1, "%s()\n", __func__); | 1214 | dprintk(1, "%s()\n", __func__); |
| 1207 | 1215 | ||
| 1208 | if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) { | 1216 | if (xc_load_fw_and_init_tuner(fe, 0) != 0) { |
| 1209 | printk(KERN_ERR "xc5000: Unable to initialise tuner\n"); | 1217 | printk(KERN_ERR "xc5000: Unable to initialise tuner\n"); |
| 1210 | return -EREMOTEIO; | 1218 | return -EREMOTEIO; |
| 1211 | } | 1219 | } |
| @@ -1224,8 +1232,10 @@ static int xc5000_release(struct dvb_frontend *fe) | |||
| 1224 | 1232 | ||
| 1225 | mutex_lock(&xc5000_list_mutex); | 1233 | mutex_lock(&xc5000_list_mutex); |
| 1226 | 1234 | ||
| 1227 | if (priv) | 1235 | if (priv) { |
| 1236 | cancel_delayed_work(&priv->timer_sleep); | ||
| 1228 | hybrid_tuner_release_state(priv); | 1237 | hybrid_tuner_release_state(priv); |
| 1238 | } | ||
| 1229 | 1239 | ||
| 1230 | mutex_unlock(&xc5000_list_mutex); | 1240 | mutex_unlock(&xc5000_list_mutex); |
| 1231 | 1241 | ||
| @@ -1297,6 +1307,8 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
| 1297 | /* new tuner instance */ | 1307 | /* new tuner instance */ |
| 1298 | priv->bandwidth = 6000000; | 1308 | priv->bandwidth = 6000000; |
| 1299 | fe->tuner_priv = priv; | 1309 | fe->tuner_priv = priv; |
| 1310 | priv->fe = fe; | ||
| 1311 | INIT_DELAYED_WORK(&priv->timer_sleep, xc5000_do_timer_sleep); | ||
| 1300 | break; | 1312 | break; |
| 1301 | default: | 1313 | default: |
| 1302 | /* existing tuner instance */ | 1314 | /* existing tuner instance */ |
| @@ -1327,7 +1339,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
| 1327 | /* Check if firmware has been loaded. It is possible that another | 1339 | /* Check if firmware has been loaded. It is possible that another |
| 1328 | instance of the driver has loaded the firmware. | 1340 | instance of the driver has loaded the firmware. |
| 1329 | */ | 1341 | */ |
| 1330 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS) | 1342 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) |
| 1331 | goto fail; | 1343 | goto fail; |
| 1332 | 1344 | ||
| 1333 | switch (id) { | 1345 | switch (id) { |
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index 4ae8b1074649..d8b5d9480279 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c | |||
| @@ -114,16 +114,20 @@ static void urb_completion(struct urb *purb) | |||
| 114 | int ptype = usb_pipetype(purb->pipe); | 114 | int ptype = usb_pipetype(purb->pipe); |
| 115 | unsigned char *ptr; | 115 | unsigned char *ptr; |
| 116 | 116 | ||
| 117 | dprintk(2, "%s()\n", __func__); | 117 | dprintk(2, "%s: %d\n", __func__, purb->actual_length); |
| 118 | 118 | ||
| 119 | if (!dev) | 119 | if (!dev) { |
| 120 | dprintk(2, "%s: no dev!\n", __func__); | ||
| 120 | return; | 121 | return; |
| 122 | } | ||
| 121 | 123 | ||
| 122 | if (dev->urb_streaming == 0) | 124 | if (dev->urb_streaming == 0) { |
| 125 | dprintk(2, "%s: not streaming!\n", __func__); | ||
| 123 | return; | 126 | return; |
| 127 | } | ||
| 124 | 128 | ||
| 125 | if (ptype != PIPE_BULK) { | 129 | if (ptype != PIPE_BULK) { |
| 126 | printk(KERN_ERR "%s() Unsupported URB type %d\n", | 130 | printk(KERN_ERR "%s: Unsupported URB type %d\n", |
| 127 | __func__, ptype); | 131 | __func__, ptype); |
| 128 | return; | 132 | return; |
| 129 | } | 133 | } |
| @@ -252,8 +256,6 @@ static void au0828_stop_transport(struct au0828_dev *dev, int full_stop) | |||
| 252 | au0828_write(dev, 0x60b, 0x00); | 256 | au0828_write(dev, 0x60b, 0x00); |
| 253 | } | 257 | } |
| 254 | 258 | ||
| 255 | |||
| 256 | |||
| 257 | static int au0828_dvb_start_feed(struct dvb_demux_feed *feed) | 259 | static int au0828_dvb_start_feed(struct dvb_demux_feed *feed) |
| 258 | { | 260 | { |
| 259 | struct dvb_demux *demux = feed->demux; | 261 | struct dvb_demux *demux = feed->demux; |
| @@ -296,6 +298,8 @@ static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed) | |||
| 296 | dprintk(1, "%s()\n", __func__); | 298 | dprintk(1, "%s()\n", __func__); |
| 297 | 299 | ||
| 298 | if (dvb) { | 300 | if (dvb) { |
| 301 | cancel_work_sync(&dev->restart_streaming); | ||
| 302 | |||
| 299 | mutex_lock(&dvb->lock); | 303 | mutex_lock(&dvb->lock); |
| 300 | dvb->stop_count++; | 304 | dvb->stop_count++; |
| 301 | dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__, | 305 | dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__, |
| @@ -338,6 +342,41 @@ static void au0828_restart_dvb_streaming(struct work_struct *work) | |||
| 338 | mutex_unlock(&dvb->lock); | 342 | mutex_unlock(&dvb->lock); |
| 339 | } | 343 | } |
| 340 | 344 | ||
| 345 | static int au0828_set_frontend(struct dvb_frontend *fe) | ||
| 346 | { | ||
| 347 | struct au0828_dev *dev = fe->dvb->priv; | ||
| 348 | struct au0828_dvb *dvb = &dev->dvb; | ||
| 349 | int ret, was_streaming; | ||
| 350 | |||
| 351 | mutex_lock(&dvb->lock); | ||
| 352 | was_streaming = dev->urb_streaming; | ||
| 353 | if (was_streaming) { | ||
| 354 | au0828_stop_transport(dev, 1); | ||
| 355 | |||
| 356 | /* | ||
| 357 | * We can't hold a mutex here, as the restart_streaming | ||
| 358 | * kthread may also hold it. | ||
| 359 | */ | ||
| 360 | mutex_unlock(&dvb->lock); | ||
| 361 | cancel_work_sync(&dev->restart_streaming); | ||
| 362 | mutex_lock(&dvb->lock); | ||
| 363 | |||
| 364 | stop_urb_transfer(dev); | ||
| 365 | } | ||
| 366 | mutex_unlock(&dvb->lock); | ||
| 367 | |||
| 368 | ret = dvb->set_frontend(fe); | ||
| 369 | |||
| 370 | if (was_streaming) { | ||
| 371 | mutex_lock(&dvb->lock); | ||
| 372 | au0828_start_transport(dev); | ||
| 373 | start_urb_transfer(dev); | ||
| 374 | mutex_unlock(&dvb->lock); | ||
| 375 | } | ||
| 376 | |||
| 377 | return ret; | ||
| 378 | } | ||
| 379 | |||
| 341 | static int dvb_register(struct au0828_dev *dev) | 380 | static int dvb_register(struct au0828_dev *dev) |
| 342 | { | 381 | { |
| 343 | struct au0828_dvb *dvb = &dev->dvb; | 382 | struct au0828_dvb *dvb = &dev->dvb; |
| @@ -382,6 +421,10 @@ static int dvb_register(struct au0828_dev *dev) | |||
| 382 | goto fail_frontend; | 421 | goto fail_frontend; |
| 383 | } | 422 | } |
| 384 | 423 | ||
| 424 | /* Hook dvb frontend */ | ||
| 425 | dvb->set_frontend = dvb->frontend->ops.set_frontend; | ||
| 426 | dvb->frontend->ops.set_frontend = au0828_set_frontend; | ||
| 427 | |||
| 385 | /* register demux stuff */ | 428 | /* register demux stuff */ |
| 386 | dvb->demux.dmx.capabilities = | 429 | dvb->demux.dmx.capabilities = |
| 387 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | | 430 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | |
| @@ -471,6 +514,8 @@ void au0828_dvb_unregister(struct au0828_dev *dev) | |||
| 471 | if (dvb->frontend == NULL) | 514 | if (dvb->frontend == NULL) |
| 472 | return; | 515 | return; |
| 473 | 516 | ||
| 517 | cancel_work_sync(&dev->restart_streaming); | ||
| 518 | |||
| 474 | dvb_net_release(&dvb->net); | 519 | dvb_net_release(&dvb->net); |
| 475 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | 520 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); |
| 476 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | 521 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); |
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index f6154546b5c0..9038194513c5 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c | |||
| @@ -1109,7 +1109,7 @@ static void au0828_init_tuner(struct au0828_dev *dev) | |||
| 1109 | /* If we've never sent the standard in tuner core, do so now. | 1109 | /* If we've never sent the standard in tuner core, do so now. |
| 1110 | We don't do this at device probe because we don't want to | 1110 | We don't do this at device probe because we don't want to |
| 1111 | incur the cost of a firmware load */ | 1111 | incur the cost of a firmware load */ |
| 1112 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->std); | 1112 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, dev->std); |
| 1113 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 1113 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); |
| 1114 | i2c_gate_ctrl(dev, 0); | 1114 | i2c_gate_ctrl(dev, 0); |
| 1115 | } | 1115 | } |
| @@ -1368,7 +1368,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 1368 | have to make the au0828 bridge adjust the size of its capture | 1368 | have to make the au0828 bridge adjust the size of its capture |
| 1369 | buffer, which is currently hardcoded at 720x480 */ | 1369 | buffer, which is currently hardcoded at 720x480 */ |
| 1370 | 1370 | ||
| 1371 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, norm); | 1371 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, norm); |
| 1372 | 1372 | ||
| 1373 | i2c_gate_ctrl(dev, 0); | 1373 | i2c_gate_ctrl(dev, 0); |
| 1374 | 1374 | ||
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 5439772c1551..7112b9d956fa 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h | |||
| @@ -104,6 +104,8 @@ struct au0828_dvb { | |||
| 104 | int feeding; | 104 | int feeding; |
| 105 | int start_count; | 105 | int start_count; |
| 106 | int stop_count; | 106 | int stop_count; |
| 107 | |||
| 108 | int (*set_frontend)(struct dvb_frontend *fe); | ||
| 107 | }; | 109 | }; |
| 108 | 110 | ||
| 109 | enum au0828_stream_state { | 111 | enum au0828_stream_state { |
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 2f63029e7a36..30a0c69fb42f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c | |||
| @@ -1516,7 +1516,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) | |||
| 1516 | dev->ts1.height = 576; | 1516 | dev->ts1.height = 576; |
| 1517 | cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, true); | 1517 | cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, true); |
| 1518 | } | 1518 | } |
| 1519 | call_all(dev, core, s_std, dev->norm); | 1519 | call_all(dev, video, s_std, dev->norm); |
| 1520 | /* do mode control overrides */ | 1520 | /* do mode control overrides */ |
| 1521 | cx231xx_do_mode_ctrl_overrides(dev); | 1521 | cx231xx_do_mode_ctrl_overrides(dev); |
| 1522 | 1522 | ||
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 990626101718..1f8751379e24 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c | |||
| @@ -1009,7 +1009,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 1009 | dev->width = 720; | 1009 | dev->width = 720; |
| 1010 | dev->height = (dev->norm & V4L2_STD_625_50) ? 576 : 480; | 1010 | dev->height = (dev->norm & V4L2_STD_625_50) ? 576 : 480; |
| 1011 | 1011 | ||
| 1012 | call_all(dev, core, s_std, dev->norm); | 1012 | call_all(dev, video, s_std, dev->norm); |
| 1013 | 1013 | ||
| 1014 | /* We need to reset basic properties in the decoder related to | 1014 | /* We need to reset basic properties in the decoder related to |
| 1015 | resolution (since a standard change effects things like the number | 1015 | resolution (since a standard change effects things like the number |
| @@ -1108,7 +1108,7 @@ int cx231xx_s_input(struct file *file, void *priv, unsigned int i) | |||
| 1108 | /* There's a tuner, so reset the standard and put it on the | 1108 | /* There's a tuner, so reset the standard and put it on the |
| 1109 | last known frequency (since it was probably powered down | 1109 | last known frequency (since it was probably powered down |
| 1110 | until now */ | 1110 | until now */ |
| 1111 | call_all(dev, core, s_std, dev->norm); | 1111 | call_all(dev, video, s_std, dev->norm); |
| 1112 | } | 1112 | } |
| 1113 | 1113 | ||
| 1114 | return 0; | 1114 | return 0; |
| @@ -2099,7 +2099,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) | |||
| 2099 | /* Set the initial input */ | 2099 | /* Set the initial input */ |
| 2100 | video_mux(dev, dev->video_input); | 2100 | video_mux(dev, dev->video_input); |
| 2101 | 2101 | ||
| 2102 | call_all(dev, core, s_std, dev->norm); | 2102 | call_all(dev, video, s_std, dev->norm); |
| 2103 | 2103 | ||
| 2104 | v4l2_ctrl_handler_init(&dev->ctrl_handler, 10); | 2104 | v4l2_ctrl_handler_init(&dev->ctrl_handler, 10); |
| 2105 | v4l2_ctrl_handler_init(&dev->radio_ctrl_handler, 5); | 2105 | v4l2_ctrl_handler_init(&dev->radio_ctrl_handler, 5); |
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index dcbd392e6efc..a676e4452847 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c | |||
| @@ -1537,6 +1537,12 @@ static const struct usb_device_id rtl28xxu_id_table[] = { | |||
| 1537 | &rtl2832u_props, "Crypto ReDi PC 50 A", NULL) }, | 1537 | &rtl2832u_props, "Crypto ReDi PC 50 A", NULL) }, |
| 1538 | { DVB_USB_DEVICE(USB_VID_KYE, 0x707f, | 1538 | { DVB_USB_DEVICE(USB_VID_KYE, 0x707f, |
| 1539 | &rtl2832u_props, "Genius TVGo DVB-T03", NULL) }, | 1539 | &rtl2832u_props, "Genius TVGo DVB-T03", NULL) }, |
| 1540 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd395, | ||
| 1541 | &rtl2832u_props, "Peak DVB-T USB", NULL) }, | ||
| 1542 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20_RTL2832U, | ||
| 1543 | &rtl2832u_props, "Sveon STV20", NULL) }, | ||
| 1544 | { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV27, | ||
| 1545 | &rtl2832u_props, "Sveon STV27", NULL) }, | ||
| 1540 | 1546 | ||
| 1541 | /* RTL2832P devices: */ | 1547 | /* RTL2832P devices: */ |
| 1542 | { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, | 1548 | { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, |
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index c11138ebf6fb..0df52ab32a7b 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c | |||
| @@ -1088,6 +1088,7 @@ static struct usb_device_id az6027_usb_table[] = { | |||
| 1088 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) }, | 1088 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) }, |
| 1089 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) }, | 1089 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) }, |
| 1090 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) }, | 1090 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) }, |
| 1091 | { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT_V2) }, | ||
| 1091 | { }, | 1092 | { }, |
| 1092 | }; | 1093 | }; |
| 1093 | 1094 | ||
| @@ -1136,7 +1137,7 @@ static struct dvb_usb_device_properties az6027_properties = { | |||
| 1136 | 1137 | ||
| 1137 | .i2c_algo = &az6027_i2c_algo, | 1138 | .i2c_algo = &az6027_i2c_algo, |
| 1138 | 1139 | ||
| 1139 | .num_device_descs = 6, | 1140 | .num_device_descs = 7, |
| 1140 | .devices = { | 1141 | .devices = { |
| 1141 | { | 1142 | { |
| 1142 | .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)", | 1143 | .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)", |
| @@ -1162,6 +1163,10 @@ static struct dvb_usb_device_properties az6027_properties = { | |||
| 1162 | .name = "Elgato EyeTV Sat", | 1163 | .name = "Elgato EyeTV Sat", |
| 1163 | .cold_ids = { &az6027_usb_table[5], NULL }, | 1164 | .cold_ids = { &az6027_usb_table[5], NULL }, |
| 1164 | .warm_ids = { NULL }, | 1165 | .warm_ids = { NULL }, |
| 1166 | }, { | ||
| 1167 | .name = "Elgato EyeTV Sat", | ||
| 1168 | .cold_ids = { &az6027_usb_table[6], NULL }, | ||
| 1169 | .warm_ids = { NULL }, | ||
| 1165 | }, | 1170 | }, |
| 1166 | { NULL }, | 1171 | { NULL }, |
| 1167 | } | 1172 | } |
diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h index 637b6123f391..927617d95616 100644 --- a/drivers/media/usb/dvb-usb/dib0700.h +++ b/drivers/media/usb/dvb-usb/dib0700.h | |||
| @@ -59,7 +59,7 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 | |||
| 59 | extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); | 59 | extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); |
| 60 | extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); | 60 | extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); |
| 61 | extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); | 61 | extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); |
| 62 | extern int dib0700_rc_setup(struct dvb_usb_device *d); | 62 | extern int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf); |
| 63 | extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); | 63 | extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); |
| 64 | extern struct i2c_algorithm dib0700_i2c_algo; | 64 | extern struct i2c_algorithm dib0700_i2c_algo; |
| 65 | extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, | 65 | extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, |
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index bf2a908d74cf..c14285fa8271 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c | |||
| @@ -754,17 +754,20 @@ resubmit: | |||
| 754 | usb_submit_urb(purb, GFP_ATOMIC); | 754 | usb_submit_urb(purb, GFP_ATOMIC); |
| 755 | } | 755 | } |
| 756 | 756 | ||
| 757 | int dib0700_rc_setup(struct dvb_usb_device *d) | 757 | int dib0700_rc_setup(struct dvb_usb_device *d, struct usb_interface *intf) |
| 758 | { | 758 | { |
| 759 | struct dib0700_state *st = d->priv; | 759 | struct dib0700_state *st = d->priv; |
| 760 | struct urb *purb; | 760 | struct urb *purb; |
| 761 | int ret; | 761 | const struct usb_endpoint_descriptor *e; |
| 762 | int ret, rc_ep = 1; | ||
| 763 | unsigned int pipe = 0; | ||
| 762 | 764 | ||
| 763 | /* Poll-based. Don't initialize bulk mode */ | 765 | /* Poll-based. Don't initialize bulk mode */ |
| 764 | if (st->fw_version < 0x10200) | 766 | if (st->fw_version < 0x10200 || !intf) |
| 765 | return 0; | 767 | return 0; |
| 766 | 768 | ||
| 767 | /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ | 769 | /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ |
| 770 | |||
| 768 | purb = usb_alloc_urb(0, GFP_KERNEL); | 771 | purb = usb_alloc_urb(0, GFP_KERNEL); |
| 769 | if (purb == NULL) { | 772 | if (purb == NULL) { |
| 770 | err("rc usb alloc urb failed"); | 773 | err("rc usb alloc urb failed"); |
| @@ -779,9 +782,35 @@ int dib0700_rc_setup(struct dvb_usb_device *d) | |||
| 779 | } | 782 | } |
| 780 | 783 | ||
| 781 | purb->status = -EINPROGRESS; | 784 | purb->status = -EINPROGRESS; |
| 782 | usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1), | 785 | |
| 783 | purb->transfer_buffer, RC_MSG_SIZE_V1_20, | 786 | /* |
| 784 | dib0700_rc_urb_completion, d); | 787 | * Some devices like the Hauppauge NovaTD model 52009 use an interrupt |
| 788 | * endpoint, while others use a bulk one. | ||
| 789 | */ | ||
| 790 | e = &intf->altsetting[0].endpoint[rc_ep].desc; | ||
| 791 | if (usb_endpoint_dir_in(e)) { | ||
| 792 | if (usb_endpoint_xfer_bulk(e)) { | ||
| 793 | pipe = usb_rcvbulkpipe(d->udev, rc_ep); | ||
| 794 | usb_fill_bulk_urb(purb, d->udev, pipe, | ||
| 795 | purb->transfer_buffer, | ||
| 796 | RC_MSG_SIZE_V1_20, | ||
| 797 | dib0700_rc_urb_completion, d); | ||
| 798 | |||
| 799 | } else if (usb_endpoint_xfer_int(e)) { | ||
| 800 | pipe = usb_rcvintpipe(d->udev, rc_ep); | ||
| 801 | usb_fill_int_urb(purb, d->udev, pipe, | ||
| 802 | purb->transfer_buffer, | ||
| 803 | RC_MSG_SIZE_V1_20, | ||
| 804 | dib0700_rc_urb_completion, d, 1); | ||
| 805 | } | ||
| 806 | } | ||
| 807 | |||
| 808 | if (!pipe) { | ||
| 809 | err("There's no endpoint for remote controller"); | ||
| 810 | kfree(purb->transfer_buffer); | ||
| 811 | usb_free_urb(purb); | ||
| 812 | return 0; | ||
| 813 | } | ||
| 785 | 814 | ||
| 786 | ret = usb_submit_urb(purb, GFP_ATOMIC); | 815 | ret = usb_submit_urb(purb, GFP_ATOMIC); |
| 787 | if (ret) { | 816 | if (ret) { |
| @@ -820,7 +849,7 @@ static int dib0700_probe(struct usb_interface *intf, | |||
| 820 | else | 849 | else |
| 821 | dev->props.rc.core.bulk_mode = false; | 850 | dev->props.rc.core.bulk_mode = false; |
| 822 | 851 | ||
| 823 | dib0700_rc_setup(dev); | 852 | dib0700_rc_setup(dev, intf); |
| 824 | 853 | ||
| 825 | return 0; | 854 | return 0; |
| 826 | } | 855 | } |
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 829323e42ca0..10e0db8d1850 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c | |||
| @@ -514,7 +514,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) | |||
| 514 | 514 | ||
| 515 | /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ | 515 | /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ |
| 516 | 516 | ||
| 517 | dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ | 517 | dib0700_rc_setup(d, NULL); /* reset ir sensor data to prevent false events */ |
| 518 | 518 | ||
| 519 | d->last_event = 0; | 519 | d->last_event = 0; |
| 520 | switch (d->props.rc.core.protocol) { | 520 | switch (d->props.rc.core.protocol) { |
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index 98d24aefb640..d947e0379008 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c | |||
| @@ -214,10 +214,10 @@ static void technisat_usb2_frontend_reset(struct usb_device *udev) | |||
| 214 | 214 | ||
| 215 | /* LED control */ | 215 | /* LED control */ |
| 216 | enum technisat_usb2_led_state { | 216 | enum technisat_usb2_led_state { |
| 217 | LED_OFF, | 217 | TECH_LED_OFF, |
| 218 | LED_BLINK, | 218 | TECH_LED_BLINK, |
| 219 | LED_ON, | 219 | TECH_LED_ON, |
| 220 | LED_UNDEFINED | 220 | TECH_LED_UNDEFINED |
| 221 | }; | 221 | }; |
| 222 | 222 | ||
| 223 | static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state) | 223 | static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state) |
| @@ -229,14 +229,14 @@ static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum techni | |||
| 229 | 0 | 229 | 0 |
| 230 | }; | 230 | }; |
| 231 | 231 | ||
| 232 | if (disable_led_control && state != LED_OFF) | 232 | if (disable_led_control && state != TECH_LED_OFF) |
| 233 | return 0; | 233 | return 0; |
| 234 | 234 | ||
| 235 | switch (state) { | 235 | switch (state) { |
| 236 | case LED_ON: | 236 | case TECH_LED_ON: |
| 237 | led[1] = 0x82; | 237 | led[1] = 0x82; |
| 238 | break; | 238 | break; |
| 239 | case LED_BLINK: | 239 | case TECH_LED_BLINK: |
| 240 | led[1] = 0x82; | 240 | led[1] = 0x82; |
| 241 | if (red) { | 241 | if (red) { |
| 242 | led[2] = 0x02; | 242 | led[2] = 0x02; |
| @@ -251,7 +251,7 @@ static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum techni | |||
| 251 | break; | 251 | break; |
| 252 | 252 | ||
| 253 | default: | 253 | default: |
| 254 | case LED_OFF: | 254 | case TECH_LED_OFF: |
| 255 | led[1] = 0x80; | 255 | led[1] = 0x80; |
| 256 | break; | 256 | break; |
| 257 | } | 257 | } |
| @@ -310,11 +310,11 @@ static void technisat_usb2_green_led_control(struct work_struct *work) | |||
| 310 | goto schedule; | 310 | goto schedule; |
| 311 | 311 | ||
| 312 | if (ber > 1000) | 312 | if (ber > 1000) |
| 313 | technisat_usb2_set_led(state->dev, 0, LED_BLINK); | 313 | technisat_usb2_set_led(state->dev, 0, TECH_LED_BLINK); |
| 314 | else | 314 | else |
| 315 | technisat_usb2_set_led(state->dev, 0, LED_ON); | 315 | technisat_usb2_set_led(state->dev, 0, TECH_LED_ON); |
| 316 | } else | 316 | } else |
| 317 | technisat_usb2_set_led(state->dev, 0, LED_OFF); | 317 | technisat_usb2_set_led(state->dev, 0, TECH_LED_OFF); |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | schedule: | 320 | schedule: |
| @@ -365,9 +365,9 @@ static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level) | |||
| 365 | return 0; | 365 | return 0; |
| 366 | 366 | ||
| 367 | /* green led is turned off in any case - will be turned on when tuning */ | 367 | /* green led is turned off in any case - will be turned on when tuning */ |
| 368 | technisat_usb2_set_led(d, 0, LED_OFF); | 368 | technisat_usb2_set_led(d, 0, TECH_LED_OFF); |
| 369 | /* red led is turned on all the time */ | 369 | /* red led is turned on all the time */ |
| 370 | technisat_usb2_set_led(d, 1, LED_ON); | 370 | technisat_usb2_set_led(d, 1, TECH_LED_ON); |
| 371 | return 0; | 371 | return 0; |
| 372 | } | 372 | } |
| 373 | 373 | ||
| @@ -667,7 +667,7 @@ static int technisat_usb2_rc_query(struct dvb_usb_device *d) | |||
| 667 | return 0; | 667 | return 0; |
| 668 | 668 | ||
| 669 | if (!disable_led_control) | 669 | if (!disable_led_control) |
| 670 | technisat_usb2_set_led(d, 1, LED_BLINK); | 670 | technisat_usb2_set_led(d, 1, TECH_LED_BLINK); |
| 671 | 671 | ||
| 672 | return 0; | 672 | return 0; |
| 673 | } | 673 | } |
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index d23a912096f7..f5d7198753c7 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig | |||
| @@ -57,6 +57,8 @@ config VIDEO_EM28XX_DVB | |||
| 57 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT | 57 | select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT |
| 58 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT | 58 | select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT |
| 59 | select DVB_DRX39XYJ if MEDIA_SUBDRV_AUTOSELECT | 59 | select DVB_DRX39XYJ if MEDIA_SUBDRV_AUTOSELECT |
| 60 | select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT | ||
| 61 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | ||
| 60 | ---help--- | 62 | ---help--- |
| 61 | This adds support for DVB cards based on the | 63 | This adds support for DVB cards based on the |
| 62 | Empiatech em28xx chips. | 64 | Empiatech em28xx chips. |
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 342490f44ed2..e881ef7b6445 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c | |||
| @@ -92,7 +92,7 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 92 | 92 | ||
| 93 | if (dev->disconnected) { | 93 | if (dev->disconnected) { |
| 94 | dprintk("device disconnected while streaming. URB status=%d.\n", urb->status); | 94 | dprintk("device disconnected while streaming. URB status=%d.\n", urb->status); |
| 95 | atomic_set(&dev->stream_started, 0); | 95 | atomic_set(&dev->adev.stream_started, 0); |
| 96 | return; | 96 | return; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| @@ -109,7 +109,7 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
| 109 | break; | 109 | break; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | if (atomic_read(&dev->stream_started) == 0) | 112 | if (atomic_read(&dev->adev.stream_started) == 0) |
| 113 | return; | 113 | return; |
| 114 | 114 | ||
| 115 | if (dev->adev.capture_pcm_substream) { | 115 | if (dev->adev.capture_pcm_substream) { |
| @@ -185,7 +185,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
| 185 | em28xx_errdev("submit of audio urb failed (error=%i)\n", | 185 | em28xx_errdev("submit of audio urb failed (error=%i)\n", |
| 186 | errCode); | 186 | errCode); |
| 187 | em28xx_deinit_isoc_audio(dev); | 187 | em28xx_deinit_isoc_audio(dev); |
| 188 | atomic_set(&dev->stream_started, 0); | 188 | atomic_set(&dev->adev.stream_started, 0); |
| 189 | return errCode; | 189 | return errCode; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| @@ -332,9 +332,9 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | |||
| 332 | dev->mute = 1; | 332 | dev->mute = 1; |
| 333 | mutex_lock(&dev->lock); | 333 | mutex_lock(&dev->lock); |
| 334 | dev->adev.users--; | 334 | dev->adev.users--; |
| 335 | if (atomic_read(&dev->stream_started) > 0) { | 335 | if (atomic_read(&dev->adev.stream_started) > 0) { |
| 336 | atomic_set(&dev->stream_started, 0); | 336 | atomic_set(&dev->adev.stream_started, 0); |
| 337 | schedule_work(&dev->wq_trigger); | 337 | schedule_work(&dev->adev.wq_trigger); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | em28xx_audio_analog_set(dev); | 340 | em28xx_audio_analog_set(dev); |
| @@ -381,12 +381,13 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, | |||
| 381 | static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) | 381 | static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) |
| 382 | { | 382 | { |
| 383 | struct em28xx *dev = snd_pcm_substream_chip(substream); | 383 | struct em28xx *dev = snd_pcm_substream_chip(substream); |
| 384 | struct em28xx_audio *adev = &dev->adev; | ||
| 384 | 385 | ||
| 385 | dprintk("Stop capture, if needed\n"); | 386 | dprintk("Stop capture, if needed\n"); |
| 386 | 387 | ||
| 387 | if (atomic_read(&dev->stream_started) > 0) { | 388 | if (atomic_read(&adev->stream_started) > 0) { |
| 388 | atomic_set(&dev->stream_started, 0); | 389 | atomic_set(&adev->stream_started, 0); |
| 389 | schedule_work(&dev->wq_trigger); | 390 | schedule_work(&adev->wq_trigger); |
| 390 | } | 391 | } |
| 391 | 392 | ||
| 392 | return 0; | 393 | return 0; |
| @@ -407,9 +408,11 @@ static int snd_em28xx_prepare(struct snd_pcm_substream *substream) | |||
| 407 | 408 | ||
| 408 | static void audio_trigger(struct work_struct *work) | 409 | static void audio_trigger(struct work_struct *work) |
| 409 | { | 410 | { |
| 410 | struct em28xx *dev = container_of(work, struct em28xx, wq_trigger); | 411 | struct em28xx_audio *adev = |
| 412 | container_of(work, struct em28xx_audio, wq_trigger); | ||
| 413 | struct em28xx *dev = container_of(adev, struct em28xx, adev); | ||
| 411 | 414 | ||
| 412 | if (atomic_read(&dev->stream_started)) { | 415 | if (atomic_read(&adev->stream_started)) { |
| 413 | dprintk("starting capture"); | 416 | dprintk("starting capture"); |
| 414 | em28xx_init_audio_isoc(dev); | 417 | em28xx_init_audio_isoc(dev); |
| 415 | } else { | 418 | } else { |
| @@ -431,17 +434,17 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, | |||
| 431 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | 434 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ |
| 432 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | 435 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ |
| 433 | case SNDRV_PCM_TRIGGER_START: | 436 | case SNDRV_PCM_TRIGGER_START: |
| 434 | atomic_set(&dev->stream_started, 1); | 437 | atomic_set(&dev->adev.stream_started, 1); |
| 435 | break; | 438 | break; |
| 436 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | 439 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ |
| 437 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | 440 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ |
| 438 | case SNDRV_PCM_TRIGGER_STOP: | 441 | case SNDRV_PCM_TRIGGER_STOP: |
| 439 | atomic_set(&dev->stream_started, 0); | 442 | atomic_set(&dev->adev.stream_started, 0); |
| 440 | break; | 443 | break; |
| 441 | default: | 444 | default: |
| 442 | retval = -EINVAL; | 445 | retval = -EINVAL; |
| 443 | } | 446 | } |
| 444 | schedule_work(&dev->wq_trigger); | 447 | schedule_work(&dev->adev.wq_trigger); |
| 445 | return retval; | 448 | return retval; |
| 446 | } | 449 | } |
| 447 | 450 | ||
| @@ -928,7 +931,7 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
| 928 | strcpy(card->shortname, "Em28xx Audio"); | 931 | strcpy(card->shortname, "Em28xx Audio"); |
| 929 | strcpy(card->longname, "Empia Em28xx Audio"); | 932 | strcpy(card->longname, "Empia Em28xx Audio"); |
| 930 | 933 | ||
| 931 | INIT_WORK(&dev->wq_trigger, audio_trigger); | 934 | INIT_WORK(&adev->wq_trigger, audio_trigger); |
| 932 | 935 | ||
| 933 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | 936 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
| 934 | em28xx_cvol_new(card, dev, "Video", AC97_VIDEO); | 937 | em28xx_cvol_new(card, dev, "Video", AC97_VIDEO); |
| @@ -983,7 +986,7 @@ static int em28xx_audio_fini(struct em28xx *dev) | |||
| 983 | 986 | ||
| 984 | if (dev->adev.sndcard) { | 987 | if (dev->adev.sndcard) { |
| 985 | snd_card_disconnect(dev->adev.sndcard); | 988 | snd_card_disconnect(dev->adev.sndcard); |
| 986 | flush_work(&dev->wq_trigger); | 989 | flush_work(&dev->adev.wq_trigger); |
| 987 | 990 | ||
| 988 | em28xx_audio_free_urb(dev); | 991 | em28xx_audio_free_urb(dev); |
| 989 | 992 | ||
| @@ -1005,7 +1008,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) | |||
| 1005 | 1008 | ||
| 1006 | em28xx_info("Suspending audio extension"); | 1009 | em28xx_info("Suspending audio extension"); |
| 1007 | em28xx_deinit_isoc_audio(dev); | 1010 | em28xx_deinit_isoc_audio(dev); |
| 1008 | atomic_set(&dev->stream_started, 0); | 1011 | atomic_set(&dev->adev.stream_started, 0); |
| 1009 | return 0; | 1012 | return 0; |
| 1010 | } | 1013 | } |
| 1011 | 1014 | ||
| @@ -1019,7 +1022,7 @@ static int em28xx_audio_resume(struct em28xx *dev) | |||
| 1019 | 1022 | ||
| 1020 | em28xx_info("Resuming audio extension"); | 1023 | em28xx_info("Resuming audio extension"); |
| 1021 | /* Nothing to do other than schedule_work() ?? */ | 1024 | /* Nothing to do other than schedule_work() ?? */ |
| 1022 | schedule_work(&dev->wq_trigger); | 1025 | schedule_work(&dev->adev.wq_trigger); |
| 1023 | return 0; | 1026 | return 0; |
| 1024 | } | 1027 | } |
| 1025 | 1028 | ||
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 505e0505be04..12d4c0326e31 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c | |||
| @@ -330,13 +330,14 @@ int em28xx_init_camera(struct em28xx *dev) | |||
| 330 | char clk_name[V4L2_SUBDEV_NAME_SIZE]; | 330 | char clk_name[V4L2_SUBDEV_NAME_SIZE]; |
| 331 | struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; | 331 | struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; |
| 332 | struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus]; | 332 | struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus]; |
| 333 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 333 | int ret = 0; | 334 | int ret = 0; |
| 334 | 335 | ||
| 335 | v4l2_clk_name_i2c(clk_name, sizeof(clk_name), | 336 | v4l2_clk_name_i2c(clk_name, sizeof(clk_name), |
| 336 | i2c_adapter_id(adap), client->addr); | 337 | i2c_adapter_id(adap), client->addr); |
| 337 | dev->clk = v4l2_clk_register_fixed(clk_name, "mclk", -EINVAL); | 338 | v4l2->clk = v4l2_clk_register_fixed(clk_name, "mclk", -EINVAL); |
| 338 | if (IS_ERR(dev->clk)) | 339 | if (IS_ERR(v4l2->clk)) |
| 339 | return PTR_ERR(dev->clk); | 340 | return PTR_ERR(v4l2->clk); |
| 340 | 341 | ||
| 341 | switch (dev->em28xx_sensor) { | 342 | switch (dev->em28xx_sensor) { |
| 342 | case EM28XX_MT9V011: | 343 | case EM28XX_MT9V011: |
| @@ -348,8 +349,8 @@ int em28xx_init_camera(struct em28xx *dev) | |||
| 348 | .platform_data = &pdata, | 349 | .platform_data = &pdata, |
| 349 | }; | 350 | }; |
| 350 | 351 | ||
| 351 | dev->sensor_xres = 640; | 352 | v4l2->sensor_xres = 640; |
| 352 | dev->sensor_yres = 480; | 353 | v4l2->sensor_yres = 480; |
| 353 | 354 | ||
| 354 | /* | 355 | /* |
| 355 | * FIXME: mt9v011 uses I2S speed as xtal clk - at least with | 356 | * FIXME: mt9v011 uses I2S speed as xtal clk - at least with |
| @@ -362,41 +363,41 @@ int em28xx_init_camera(struct em28xx *dev) | |||
| 362 | */ | 363 | */ |
| 363 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; | 364 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; |
| 364 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); | 365 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); |
| 365 | dev->sensor_xtal = 4300000; | 366 | v4l2->sensor_xtal = 4300000; |
| 366 | pdata.xtal = dev->sensor_xtal; | 367 | pdata.xtal = v4l2->sensor_xtal; |
| 367 | if (NULL == | 368 | if (NULL == |
| 368 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, adap, | 369 | v4l2_i2c_new_subdev_board(&dev->v4l2->v4l2_dev, adap, |
| 369 | &mt9v011_info, NULL)) { | 370 | &mt9v011_info, NULL)) { |
| 370 | ret = -ENODEV; | 371 | ret = -ENODEV; |
| 371 | break; | 372 | break; |
| 372 | } | 373 | } |
| 373 | /* probably means GRGB 16 bit bayer */ | 374 | /* probably means GRGB 16 bit bayer */ |
| 374 | dev->vinmode = 0x0d; | 375 | v4l2->vinmode = 0x0d; |
| 375 | dev->vinctl = 0x00; | 376 | v4l2->vinctl = 0x00; |
| 376 | 377 | ||
| 377 | break; | 378 | break; |
| 378 | } | 379 | } |
| 379 | case EM28XX_MT9M001: | 380 | case EM28XX_MT9M001: |
| 380 | dev->sensor_xres = 1280; | 381 | v4l2->sensor_xres = 1280; |
| 381 | dev->sensor_yres = 1024; | 382 | v4l2->sensor_yres = 1024; |
| 382 | 383 | ||
| 383 | em28xx_initialize_mt9m001(dev); | 384 | em28xx_initialize_mt9m001(dev); |
| 384 | 385 | ||
| 385 | /* probably means BGGR 16 bit bayer */ | 386 | /* probably means BGGR 16 bit bayer */ |
| 386 | dev->vinmode = 0x0c; | 387 | v4l2->vinmode = 0x0c; |
| 387 | dev->vinctl = 0x00; | 388 | v4l2->vinctl = 0x00; |
| 388 | 389 | ||
| 389 | break; | 390 | break; |
| 390 | case EM28XX_MT9M111: | 391 | case EM28XX_MT9M111: |
| 391 | dev->sensor_xres = 640; | 392 | v4l2->sensor_xres = 640; |
| 392 | dev->sensor_yres = 512; | 393 | v4l2->sensor_yres = 512; |
| 393 | 394 | ||
| 394 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; | 395 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; |
| 395 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); | 396 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); |
| 396 | em28xx_initialize_mt9m111(dev); | 397 | em28xx_initialize_mt9m111(dev); |
| 397 | 398 | ||
| 398 | dev->vinmode = 0x0a; | 399 | v4l2->vinmode = 0x0a; |
| 399 | dev->vinctl = 0x00; | 400 | v4l2->vinctl = 0x00; |
| 400 | 401 | ||
| 401 | break; | 402 | break; |
| 402 | case EM28XX_OV2640: | 403 | case EM28XX_OV2640: |
| @@ -418,11 +419,11 @@ int em28xx_init_camera(struct em28xx *dev) | |||
| 418 | * - adjust bridge xclk | 419 | * - adjust bridge xclk |
| 419 | * - disable 16 bit (12 bit) output formats on high resolutions | 420 | * - disable 16 bit (12 bit) output formats on high resolutions |
| 420 | */ | 421 | */ |
| 421 | dev->sensor_xres = 640; | 422 | v4l2->sensor_xres = 640; |
| 422 | dev->sensor_yres = 480; | 423 | v4l2->sensor_yres = 480; |
| 423 | 424 | ||
| 424 | subdev = | 425 | subdev = |
| 425 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, adap, | 426 | v4l2_i2c_new_subdev_board(&dev->v4l2->v4l2_dev, adap, |
| 426 | &ov2640_info, NULL); | 427 | &ov2640_info, NULL); |
| 427 | if (NULL == subdev) { | 428 | if (NULL == subdev) { |
| 428 | ret = -ENODEV; | 429 | ret = -ENODEV; |
| @@ -437,8 +438,8 @@ int em28xx_init_camera(struct em28xx *dev) | |||
| 437 | /* NOTE: for UXGA=1600x1200 switch to 12MHz */ | 438 | /* NOTE: for UXGA=1600x1200 switch to 12MHz */ |
| 438 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; | 439 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; |
| 439 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); | 440 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); |
| 440 | dev->vinmode = 0x08; | 441 | v4l2->vinmode = 0x08; |
| 441 | dev->vinctl = 0x00; | 442 | v4l2->vinctl = 0x00; |
| 442 | 443 | ||
| 443 | break; | 444 | break; |
| 444 | } | 445 | } |
| @@ -448,8 +449,8 @@ int em28xx_init_camera(struct em28xx *dev) | |||
| 448 | } | 449 | } |
| 449 | 450 | ||
| 450 | if (ret < 0) { | 451 | if (ret < 0) { |
| 451 | v4l2_clk_unregister_fixed(dev->clk); | 452 | v4l2_clk_unregister_fixed(v4l2->clk); |
| 452 | dev->clk = NULL; | 453 | v4l2->clk = NULL; |
| 453 | } | 454 | } |
| 454 | 455 | ||
| 455 | return ret; | 456 | return ret; |
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 50aa5a5317f2..15ad47045553 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
| @@ -467,6 +467,18 @@ static struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = { | |||
| 467 | { -1, -1, -1, -1}, | 467 | { -1, -1, -1, -1}, |
| 468 | }; | 468 | }; |
| 469 | 469 | ||
| 470 | static struct em28xx_reg_seq pctv_292e[] = { | ||
| 471 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, | ||
| 472 | {0x0d, 0xff, 0xff, 950}, | ||
| 473 | {EM2874_R80_GPIO_P0_CTRL, 0xbd, 0xff, 100}, | ||
| 474 | {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 410}, | ||
| 475 | {EM2874_R80_GPIO_P0_CTRL, 0x7d, 0xff, 300}, | ||
| 476 | {EM2874_R80_GPIO_P0_CTRL, 0x7c, 0xff, 60}, | ||
| 477 | {0x0d, 0x42, 0xff, 50}, | ||
| 478 | {EM2874_R5F_TS_ENABLE, 0x85, 0xff, 0}, | ||
| 479 | {-1, -1, -1, -1}, | ||
| 480 | }; | ||
| 481 | |||
| 470 | /* | 482 | /* |
| 471 | * Button definitions | 483 | * Button definitions |
| 472 | */ | 484 | */ |
| @@ -2220,6 +2232,17 @@ struct em28xx_board em28xx_boards[] = { | |||
| 2220 | .has_dvb = 1, | 2232 | .has_dvb = 1, |
| 2221 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | 2233 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, |
| 2222 | }, | 2234 | }, |
| 2235 | /* 2013:025f PCTV tripleStick (292e). | ||
| 2236 | * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157 */ | ||
| 2237 | [EM28178_BOARD_PCTV_292E] = { | ||
| 2238 | .name = "PCTV tripleStick (292e)", | ||
| 2239 | .def_i2c_bus = 1, | ||
| 2240 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | ||
| 2241 | .tuner_type = TUNER_ABSENT, | ||
| 2242 | .tuner_gpio = pctv_292e, | ||
| 2243 | .has_dvb = 1, | ||
| 2244 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
| 2245 | }, | ||
| 2223 | }; | 2246 | }; |
| 2224 | EXPORT_SYMBOL_GPL(em28xx_boards); | 2247 | EXPORT_SYMBOL_GPL(em28xx_boards); |
| 2225 | 2248 | ||
| @@ -2397,6 +2420,8 @@ struct usb_device_id em28xx_id_table[] = { | |||
| 2397 | .driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE }, | 2420 | .driver_info = EM2765_BOARD_SPEEDLINK_VAD_LAPLACE }, |
| 2398 | { USB_DEVICE(0x2013, 0x0258), | 2421 | { USB_DEVICE(0x2013, 0x0258), |
| 2399 | .driver_info = EM28178_BOARD_PCTV_461E }, | 2422 | .driver_info = EM28178_BOARD_PCTV_461E }, |
| 2423 | { USB_DEVICE(0x2013, 0x025f), | ||
| 2424 | .driver_info = EM28178_BOARD_PCTV_292E }, | ||
| 2400 | { }, | 2425 | { }, |
| 2401 | }; | 2426 | }; |
| 2402 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 2427 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); |
| @@ -2682,8 +2707,6 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
| 2682 | if (dev->board.is_webcam) { | 2707 | if (dev->board.is_webcam) { |
| 2683 | if (em28xx_detect_sensor(dev) < 0) | 2708 | if (em28xx_detect_sensor(dev) < 0) |
| 2684 | dev->board.is_webcam = 0; | 2709 | dev->board.is_webcam = 0; |
| 2685 | else | ||
| 2686 | dev->progressive = 1; | ||
| 2687 | } | 2710 | } |
| 2688 | 2711 | ||
| 2689 | switch (dev->model) { | 2712 | switch (dev->model) { |
| @@ -2718,11 +2741,6 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
| 2718 | dev->board.name, dev->model); | 2741 | dev->board.name, dev->model); |
| 2719 | 2742 | ||
| 2720 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; | 2743 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; |
| 2721 | if (em28xx_boards[dev->model].tuner_addr) | ||
| 2722 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; | ||
| 2723 | |||
| 2724 | if (em28xx_boards[dev->model].tda9887_conf) | ||
| 2725 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
| 2726 | 2744 | ||
| 2727 | /* request some modules */ | 2745 | /* request some modules */ |
| 2728 | switch (dev->model) { | 2746 | switch (dev->model) { |
| @@ -2991,8 +3009,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | |||
| 2991 | const char *chip_name = default_chip_name; | 3009 | const char *chip_name = default_chip_name; |
| 2992 | 3010 | ||
| 2993 | dev->udev = udev; | 3011 | dev->udev = udev; |
| 2994 | mutex_init(&dev->vb_queue_lock); | ||
| 2995 | mutex_init(&dev->vb_vbi_queue_lock); | ||
| 2996 | mutex_init(&dev->ctrl_urb_lock); | 3012 | mutex_init(&dev->ctrl_urb_lock); |
| 2997 | spin_lock_init(&dev->slock); | 3013 | spin_lock_init(&dev->slock); |
| 2998 | 3014 | ||
| @@ -3416,15 +3432,14 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
| 3416 | 3432 | ||
| 3417 | /* Select USB transfer types to use */ | 3433 | /* Select USB transfer types to use */ |
| 3418 | if (has_video) { | 3434 | if (has_video) { |
| 3419 | if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) | 3435 | if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) |
| 3420 | dev->analog_xfer_bulk = 1; | 3436 | dev->analog_xfer_bulk = 1; |
| 3421 | em28xx_info("analog set to %s mode.\n", | 3437 | em28xx_info("analog set to %s mode.\n", |
| 3422 | dev->analog_xfer_bulk ? "bulk" : "isoc"); | 3438 | dev->analog_xfer_bulk ? "bulk" : "isoc"); |
| 3423 | } | 3439 | } |
| 3424 | if (has_dvb) { | 3440 | if (has_dvb) { |
| 3425 | if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) | 3441 | if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) |
| 3426 | dev->dvb_xfer_bulk = 1; | 3442 | dev->dvb_xfer_bulk = 1; |
| 3427 | |||
| 3428 | em28xx_info("dvb set to %s mode.\n", | 3443 | em28xx_info("dvb set to %s mode.\n", |
| 3429 | dev->dvb_xfer_bulk ? "bulk" : "isoc"); | 3444 | dev->dvb_xfer_bulk ? "bulk" : "isoc"); |
| 3430 | } | 3445 | } |
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index f599b18ef7ca..a121ed9561fd 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
| @@ -55,6 +55,8 @@ | |||
| 55 | #include "mb86a20s.h" | 55 | #include "mb86a20s.h" |
| 56 | #include "m88ds3103.h" | 56 | #include "m88ds3103.h" |
| 57 | #include "m88ts2022.h" | 57 | #include "m88ts2022.h" |
| 58 | #include "si2168.h" | ||
| 59 | #include "si2157.h" | ||
| 58 | 60 | ||
| 59 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 61 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
| 60 | MODULE_LICENSE("GPL"); | 62 | MODULE_LICENSE("GPL"); |
| @@ -93,6 +95,7 @@ struct em28xx_dvb { | |||
| 93 | struct semaphore pll_mutex; | 95 | struct semaphore pll_mutex; |
| 94 | bool dont_attach_fe1; | 96 | bool dont_attach_fe1; |
| 95 | int lna_gpio; | 97 | int lna_gpio; |
| 98 | struct i2c_client *i2c_client_demod; | ||
| 96 | struct i2c_client *i2c_client_tuner; | 99 | struct i2c_client *i2c_client_tuner; |
| 97 | }; | 100 | }; |
| 98 | 101 | ||
| @@ -743,6 +746,21 @@ static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) | |||
| 743 | #endif | 746 | #endif |
| 744 | } | 747 | } |
| 745 | 748 | ||
| 749 | static int em28xx_pctv_292e_set_lna(struct dvb_frontend *fe) | ||
| 750 | { | ||
| 751 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
| 752 | struct em28xx_i2c_bus *i2c_bus = fe->dvb->priv; | ||
| 753 | struct em28xx *dev = i2c_bus->dev; | ||
| 754 | u8 lna; | ||
| 755 | |||
| 756 | if (c->lna == 1) | ||
| 757 | lna = 0x01; | ||
| 758 | else | ||
| 759 | lna = 0x00; | ||
| 760 | |||
| 761 | return em28xx_write_reg_bits(dev, EM2874_R80_GPIO_P0_CTRL, lna, 0x01); | ||
| 762 | } | ||
| 763 | |||
| 746 | static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) | 764 | static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) |
| 747 | { | 765 | { |
| 748 | /* Values extracted from a USB trace of the Terratec Windows driver */ | 766 | /* Values extracted from a USB trace of the Terratec Windows driver */ |
| @@ -1496,6 +1514,63 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
| 1496 | dvb->i2c_client_tuner = client; | 1514 | dvb->i2c_client_tuner = client; |
| 1497 | } | 1515 | } |
| 1498 | break; | 1516 | break; |
| 1517 | case EM28178_BOARD_PCTV_292E: | ||
| 1518 | { | ||
| 1519 | struct i2c_adapter *adapter; | ||
| 1520 | struct i2c_client *client; | ||
| 1521 | struct i2c_board_info info; | ||
| 1522 | struct si2168_config si2168_config; | ||
| 1523 | struct si2157_config si2157_config; | ||
| 1524 | |||
| 1525 | /* attach demod */ | ||
| 1526 | si2168_config.i2c_adapter = &adapter; | ||
| 1527 | si2168_config.fe = &dvb->fe[0]; | ||
| 1528 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 1529 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | ||
| 1530 | info.addr = 0x64; | ||
| 1531 | info.platform_data = &si2168_config; | ||
| 1532 | request_module(info.type); | ||
| 1533 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); | ||
| 1534 | if (client == NULL || client->dev.driver == NULL) { | ||
| 1535 | result = -ENODEV; | ||
| 1536 | goto out_free; | ||
| 1537 | } | ||
| 1538 | |||
| 1539 | if (!try_module_get(client->dev.driver->owner)) { | ||
| 1540 | i2c_unregister_device(client); | ||
| 1541 | result = -ENODEV; | ||
| 1542 | goto out_free; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | dvb->i2c_client_demod = client; | ||
| 1546 | |||
| 1547 | /* attach tuner */ | ||
| 1548 | si2157_config.fe = dvb->fe[0]; | ||
| 1549 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 1550 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
| 1551 | info.addr = 0x60; | ||
| 1552 | info.platform_data = &si2157_config; | ||
| 1553 | request_module(info.type); | ||
| 1554 | client = i2c_new_device(adapter, &info); | ||
| 1555 | if (client == NULL || client->dev.driver == NULL) { | ||
| 1556 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
| 1557 | i2c_unregister_device(dvb->i2c_client_demod); | ||
| 1558 | result = -ENODEV; | ||
| 1559 | goto out_free; | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | if (!try_module_get(client->dev.driver->owner)) { | ||
| 1563 | i2c_unregister_device(client); | ||
| 1564 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
| 1565 | i2c_unregister_device(dvb->i2c_client_demod); | ||
| 1566 | result = -ENODEV; | ||
| 1567 | goto out_free; | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | dvb->i2c_client_tuner = client; | ||
| 1571 | dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; | ||
| 1572 | } | ||
| 1573 | break; | ||
| 1499 | default: | 1574 | default: |
| 1500 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" | 1575 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" |
| 1501 | " isn't supported yet\n"); | 1576 | " isn't supported yet\n"); |
| @@ -1582,6 +1657,13 @@ static int em28xx_dvb_fini(struct em28xx *dev) | |||
| 1582 | i2c_unregister_device(client); | 1657 | i2c_unregister_device(client); |
| 1583 | } | 1658 | } |
| 1584 | 1659 | ||
| 1660 | /* remove I2C demod */ | ||
| 1661 | client = dvb->i2c_client_demod; | ||
| 1662 | if (client) { | ||
| 1663 | module_put(client->dev.driver->owner); | ||
| 1664 | i2c_unregister_device(client); | ||
| 1665 | } | ||
| 1666 | |||
| 1585 | em28xx_unregister_dvb(dvb); | 1667 | em28xx_unregister_dvb(dvb); |
| 1586 | kfree(dvb); | 1668 | kfree(dvb); |
| 1587 | dev->dvb = NULL; | 1669 | dev->dvb = NULL; |
| @@ -1647,6 +1729,13 @@ static int em28xx_dvb_resume(struct em28xx *dev) | |||
| 1647 | i2c_unregister_device(client); | 1729 | i2c_unregister_device(client); |
| 1648 | } | 1730 | } |
| 1649 | 1731 | ||
| 1732 | /* remove I2C demod */ | ||
| 1733 | client = dvb->i2c_client_demod; | ||
| 1734 | if (client) { | ||
| 1735 | module_put(client->dev.driver->owner); | ||
| 1736 | i2c_unregister_device(client); | ||
| 1737 | } | ||
| 1738 | |||
| 1650 | em28xx_unregister_dvb(dvb); | 1739 | em28xx_unregister_dvb(dvb); |
| 1651 | kfree(dvb); | 1740 | kfree(dvb); |
| 1652 | dev->dvb = NULL; | 1741 | dev->dvb = NULL; |
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index ba6433c3a643..b58d4ebf6419 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c | |||
| @@ -939,7 +939,6 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, | |||
| 939 | dev->i2c_bus[bus].algo_type = algo_type; | 939 | dev->i2c_bus[bus].algo_type = algo_type; |
| 940 | dev->i2c_bus[bus].dev = dev; | 940 | dev->i2c_bus[bus].dev = dev; |
| 941 | dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; | 941 | dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; |
| 942 | i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev); | ||
| 943 | 942 | ||
| 944 | retval = i2c_add_adapter(&dev->i2c_adap[bus]); | 943 | retval = i2c_add_adapter(&dev->i2c_adap[bus]); |
| 945 | if (retval < 0) { | 944 | if (retval < 0) { |
diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h index bce438691e0e..432862c20bbf 100644 --- a/drivers/media/usb/em28xx/em28xx-v4l.h +++ b/drivers/media/usb/em28xx/em28xx-v4l.h | |||
| @@ -16,5 +16,5 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); | 18 | int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); |
| 19 | int em28xx_stop_vbi_streaming(struct vb2_queue *vq); | 19 | void em28xx_stop_vbi_streaming(struct vb2_queue *vq); |
| 20 | extern struct vb2_ops em28xx_vbi_qops; | 20 | extern struct vb2_ops em28xx_vbi_qops; |
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index db3d655600df..6d7f657f6f55 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c | |||
| @@ -47,12 +47,13 @@ static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
| 47 | unsigned int sizes[], void *alloc_ctxs[]) | 47 | unsigned int sizes[], void *alloc_ctxs[]) |
| 48 | { | 48 | { |
| 49 | struct em28xx *dev = vb2_get_drv_priv(vq); | 49 | struct em28xx *dev = vb2_get_drv_priv(vq); |
| 50 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 50 | unsigned long size; | 51 | unsigned long size; |
| 51 | 52 | ||
| 52 | if (fmt) | 53 | if (fmt) |
| 53 | size = fmt->fmt.pix.sizeimage; | 54 | size = fmt->fmt.pix.sizeimage; |
| 54 | else | 55 | else |
| 55 | size = dev->vbi_width * dev->vbi_height * 2; | 56 | size = v4l2->vbi_width * v4l2->vbi_height * 2; |
| 56 | 57 | ||
| 57 | if (0 == *nbuffers) | 58 | if (0 == *nbuffers) |
| 58 | *nbuffers = 32; | 59 | *nbuffers = 32; |
| @@ -69,11 +70,12 @@ static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
| 69 | 70 | ||
| 70 | static int vbi_buffer_prepare(struct vb2_buffer *vb) | 71 | static int vbi_buffer_prepare(struct vb2_buffer *vb) |
| 71 | { | 72 | { |
| 72 | struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue); | 73 | struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue); |
| 73 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | 74 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
| 75 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
| 74 | unsigned long size; | 76 | unsigned long size; |
| 75 | 77 | ||
| 76 | size = dev->vbi_width * dev->vbi_height * 2; | 78 | size = v4l2->vbi_width * v4l2->vbi_height * 2; |
| 77 | 79 | ||
| 78 | if (vb2_plane_size(vb, 0) < size) { | 80 | if (vb2_plane_size(vb, 0) < size) { |
| 79 | printk(KERN_INFO "%s data will not fit into plane (%lu < %lu)\n", | 81 | printk(KERN_INFO "%s data will not fit into plane (%lu < %lu)\n", |
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 0856e5d367b6..f6b49c98e2c9 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
| @@ -141,6 +141,33 @@ static struct em28xx_fmt format[] = { | |||
| 141 | }, | 141 | }, |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | /*FIXME: maxw should be dependent of alt mode */ | ||
| 145 | static inline unsigned int norm_maxw(struct em28xx *dev) | ||
| 146 | { | ||
| 147 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 148 | |||
| 149 | if (dev->board.is_webcam) | ||
| 150 | return v4l2->sensor_xres; | ||
| 151 | |||
| 152 | if (dev->board.max_range_640_480) | ||
| 153 | return 640; | ||
| 154 | |||
| 155 | return 720; | ||
| 156 | } | ||
| 157 | |||
| 158 | static inline unsigned int norm_maxh(struct em28xx *dev) | ||
| 159 | { | ||
| 160 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 161 | |||
| 162 | if (dev->board.is_webcam) | ||
| 163 | return v4l2->sensor_yres; | ||
| 164 | |||
| 165 | if (dev->board.max_range_640_480) | ||
| 166 | return 480; | ||
| 167 | |||
| 168 | return (v4l2->norm & V4L2_STD_625_50) ? 576 : 480; | ||
| 169 | } | ||
| 170 | |||
| 144 | static int em28xx_vbi_supported(struct em28xx *dev) | 171 | static int em28xx_vbi_supported(struct em28xx *dev) |
| 145 | { | 172 | { |
| 146 | /* Modprobe option to manually disable */ | 173 | /* Modprobe option to manually disable */ |
| @@ -166,10 +193,11 @@ static int em28xx_vbi_supported(struct em28xx *dev) | |||
| 166 | */ | 193 | */ |
| 167 | static void em28xx_wake_i2c(struct em28xx *dev) | 194 | static void em28xx_wake_i2c(struct em28xx *dev) |
| 168 | { | 195 | { |
| 169 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0); | 196 | struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev; |
| 170 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, | 197 | v4l2_device_call_all(v4l2_dev, 0, core, reset, 0); |
| 198 | v4l2_device_call_all(v4l2_dev, 0, video, s_routing, | ||
| 171 | INPUT(dev->ctl_input)->vmux, 0, 0); | 199 | INPUT(dev->ctl_input)->vmux, 0, 0); |
| 172 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | 200 | v4l2_device_call_all(v4l2_dev, 0, video, s_stream, 0); |
| 173 | } | 201 | } |
| 174 | 202 | ||
| 175 | static int em28xx_colorlevels_set_default(struct em28xx *dev) | 203 | static int em28xx_colorlevels_set_default(struct em28xx *dev) |
| @@ -194,8 +222,9 @@ static int em28xx_set_outfmt(struct em28xx *dev) | |||
| 194 | { | 222 | { |
| 195 | int ret; | 223 | int ret; |
| 196 | u8 fmt, vinctrl; | 224 | u8 fmt, vinctrl; |
| 225 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 197 | 226 | ||
| 198 | fmt = dev->format->reg; | 227 | fmt = v4l2->format->reg; |
| 199 | if (!dev->is_em25xx) | 228 | if (!dev->is_em25xx) |
| 200 | fmt |= 0x20; | 229 | fmt |= 0x20; |
| 201 | /* | 230 | /* |
| @@ -211,20 +240,20 @@ static int em28xx_set_outfmt(struct em28xx *dev) | |||
| 211 | if (ret < 0) | 240 | if (ret < 0) |
| 212 | return ret; | 241 | return ret; |
| 213 | 242 | ||
| 214 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode); | 243 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, v4l2->vinmode); |
| 215 | if (ret < 0) | 244 | if (ret < 0) |
| 216 | return ret; | 245 | return ret; |
| 217 | 246 | ||
| 218 | vinctrl = dev->vinctl; | 247 | vinctrl = v4l2->vinctl; |
| 219 | if (em28xx_vbi_supported(dev) == 1) { | 248 | if (em28xx_vbi_supported(dev) == 1) { |
| 220 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; | 249 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; |
| 221 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); | 250 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); |
| 222 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4); | 251 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, v4l2->vbi_width/4); |
| 223 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height); | 252 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, v4l2->vbi_height); |
| 224 | if (dev->norm & V4L2_STD_525_60) { | 253 | if (v4l2->norm & V4L2_STD_525_60) { |
| 225 | /* NTSC */ | 254 | /* NTSC */ |
| 226 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); | 255 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); |
| 227 | } else if (dev->norm & V4L2_STD_625_50) { | 256 | } else if (v4l2->norm & V4L2_STD_625_50) { |
| 228 | /* PAL */ | 257 | /* PAL */ |
| 229 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07); | 258 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07); |
| 230 | } | 259 | } |
| @@ -274,7 +303,7 @@ static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | |||
| 274 | 303 | ||
| 275 | static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | 304 | static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) |
| 276 | { | 305 | { |
| 277 | u8 mode; | 306 | u8 mode = 0x00; |
| 278 | /* the em2800 scaler only supports scaling down to 50% */ | 307 | /* the em2800 scaler only supports scaling down to 50% */ |
| 279 | 308 | ||
| 280 | if (dev->board.is_em2800) { | 309 | if (dev->board.is_em2800) { |
| @@ -293,22 +322,22 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
| 293 | to work correctly */ | 322 | to work correctly */ |
| 294 | mode = (h || v) ? 0x30 : 0x00; | 323 | mode = (h || v) ? 0x30 : 0x00; |
| 295 | } | 324 | } |
| 296 | return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); | 325 | return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode); |
| 297 | } | 326 | } |
| 298 | 327 | ||
| 299 | /* FIXME: this only function read values from dev */ | 328 | /* FIXME: this only function read values from dev */ |
| 300 | static int em28xx_resolution_set(struct em28xx *dev) | 329 | static int em28xx_resolution_set(struct em28xx *dev) |
| 301 | { | 330 | { |
| 302 | int width, height; | 331 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
| 303 | width = norm_maxw(dev); | 332 | int width = norm_maxw(dev); |
| 304 | height = norm_maxh(dev); | 333 | int height = norm_maxh(dev); |
| 305 | 334 | ||
| 306 | /* Properly setup VBI */ | 335 | /* Properly setup VBI */ |
| 307 | dev->vbi_width = 720; | 336 | v4l2->vbi_width = 720; |
| 308 | if (dev->norm & V4L2_STD_525_60) | 337 | if (v4l2->norm & V4L2_STD_525_60) |
| 309 | dev->vbi_height = 12; | 338 | v4l2->vbi_height = 12; |
| 310 | else | 339 | else |
| 311 | dev->vbi_height = 18; | 340 | v4l2->vbi_height = 18; |
| 312 | 341 | ||
| 313 | em28xx_set_outfmt(dev); | 342 | em28xx_set_outfmt(dev); |
| 314 | 343 | ||
| @@ -326,15 +355,16 @@ static int em28xx_resolution_set(struct em28xx *dev) | |||
| 326 | else | 355 | else |
| 327 | em28xx_capture_area_set(dev, 0, 0, width, height); | 356 | em28xx_capture_area_set(dev, 0, 0, width, height); |
| 328 | 357 | ||
| 329 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); | 358 | return em28xx_scaler_set(dev, v4l2->hscale, v4l2->vscale); |
| 330 | } | 359 | } |
| 331 | 360 | ||
| 332 | /* Set USB alternate setting for analog video */ | 361 | /* Set USB alternate setting for analog video */ |
| 333 | static int em28xx_set_alternate(struct em28xx *dev) | 362 | static int em28xx_set_alternate(struct em28xx *dev) |
| 334 | { | 363 | { |
| 364 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 335 | int errCode; | 365 | int errCode; |
| 336 | int i; | 366 | int i; |
| 337 | unsigned int min_pkt_size = dev->width * 2 + 4; | 367 | unsigned int min_pkt_size = v4l2->width * 2 + 4; |
| 338 | 368 | ||
| 339 | /* NOTE: for isoc transfers, only alt settings > 0 are allowed | 369 | /* NOTE: for isoc transfers, only alt settings > 0 are allowed |
| 340 | bulk transfers seem to work only with alt=0 ! */ | 370 | bulk transfers seem to work only with alt=0 ! */ |
| @@ -351,7 +381,7 @@ static int em28xx_set_alternate(struct em28xx *dev) | |||
| 351 | the frame size should be increased, otherwise, only | 381 | the frame size should be increased, otherwise, only |
| 352 | green screen will be received. | 382 | green screen will be received. |
| 353 | */ | 383 | */ |
| 354 | if (dev->width * 2 * dev->height > 720 * 240 * 2) | 384 | if (v4l2->width * 2 * v4l2->height > 720 * 240 * 2) |
| 355 | min_pkt_size *= 2; | 385 | min_pkt_size *= 2; |
| 356 | 386 | ||
| 357 | for (i = 0; i < dev->num_alt; i++) { | 387 | for (i = 0; i < dev->num_alt; i++) { |
| @@ -404,7 +434,7 @@ static inline void finish_buffer(struct em28xx *dev, | |||
| 404 | { | 434 | { |
| 405 | em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field); | 435 | em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field); |
| 406 | 436 | ||
| 407 | buf->vb.v4l2_buf.sequence = dev->field_count++; | 437 | buf->vb.v4l2_buf.sequence = dev->v4l2->field_count++; |
| 408 | buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; | 438 | buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED; |
| 409 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); | 439 | v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); |
| 410 | 440 | ||
| @@ -419,9 +449,10 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
| 419 | unsigned char *usb_buf, | 449 | unsigned char *usb_buf, |
| 420 | unsigned long len) | 450 | unsigned long len) |
| 421 | { | 451 | { |
| 452 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 422 | void *fieldstart, *startwrite, *startread; | 453 | void *fieldstart, *startwrite, *startread; |
| 423 | int linesdone, currlinedone, offset, lencopy, remain; | 454 | int linesdone, currlinedone, offset, lencopy, remain; |
| 424 | int bytesperline = dev->width << 1; | 455 | int bytesperline = v4l2->width << 1; |
| 425 | 456 | ||
| 426 | if (buf->pos + len > buf->length) | 457 | if (buf->pos + len > buf->length) |
| 427 | len = buf->length - buf->pos; | 458 | len = buf->length - buf->pos; |
| @@ -429,7 +460,7 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
| 429 | startread = usb_buf; | 460 | startread = usb_buf; |
| 430 | remain = len; | 461 | remain = len; |
| 431 | 462 | ||
| 432 | if (dev->progressive || buf->top_field) | 463 | if (v4l2->progressive || buf->top_field) |
| 433 | fieldstart = buf->vb_buf; | 464 | fieldstart = buf->vb_buf; |
| 434 | else /* interlaced mode, even nr. of lines */ | 465 | else /* interlaced mode, even nr. of lines */ |
| 435 | fieldstart = buf->vb_buf + bytesperline; | 466 | fieldstart = buf->vb_buf + bytesperline; |
| @@ -437,7 +468,7 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
| 437 | linesdone = buf->pos / bytesperline; | 468 | linesdone = buf->pos / bytesperline; |
| 438 | currlinedone = buf->pos % bytesperline; | 469 | currlinedone = buf->pos % bytesperline; |
| 439 | 470 | ||
| 440 | if (dev->progressive) | 471 | if (v4l2->progressive) |
| 441 | offset = linesdone * bytesperline + currlinedone; | 472 | offset = linesdone * bytesperline + currlinedone; |
| 442 | else | 473 | else |
| 443 | offset = linesdone * bytesperline * 2 + currlinedone; | 474 | offset = linesdone * bytesperline * 2 + currlinedone; |
| @@ -461,7 +492,7 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
| 461 | remain -= lencopy; | 492 | remain -= lencopy; |
| 462 | 493 | ||
| 463 | while (remain > 0) { | 494 | while (remain > 0) { |
| 464 | if (dev->progressive) | 495 | if (v4l2->progressive) |
| 465 | startwrite += lencopy; | 496 | startwrite += lencopy; |
| 466 | else | 497 | else |
| 467 | startwrite += lencopy + bytesperline; | 498 | startwrite += lencopy + bytesperline; |
| @@ -507,7 +538,7 @@ static void em28xx_copy_vbi(struct em28xx *dev, | |||
| 507 | offset = buf->pos; | 538 | offset = buf->pos; |
| 508 | /* Make sure the bottom field populates the second half of the frame */ | 539 | /* Make sure the bottom field populates the second half of the frame */ |
| 509 | if (buf->top_field == 0) | 540 | if (buf->top_field == 0) |
| 510 | offset += dev->vbi_width * dev->vbi_height; | 541 | offset += dev->v4l2->vbi_width * dev->v4l2->vbi_height; |
| 511 | 542 | ||
| 512 | memcpy(buf->vb_buf + offset, usb_buf, len); | 543 | memcpy(buf->vb_buf + offset, usb_buf, len); |
| 513 | buf->pos += len; | 544 | buf->pos += len; |
| @@ -583,13 +614,15 @@ finish_field_prepare_next(struct em28xx *dev, | |||
| 583 | struct em28xx_buffer *buf, | 614 | struct em28xx_buffer *buf, |
| 584 | struct em28xx_dmaqueue *dma_q) | 615 | struct em28xx_dmaqueue *dma_q) |
| 585 | { | 616 | { |
| 586 | if (dev->progressive || dev->top_field) { /* Brand new frame */ | 617 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
| 618 | |||
| 619 | if (v4l2->progressive || v4l2->top_field) { /* Brand new frame */ | ||
| 587 | if (buf != NULL) | 620 | if (buf != NULL) |
| 588 | finish_buffer(dev, buf); | 621 | finish_buffer(dev, buf); |
| 589 | buf = get_next_buf(dev, dma_q); | 622 | buf = get_next_buf(dev, dma_q); |
| 590 | } | 623 | } |
| 591 | if (buf != NULL) { | 624 | if (buf != NULL) { |
| 592 | buf->top_field = dev->top_field; | 625 | buf->top_field = v4l2->top_field; |
| 593 | buf->pos = 0; | 626 | buf->pos = 0; |
| 594 | } | 627 | } |
| 595 | 628 | ||
| @@ -603,6 +636,7 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
| 603 | unsigned char *data_pkt, | 636 | unsigned char *data_pkt, |
| 604 | unsigned int data_len) | 637 | unsigned int data_len) |
| 605 | { | 638 | { |
| 639 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 606 | struct em28xx_buffer *buf = dev->usb_ctl.vid_buf; | 640 | struct em28xx_buffer *buf = dev->usb_ctl.vid_buf; |
| 607 | struct em28xx_buffer *vbi_buf = dev->usb_ctl.vbi_buf; | 641 | struct em28xx_buffer *vbi_buf = dev->usb_ctl.vbi_buf; |
| 608 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 642 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
| @@ -622,17 +656,17 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
| 622 | data_len -= 4; | 656 | data_len -= 4; |
| 623 | } else if (data_pkt[0] == 0x33 && data_pkt[1] == 0x95) { | 657 | } else if (data_pkt[0] == 0x33 && data_pkt[1] == 0x95) { |
| 624 | /* Field start (VBI mode) */ | 658 | /* Field start (VBI mode) */ |
| 625 | dev->capture_type = 0; | 659 | v4l2->capture_type = 0; |
| 626 | dev->vbi_read = 0; | 660 | v4l2->vbi_read = 0; |
| 627 | em28xx_isocdbg("VBI START HEADER !!!\n"); | 661 | em28xx_isocdbg("VBI START HEADER !!!\n"); |
| 628 | dev->top_field = !(data_pkt[2] & 1); | 662 | v4l2->top_field = !(data_pkt[2] & 1); |
| 629 | data_pkt += 4; | 663 | data_pkt += 4; |
| 630 | data_len -= 4; | 664 | data_len -= 4; |
| 631 | } else if (data_pkt[0] == 0x22 && data_pkt[1] == 0x5a) { | 665 | } else if (data_pkt[0] == 0x22 && data_pkt[1] == 0x5a) { |
| 632 | /* Field start (VBI disabled) */ | 666 | /* Field start (VBI disabled) */ |
| 633 | dev->capture_type = 2; | 667 | v4l2->capture_type = 2; |
| 634 | em28xx_isocdbg("VIDEO START HEADER !!!\n"); | 668 | em28xx_isocdbg("VIDEO START HEADER !!!\n"); |
| 635 | dev->top_field = !(data_pkt[2] & 1); | 669 | v4l2->top_field = !(data_pkt[2] & 1); |
| 636 | data_pkt += 4; | 670 | data_pkt += 4; |
| 637 | data_len -= 4; | 671 | data_len -= 4; |
| 638 | } | 672 | } |
| @@ -640,37 +674,37 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
| 640 | /* NOTE: With bulk transfers, intermediate data packets | 674 | /* NOTE: With bulk transfers, intermediate data packets |
| 641 | * have no continuation header */ | 675 | * have no continuation header */ |
| 642 | 676 | ||
| 643 | if (dev->capture_type == 0) { | 677 | if (v4l2->capture_type == 0) { |
| 644 | vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); | 678 | vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); |
| 645 | dev->usb_ctl.vbi_buf = vbi_buf; | 679 | dev->usb_ctl.vbi_buf = vbi_buf; |
| 646 | dev->capture_type = 1; | 680 | v4l2->capture_type = 1; |
| 647 | } | 681 | } |
| 648 | 682 | ||
| 649 | if (dev->capture_type == 1) { | 683 | if (v4l2->capture_type == 1) { |
| 650 | int vbi_size = dev->vbi_width * dev->vbi_height; | 684 | int vbi_size = v4l2->vbi_width * v4l2->vbi_height; |
| 651 | int vbi_data_len = ((dev->vbi_read + data_len) > vbi_size) ? | 685 | int vbi_data_len = ((v4l2->vbi_read + data_len) > vbi_size) ? |
| 652 | (vbi_size - dev->vbi_read) : data_len; | 686 | (vbi_size - v4l2->vbi_read) : data_len; |
| 653 | 687 | ||
| 654 | /* Copy VBI data */ | 688 | /* Copy VBI data */ |
| 655 | if (vbi_buf != NULL) | 689 | if (vbi_buf != NULL) |
| 656 | em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len); | 690 | em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len); |
| 657 | dev->vbi_read += vbi_data_len; | 691 | v4l2->vbi_read += vbi_data_len; |
| 658 | 692 | ||
| 659 | if (vbi_data_len < data_len) { | 693 | if (vbi_data_len < data_len) { |
| 660 | /* Continue with copying video data */ | 694 | /* Continue with copying video data */ |
| 661 | dev->capture_type = 2; | 695 | v4l2->capture_type = 2; |
| 662 | data_pkt += vbi_data_len; | 696 | data_pkt += vbi_data_len; |
| 663 | data_len -= vbi_data_len; | 697 | data_len -= vbi_data_len; |
| 664 | } | 698 | } |
| 665 | } | 699 | } |
| 666 | 700 | ||
| 667 | if (dev->capture_type == 2) { | 701 | if (v4l2->capture_type == 2) { |
| 668 | buf = finish_field_prepare_next(dev, buf, dma_q); | 702 | buf = finish_field_prepare_next(dev, buf, dma_q); |
| 669 | dev->usb_ctl.vid_buf = buf; | 703 | dev->usb_ctl.vid_buf = buf; |
| 670 | dev->capture_type = 3; | 704 | v4l2->capture_type = 3; |
| 671 | } | 705 | } |
| 672 | 706 | ||
| 673 | if (dev->capture_type == 3 && buf != NULL && data_len > 0) | 707 | if (v4l2->capture_type == 3 && buf != NULL && data_len > 0) |
| 674 | em28xx_copy_video(dev, buf, data_pkt, data_len); | 708 | em28xx_copy_video(dev, buf, data_pkt, data_len); |
| 675 | } | 709 | } |
| 676 | 710 | ||
| @@ -683,6 +717,7 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, | |||
| 683 | { | 717 | { |
| 684 | struct em28xx_buffer *buf = dev->usb_ctl.vid_buf; | 718 | struct em28xx_buffer *buf = dev->usb_ctl.vid_buf; |
| 685 | struct em28xx_dmaqueue *dmaq = &dev->vidq; | 719 | struct em28xx_dmaqueue *dmaq = &dev->vidq; |
| 720 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 686 | bool frame_end = 0; | 721 | bool frame_end = 0; |
| 687 | 722 | ||
| 688 | /* Check for header */ | 723 | /* Check for header */ |
| @@ -691,7 +726,7 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, | |||
| 691 | if (data_len >= 2) { /* em25xx header is only 2 bytes long */ | 726 | if (data_len >= 2) { /* em25xx header is only 2 bytes long */ |
| 692 | if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) && | 727 | if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) && |
| 693 | ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) { | 728 | ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) { |
| 694 | dev->top_field = !(data_pkt[1] & | 729 | v4l2->top_field = !(data_pkt[1] & |
| 695 | EM25XX_FRMDATAHDR_BYTE2_FRAME_ID); | 730 | EM25XX_FRMDATAHDR_BYTE2_FRAME_ID); |
| 696 | frame_end = data_pkt[1] & | 731 | frame_end = data_pkt[1] & |
| 697 | EM25XX_FRMDATAHDR_BYTE2_FRAME_END; | 732 | EM25XX_FRMDATAHDR_BYTE2_FRAME_END; |
| @@ -841,12 +876,14 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |||
| 841 | unsigned int sizes[], void *alloc_ctxs[]) | 876 | unsigned int sizes[], void *alloc_ctxs[]) |
| 842 | { | 877 | { |
| 843 | struct em28xx *dev = vb2_get_drv_priv(vq); | 878 | struct em28xx *dev = vb2_get_drv_priv(vq); |
| 879 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 844 | unsigned long size; | 880 | unsigned long size; |
| 845 | 881 | ||
| 846 | if (fmt) | 882 | if (fmt) |
| 847 | size = fmt->fmt.pix.sizeimage; | 883 | size = fmt->fmt.pix.sizeimage; |
| 848 | else | 884 | else |
| 849 | size = (dev->width * dev->height * dev->format->depth + 7) >> 3; | 885 | size = |
| 886 | (v4l2->width * v4l2->height * v4l2->format->depth + 7) >> 3; | ||
| 850 | 887 | ||
| 851 | if (size == 0) | 888 | if (size == 0) |
| 852 | return -EINVAL; | 889 | return -EINVAL; |
| @@ -864,12 +901,13 @@ static int | |||
| 864 | buffer_prepare(struct vb2_buffer *vb) | 901 | buffer_prepare(struct vb2_buffer *vb) |
| 865 | { | 902 | { |
| 866 | struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue); | 903 | struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue); |
| 904 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 867 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | 905 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); |
| 868 | unsigned long size; | 906 | unsigned long size; |
| 869 | 907 | ||
| 870 | em28xx_videodbg("%s, field=%d\n", __func__, vb->v4l2_buf.field); | 908 | em28xx_videodbg("%s, field=%d\n", __func__, vb->v4l2_buf.field); |
| 871 | 909 | ||
| 872 | size = (dev->width * dev->height * dev->format->depth + 7) >> 3; | 910 | size = (v4l2->width * v4l2->height * v4l2->format->depth + 7) >> 3; |
| 873 | 911 | ||
| 874 | if (vb2_plane_size(vb, 0) < size) { | 912 | if (vb2_plane_size(vb, 0) < size) { |
| 875 | em28xx_videodbg("%s data will not fit into plane (%lu < %lu)\n", | 913 | em28xx_videodbg("%s data will not fit into plane (%lu < %lu)\n", |
| @@ -884,6 +922,7 @@ buffer_prepare(struct vb2_buffer *vb) | |||
| 884 | int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | 922 | int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) |
| 885 | { | 923 | { |
| 886 | struct em28xx *dev = vb2_get_drv_priv(vq); | 924 | struct em28xx *dev = vb2_get_drv_priv(vq); |
| 925 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 887 | struct v4l2_frequency f; | 926 | struct v4l2_frequency f; |
| 888 | int rc = 0; | 927 | int rc = 0; |
| 889 | 928 | ||
| @@ -895,7 +934,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 895 | if (rc) | 934 | if (rc) |
| 896 | return rc; | 935 | return rc; |
| 897 | 936 | ||
| 898 | if (dev->streaming_users == 0) { | 937 | if (v4l2->streaming_users == 0) { |
| 899 | /* First active streaming user, so allocate all the URBs */ | 938 | /* First active streaming user, so allocate all the URBs */ |
| 900 | 939 | ||
| 901 | /* Allocate the USB bandwidth */ | 940 | /* Allocate the USB bandwidth */ |
| @@ -906,7 +945,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 906 | */ | 945 | */ |
| 907 | em28xx_wake_i2c(dev); | 946 | em28xx_wake_i2c(dev); |
| 908 | 947 | ||
| 909 | dev->capture_type = -1; | 948 | v4l2->capture_type = -1; |
| 910 | rc = em28xx_init_usb_xfer(dev, EM28XX_ANALOG_MODE, | 949 | rc = em28xx_init_usb_xfer(dev, EM28XX_ANALOG_MODE, |
| 911 | dev->analog_xfer_bulk, | 950 | dev->analog_xfer_bulk, |
| 912 | EM28XX_NUM_BUFS, | 951 | EM28XX_NUM_BUFS, |
| @@ -924,22 +963,24 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 924 | 963 | ||
| 925 | /* Ask tuner to go to analog or radio mode */ | 964 | /* Ask tuner to go to analog or radio mode */ |
| 926 | memset(&f, 0, sizeof(f)); | 965 | memset(&f, 0, sizeof(f)); |
| 927 | f.frequency = dev->ctl_freq; | 966 | f.frequency = v4l2->frequency; |
| 928 | if (vq->owner && vq->owner->vdev->vfl_type == VFL_TYPE_RADIO) | 967 | if (vq->owner && vq->owner->vdev->vfl_type == VFL_TYPE_RADIO) |
| 929 | f.type = V4L2_TUNER_RADIO; | 968 | f.type = V4L2_TUNER_RADIO; |
| 930 | else | 969 | else |
| 931 | f.type = V4L2_TUNER_ANALOG_TV; | 970 | f.type = V4L2_TUNER_ANALOG_TV; |
| 932 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 971 | v4l2_device_call_all(&v4l2->v4l2_dev, |
| 972 | 0, tuner, s_frequency, &f); | ||
| 933 | } | 973 | } |
| 934 | 974 | ||
| 935 | dev->streaming_users++; | 975 | v4l2->streaming_users++; |
| 936 | 976 | ||
| 937 | return rc; | 977 | return rc; |
| 938 | } | 978 | } |
| 939 | 979 | ||
| 940 | static int em28xx_stop_streaming(struct vb2_queue *vq) | 980 | static void em28xx_stop_streaming(struct vb2_queue *vq) |
| 941 | { | 981 | { |
| 942 | struct em28xx *dev = vb2_get_drv_priv(vq); | 982 | struct em28xx *dev = vb2_get_drv_priv(vq); |
| 983 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 943 | struct em28xx_dmaqueue *vidq = &dev->vidq; | 984 | struct em28xx_dmaqueue *vidq = &dev->vidq; |
| 944 | unsigned long flags = 0; | 985 | unsigned long flags = 0; |
| 945 | 986 | ||
| @@ -947,7 +988,7 @@ static int em28xx_stop_streaming(struct vb2_queue *vq) | |||
| 947 | 988 | ||
| 948 | res_free(dev, vq->type); | 989 | res_free(dev, vq->type); |
| 949 | 990 | ||
| 950 | if (dev->streaming_users-- == 1) { | 991 | if (v4l2->streaming_users-- == 1) { |
| 951 | /* Last active user, so shutdown all the URBS */ | 992 | /* Last active user, so shutdown all the URBS */ |
| 952 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); | 993 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); |
| 953 | } | 994 | } |
| @@ -961,13 +1002,12 @@ static int em28xx_stop_streaming(struct vb2_queue *vq) | |||
| 961 | } | 1002 | } |
| 962 | dev->usb_ctl.vid_buf = NULL; | 1003 | dev->usb_ctl.vid_buf = NULL; |
| 963 | spin_unlock_irqrestore(&dev->slock, flags); | 1004 | spin_unlock_irqrestore(&dev->slock, flags); |
| 964 | |||
| 965 | return 0; | ||
| 966 | } | 1005 | } |
| 967 | 1006 | ||
| 968 | int em28xx_stop_vbi_streaming(struct vb2_queue *vq) | 1007 | void em28xx_stop_vbi_streaming(struct vb2_queue *vq) |
| 969 | { | 1008 | { |
| 970 | struct em28xx *dev = vb2_get_drv_priv(vq); | 1009 | struct em28xx *dev = vb2_get_drv_priv(vq); |
| 1010 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 971 | struct em28xx_dmaqueue *vbiq = &dev->vbiq; | 1011 | struct em28xx_dmaqueue *vbiq = &dev->vbiq; |
| 972 | unsigned long flags = 0; | 1012 | unsigned long flags = 0; |
| 973 | 1013 | ||
| @@ -975,7 +1015,7 @@ int em28xx_stop_vbi_streaming(struct vb2_queue *vq) | |||
| 975 | 1015 | ||
| 976 | res_free(dev, vq->type); | 1016 | res_free(dev, vq->type); |
| 977 | 1017 | ||
| 978 | if (dev->streaming_users-- == 1) { | 1018 | if (v4l2->streaming_users-- == 1) { |
| 979 | /* Last active user, so shutdown all the URBS */ | 1019 | /* Last active user, so shutdown all the URBS */ |
| 980 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); | 1020 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); |
| 981 | } | 1021 | } |
| @@ -989,8 +1029,6 @@ int em28xx_stop_vbi_streaming(struct vb2_queue *vq) | |||
| 989 | } | 1029 | } |
| 990 | dev->usb_ctl.vbi_buf = NULL; | 1030 | dev->usb_ctl.vbi_buf = NULL; |
| 991 | spin_unlock_irqrestore(&dev->slock, flags); | 1031 | spin_unlock_irqrestore(&dev->slock, flags); |
| 992 | |||
| 993 | return 0; | ||
| 994 | } | 1032 | } |
| 995 | 1033 | ||
| 996 | static void | 1034 | static void |
| @@ -1024,9 +1062,10 @@ static int em28xx_vb2_setup(struct em28xx *dev) | |||
| 1024 | { | 1062 | { |
| 1025 | int rc; | 1063 | int rc; |
| 1026 | struct vb2_queue *q; | 1064 | struct vb2_queue *q; |
| 1065 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1027 | 1066 | ||
| 1028 | /* Setup Videobuf2 for Video capture */ | 1067 | /* Setup Videobuf2 for Video capture */ |
| 1029 | q = &dev->vb_vidq; | 1068 | q = &v4l2->vb_vidq; |
| 1030 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1069 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 1031 | q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; | 1070 | q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; |
| 1032 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 1071 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| @@ -1040,7 +1079,7 @@ static int em28xx_vb2_setup(struct em28xx *dev) | |||
| 1040 | return rc; | 1079 | return rc; |
| 1041 | 1080 | ||
| 1042 | /* Setup Videobuf2 for VBI capture */ | 1081 | /* Setup Videobuf2 for VBI capture */ |
| 1043 | q = &dev->vb_vbiq; | 1082 | q = &v4l2->vb_vbiq; |
| 1044 | q->type = V4L2_BUF_TYPE_VBI_CAPTURE; | 1083 | q->type = V4L2_BUF_TYPE_VBI_CAPTURE; |
| 1045 | q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR; | 1084 | q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR; |
| 1046 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 1085 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
| @@ -1060,6 +1099,7 @@ static int em28xx_vb2_setup(struct em28xx *dev) | |||
| 1060 | 1099 | ||
| 1061 | static void video_mux(struct em28xx *dev, int index) | 1100 | static void video_mux(struct em28xx *dev, int index) |
| 1062 | { | 1101 | { |
| 1102 | struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev; | ||
| 1063 | dev->ctl_input = index; | 1103 | dev->ctl_input = index; |
| 1064 | dev->ctl_ainput = INPUT(index)->amux; | 1104 | dev->ctl_ainput = INPUT(index)->amux; |
| 1065 | dev->ctl_aoutput = INPUT(index)->aout; | 1105 | dev->ctl_aoutput = INPUT(index)->aout; |
| @@ -1067,21 +1107,21 @@ static void video_mux(struct em28xx *dev, int index) | |||
| 1067 | if (!dev->ctl_aoutput) | 1107 | if (!dev->ctl_aoutput) |
| 1068 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | 1108 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; |
| 1069 | 1109 | ||
| 1070 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, | 1110 | v4l2_device_call_all(v4l2_dev, 0, video, s_routing, |
| 1071 | INPUT(index)->vmux, 0, 0); | 1111 | INPUT(index)->vmux, 0, 0); |
| 1072 | 1112 | ||
| 1073 | if (dev->board.has_msp34xx) { | 1113 | if (dev->board.has_msp34xx) { |
| 1074 | if (dev->i2s_speed) { | 1114 | if (dev->i2s_speed) { |
| 1075 | v4l2_device_call_all(&dev->v4l2_dev, 0, audio, | 1115 | v4l2_device_call_all(v4l2_dev, 0, audio, |
| 1076 | s_i2s_clock_freq, dev->i2s_speed); | 1116 | s_i2s_clock_freq, dev->i2s_speed); |
| 1077 | } | 1117 | } |
| 1078 | /* Note: this is msp3400 specific */ | 1118 | /* Note: this is msp3400 specific */ |
| 1079 | v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, | 1119 | v4l2_device_call_all(v4l2_dev, 0, audio, s_routing, |
| 1080 | dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); | 1120 | dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); |
| 1081 | } | 1121 | } |
| 1082 | 1122 | ||
| 1083 | if (dev->board.adecoder != EM28XX_NOADECODER) { | 1123 | if (dev->board.adecoder != EM28XX_NOADECODER) { |
| 1084 | v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, | 1124 | v4l2_device_call_all(v4l2_dev, 0, audio, s_routing, |
| 1085 | dev->ctl_ainput, dev->ctl_aoutput, 0); | 1125 | dev->ctl_ainput, dev->ctl_aoutput, 0); |
| 1086 | } | 1126 | } |
| 1087 | 1127 | ||
| @@ -1112,7 +1152,9 @@ static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv) | |||
| 1112 | 1152 | ||
| 1113 | static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl) | 1153 | static int em28xx_s_ctrl(struct v4l2_ctrl *ctrl) |
| 1114 | { | 1154 | { |
| 1115 | struct em28xx *dev = container_of(ctrl->handler, struct em28xx, ctrl_handler); | 1155 | struct em28xx_v4l2 *v4l2 = |
| 1156 | container_of(ctrl->handler, struct em28xx_v4l2, ctrl_handler); | ||
| 1157 | struct em28xx *dev = v4l2->dev; | ||
| 1116 | int ret = -EINVAL; | 1158 | int ret = -EINVAL; |
| 1117 | 1159 | ||
| 1118 | switch (ctrl->id) { | 1160 | switch (ctrl->id) { |
| @@ -1187,19 +1229,20 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
| 1187 | { | 1229 | { |
| 1188 | struct em28xx_fh *fh = priv; | 1230 | struct em28xx_fh *fh = priv; |
| 1189 | struct em28xx *dev = fh->dev; | 1231 | struct em28xx *dev = fh->dev; |
| 1232 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1190 | 1233 | ||
| 1191 | f->fmt.pix.width = dev->width; | 1234 | f->fmt.pix.width = v4l2->width; |
| 1192 | f->fmt.pix.height = dev->height; | 1235 | f->fmt.pix.height = v4l2->height; |
| 1193 | f->fmt.pix.pixelformat = dev->format->fourcc; | 1236 | f->fmt.pix.pixelformat = v4l2->format->fourcc; |
| 1194 | f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3; | 1237 | f->fmt.pix.bytesperline = (v4l2->width * v4l2->format->depth + 7) >> 3; |
| 1195 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; | 1238 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * v4l2->height; |
| 1196 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 1239 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
| 1197 | 1240 | ||
| 1198 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | 1241 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ |
| 1199 | if (dev->progressive) | 1242 | if (v4l2->progressive) |
| 1200 | f->fmt.pix.field = V4L2_FIELD_NONE; | 1243 | f->fmt.pix.field = V4L2_FIELD_NONE; |
| 1201 | else | 1244 | else |
| 1202 | f->fmt.pix.field = dev->interlaced ? | 1245 | f->fmt.pix.field = v4l2->interlaced_fieldmode ? |
| 1203 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | 1246 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; |
| 1204 | return 0; | 1247 | return 0; |
| 1205 | } | 1248 | } |
| @@ -1220,6 +1263,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1220 | { | 1263 | { |
| 1221 | struct em28xx_fh *fh = priv; | 1264 | struct em28xx_fh *fh = priv; |
| 1222 | struct em28xx *dev = fh->dev; | 1265 | struct em28xx *dev = fh->dev; |
| 1266 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1223 | unsigned int width = f->fmt.pix.width; | 1267 | unsigned int width = f->fmt.pix.width; |
| 1224 | unsigned int height = f->fmt.pix.height; | 1268 | unsigned int height = f->fmt.pix.height; |
| 1225 | unsigned int maxw = norm_maxw(dev); | 1269 | unsigned int maxw = norm_maxw(dev); |
| @@ -1261,10 +1305,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1261 | f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3; | 1305 | f->fmt.pix.bytesperline = (width * fmt->depth + 7) >> 3; |
| 1262 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; | 1306 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; |
| 1263 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 1307 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
| 1264 | if (dev->progressive) | 1308 | if (v4l2->progressive) |
| 1265 | f->fmt.pix.field = V4L2_FIELD_NONE; | 1309 | f->fmt.pix.field = V4L2_FIELD_NONE; |
| 1266 | else | 1310 | else |
| 1267 | f->fmt.pix.field = dev->interlaced ? | 1311 | f->fmt.pix.field = v4l2->interlaced_fieldmode ? |
| 1268 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | 1312 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; |
| 1269 | f->fmt.pix.priv = 0; | 1313 | f->fmt.pix.priv = 0; |
| 1270 | 1314 | ||
| @@ -1275,17 +1319,19 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | |||
| 1275 | unsigned width, unsigned height) | 1319 | unsigned width, unsigned height) |
| 1276 | { | 1320 | { |
| 1277 | struct em28xx_fmt *fmt; | 1321 | struct em28xx_fmt *fmt; |
| 1322 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1278 | 1323 | ||
| 1279 | fmt = format_by_fourcc(fourcc); | 1324 | fmt = format_by_fourcc(fourcc); |
| 1280 | if (!fmt) | 1325 | if (!fmt) |
| 1281 | return -EINVAL; | 1326 | return -EINVAL; |
| 1282 | 1327 | ||
| 1283 | dev->format = fmt; | 1328 | v4l2->format = fmt; |
| 1284 | dev->width = width; | 1329 | v4l2->width = width; |
| 1285 | dev->height = height; | 1330 | v4l2->height = height; |
| 1286 | 1331 | ||
| 1287 | /* set new image size */ | 1332 | /* set new image size */ |
| 1288 | size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 1333 | size_to_scale(dev, v4l2->width, v4l2->height, |
| 1334 | &v4l2->hscale, &v4l2->vscale); | ||
| 1289 | 1335 | ||
| 1290 | em28xx_resolution_set(dev); | 1336 | em28xx_resolution_set(dev); |
| 1291 | 1337 | ||
| @@ -1296,8 +1342,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 1296 | struct v4l2_format *f) | 1342 | struct v4l2_format *f) |
| 1297 | { | 1343 | { |
| 1298 | struct em28xx *dev = video_drvdata(file); | 1344 | struct em28xx *dev = video_drvdata(file); |
| 1345 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1299 | 1346 | ||
| 1300 | if (dev->streaming_users > 0) | 1347 | if (v4l2->streaming_users > 0) |
| 1301 | return -EBUSY; | 1348 | return -EBUSY; |
| 1302 | 1349 | ||
| 1303 | vidioc_try_fmt_vid_cap(file, priv, f); | 1350 | vidioc_try_fmt_vid_cap(file, priv, f); |
| @@ -1311,7 +1358,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) | |||
| 1311 | struct em28xx_fh *fh = priv; | 1358 | struct em28xx_fh *fh = priv; |
| 1312 | struct em28xx *dev = fh->dev; | 1359 | struct em28xx *dev = fh->dev; |
| 1313 | 1360 | ||
| 1314 | *norm = dev->norm; | 1361 | *norm = dev->v4l2->norm; |
| 1315 | 1362 | ||
| 1316 | return 0; | 1363 | return 0; |
| 1317 | } | 1364 | } |
| @@ -1321,24 +1368,25 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) | |||
| 1321 | struct em28xx_fh *fh = priv; | 1368 | struct em28xx_fh *fh = priv; |
| 1322 | struct em28xx *dev = fh->dev; | 1369 | struct em28xx *dev = fh->dev; |
| 1323 | 1370 | ||
| 1324 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm); | 1371 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, video, querystd, norm); |
| 1325 | 1372 | ||
| 1326 | return 0; | 1373 | return 0; |
| 1327 | } | 1374 | } |
| 1328 | 1375 | ||
| 1329 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | 1376 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) |
| 1330 | { | 1377 | { |
| 1331 | struct em28xx_fh *fh = priv; | 1378 | struct em28xx_fh *fh = priv; |
| 1332 | struct em28xx *dev = fh->dev; | 1379 | struct em28xx *dev = fh->dev; |
| 1380 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1333 | struct v4l2_format f; | 1381 | struct v4l2_format f; |
| 1334 | 1382 | ||
| 1335 | if (norm == dev->norm) | 1383 | if (norm == v4l2->norm) |
| 1336 | return 0; | 1384 | return 0; |
| 1337 | 1385 | ||
| 1338 | if (dev->streaming_users > 0) | 1386 | if (v4l2->streaming_users > 0) |
| 1339 | return -EBUSY; | 1387 | return -EBUSY; |
| 1340 | 1388 | ||
| 1341 | dev->norm = norm; | 1389 | v4l2->norm = norm; |
| 1342 | 1390 | ||
| 1343 | /* Adjusts width/height, if needed */ | 1391 | /* Adjusts width/height, if needed */ |
| 1344 | f.fmt.pix.width = 720; | 1392 | f.fmt.pix.width = 720; |
| @@ -1346,12 +1394,13 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 1346 | vidioc_try_fmt_vid_cap(file, priv, &f); | 1394 | vidioc_try_fmt_vid_cap(file, priv, &f); |
| 1347 | 1395 | ||
| 1348 | /* set new image size */ | 1396 | /* set new image size */ |
| 1349 | dev->width = f.fmt.pix.width; | 1397 | v4l2->width = f.fmt.pix.width; |
| 1350 | dev->height = f.fmt.pix.height; | 1398 | v4l2->height = f.fmt.pix.height; |
| 1351 | size_to_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 1399 | size_to_scale(dev, v4l2->width, v4l2->height, |
| 1400 | &v4l2->hscale, &v4l2->vscale); | ||
| 1352 | 1401 | ||
| 1353 | em28xx_resolution_set(dev); | 1402 | em28xx_resolution_set(dev); |
| 1354 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | 1403 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, video, s_std, v4l2->norm); |
| 1355 | 1404 | ||
| 1356 | return 0; | 1405 | return 0; |
| 1357 | } | 1406 | } |
| @@ -1359,16 +1408,17 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 1359 | static int vidioc_g_parm(struct file *file, void *priv, | 1408 | static int vidioc_g_parm(struct file *file, void *priv, |
| 1360 | struct v4l2_streamparm *p) | 1409 | struct v4l2_streamparm *p) |
| 1361 | { | 1410 | { |
| 1362 | struct em28xx_fh *fh = priv; | 1411 | struct em28xx_fh *fh = priv; |
| 1363 | struct em28xx *dev = fh->dev; | 1412 | struct em28xx *dev = fh->dev; |
| 1413 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1364 | int rc = 0; | 1414 | int rc = 0; |
| 1365 | 1415 | ||
| 1366 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; | 1416 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; |
| 1367 | if (dev->board.is_webcam) | 1417 | if (dev->board.is_webcam) |
| 1368 | rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, | 1418 | rc = v4l2_device_call_until_err(&v4l2->v4l2_dev, 0, |
| 1369 | video, g_parm, p); | 1419 | video, g_parm, p); |
| 1370 | else | 1420 | else |
| 1371 | v4l2_video_std_frame_period(dev->norm, | 1421 | v4l2_video_std_frame_period(v4l2->norm, |
| 1372 | &p->parm.capture.timeperframe); | 1422 | &p->parm.capture.timeperframe); |
| 1373 | 1423 | ||
| 1374 | return rc; | 1424 | return rc; |
| @@ -1381,7 +1431,8 @@ static int vidioc_s_parm(struct file *file, void *priv, | |||
| 1381 | struct em28xx *dev = fh->dev; | 1431 | struct em28xx *dev = fh->dev; |
| 1382 | 1432 | ||
| 1383 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; | 1433 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; |
| 1384 | return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p); | 1434 | return v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, |
| 1435 | 0, video, s_parm, p); | ||
| 1385 | } | 1436 | } |
| 1386 | 1437 | ||
| 1387 | static const char *iname[] = { | 1438 | static const char *iname[] = { |
| @@ -1418,7 +1469,7 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
| 1418 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) | 1469 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) |
| 1419 | i->type = V4L2_INPUT_TYPE_TUNER; | 1470 | i->type = V4L2_INPUT_TYPE_TUNER; |
| 1420 | 1471 | ||
| 1421 | i->std = dev->vdev->tvnorms; | 1472 | i->std = dev->v4l2->vdev->tvnorms; |
| 1422 | /* webcams do not have the STD API */ | 1473 | /* webcams do not have the STD API */ |
| 1423 | if (dev->board.is_webcam) | 1474 | if (dev->board.is_webcam) |
| 1424 | i->capabilities = 0; | 1475 | i->capabilities = 0; |
| @@ -1520,7 +1571,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
| 1520 | 1571 | ||
| 1521 | strcpy(t->name, "Tuner"); | 1572 | strcpy(t->name, "Tuner"); |
| 1522 | 1573 | ||
| 1523 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); | 1574 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t); |
| 1524 | return 0; | 1575 | return 0; |
| 1525 | } | 1576 | } |
| 1526 | 1577 | ||
| @@ -1533,7 +1584,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
| 1533 | if (0 != t->index) | 1584 | if (0 != t->index) |
| 1534 | return -EINVAL; | 1585 | return -EINVAL; |
| 1535 | 1586 | ||
| 1536 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); | 1587 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); |
| 1537 | return 0; | 1588 | return 0; |
| 1538 | } | 1589 | } |
| 1539 | 1590 | ||
| @@ -1542,27 +1593,29 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
| 1542 | { | 1593 | { |
| 1543 | struct em28xx_fh *fh = priv; | 1594 | struct em28xx_fh *fh = priv; |
| 1544 | struct em28xx *dev = fh->dev; | 1595 | struct em28xx *dev = fh->dev; |
| 1596 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1545 | 1597 | ||
| 1546 | if (0 != f->tuner) | 1598 | if (0 != f->tuner) |
| 1547 | return -EINVAL; | 1599 | return -EINVAL; |
| 1548 | 1600 | ||
| 1549 | f->frequency = dev->ctl_freq; | 1601 | f->frequency = v4l2->frequency; |
| 1550 | return 0; | 1602 | return 0; |
| 1551 | } | 1603 | } |
| 1552 | 1604 | ||
| 1553 | static int vidioc_s_frequency(struct file *file, void *priv, | 1605 | static int vidioc_s_frequency(struct file *file, void *priv, |
| 1554 | const struct v4l2_frequency *f) | 1606 | const struct v4l2_frequency *f) |
| 1555 | { | 1607 | { |
| 1556 | struct v4l2_frequency new_freq = *f; | 1608 | struct v4l2_frequency new_freq = *f; |
| 1557 | struct em28xx_fh *fh = priv; | 1609 | struct em28xx_fh *fh = priv; |
| 1558 | struct em28xx *dev = fh->dev; | 1610 | struct em28xx *dev = fh->dev; |
| 1611 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1559 | 1612 | ||
| 1560 | if (0 != f->tuner) | 1613 | if (0 != f->tuner) |
| 1561 | return -EINVAL; | 1614 | return -EINVAL; |
| 1562 | 1615 | ||
| 1563 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); | 1616 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_frequency, f); |
| 1564 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq); | 1617 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, g_frequency, &new_freq); |
| 1565 | dev->ctl_freq = new_freq.frequency; | 1618 | v4l2->frequency = new_freq.frequency; |
| 1566 | 1619 | ||
| 1567 | return 0; | 1620 | return 0; |
| 1568 | } | 1621 | } |
| @@ -1579,7 +1632,8 @@ static int vidioc_g_chip_info(struct file *file, void *priv, | |||
| 1579 | if (chip->match.addr == 1) | 1632 | if (chip->match.addr == 1) |
| 1580 | strlcpy(chip->name, "ac97", sizeof(chip->name)); | 1633 | strlcpy(chip->name, "ac97", sizeof(chip->name)); |
| 1581 | else | 1634 | else |
| 1582 | strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name)); | 1635 | strlcpy(chip->name, |
| 1636 | dev->v4l2->v4l2_dev.name, sizeof(chip->name)); | ||
| 1583 | return 0; | 1637 | return 0; |
| 1584 | } | 1638 | } |
| 1585 | 1639 | ||
| @@ -1660,9 +1714,10 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
| 1660 | static int vidioc_querycap(struct file *file, void *priv, | 1714 | static int vidioc_querycap(struct file *file, void *priv, |
| 1661 | struct v4l2_capability *cap) | 1715 | struct v4l2_capability *cap) |
| 1662 | { | 1716 | { |
| 1663 | struct video_device *vdev = video_devdata(file); | 1717 | struct video_device *vdev = video_devdata(file); |
| 1664 | struct em28xx_fh *fh = priv; | 1718 | struct em28xx_fh *fh = priv; |
| 1665 | struct em28xx *dev = fh->dev; | 1719 | struct em28xx *dev = fh->dev; |
| 1720 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1666 | 1721 | ||
| 1667 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | 1722 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); |
| 1668 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | 1723 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); |
| @@ -1684,9 +1739,9 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
| 1684 | 1739 | ||
| 1685 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | | 1740 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | |
| 1686 | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1741 | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
| 1687 | if (dev->vbi_dev) | 1742 | if (v4l2->vbi_dev) |
| 1688 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; | 1743 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; |
| 1689 | if (dev->radio_dev) | 1744 | if (v4l2->radio_dev) |
| 1690 | cap->capabilities |= V4L2_CAP_RADIO; | 1745 | cap->capabilities |= V4L2_CAP_RADIO; |
| 1691 | return 0; | 1746 | return 0; |
| 1692 | } | 1747 | } |
| @@ -1751,24 +1806,25 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, | |||
| 1751 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | 1806 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, |
| 1752 | struct v4l2_format *format) | 1807 | struct v4l2_format *format) |
| 1753 | { | 1808 | { |
| 1754 | struct em28xx_fh *fh = priv; | 1809 | struct em28xx_fh *fh = priv; |
| 1755 | struct em28xx *dev = fh->dev; | 1810 | struct em28xx *dev = fh->dev; |
| 1811 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1756 | 1812 | ||
| 1757 | format->fmt.vbi.samples_per_line = dev->vbi_width; | 1813 | format->fmt.vbi.samples_per_line = v4l2->vbi_width; |
| 1758 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | 1814 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; |
| 1759 | format->fmt.vbi.offset = 0; | 1815 | format->fmt.vbi.offset = 0; |
| 1760 | format->fmt.vbi.flags = 0; | 1816 | format->fmt.vbi.flags = 0; |
| 1761 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; | 1817 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; |
| 1762 | format->fmt.vbi.count[0] = dev->vbi_height; | 1818 | format->fmt.vbi.count[0] = v4l2->vbi_height; |
| 1763 | format->fmt.vbi.count[1] = dev->vbi_height; | 1819 | format->fmt.vbi.count[1] = v4l2->vbi_height; |
| 1764 | memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved)); | 1820 | memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved)); |
| 1765 | 1821 | ||
| 1766 | /* Varies by video standard (NTSC, PAL, etc.) */ | 1822 | /* Varies by video standard (NTSC, PAL, etc.) */ |
| 1767 | if (dev->norm & V4L2_STD_525_60) { | 1823 | if (v4l2->norm & V4L2_STD_525_60) { |
| 1768 | /* NTSC */ | 1824 | /* NTSC */ |
| 1769 | format->fmt.vbi.start[0] = 10; | 1825 | format->fmt.vbi.start[0] = 10; |
| 1770 | format->fmt.vbi.start[1] = 273; | 1826 | format->fmt.vbi.start[1] = 273; |
| 1771 | } else if (dev->norm & V4L2_STD_625_50) { | 1827 | } else if (v4l2->norm & V4L2_STD_625_50) { |
| 1772 | /* PAL */ | 1828 | /* PAL */ |
| 1773 | format->fmt.vbi.start[0] = 6; | 1829 | format->fmt.vbi.start[0] = 6; |
| 1774 | format->fmt.vbi.start[1] = 318; | 1830 | format->fmt.vbi.start[1] = 318; |
| @@ -1791,7 +1847,7 @@ static int radio_g_tuner(struct file *file, void *priv, | |||
| 1791 | 1847 | ||
| 1792 | strcpy(t->name, "Radio"); | 1848 | strcpy(t->name, "Radio"); |
| 1793 | 1849 | ||
| 1794 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); | 1850 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, g_tuner, t); |
| 1795 | 1851 | ||
| 1796 | return 0; | 1852 | return 0; |
| 1797 | } | 1853 | } |
| @@ -1804,12 +1860,27 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
| 1804 | if (0 != t->index) | 1860 | if (0 != t->index) |
| 1805 | return -EINVAL; | 1861 | return -EINVAL; |
| 1806 | 1862 | ||
| 1807 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); | 1863 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); |
| 1808 | 1864 | ||
| 1809 | return 0; | 1865 | return 0; |
| 1810 | } | 1866 | } |
| 1811 | 1867 | ||
| 1812 | /* | 1868 | /* |
| 1869 | * em28xx_free_v4l2() - Free struct em28xx_v4l2 | ||
| 1870 | * | ||
| 1871 | * @ref: struct kref for struct em28xx_v4l2 | ||
| 1872 | * | ||
| 1873 | * Called when all users of struct em28xx_v4l2 are gone | ||
| 1874 | */ | ||
| 1875 | static void em28xx_free_v4l2(struct kref *ref) | ||
| 1876 | { | ||
| 1877 | struct em28xx_v4l2 *v4l2 = container_of(ref, struct em28xx_v4l2, ref); | ||
| 1878 | |||
| 1879 | v4l2->dev->v4l2 = NULL; | ||
| 1880 | kfree(v4l2); | ||
| 1881 | } | ||
| 1882 | |||
| 1883 | /* | ||
| 1813 | * em28xx_v4l2_open() | 1884 | * em28xx_v4l2_open() |
| 1814 | * inits the device and starts isoc transfer | 1885 | * inits the device and starts isoc transfer |
| 1815 | */ | 1886 | */ |
| @@ -1817,6 +1888,7 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1817 | { | 1888 | { |
| 1818 | struct video_device *vdev = video_devdata(filp); | 1889 | struct video_device *vdev = video_devdata(filp); |
| 1819 | struct em28xx *dev = video_drvdata(filp); | 1890 | struct em28xx *dev = video_drvdata(filp); |
| 1891 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1820 | enum v4l2_buf_type fh_type = 0; | 1892 | enum v4l2_buf_type fh_type = 0; |
| 1821 | struct em28xx_fh *fh; | 1893 | struct em28xx_fh *fh; |
| 1822 | 1894 | ||
| @@ -1835,7 +1907,7 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1835 | 1907 | ||
| 1836 | em28xx_videodbg("open dev=%s type=%s users=%d\n", | 1908 | em28xx_videodbg("open dev=%s type=%s users=%d\n", |
| 1837 | video_device_node_name(vdev), v4l2_type_names[fh_type], | 1909 | video_device_node_name(vdev), v4l2_type_names[fh_type], |
| 1838 | dev->users); | 1910 | v4l2->users); |
| 1839 | 1911 | ||
| 1840 | if (mutex_lock_interruptible(&dev->lock)) | 1912 | if (mutex_lock_interruptible(&dev->lock)) |
| 1841 | return -ERESTARTSYS; | 1913 | return -ERESTARTSYS; |
| @@ -1850,7 +1922,7 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1850 | fh->type = fh_type; | 1922 | fh->type = fh_type; |
| 1851 | filp->private_data = fh; | 1923 | filp->private_data = fh; |
| 1852 | 1924 | ||
| 1853 | if (dev->users == 0) { | 1925 | if (v4l2->users == 0) { |
| 1854 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 1926 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
| 1855 | 1927 | ||
| 1856 | if (vdev->vfl_type != VFL_TYPE_RADIO) | 1928 | if (vdev->vfl_type != VFL_TYPE_RADIO) |
| @@ -1865,11 +1937,12 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1865 | 1937 | ||
| 1866 | if (vdev->vfl_type == VFL_TYPE_RADIO) { | 1938 | if (vdev->vfl_type == VFL_TYPE_RADIO) { |
| 1867 | em28xx_videodbg("video_open: setting radio device\n"); | 1939 | em28xx_videodbg("video_open: setting radio device\n"); |
| 1868 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio); | 1940 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_radio); |
| 1869 | } | 1941 | } |
| 1870 | 1942 | ||
| 1871 | kref_get(&dev->ref); | 1943 | kref_get(&dev->ref); |
| 1872 | dev->users++; | 1944 | kref_get(&v4l2->ref); |
| 1945 | v4l2->users++; | ||
| 1873 | 1946 | ||
| 1874 | mutex_unlock(&dev->lock); | 1947 | mutex_unlock(&dev->lock); |
| 1875 | v4l2_fh_add(&fh->fh); | 1948 | v4l2_fh_add(&fh->fh); |
| @@ -1884,6 +1957,8 @@ static int em28xx_v4l2_open(struct file *filp) | |||
| 1884 | */ | 1957 | */ |
| 1885 | static int em28xx_v4l2_fini(struct em28xx *dev) | 1958 | static int em28xx_v4l2_fini(struct em28xx *dev) |
| 1886 | { | 1959 | { |
| 1960 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1961 | |||
| 1887 | if (dev->is_audio_only) { | 1962 | if (dev->is_audio_only) { |
| 1888 | /* Shouldn't initialize IR for this interface */ | 1963 | /* Shouldn't initialize IR for this interface */ |
| 1889 | return 0; | 1964 | return 0; |
| @@ -1894,39 +1969,45 @@ static int em28xx_v4l2_fini(struct em28xx *dev) | |||
| 1894 | return 0; | 1969 | return 0; |
| 1895 | } | 1970 | } |
| 1896 | 1971 | ||
| 1972 | if (v4l2 == NULL) | ||
| 1973 | return 0; | ||
| 1974 | |||
| 1897 | em28xx_info("Closing video extension"); | 1975 | em28xx_info("Closing video extension"); |
| 1898 | 1976 | ||
| 1899 | mutex_lock(&dev->lock); | 1977 | mutex_lock(&dev->lock); |
| 1900 | 1978 | ||
| 1901 | v4l2_device_disconnect(&dev->v4l2_dev); | 1979 | v4l2_device_disconnect(&v4l2->v4l2_dev); |
| 1902 | 1980 | ||
| 1903 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); | 1981 | em28xx_uninit_usb_xfer(dev, EM28XX_ANALOG_MODE); |
| 1904 | 1982 | ||
| 1905 | if (dev->radio_dev) { | 1983 | if (v4l2->radio_dev) { |
| 1906 | em28xx_info("V4L2 device %s deregistered\n", | 1984 | em28xx_info("V4L2 device %s deregistered\n", |
| 1907 | video_device_node_name(dev->radio_dev)); | 1985 | video_device_node_name(v4l2->radio_dev)); |
| 1908 | video_unregister_device(dev->radio_dev); | 1986 | video_unregister_device(v4l2->radio_dev); |
| 1909 | } | 1987 | } |
| 1910 | if (dev->vbi_dev) { | 1988 | if (v4l2->vbi_dev) { |
| 1911 | em28xx_info("V4L2 device %s deregistered\n", | 1989 | em28xx_info("V4L2 device %s deregistered\n", |
| 1912 | video_device_node_name(dev->vbi_dev)); | 1990 | video_device_node_name(v4l2->vbi_dev)); |
| 1913 | video_unregister_device(dev->vbi_dev); | 1991 | video_unregister_device(v4l2->vbi_dev); |
| 1914 | } | 1992 | } |
| 1915 | if (dev->vdev) { | 1993 | if (v4l2->vdev) { |
| 1916 | em28xx_info("V4L2 device %s deregistered\n", | 1994 | em28xx_info("V4L2 device %s deregistered\n", |
| 1917 | video_device_node_name(dev->vdev)); | 1995 | video_device_node_name(v4l2->vdev)); |
| 1918 | video_unregister_device(dev->vdev); | 1996 | video_unregister_device(v4l2->vdev); |
| 1919 | } | 1997 | } |
| 1920 | 1998 | ||
| 1921 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 1999 | v4l2_ctrl_handler_free(&v4l2->ctrl_handler); |
| 1922 | v4l2_device_unregister(&dev->v4l2_dev); | 2000 | v4l2_device_unregister(&v4l2->v4l2_dev); |
| 1923 | 2001 | ||
| 1924 | if (dev->clk) { | 2002 | if (v4l2->clk) { |
| 1925 | v4l2_clk_unregister_fixed(dev->clk); | 2003 | v4l2_clk_unregister_fixed(v4l2->clk); |
| 1926 | dev->clk = NULL; | 2004 | v4l2->clk = NULL; |
| 1927 | } | 2005 | } |
| 1928 | 2006 | ||
| 2007 | kref_put(&v4l2->ref, em28xx_free_v4l2); | ||
| 2008 | |||
| 1929 | mutex_unlock(&dev->lock); | 2009 | mutex_unlock(&dev->lock); |
| 2010 | |||
| 1930 | kref_put(&dev->ref, em28xx_free_device); | 2011 | kref_put(&dev->ref, em28xx_free_device); |
| 1931 | 2012 | ||
| 1932 | return 0; | 2013 | return 0; |
| @@ -1965,22 +2046,23 @@ static int em28xx_v4l2_resume(struct em28xx *dev) | |||
| 1965 | */ | 2046 | */ |
| 1966 | static int em28xx_v4l2_close(struct file *filp) | 2047 | static int em28xx_v4l2_close(struct file *filp) |
| 1967 | { | 2048 | { |
| 1968 | struct em28xx_fh *fh = filp->private_data; | 2049 | struct em28xx_fh *fh = filp->private_data; |
| 1969 | struct em28xx *dev = fh->dev; | 2050 | struct em28xx *dev = fh->dev; |
| 2051 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | ||
| 1970 | int errCode; | 2052 | int errCode; |
| 1971 | 2053 | ||
| 1972 | em28xx_videodbg("users=%d\n", dev->users); | 2054 | em28xx_videodbg("users=%d\n", v4l2->users); |
| 1973 | 2055 | ||
| 1974 | vb2_fop_release(filp); | 2056 | vb2_fop_release(filp); |
| 1975 | mutex_lock(&dev->lock); | 2057 | mutex_lock(&dev->lock); |
| 1976 | 2058 | ||
| 1977 | if (dev->users == 1) { | 2059 | if (v4l2->users == 1) { |
| 1978 | /* No sense to try to write to the device */ | 2060 | /* No sense to try to write to the device */ |
| 1979 | if (dev->disconnected) | 2061 | if (dev->disconnected) |
| 1980 | goto exit; | 2062 | goto exit; |
| 1981 | 2063 | ||
| 1982 | /* Save some power by putting tuner to sleep */ | 2064 | /* Save some power by putting tuner to sleep */ |
| 1983 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); | 2065 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); |
| 1984 | 2066 | ||
| 1985 | /* do this before setting alternate! */ | 2067 | /* do this before setting alternate! */ |
| 1986 | em28xx_set_mode(dev, EM28XX_SUSPEND); | 2068 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
| @@ -1996,30 +2078,14 @@ static int em28xx_v4l2_close(struct file *filp) | |||
| 1996 | } | 2078 | } |
| 1997 | 2079 | ||
| 1998 | exit: | 2080 | exit: |
| 1999 | dev->users--; | 2081 | v4l2->users--; |
| 2082 | kref_put(&v4l2->ref, em28xx_free_v4l2); | ||
| 2000 | mutex_unlock(&dev->lock); | 2083 | mutex_unlock(&dev->lock); |
| 2001 | kref_put(&dev->ref, em28xx_free_device); | 2084 | kref_put(&dev->ref, em28xx_free_device); |
| 2002 | 2085 | ||
| 2003 | return 0; | 2086 | return 0; |
| 2004 | } | 2087 | } |
| 2005 | 2088 | ||
| 2006 | /* | ||
| 2007 | * em28xx_videodevice_release() | ||
| 2008 | * called when the last user of the video device exits and frees the memeory | ||
| 2009 | */ | ||
| 2010 | static void em28xx_videodevice_release(struct video_device *vdev) | ||
| 2011 | { | ||
| 2012 | struct em28xx *dev = video_get_drvdata(vdev); | ||
| 2013 | |||
| 2014 | video_device_release(vdev); | ||
| 2015 | if (vdev == dev->vdev) | ||
| 2016 | dev->vdev = NULL; | ||
| 2017 | else if (vdev == dev->vbi_dev) | ||
| 2018 | dev->vbi_dev = NULL; | ||
| 2019 | else if (vdev == dev->radio_dev) | ||
| 2020 | dev->radio_dev = NULL; | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | static const struct v4l2_file_operations em28xx_v4l_fops = { | 2089 | static const struct v4l2_file_operations em28xx_v4l_fops = { |
| 2024 | .owner = THIS_MODULE, | 2090 | .owner = THIS_MODULE, |
| 2025 | .open = em28xx_v4l2_open, | 2091 | .open = em28xx_v4l2_open, |
| @@ -2076,7 +2142,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
| 2076 | static const struct video_device em28xx_video_template = { | 2142 | static const struct video_device em28xx_video_template = { |
| 2077 | .fops = &em28xx_v4l_fops, | 2143 | .fops = &em28xx_v4l_fops, |
| 2078 | .ioctl_ops = &video_ioctl_ops, | 2144 | .ioctl_ops = &video_ioctl_ops, |
| 2079 | .release = em28xx_videodevice_release, | 2145 | .release = video_device_release, |
| 2080 | .tvnorms = V4L2_STD_ALL, | 2146 | .tvnorms = V4L2_STD_ALL, |
| 2081 | }; | 2147 | }; |
| 2082 | 2148 | ||
| @@ -2105,7 +2171,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { | |||
| 2105 | static struct video_device em28xx_radio_template = { | 2171 | static struct video_device em28xx_radio_template = { |
| 2106 | .fops = &radio_fops, | 2172 | .fops = &radio_fops, |
| 2107 | .ioctl_ops = &radio_ioctl_ops, | 2173 | .ioctl_ops = &radio_ioctl_ops, |
| 2108 | .release = em28xx_videodevice_release, | 2174 | .release = video_device_release, |
| 2109 | }; | 2175 | }; |
| 2110 | 2176 | ||
| 2111 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ | 2177 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ |
| @@ -2139,7 +2205,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
| 2139 | return NULL; | 2205 | return NULL; |
| 2140 | 2206 | ||
| 2141 | *vfd = *template; | 2207 | *vfd = *template; |
| 2142 | vfd->v4l2_dev = &dev->v4l2_dev; | 2208 | vfd->v4l2_dev = &dev->v4l2->v4l2_dev; |
| 2143 | vfd->debug = video_debug; | 2209 | vfd->debug = video_debug; |
| 2144 | vfd->lock = &dev->lock; | 2210 | vfd->lock = &dev->lock; |
| 2145 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | 2211 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); |
| @@ -2153,13 +2219,12 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
| 2153 | return vfd; | 2219 | return vfd; |
| 2154 | } | 2220 | } |
| 2155 | 2221 | ||
| 2156 | static void em28xx_tuner_setup(struct em28xx *dev) | 2222 | static void em28xx_tuner_setup(struct em28xx *dev, unsigned short tuner_addr) |
| 2157 | { | 2223 | { |
| 2158 | struct tuner_setup tun_setup; | 2224 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
| 2159 | struct v4l2_frequency f; | 2225 | struct v4l2_device *v4l2_dev = &v4l2->v4l2_dev; |
| 2160 | 2226 | struct tuner_setup tun_setup; | |
| 2161 | if (dev->tuner_type == TUNER_ABSENT) | 2227 | struct v4l2_frequency f; |
| 2162 | return; | ||
| 2163 | 2228 | ||
| 2164 | memset(&tun_setup, 0, sizeof(tun_setup)); | 2229 | memset(&tun_setup, 0, sizeof(tun_setup)); |
| 2165 | 2230 | ||
| @@ -2170,23 +2235,26 @@ static void em28xx_tuner_setup(struct em28xx *dev) | |||
| 2170 | tun_setup.type = dev->board.radio.type; | 2235 | tun_setup.type = dev->board.radio.type; |
| 2171 | tun_setup.addr = dev->board.radio_addr; | 2236 | tun_setup.addr = dev->board.radio_addr; |
| 2172 | 2237 | ||
| 2173 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); | 2238 | v4l2_device_call_all(v4l2_dev, |
| 2239 | 0, tuner, s_type_addr, &tun_setup); | ||
| 2174 | } | 2240 | } |
| 2175 | 2241 | ||
| 2176 | if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) { | 2242 | if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) { |
| 2177 | tun_setup.type = dev->tuner_type; | 2243 | tun_setup.type = dev->tuner_type; |
| 2178 | tun_setup.addr = dev->tuner_addr; | 2244 | tun_setup.addr = tuner_addr; |
| 2179 | 2245 | ||
| 2180 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); | 2246 | v4l2_device_call_all(v4l2_dev, |
| 2247 | 0, tuner, s_type_addr, &tun_setup); | ||
| 2181 | } | 2248 | } |
| 2182 | 2249 | ||
| 2183 | if (dev->tda9887_conf) { | 2250 | if (dev->board.tda9887_conf) { |
| 2184 | struct v4l2_priv_tun_config tda9887_cfg; | 2251 | struct v4l2_priv_tun_config tda9887_cfg; |
| 2185 | 2252 | ||
| 2186 | tda9887_cfg.tuner = TUNER_TDA9887; | 2253 | tda9887_cfg.tuner = TUNER_TDA9887; |
| 2187 | tda9887_cfg.priv = &dev->tda9887_conf; | 2254 | tda9887_cfg.priv = &dev->board.tda9887_conf; |
| 2188 | 2255 | ||
| 2189 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg); | 2256 | v4l2_device_call_all(v4l2_dev, |
| 2257 | 0, tuner, s_config, &tda9887_cfg); | ||
| 2190 | } | 2258 | } |
| 2191 | 2259 | ||
| 2192 | if (dev->tuner_type == TUNER_XC2028) { | 2260 | if (dev->tuner_type == TUNER_XC2028) { |
| @@ -2201,15 +2269,15 @@ static void em28xx_tuner_setup(struct em28xx *dev) | |||
| 2201 | xc2028_cfg.tuner = TUNER_XC2028; | 2269 | xc2028_cfg.tuner = TUNER_XC2028; |
| 2202 | xc2028_cfg.priv = &ctl; | 2270 | xc2028_cfg.priv = &ctl; |
| 2203 | 2271 | ||
| 2204 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg); | 2272 | v4l2_device_call_all(v4l2_dev, 0, tuner, s_config, &xc2028_cfg); |
| 2205 | } | 2273 | } |
| 2206 | 2274 | ||
| 2207 | /* configure tuner */ | 2275 | /* configure tuner */ |
| 2208 | f.tuner = 0; | 2276 | f.tuner = 0; |
| 2209 | f.type = V4L2_TUNER_ANALOG_TV; | 2277 | f.type = V4L2_TUNER_ANALOG_TV; |
| 2210 | f.frequency = 9076; /* just a magic number */ | 2278 | f.frequency = 9076; /* just a magic number */ |
| 2211 | dev->ctl_freq = f.frequency; | 2279 | v4l2->frequency = f.frequency; |
| 2212 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 2280 | v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency, &f); |
| 2213 | } | 2281 | } |
| 2214 | 2282 | ||
| 2215 | static int em28xx_v4l2_init(struct em28xx *dev) | 2283 | static int em28xx_v4l2_init(struct em28xx *dev) |
| @@ -2217,7 +2285,8 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2217 | u8 val; | 2285 | u8 val; |
| 2218 | int ret; | 2286 | int ret; |
| 2219 | unsigned int maxw; | 2287 | unsigned int maxw; |
| 2220 | struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; | 2288 | struct v4l2_ctrl_handler *hdl; |
| 2289 | struct em28xx_v4l2 *v4l2; | ||
| 2221 | 2290 | ||
| 2222 | if (dev->is_audio_only) { | 2291 | if (dev->is_audio_only) { |
| 2223 | /* Shouldn't initialize IR for this interface */ | 2292 | /* Shouldn't initialize IR for this interface */ |
| @@ -2233,71 +2302,93 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2233 | 2302 | ||
| 2234 | mutex_lock(&dev->lock); | 2303 | mutex_lock(&dev->lock); |
| 2235 | 2304 | ||
| 2236 | ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); | 2305 | v4l2 = kzalloc(sizeof(struct em28xx_v4l2), GFP_KERNEL); |
| 2306 | if (v4l2 == NULL) { | ||
| 2307 | em28xx_info("em28xx_v4l: memory allocation failed\n"); | ||
| 2308 | mutex_unlock(&dev->lock); | ||
| 2309 | return -ENOMEM; | ||
| 2310 | } | ||
| 2311 | kref_init(&v4l2->ref); | ||
| 2312 | v4l2->dev = dev; | ||
| 2313 | dev->v4l2 = v4l2; | ||
| 2314 | |||
| 2315 | ret = v4l2_device_register(&dev->udev->dev, &v4l2->v4l2_dev); | ||
| 2237 | if (ret < 0) { | 2316 | if (ret < 0) { |
| 2238 | em28xx_errdev("Call to v4l2_device_register() failed!\n"); | 2317 | em28xx_errdev("Call to v4l2_device_register() failed!\n"); |
| 2239 | goto err; | 2318 | goto err; |
| 2240 | } | 2319 | } |
| 2241 | 2320 | ||
| 2321 | hdl = &v4l2->ctrl_handler; | ||
| 2242 | v4l2_ctrl_handler_init(hdl, 8); | 2322 | v4l2_ctrl_handler_init(hdl, 8); |
| 2243 | dev->v4l2_dev.ctrl_handler = hdl; | 2323 | v4l2->v4l2_dev.ctrl_handler = hdl; |
| 2324 | |||
| 2325 | if (dev->board.is_webcam) | ||
| 2326 | v4l2->progressive = 1; | ||
| 2244 | 2327 | ||
| 2245 | /* | 2328 | /* |
| 2246 | * Default format, used for tvp5150 or saa711x output formats | 2329 | * Default format, used for tvp5150 or saa711x output formats |
| 2247 | */ | 2330 | */ |
| 2248 | dev->vinmode = 0x10; | 2331 | v4l2->vinmode = 0x10; |
| 2249 | dev->vinctl = EM28XX_VINCTRL_INTERLACED | | 2332 | v4l2->vinctl = EM28XX_VINCTRL_INTERLACED | |
| 2250 | EM28XX_VINCTRL_CCIR656_ENABLE; | 2333 | EM28XX_VINCTRL_CCIR656_ENABLE; |
| 2251 | 2334 | ||
| 2252 | /* request some modules */ | 2335 | /* request some modules */ |
| 2253 | 2336 | ||
| 2254 | if (dev->board.has_msp34xx) | 2337 | if (dev->board.has_msp34xx) |
| 2255 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2338 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2256 | "msp3400", 0, msp3400_addrs); | 2339 | &dev->i2c_adap[dev->def_i2c_bus], |
| 2340 | "msp3400", 0, msp3400_addrs); | ||
| 2257 | 2341 | ||
| 2258 | if (dev->board.decoder == EM28XX_SAA711X) | 2342 | if (dev->board.decoder == EM28XX_SAA711X) |
| 2259 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2343 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2260 | "saa7115_auto", 0, saa711x_addrs); | 2344 | &dev->i2c_adap[dev->def_i2c_bus], |
| 2345 | "saa7115_auto", 0, saa711x_addrs); | ||
| 2261 | 2346 | ||
| 2262 | if (dev->board.decoder == EM28XX_TVP5150) | 2347 | if (dev->board.decoder == EM28XX_TVP5150) |
| 2263 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2348 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2264 | "tvp5150", 0, tvp5150_addrs); | 2349 | &dev->i2c_adap[dev->def_i2c_bus], |
| 2350 | "tvp5150", 0, tvp5150_addrs); | ||
| 2265 | 2351 | ||
| 2266 | if (dev->board.adecoder == EM28XX_TVAUDIO) | 2352 | if (dev->board.adecoder == EM28XX_TVAUDIO) |
| 2267 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2353 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2268 | "tvaudio", dev->board.tvaudio_addr, NULL); | 2354 | &dev->i2c_adap[dev->def_i2c_bus], |
| 2355 | "tvaudio", dev->board.tvaudio_addr, NULL); | ||
| 2269 | 2356 | ||
| 2270 | /* Initialize tuner and camera */ | 2357 | /* Initialize tuner and camera */ |
| 2271 | 2358 | ||
| 2272 | if (dev->board.tuner_type != TUNER_ABSENT) { | 2359 | if (dev->board.tuner_type != TUNER_ABSENT) { |
| 2273 | int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); | 2360 | unsigned short tuner_addr = dev->board.tuner_addr; |
| 2361 | int has_demod = (dev->board.tda9887_conf & TDA9887_PRESENT); | ||
| 2274 | 2362 | ||
| 2275 | if (dev->board.radio.type) | 2363 | if (dev->board.radio.type) |
| 2276 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2364 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2277 | "tuner", dev->board.radio_addr, NULL); | 2365 | &dev->i2c_adap[dev->def_i2c_bus], |
| 2366 | "tuner", dev->board.radio_addr, NULL); | ||
| 2278 | 2367 | ||
| 2279 | if (has_demod) | 2368 | if (has_demod) |
| 2280 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | 2369 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2281 | &dev->i2c_adap[dev->def_i2c_bus], "tuner", | 2370 | &dev->i2c_adap[dev->def_i2c_bus], "tuner", |
| 2282 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | 2371 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); |
| 2283 | if (dev->tuner_addr == 0) { | 2372 | if (tuner_addr == 0) { |
| 2284 | enum v4l2_i2c_tuner_type type = | 2373 | enum v4l2_i2c_tuner_type type = |
| 2285 | has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; | 2374 | has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; |
| 2286 | struct v4l2_subdev *sd; | 2375 | struct v4l2_subdev *sd; |
| 2287 | 2376 | ||
| 2288 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | 2377 | sd = v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2289 | &dev->i2c_adap[dev->def_i2c_bus], "tuner", | 2378 | &dev->i2c_adap[dev->def_i2c_bus], "tuner", |
| 2290 | 0, v4l2_i2c_tuner_addrs(type)); | 2379 | 0, v4l2_i2c_tuner_addrs(type)); |
| 2291 | 2380 | ||
| 2292 | if (sd) | 2381 | if (sd) |
| 2293 | dev->tuner_addr = v4l2_i2c_subdev_addr(sd); | 2382 | tuner_addr = v4l2_i2c_subdev_addr(sd); |
| 2294 | } else { | 2383 | } else { |
| 2295 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2384 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
| 2296 | "tuner", dev->tuner_addr, NULL); | 2385 | &dev->i2c_adap[dev->def_i2c_bus], |
| 2386 | "tuner", tuner_addr, NULL); | ||
| 2297 | } | 2387 | } |
| 2388 | |||
| 2389 | em28xx_tuner_setup(dev, tuner_addr); | ||
| 2298 | } | 2390 | } |
| 2299 | 2391 | ||
| 2300 | em28xx_tuner_setup(dev); | ||
| 2301 | if (dev->em28xx_sensor != EM28XX_NOSENSOR) | 2392 | if (dev->em28xx_sensor != EM28XX_NOSENSOR) |
| 2302 | em28xx_init_camera(dev); | 2393 | em28xx_init_camera(dev); |
| 2303 | 2394 | ||
| @@ -2348,12 +2439,12 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2348 | } | 2439 | } |
| 2349 | 2440 | ||
| 2350 | /* set default norm */ | 2441 | /* set default norm */ |
| 2351 | dev->norm = V4L2_STD_PAL; | 2442 | v4l2->norm = V4L2_STD_PAL; |
| 2352 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | 2443 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, video, s_std, v4l2->norm); |
| 2353 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | 2444 | v4l2->interlaced_fieldmode = EM28XX_INTERLACED_DEFAULT; |
| 2354 | 2445 | ||
| 2355 | /* Analog specific initialization */ | 2446 | /* Analog specific initialization */ |
| 2356 | dev->format = &format[0]; | 2447 | v4l2->format = &format[0]; |
| 2357 | 2448 | ||
| 2358 | maxw = norm_maxw(dev); | 2449 | maxw = norm_maxw(dev); |
| 2359 | /* MaxPacketSize for em2800 is too small to capture at full resolution | 2450 | /* MaxPacketSize for em2800 is too small to capture at full resolution |
| @@ -2376,74 +2467,75 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2376 | (EM28XX_XCLK_AUDIO_UNMUTE | val)); | 2467 | (EM28XX_XCLK_AUDIO_UNMUTE | val)); |
| 2377 | 2468 | ||
| 2378 | em28xx_set_outfmt(dev); | 2469 | em28xx_set_outfmt(dev); |
| 2379 | em28xx_compression_disable(dev); | ||
| 2380 | 2470 | ||
| 2381 | /* Add image controls */ | 2471 | /* Add image controls */ |
| 2382 | /* NOTE: at this point, the subdevices are already registered, so bridge | 2472 | /* NOTE: at this point, the subdevices are already registered, so bridge |
| 2383 | * controls are only added/enabled when no subdevice provides them */ | 2473 | * controls are only added/enabled when no subdevice provides them */ |
| 2384 | if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_CONTRAST)) | 2474 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST)) |
| 2385 | v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, | 2475 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
| 2386 | V4L2_CID_CONTRAST, | 2476 | V4L2_CID_CONTRAST, |
| 2387 | 0, 0x1f, 1, CONTRAST_DEFAULT); | 2477 | 0, 0x1f, 1, CONTRAST_DEFAULT); |
| 2388 | if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BRIGHTNESS)) | 2478 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS)) |
| 2389 | v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, | 2479 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
| 2390 | V4L2_CID_BRIGHTNESS, | 2480 | V4L2_CID_BRIGHTNESS, |
| 2391 | -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); | 2481 | -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); |
| 2392 | if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SATURATION)) | 2482 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SATURATION)) |
| 2393 | v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, | 2483 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
| 2394 | V4L2_CID_SATURATION, | 2484 | V4L2_CID_SATURATION, |
| 2395 | 0, 0x1f, 1, SATURATION_DEFAULT); | 2485 | 0, 0x1f, 1, SATURATION_DEFAULT); |
| 2396 | if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_BLUE_BALANCE)) | 2486 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE)) |
| 2397 | v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, | 2487 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
| 2398 | V4L2_CID_BLUE_BALANCE, | 2488 | V4L2_CID_BLUE_BALANCE, |
| 2399 | -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); | 2489 | -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); |
| 2400 | if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RED_BALANCE)) | 2490 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE)) |
| 2401 | v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, | 2491 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
| 2402 | V4L2_CID_RED_BALANCE, | 2492 | V4L2_CID_RED_BALANCE, |
| 2403 | -0x30, 0x30, 1, RED_BALANCE_DEFAULT); | 2493 | -0x30, 0x30, 1, RED_BALANCE_DEFAULT); |
| 2404 | if (NULL == v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_SHARPNESS)) | 2494 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS)) |
| 2405 | v4l2_ctrl_new_std(&dev->ctrl_handler, &em28xx_ctrl_ops, | 2495 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
| 2406 | V4L2_CID_SHARPNESS, | 2496 | V4L2_CID_SHARPNESS, |
| 2407 | 0, 0x0f, 1, SHARPNESS_DEFAULT); | 2497 | 0, 0x0f, 1, SHARPNESS_DEFAULT); |
| 2408 | 2498 | ||
| 2409 | /* Reset image controls */ | 2499 | /* Reset image controls */ |
| 2410 | em28xx_colorlevels_set_default(dev); | 2500 | em28xx_colorlevels_set_default(dev); |
| 2411 | v4l2_ctrl_handler_setup(&dev->ctrl_handler); | 2501 | v4l2_ctrl_handler_setup(hdl); |
| 2412 | ret = dev->ctrl_handler.error; | 2502 | ret = hdl->error; |
| 2413 | if (ret) | 2503 | if (ret) |
| 2414 | goto unregister_dev; | 2504 | goto unregister_dev; |
| 2415 | 2505 | ||
| 2416 | /* allocate and fill video video_device struct */ | 2506 | /* allocate and fill video video_device struct */ |
| 2417 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | 2507 | v4l2->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); |
| 2418 | if (!dev->vdev) { | 2508 | if (!v4l2->vdev) { |
| 2419 | em28xx_errdev("cannot allocate video_device.\n"); | 2509 | em28xx_errdev("cannot allocate video_device.\n"); |
| 2420 | ret = -ENODEV; | 2510 | ret = -ENODEV; |
| 2421 | goto unregister_dev; | 2511 | goto unregister_dev; |
| 2422 | } | 2512 | } |
| 2423 | dev->vdev->queue = &dev->vb_vidq; | 2513 | mutex_init(&v4l2->vb_queue_lock); |
| 2424 | dev->vdev->queue->lock = &dev->vb_queue_lock; | 2514 | mutex_init(&v4l2->vb_vbi_queue_lock); |
| 2515 | v4l2->vdev->queue = &v4l2->vb_vidq; | ||
| 2516 | v4l2->vdev->queue->lock = &v4l2->vb_queue_lock; | ||
| 2425 | 2517 | ||
| 2426 | /* disable inapplicable ioctls */ | 2518 | /* disable inapplicable ioctls */ |
| 2427 | if (dev->board.is_webcam) { | 2519 | if (dev->board.is_webcam) { |
| 2428 | v4l2_disable_ioctl(dev->vdev, VIDIOC_QUERYSTD); | 2520 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_QUERYSTD); |
| 2429 | v4l2_disable_ioctl(dev->vdev, VIDIOC_G_STD); | 2521 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_STD); |
| 2430 | v4l2_disable_ioctl(dev->vdev, VIDIOC_S_STD); | 2522 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_STD); |
| 2431 | } else { | 2523 | } else { |
| 2432 | v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM); | 2524 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_PARM); |
| 2433 | } | 2525 | } |
| 2434 | if (dev->tuner_type == TUNER_ABSENT) { | 2526 | if (dev->tuner_type == TUNER_ABSENT) { |
| 2435 | v4l2_disable_ioctl(dev->vdev, VIDIOC_G_TUNER); | 2527 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_TUNER); |
| 2436 | v4l2_disable_ioctl(dev->vdev, VIDIOC_S_TUNER); | 2528 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_TUNER); |
| 2437 | v4l2_disable_ioctl(dev->vdev, VIDIOC_G_FREQUENCY); | 2529 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_FREQUENCY); |
| 2438 | v4l2_disable_ioctl(dev->vdev, VIDIOC_S_FREQUENCY); | 2530 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_FREQUENCY); |
| 2439 | } | 2531 | } |
| 2440 | if (!dev->audio_mode.has_audio) { | 2532 | if (!dev->audio_mode.has_audio) { |
| 2441 | v4l2_disable_ioctl(dev->vdev, VIDIOC_G_AUDIO); | 2533 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_G_AUDIO); |
| 2442 | v4l2_disable_ioctl(dev->vdev, VIDIOC_S_AUDIO); | 2534 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_AUDIO); |
| 2443 | } | 2535 | } |
| 2444 | 2536 | ||
| 2445 | /* register v4l2 video video_device */ | 2537 | /* register v4l2 video video_device */ |
| 2446 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | 2538 | ret = video_register_device(v4l2->vdev, VFL_TYPE_GRABBER, |
| 2447 | video_nr[dev->devno]); | 2539 | video_nr[dev->devno]); |
| 2448 | if (ret) { | 2540 | if (ret) { |
| 2449 | em28xx_errdev("unable to register video device (error=%i).\n", | 2541 | em28xx_errdev("unable to register video device (error=%i).\n", |
| @@ -2453,27 +2545,27 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2453 | 2545 | ||
| 2454 | /* Allocate and fill vbi video_device struct */ | 2546 | /* Allocate and fill vbi video_device struct */ |
| 2455 | if (em28xx_vbi_supported(dev) == 1) { | 2547 | if (em28xx_vbi_supported(dev) == 1) { |
| 2456 | dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, | 2548 | v4l2->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, |
| 2457 | "vbi"); | 2549 | "vbi"); |
| 2458 | 2550 | ||
| 2459 | dev->vbi_dev->queue = &dev->vb_vbiq; | 2551 | v4l2->vbi_dev->queue = &v4l2->vb_vbiq; |
| 2460 | dev->vbi_dev->queue->lock = &dev->vb_vbi_queue_lock; | 2552 | v4l2->vbi_dev->queue->lock = &v4l2->vb_vbi_queue_lock; |
| 2461 | 2553 | ||
| 2462 | /* disable inapplicable ioctls */ | 2554 | /* disable inapplicable ioctls */ |
| 2463 | v4l2_disable_ioctl(dev->vdev, VIDIOC_S_PARM); | 2555 | v4l2_disable_ioctl(v4l2->vdev, VIDIOC_S_PARM); |
| 2464 | if (dev->tuner_type == TUNER_ABSENT) { | 2556 | if (dev->tuner_type == TUNER_ABSENT) { |
| 2465 | v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_TUNER); | 2557 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_TUNER); |
| 2466 | v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_TUNER); | 2558 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_TUNER); |
| 2467 | v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_FREQUENCY); | 2559 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_FREQUENCY); |
| 2468 | v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_FREQUENCY); | 2560 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_FREQUENCY); |
| 2469 | } | 2561 | } |
| 2470 | if (!dev->audio_mode.has_audio) { | 2562 | if (!dev->audio_mode.has_audio) { |
| 2471 | v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_G_AUDIO); | 2563 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_G_AUDIO); |
| 2472 | v4l2_disable_ioctl(dev->vbi_dev, VIDIOC_S_AUDIO); | 2564 | v4l2_disable_ioctl(v4l2->vbi_dev, VIDIOC_S_AUDIO); |
| 2473 | } | 2565 | } |
| 2474 | 2566 | ||
| 2475 | /* register v4l2 vbi video_device */ | 2567 | /* register v4l2 vbi video_device */ |
| 2476 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | 2568 | ret = video_register_device(v4l2->vbi_dev, VFL_TYPE_VBI, |
| 2477 | vbi_nr[dev->devno]); | 2569 | vbi_nr[dev->devno]); |
| 2478 | if (ret < 0) { | 2570 | if (ret < 0) { |
| 2479 | em28xx_errdev("unable to register vbi device\n"); | 2571 | em28xx_errdev("unable to register vbi device\n"); |
| @@ -2482,32 +2574,32 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2482 | } | 2574 | } |
| 2483 | 2575 | ||
| 2484 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | 2576 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { |
| 2485 | dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, | 2577 | v4l2->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, |
| 2486 | "radio"); | 2578 | "radio"); |
| 2487 | if (!dev->radio_dev) { | 2579 | if (!v4l2->radio_dev) { |
| 2488 | em28xx_errdev("cannot allocate video_device.\n"); | 2580 | em28xx_errdev("cannot allocate video_device.\n"); |
| 2489 | ret = -ENODEV; | 2581 | ret = -ENODEV; |
| 2490 | goto unregister_dev; | 2582 | goto unregister_dev; |
| 2491 | } | 2583 | } |
| 2492 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | 2584 | ret = video_register_device(v4l2->radio_dev, VFL_TYPE_RADIO, |
| 2493 | radio_nr[dev->devno]); | 2585 | radio_nr[dev->devno]); |
| 2494 | if (ret < 0) { | 2586 | if (ret < 0) { |
| 2495 | em28xx_errdev("can't register radio device\n"); | 2587 | em28xx_errdev("can't register radio device\n"); |
| 2496 | goto unregister_dev; | 2588 | goto unregister_dev; |
| 2497 | } | 2589 | } |
| 2498 | em28xx_info("Registered radio device as %s\n", | 2590 | em28xx_info("Registered radio device as %s\n", |
| 2499 | video_device_node_name(dev->radio_dev)); | 2591 | video_device_node_name(v4l2->radio_dev)); |
| 2500 | } | 2592 | } |
| 2501 | 2593 | ||
| 2502 | em28xx_info("V4L2 video device registered as %s\n", | 2594 | em28xx_info("V4L2 video device registered as %s\n", |
| 2503 | video_device_node_name(dev->vdev)); | 2595 | video_device_node_name(v4l2->vdev)); |
| 2504 | 2596 | ||
| 2505 | if (dev->vbi_dev) | 2597 | if (v4l2->vbi_dev) |
| 2506 | em28xx_info("V4L2 VBI device registered as %s\n", | 2598 | em28xx_info("V4L2 VBI device registered as %s\n", |
| 2507 | video_device_node_name(dev->vbi_dev)); | 2599 | video_device_node_name(v4l2->vbi_dev)); |
| 2508 | 2600 | ||
| 2509 | /* Save some power by putting tuner to sleep */ | 2601 | /* Save some power by putting tuner to sleep */ |
| 2510 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); | 2602 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); |
| 2511 | 2603 | ||
| 2512 | /* initialize videobuf2 stuff */ | 2604 | /* initialize videobuf2 stuff */ |
| 2513 | em28xx_vb2_setup(dev); | 2605 | em28xx_vb2_setup(dev); |
| @@ -2520,9 +2612,11 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
| 2520 | return 0; | 2612 | return 0; |
| 2521 | 2613 | ||
| 2522 | unregister_dev: | 2614 | unregister_dev: |
| 2523 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 2615 | v4l2_ctrl_handler_free(&v4l2->ctrl_handler); |
| 2524 | v4l2_device_unregister(&dev->v4l2_dev); | 2616 | v4l2_device_unregister(&v4l2->v4l2_dev); |
| 2525 | err: | 2617 | err: |
| 2618 | dev->v4l2 = NULL; | ||
| 2619 | kref_put(&v4l2->ref, em28xx_free_v4l2); | ||
| 2526 | mutex_unlock(&dev->lock); | 2620 | mutex_unlock(&dev->lock); |
| 2527 | return ret; | 2621 | return ret; |
| 2528 | } | 2622 | } |
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 2051fc9fb932..b4c837d77e5d 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h | |||
| @@ -140,6 +140,7 @@ | |||
| 140 | #define EM2765_BOARD_SPEEDLINK_VAD_LAPLACE 91 | 140 | #define EM2765_BOARD_SPEEDLINK_VAD_LAPLACE 91 |
| 141 | #define EM28178_BOARD_PCTV_461E 92 | 141 | #define EM28178_BOARD_PCTV_461E 92 |
| 142 | #define EM2874_BOARD_KWORLD_UB435Q_V3 93 | 142 | #define EM2874_BOARD_KWORLD_UB435Q_V3 93 |
| 143 | #define EM28178_BOARD_PCTV_292E 94 | ||
| 143 | 144 | ||
| 144 | /* Limits minimum and default number of buffers */ | 145 | /* Limits minimum and default number of buffers */ |
| 145 | #define EM28XX_MIN_BUF 4 | 146 | #define EM28XX_MIN_BUF 4 |
| @@ -497,6 +498,60 @@ struct em28xx_eeprom { | |||
| 497 | #define EM28XX_RESOURCE_VIDEO 0x01 | 498 | #define EM28XX_RESOURCE_VIDEO 0x01 |
| 498 | #define EM28XX_RESOURCE_VBI 0x02 | 499 | #define EM28XX_RESOURCE_VBI 0x02 |
| 499 | 500 | ||
| 501 | struct em28xx_v4l2 { | ||
| 502 | struct kref ref; | ||
| 503 | struct em28xx *dev; | ||
| 504 | |||
| 505 | struct v4l2_device v4l2_dev; | ||
| 506 | struct v4l2_ctrl_handler ctrl_handler; | ||
| 507 | struct v4l2_clk *clk; | ||
| 508 | |||
| 509 | struct video_device *vdev; | ||
| 510 | struct video_device *vbi_dev; | ||
| 511 | struct video_device *radio_dev; | ||
| 512 | |||
| 513 | /* Videobuf2 */ | ||
| 514 | struct vb2_queue vb_vidq; | ||
| 515 | struct vb2_queue vb_vbiq; | ||
| 516 | struct mutex vb_queue_lock; | ||
| 517 | struct mutex vb_vbi_queue_lock; | ||
| 518 | |||
| 519 | u8 vinmode; | ||
| 520 | u8 vinctl; | ||
| 521 | |||
| 522 | /* Camera specific fields */ | ||
| 523 | int sensor_xres; | ||
| 524 | int sensor_yres; | ||
| 525 | int sensor_xtal; | ||
| 526 | |||
| 527 | int users; /* user count for exclusive use */ | ||
| 528 | int streaming_users; /* number of actively streaming users */ | ||
| 529 | |||
| 530 | u32 frequency; /* selected tuner frequency */ | ||
| 531 | |||
| 532 | struct em28xx_fmt *format; | ||
| 533 | v4l2_std_id norm; /* selected tv norm */ | ||
| 534 | |||
| 535 | /* Progressive/interlaced mode */ | ||
| 536 | bool progressive; | ||
| 537 | int interlaced_fieldmode; /* 1=interlaced fields, 0=just top fields */ | ||
| 538 | /* FIXME: everything else than interlaced_fieldmode=1 doesn't work */ | ||
| 539 | |||
| 540 | /* Frame properties */ | ||
| 541 | int width; /* current frame width */ | ||
| 542 | int height; /* current frame height */ | ||
| 543 | unsigned hscale; /* horizontal scale factor (see datasheet) */ | ||
| 544 | unsigned vscale; /* vertical scale factor (see datasheet) */ | ||
| 545 | unsigned int vbi_width; | ||
| 546 | unsigned int vbi_height; /* lines per field */ | ||
| 547 | |||
| 548 | /* Capture state tracking */ | ||
| 549 | int capture_type; | ||
| 550 | bool top_field; | ||
| 551 | int vbi_read; | ||
| 552 | unsigned int field_count; | ||
| 553 | }; | ||
| 554 | |||
| 500 | struct em28xx_audio { | 555 | struct em28xx_audio { |
| 501 | char name[50]; | 556 | char name[50]; |
| 502 | unsigned num_urb; | 557 | unsigned num_urb; |
| @@ -513,6 +568,10 @@ struct em28xx_audio { | |||
| 513 | 568 | ||
| 514 | int users; | 569 | int users; |
| 515 | spinlock_t slock; | 570 | spinlock_t slock; |
| 571 | |||
| 572 | /* Controls streaming */ | ||
| 573 | struct work_struct wq_trigger; /* trigger to start/stop audio */ | ||
| 574 | atomic_t stream_started; /* stream should be running if true */ | ||
| 516 | }; | 575 | }; |
| 517 | 576 | ||
| 518 | struct em28xx; | 577 | struct em28xx; |
| @@ -541,6 +600,12 @@ struct em28xx_i2c_bus { | |||
| 541 | struct em28xx { | 600 | struct em28xx { |
| 542 | struct kref ref; | 601 | struct kref ref; |
| 543 | 602 | ||
| 603 | /* Sub-module data */ | ||
| 604 | struct em28xx_v4l2 *v4l2; | ||
| 605 | struct em28xx_dvb *dvb; | ||
| 606 | struct em28xx_audio adev; | ||
| 607 | struct em28xx_IR *ir; | ||
| 608 | |||
| 544 | /* generic device properties */ | 609 | /* generic device properties */ |
| 545 | char name[30]; /* name (including minor) of the device */ | 610 | char name[30]; /* name (including minor) of the device */ |
| 546 | int model; /* index in the device_data struct */ | 611 | int model; /* index in the device_data struct */ |
| @@ -554,29 +619,9 @@ struct em28xx { | |||
| 554 | unsigned int has_alsa_audio:1; | 619 | unsigned int has_alsa_audio:1; |
| 555 | unsigned int is_audio_only:1; | 620 | unsigned int is_audio_only:1; |
| 556 | 621 | ||
| 557 | struct v4l2_device v4l2_dev; | ||
| 558 | struct v4l2_ctrl_handler ctrl_handler; | ||
| 559 | struct v4l2_clk *clk; | ||
| 560 | struct em28xx_board board; | 622 | struct em28xx_board board; |
| 561 | 623 | ||
| 562 | /* Webcam specific fields */ | 624 | enum em28xx_sensor em28xx_sensor; /* camera specific */ |
| 563 | enum em28xx_sensor em28xx_sensor; | ||
| 564 | int sensor_xres, sensor_yres; | ||
| 565 | int sensor_xtal; | ||
| 566 | |||
| 567 | /* Progressive (non-interlaced) mode */ | ||
| 568 | int progressive; | ||
| 569 | |||
| 570 | /* Vinmode/Vinctl used at the driver */ | ||
| 571 | int vinmode, vinctl; | ||
| 572 | |||
| 573 | /* Controls audio streaming */ | ||
| 574 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ | ||
| 575 | atomic_t stream_started; /* stream should be running if true */ | ||
| 576 | |||
| 577 | struct em28xx_fmt *format; | ||
| 578 | |||
| 579 | struct em28xx_IR *ir; | ||
| 580 | 625 | ||
| 581 | /* Some older em28xx chips needs a waiting time after writing */ | 626 | /* Some older em28xx chips needs a waiting time after writing */ |
| 582 | unsigned int wait_after_write; | 627 | unsigned int wait_after_write; |
| @@ -588,8 +633,6 @@ struct em28xx { | |||
| 588 | struct em28xx_audio_mode audio_mode; | 633 | struct em28xx_audio_mode audio_mode; |
| 589 | 634 | ||
| 590 | int tuner_type; /* type of the tuner */ | 635 | int tuner_type; /* type of the tuner */ |
| 591 | int tuner_addr; /* tuner address */ | ||
| 592 | int tda9887_conf; | ||
| 593 | 636 | ||
| 594 | /* i2c i/o */ | 637 | /* i2c i/o */ |
| 595 | struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; | 638 | struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; |
| @@ -602,52 +645,21 @@ struct em28xx { | |||
| 602 | struct rt_mutex i2c_bus_lock; | 645 | struct rt_mutex i2c_bus_lock; |
| 603 | 646 | ||
| 604 | /* video for linux */ | 647 | /* video for linux */ |
| 605 | int users; /* user count for exclusive use */ | ||
| 606 | int streaming_users; /* Number of actively streaming users */ | ||
| 607 | struct video_device *vdev; /* video for linux device struct */ | ||
| 608 | v4l2_std_id norm; /* selected tv norm */ | ||
| 609 | int ctl_freq; /* selected frequency */ | ||
| 610 | unsigned int ctl_input; /* selected input */ | 648 | unsigned int ctl_input; /* selected input */ |
| 611 | unsigned int ctl_ainput;/* selected audio input */ | 649 | unsigned int ctl_ainput;/* selected audio input */ |
| 612 | unsigned int ctl_aoutput;/* selected audio output */ | 650 | unsigned int ctl_aoutput;/* selected audio output */ |
| 613 | int mute; | 651 | int mute; |
| 614 | int volume; | 652 | int volume; |
| 615 | /* frame properties */ | ||
| 616 | int width; /* current frame width */ | ||
| 617 | int height; /* current frame height */ | ||
| 618 | unsigned hscale; /* horizontal scale factor (see datasheet) */ | ||
| 619 | unsigned vscale; /* vertical scale factor (see datasheet) */ | ||
| 620 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ | ||
| 621 | unsigned int video_bytesread; /* Number of bytes read */ | ||
| 622 | 653 | ||
| 623 | unsigned long hash; /* eeprom hash - for boards with generic ID */ | 654 | unsigned long hash; /* eeprom hash - for boards with generic ID */ |
| 624 | unsigned long i2c_hash; /* i2c devicelist hash - | 655 | unsigned long i2c_hash; /* i2c devicelist hash - |
| 625 | for boards with generic ID */ | 656 | for boards with generic ID */ |
| 626 | 657 | ||
| 627 | struct em28xx_audio adev; | ||
| 628 | |||
| 629 | /* capture state tracking */ | ||
| 630 | int capture_type; | ||
| 631 | unsigned char top_field:1; | ||
| 632 | int vbi_read; | ||
| 633 | unsigned int vbi_width; | ||
| 634 | unsigned int vbi_height; /* lines per field */ | ||
| 635 | |||
| 636 | struct work_struct request_module_wk; | 658 | struct work_struct request_module_wk; |
| 637 | 659 | ||
| 638 | /* locks */ | 660 | /* locks */ |
| 639 | struct mutex lock; | 661 | struct mutex lock; |
| 640 | struct mutex ctrl_urb_lock; /* protects urb_buf */ | 662 | struct mutex ctrl_urb_lock; /* protects urb_buf */ |
| 641 | /* spinlock_t queue_lock; */ | ||
| 642 | struct list_head inqueue, outqueue; | ||
| 643 | struct video_device *vbi_dev; | ||
| 644 | struct video_device *radio_dev; | ||
| 645 | |||
| 646 | /* Videobuf2 */ | ||
| 647 | struct vb2_queue vb_vidq; | ||
| 648 | struct vb2_queue vb_vbiq; | ||
| 649 | struct mutex vb_queue_lock; | ||
| 650 | struct mutex vb_vbi_queue_lock; | ||
| 651 | 663 | ||
| 652 | /* resources in use */ | 664 | /* resources in use */ |
| 653 | unsigned int resources; | 665 | unsigned int resources; |
| @@ -662,9 +674,6 @@ struct em28xx { | |||
| 662 | struct em28xx_usb_ctl usb_ctl; | 674 | struct em28xx_usb_ctl usb_ctl; |
| 663 | spinlock_t slock; | 675 | spinlock_t slock; |
| 664 | 676 | ||
| 665 | unsigned int field_count; | ||
| 666 | unsigned int vbi_field_count; | ||
| 667 | |||
| 668 | /* usb transfer */ | 677 | /* usb transfer */ |
| 669 | struct usb_device *udev; /* the usb device */ | 678 | struct usb_device *udev; /* the usb device */ |
| 670 | u8 ifnum; /* number of the assigned usb interface */ | 679 | u8 ifnum; /* number of the assigned usb interface */ |
| @@ -708,8 +717,6 @@ struct em28xx { | |||
| 708 | /* Snapshot button input device */ | 717 | /* Snapshot button input device */ |
| 709 | char snapshot_button_path[30]; /* path of the input dev */ | 718 | char snapshot_button_path[30]; /* path of the input dev */ |
| 710 | struct input_dev *sbutton_input_dev; | 719 | struct input_dev *sbutton_input_dev; |
| 711 | |||
| 712 | struct em28xx_dvb *dvb; | ||
| 713 | }; | 720 | }; |
| 714 | 721 | ||
| 715 | #define kref_to_dev(d) container_of(d, struct em28xx, ref) | 722 | #define kref_to_dev(d) container_of(d, struct em28xx, ref) |
| @@ -797,32 +804,4 @@ int em28xx_init_camera(struct em28xx *dev); | |||
| 797 | printk(KERN_WARNING "%s: "fmt,\ | 804 | printk(KERN_WARNING "%s: "fmt,\ |
| 798 | dev->name , ##arg); } while (0) | 805 | dev->name , ##arg); } while (0) |
| 799 | 806 | ||
| 800 | static inline int em28xx_compression_disable(struct em28xx *dev) | ||
| 801 | { | ||
| 802 | /* side effect of disabling scaler and mixer */ | ||
| 803 | return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00); | ||
| 804 | } | ||
| 805 | |||
| 806 | /*FIXME: maxw should be dependent of alt mode */ | ||
| 807 | static inline unsigned int norm_maxw(struct em28xx *dev) | ||
| 808 | { | ||
| 809 | if (dev->board.is_webcam) | ||
| 810 | return dev->sensor_xres; | ||
| 811 | |||
| 812 | if (dev->board.max_range_640_480) | ||
| 813 | return 640; | ||
| 814 | |||
| 815 | return 720; | ||
| 816 | } | ||
| 817 | |||
| 818 | static inline unsigned int norm_maxh(struct em28xx *dev) | ||
| 819 | { | ||
| 820 | if (dev->board.is_webcam) | ||
| 821 | return dev->sensor_yres; | ||
| 822 | |||
| 823 | if (dev->board.max_range_640_480) | ||
| 824 | return 480; | ||
| 825 | |||
| 826 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; | ||
| 827 | } | ||
| 828 | #endif | 807 | #endif |
diff --git a/drivers/media/usb/gspca/Kconfig b/drivers/media/usb/gspca/Kconfig index 4f0c6d566c85..eed10d782535 100644 --- a/drivers/media/usb/gspca/Kconfig +++ b/drivers/media/usb/gspca/Kconfig | |||
| @@ -50,6 +50,16 @@ config USB_GSPCA_CPIA1 | |||
| 50 | To compile this driver as a module, choose M here: the | 50 | To compile this driver as a module, choose M here: the |
| 51 | module will be called gspca_cpia1. | 51 | module will be called gspca_cpia1. |
| 52 | 52 | ||
| 53 | config USB_GSPCA_DTCS033 | ||
| 54 | tristate "DTCS033 (Scopium) USB Astro-Camera Driver" | ||
| 55 | depends on VIDEO_V4L2 && USB_GSPCA | ||
| 56 | help | ||
| 57 | Say Y here if you want support for the Scopium camera | ||
| 58 | for planetary astrophotography. | ||
| 59 | |||
| 60 | To compile this driver as a module, choose M here: the | ||
| 61 | module will be called gspca_dtcs033. | ||
| 62 | |||
| 53 | config USB_GSPCA_ETOMS | 63 | config USB_GSPCA_ETOMS |
| 54 | tristate "Etoms USB Camera Driver" | 64 | tristate "Etoms USB Camera Driver" |
| 55 | depends on VIDEO_V4L2 && USB_GSPCA | 65 | depends on VIDEO_V4L2 && USB_GSPCA |
diff --git a/drivers/media/usb/gspca/Makefile b/drivers/media/usb/gspca/Makefile index 5855131ab8b6..f46975e4c82d 100644 --- a/drivers/media/usb/gspca/Makefile +++ b/drivers/media/usb/gspca/Makefile | |||
| @@ -2,6 +2,7 @@ obj-$(CONFIG_USB_GSPCA) += gspca_main.o | |||
| 2 | obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o | 2 | obj-$(CONFIG_USB_GSPCA_BENQ) += gspca_benq.o |
| 3 | obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o | 3 | obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o |
| 4 | obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o | 4 | obj-$(CONFIG_USB_GSPCA_CPIA1) += gspca_cpia1.o |
| 5 | obj-$(CONFIG_USB_GSPCA_DTCS033) += gspca_dtcs033.o | ||
| 5 | obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o | 6 | obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o |
| 6 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o | 7 | obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o |
| 7 | obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o | 8 | obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o |
| @@ -48,6 +49,7 @@ gspca_main-objs := gspca.o autogain_functions.o | |||
| 48 | gspca_benq-objs := benq.o | 49 | gspca_benq-objs := benq.o |
| 49 | gspca_conex-objs := conex.o | 50 | gspca_conex-objs := conex.o |
| 50 | gspca_cpia1-objs := cpia1.o | 51 | gspca_cpia1-objs := cpia1.o |
| 52 | gspca_dtcs033-objs := dtcs033.o | ||
| 51 | gspca_etoms-objs := etoms.o | 53 | gspca_etoms-objs := etoms.o |
| 52 | gspca_finepix-objs := finepix.o | 54 | gspca_finepix-objs := finepix.o |
| 53 | gspca_jeilinj-objs := jeilinj.o | 55 | gspca_jeilinj-objs := jeilinj.o |
diff --git a/drivers/media/usb/gspca/dtcs033.c b/drivers/media/usb/gspca/dtcs033.c new file mode 100644 index 000000000000..96bfd4e0f0eb --- /dev/null +++ b/drivers/media/usb/gspca/dtcs033.c | |||
| @@ -0,0 +1,441 @@ | |||
| 1 | /* | ||
| 2 | * Subdriver for Scopium astro-camera (DTCS033, 0547:7303) | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Robert Butora (robert.butora.fi@gmail.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 18 | #define MODULE_NAME "dtcs033" | ||
| 19 | #include "gspca.h" | ||
| 20 | |||
| 21 | MODULE_AUTHOR("Robert Butora <robert.butora.fi@gmail.com>"); | ||
| 22 | MODULE_DESCRIPTION("Scopium DTCS033 astro-cam USB Camera Driver"); | ||
| 23 | MODULE_LICENSE("GPL"); | ||
| 24 | |||
| 25 | struct dtcs033_usb_requests { | ||
| 26 | u8 bRequestType; | ||
| 27 | u8 bRequest; | ||
| 28 | u16 wValue; | ||
| 29 | u16 wIndex; | ||
| 30 | u16 wLength; | ||
| 31 | }; | ||
| 32 | |||
| 33 | /* send a usb request */ | ||
| 34 | static void reg_rw(struct gspca_dev *gspca_dev, | ||
| 35 | u8 bRequestType, u8 bRequest, | ||
| 36 | u16 wValue, u16 wIndex, u16 wLength) | ||
| 37 | { | ||
| 38 | struct usb_device *udev = gspca_dev->dev; | ||
| 39 | int ret; | ||
| 40 | |||
| 41 | if (gspca_dev->usb_err < 0) | ||
| 42 | return; | ||
| 43 | |||
| 44 | ret = usb_control_msg(udev, | ||
| 45 | usb_rcvctrlpipe(udev, 0), | ||
| 46 | bRequest, | ||
| 47 | bRequestType, | ||
| 48 | wValue, wIndex, | ||
| 49 | gspca_dev->usb_buf, wLength, 500); | ||
| 50 | |||
| 51 | if (ret < 0) { | ||
| 52 | gspca_dev->usb_err = ret; | ||
| 53 | pr_err("usb_control_msg error %d\n", ret); | ||
| 54 | } | ||
| 55 | |||
| 56 | return; | ||
| 57 | } | ||
| 58 | /* send several usb in/out requests */ | ||
| 59 | static int reg_reqs(struct gspca_dev *gspca_dev, | ||
| 60 | const struct dtcs033_usb_requests *preqs, int n_reqs) | ||
| 61 | { | ||
| 62 | int i = 0; | ||
| 63 | const struct dtcs033_usb_requests *preq; | ||
| 64 | |||
| 65 | while ((i < n_reqs) && (gspca_dev->usb_err >= 0)) { | ||
| 66 | |||
| 67 | preq = &preqs[i]; | ||
| 68 | |||
| 69 | reg_rw(gspca_dev, preq->bRequestType, preq->bRequest, | ||
| 70 | preq->wValue, preq->wIndex, preq->wLength); | ||
| 71 | |||
| 72 | if (gspca_dev->usb_err < 0) { | ||
| 73 | |||
| 74 | PERR("usb error request no: %d / %d\n", | ||
| 75 | i, n_reqs); | ||
| 76 | } else if (preq->bRequestType & USB_DIR_IN) { | ||
| 77 | |||
| 78 | PDEBUG(D_STREAM, | ||
| 79 | "USB IN (%d) returned[%d] %02X %02X %02X %s", | ||
| 80 | i, | ||
| 81 | preq->wLength, | ||
| 82 | gspca_dev->usb_buf[0], | ||
| 83 | gspca_dev->usb_buf[1], | ||
| 84 | gspca_dev->usb_buf[2], | ||
| 85 | preq->wLength > 3 ? "...\n" : "\n"); | ||
| 86 | } | ||
| 87 | |||
| 88 | i++; | ||
| 89 | } | ||
| 90 | return gspca_dev->usb_err; | ||
| 91 | } | ||
| 92 | |||
| 93 | /* -- subdriver interface implementation -- */ | ||
| 94 | |||
| 95 | #define DT_COLS (640) | ||
| 96 | static const struct v4l2_pix_format dtcs033_mode[] = { | ||
| 97 | /* raw Bayer patterned output */ | ||
| 98 | {DT_COLS, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, | ||
| 99 | .bytesperline = DT_COLS, | ||
| 100 | .sizeimage = DT_COLS*480, | ||
| 101 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 102 | }, | ||
| 103 | /* this mode will demosaic the Bayer pattern */ | ||
| 104 | {DT_COLS, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE, | ||
| 105 | .bytesperline = DT_COLS, | ||
| 106 | .sizeimage = DT_COLS*480, | ||
| 107 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 108 | } | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* config called at probe time */ | ||
| 112 | static int sd_config(struct gspca_dev *gspca_dev, | ||
| 113 | const struct usb_device_id *id) | ||
| 114 | { | ||
| 115 | gspca_dev->cam.cam_mode = dtcs033_mode; | ||
| 116 | gspca_dev->cam.nmodes = ARRAY_SIZE(dtcs033_mode); | ||
| 117 | |||
| 118 | gspca_dev->cam.bulk = 1; | ||
| 119 | gspca_dev->cam.bulk_nurbs = 1; | ||
| 120 | gspca_dev->cam.bulk_size = DT_COLS*512; | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | /* init called at probe and resume time */ | ||
| 126 | static int sd_init(struct gspca_dev *gspca_dev) | ||
| 127 | { | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | /* start stop the camera */ | ||
| 132 | static int dtcs033_start(struct gspca_dev *gspca_dev); | ||
| 133 | static void dtcs033_stopN(struct gspca_dev *gspca_dev); | ||
| 134 | |||
| 135 | /* intercept camera image data */ | ||
| 136 | static void dtcs033_pkt_scan(struct gspca_dev *gspca_dev, | ||
| 137 | u8 *data, /* packet data */ | ||
| 138 | int len) /* packet data length */ | ||
| 139 | { | ||
| 140 | /* drop incomplete frames */ | ||
| 141 | if (len != DT_COLS*512) { | ||
| 142 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
| 143 | /* gspca.c: discard invalidates the whole frame. */ | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | |||
| 147 | /* forward complete frames */ | ||
| 148 | gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0); | ||
| 149 | gspca_frame_add(gspca_dev, INTER_PACKET, | ||
| 150 | data + 16*DT_COLS, | ||
| 151 | len - 32*DT_COLS); /* skip first & last 16 lines */ | ||
| 152 | gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); | ||
| 153 | |||
| 154 | return; | ||
| 155 | } | ||
| 156 | |||
| 157 | /* -- controls: exposure and gain -- */ | ||
| 158 | |||
| 159 | static void dtcs033_setexposure(struct gspca_dev *gspca_dev, | ||
| 160 | s32 expo, s32 gain) | ||
| 161 | { | ||
| 162 | /* gain [dB] encoding */ | ||
| 163 | u16 sGain = (u16)gain; | ||
| 164 | u16 gainVal = 224+(sGain-14)*(768-224)/(33-14); | ||
| 165 | u16 wIndex = 0x0100|(0x00FF&gainVal); | ||
| 166 | u16 wValue = (0xFF00&gainVal)>>8; | ||
| 167 | |||
| 168 | /* exposure time [msec] encoding */ | ||
| 169 | u16 sXTime = (u16)expo; | ||
| 170 | u16 xtimeVal = (524*(150-(sXTime-1)))/150; | ||
| 171 | |||
| 172 | const u8 bRequestType = | ||
| 173 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; | ||
| 174 | const u8 bRequest = 0x18; | ||
| 175 | |||
| 176 | reg_rw(gspca_dev, | ||
| 177 | bRequestType, bRequest, wValue, wIndex, 0); | ||
| 178 | if (gspca_dev->usb_err < 0) | ||
| 179 | PERR("usb error in setexposure(gain) sequence.\n"); | ||
| 180 | |||
| 181 | reg_rw(gspca_dev, | ||
| 182 | bRequestType, bRequest, (xtimeVal<<4), 0x6300, 0); | ||
| 183 | if (gspca_dev->usb_err < 0) | ||
| 184 | PERR("usb error in setexposure(time) sequence.\n"); | ||
| 185 | } | ||
| 186 | |||
| 187 | /* specific webcam descriptor */ | ||
| 188 | struct sd { | ||
| 189 | struct gspca_dev gspca_dev;/* !! must be the first item */ | ||
| 190 | |||
| 191 | /* exposure & gain controls */ | ||
| 192 | struct { | ||
| 193 | struct v4l2_ctrl *exposure; | ||
| 194 | struct v4l2_ctrl *gain; | ||
| 195 | }; | ||
| 196 | }; | ||
| 197 | |||
| 198 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | ||
| 199 | { | ||
| 200 | struct gspca_dev *gspca_dev = | ||
| 201 | container_of(ctrl->handler, | ||
| 202 | struct gspca_dev, ctrl_handler); | ||
| 203 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 204 | |||
| 205 | gspca_dev->usb_err = 0; | ||
| 206 | |||
| 207 | if (!gspca_dev->streaming) | ||
| 208 | return 0; | ||
| 209 | |||
| 210 | switch (ctrl->id) { | ||
| 211 | case V4L2_CID_EXPOSURE: | ||
| 212 | dtcs033_setexposure(gspca_dev, | ||
| 213 | ctrl->val, sd->gain->val); | ||
| 214 | break; | ||
| 215 | case V4L2_CID_GAIN: | ||
| 216 | dtcs033_setexposure(gspca_dev, | ||
| 217 | sd->exposure->val, ctrl->val); | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | return gspca_dev->usb_err; | ||
| 221 | } | ||
| 222 | |||
| 223 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { | ||
| 224 | .s_ctrl = sd_s_ctrl, | ||
| 225 | }; | ||
| 226 | |||
| 227 | static int dtcs033_init_controls(struct gspca_dev *gspca_dev) | ||
| 228 | { | ||
| 229 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
| 230 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 231 | |||
| 232 | gspca_dev->vdev.ctrl_handler = hdl; | ||
| 233 | v4l2_ctrl_handler_init(hdl, 2); | ||
| 234 | /* min max step default */ | ||
| 235 | sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
| 236 | V4L2_CID_EXPOSURE, | ||
| 237 | 1, 150, 1, 75);/* [msec] */ | ||
| 238 | sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
| 239 | V4L2_CID_GAIN, | ||
| 240 | 14, 33, 1, 24);/* [dB] */ | ||
| 241 | if (hdl->error) { | ||
| 242 | PERR("Could not initialize controls: %d\n", | ||
| 243 | hdl->error); | ||
| 244 | return hdl->error; | ||
| 245 | } | ||
| 246 | |||
| 247 | v4l2_ctrl_cluster(2, &sd->exposure); | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | /* sub-driver description */ | ||
| 252 | static const struct sd_desc sd_desc = { | ||
| 253 | .name = MODULE_NAME, | ||
| 254 | .config = sd_config, | ||
| 255 | .init = sd_init, | ||
| 256 | .start = dtcs033_start, | ||
| 257 | .stopN = dtcs033_stopN, | ||
| 258 | .pkt_scan = dtcs033_pkt_scan, | ||
| 259 | .init_controls = dtcs033_init_controls, | ||
| 260 | }; | ||
| 261 | |||
| 262 | /* -- module initialisation -- */ | ||
| 263 | |||
| 264 | static const struct usb_device_id device_table[] = { | ||
| 265 | {USB_DEVICE(0x0547, 0x7303)}, | ||
| 266 | {} | ||
| 267 | }; | ||
| 268 | MODULE_DEVICE_TABLE(usb, device_table); | ||
| 269 | |||
| 270 | /* device connect */ | ||
| 271 | static int sd_probe(struct usb_interface *intf, | ||
| 272 | const struct usb_device_id *id) | ||
| 273 | { | ||
| 274 | return gspca_dev_probe(intf, id, | ||
| 275 | &sd_desc, sizeof(struct sd), | ||
| 276 | THIS_MODULE); | ||
| 277 | } | ||
| 278 | |||
| 279 | static struct usb_driver sd_driver = { | ||
| 280 | .name = MODULE_NAME, | ||
| 281 | .id_table = device_table, | ||
| 282 | .probe = sd_probe, | ||
| 283 | .disconnect = gspca_disconnect, | ||
| 284 | #ifdef CONFIG_PM | ||
| 285 | .suspend = gspca_suspend, | ||
| 286 | .resume = gspca_resume, | ||
| 287 | .reset_resume = gspca_resume, | ||
| 288 | #endif | ||
| 289 | }; | ||
| 290 | module_usb_driver(sd_driver); | ||
| 291 | |||
| 292 | |||
| 293 | /* --------------------------------------------------------- | ||
| 294 | USB requests to start/stop the camera [USB 2.0 spec Ch.9]. | ||
| 295 | |||
| 296 | bRequestType : | ||
| 297 | 0x40 = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 298 | 0xC0 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 299 | */ | ||
| 300 | static const struct dtcs033_usb_requests dtcs033_start_reqs[] = { | ||
| 301 | /* -- bRequest,wValue,wIndex,wLength */ | ||
| 302 | { 0x40, 0x01, 0x0001, 0x000F, 0x0000 }, | ||
| 303 | { 0x40, 0x01, 0x0000, 0x000F, 0x0000 }, | ||
| 304 | { 0x40, 0x01, 0x0001, 0x000F, 0x0000 }, | ||
| 305 | { 0x40, 0x18, 0x0000, 0x7F00, 0x0000 }, | ||
| 306 | { 0x40, 0x18, 0x0000, 0x1001, 0x0000 }, | ||
| 307 | { 0x40, 0x18, 0x0000, 0x0004, 0x0000 }, | ||
| 308 | { 0x40, 0x18, 0x0000, 0x7F01, 0x0000 }, | ||
| 309 | { 0x40, 0x18, 0x30E0, 0x0009, 0x0000 }, | ||
| 310 | { 0x40, 0x18, 0x0500, 0x012C, 0x0000 }, | ||
| 311 | { 0x40, 0x18, 0x0380, 0x0200, 0x0000 }, | ||
| 312 | { 0x40, 0x18, 0x0000, 0x035C, 0x0000 }, | ||
| 313 | { 0x40, 0x18, 0x05C0, 0x0438, 0x0000 }, | ||
| 314 | { 0x40, 0x18, 0x0440, 0x0500, 0x0000 }, | ||
| 315 | { 0x40, 0x18, 0x0000, 0x0668, 0x0000 }, | ||
| 316 | { 0x40, 0x18, 0x0000, 0x0700, 0x0000 }, | ||
| 317 | { 0x40, 0x18, 0x0000, 0x0800, 0x0000 }, | ||
| 318 | { 0x40, 0x18, 0x0000, 0x0900, 0x0000 }, | ||
| 319 | { 0x40, 0x18, 0x0000, 0x0A00, 0x0000 }, | ||
| 320 | { 0x40, 0x18, 0x0000, 0x0B00, 0x0000 }, | ||
| 321 | { 0x40, 0x18, 0x30E0, 0x6009, 0x0000 }, | ||
| 322 | { 0x40, 0x18, 0x0500, 0x612C, 0x0000 }, | ||
| 323 | { 0x40, 0x18, 0x2090, 0x6274, 0x0000 }, | ||
| 324 | { 0x40, 0x18, 0x05C0, 0x6338, 0x0000 }, | ||
| 325 | { 0x40, 0x18, 0x0000, 0x6400, 0x0000 }, | ||
| 326 | { 0x40, 0x18, 0x05C0, 0x6538, 0x0000 }, | ||
| 327 | { 0x40, 0x18, 0x0000, 0x6600, 0x0000 }, | ||
| 328 | { 0x40, 0x18, 0x0680, 0x6744, 0x0000 }, | ||
| 329 | { 0x40, 0x18, 0x0000, 0x6800, 0x0000 }, | ||
| 330 | { 0x40, 0x18, 0x0000, 0x6900, 0x0000 }, | ||
| 331 | { 0x40, 0x18, 0x0000, 0x6A00, 0x0000 }, | ||
| 332 | { 0x40, 0x18, 0x0000, 0x6B00, 0x0000 }, | ||
| 333 | { 0x40, 0x18, 0x0000, 0x6C00, 0x0000 }, | ||
| 334 | { 0x40, 0x18, 0x0000, 0x6D00, 0x0000 }, | ||
| 335 | { 0x40, 0x18, 0x0000, 0x6E00, 0x0000 }, | ||
| 336 | { 0x40, 0x18, 0x0000, 0x808C, 0x0000 }, | ||
| 337 | { 0x40, 0x18, 0x0010, 0x8101, 0x0000 }, | ||
| 338 | { 0x40, 0x18, 0x30E0, 0x8200, 0x0000 }, | ||
| 339 | { 0x40, 0x18, 0x0810, 0x832C, 0x0000 }, | ||
| 340 | { 0x40, 0x18, 0x0680, 0x842B, 0x0000 }, | ||
| 341 | { 0x40, 0x18, 0x0000, 0x8500, 0x0000 }, | ||
| 342 | { 0x40, 0x18, 0x0000, 0x8600, 0x0000 }, | ||
| 343 | { 0x40, 0x18, 0x0280, 0x8715, 0x0000 }, | ||
| 344 | { 0x40, 0x18, 0x0000, 0x880C, 0x0000 }, | ||
| 345 | { 0x40, 0x18, 0x0010, 0x8901, 0x0000 }, | ||
| 346 | { 0x40, 0x18, 0x30E0, 0x8A00, 0x0000 }, | ||
| 347 | { 0x40, 0x18, 0x0810, 0x8B2C, 0x0000 }, | ||
| 348 | { 0x40, 0x18, 0x0680, 0x8C2B, 0x0000 }, | ||
| 349 | { 0x40, 0x18, 0x0000, 0x8D00, 0x0000 }, | ||
| 350 | { 0x40, 0x18, 0x0000, 0x8E00, 0x0000 }, | ||
| 351 | { 0x40, 0x18, 0x0280, 0x8F15, 0x0000 }, | ||
| 352 | { 0x40, 0x18, 0x0010, 0xD040, 0x0000 }, | ||
| 353 | { 0x40, 0x18, 0x0000, 0xD100, 0x0000 }, | ||
| 354 | { 0x40, 0x18, 0x00B0, 0xD20A, 0x0000 }, | ||
| 355 | { 0x40, 0x18, 0x0000, 0xD300, 0x0000 }, | ||
| 356 | { 0x40, 0x18, 0x30E2, 0xD40D, 0x0000 }, | ||
| 357 | { 0x40, 0x18, 0x0001, 0xD5C0, 0x0000 }, | ||
| 358 | { 0x40, 0x18, 0x00A0, 0xD60A, 0x0000 }, | ||
| 359 | { 0x40, 0x18, 0x0000, 0xD700, 0x0000 }, | ||
| 360 | { 0x40, 0x18, 0x0000, 0x7F00, 0x0000 }, | ||
| 361 | { 0x40, 0x18, 0x0000, 0x1501, 0x0000 }, | ||
| 362 | { 0x40, 0x18, 0x0001, 0x01FF, 0x0000 }, | ||
| 363 | { 0x40, 0x18, 0x0000, 0x0200, 0x0000 }, | ||
| 364 | { 0x40, 0x18, 0x0000, 0x0304, 0x0000 }, | ||
| 365 | { 0x40, 0x18, 0x0000, 0x1101, 0x0000 }, | ||
| 366 | { 0x40, 0x18, 0x0000, 0x1201, 0x0000 }, | ||
| 367 | { 0x40, 0x18, 0x0000, 0x1300, 0x0000 }, | ||
| 368 | { 0x40, 0x18, 0x0000, 0x1400, 0x0000 }, | ||
| 369 | { 0x40, 0x18, 0x0000, 0x1601, 0x0000 }, | ||
| 370 | { 0x40, 0x18, 0x0000, 0x1800, 0x0000 }, | ||
| 371 | { 0x40, 0x18, 0x0000, 0x1900, 0x0000 }, | ||
| 372 | { 0x40, 0x18, 0x0000, 0x1A00, 0x0000 }, | ||
| 373 | { 0x40, 0x18, 0x2000, 0x1B00, 0x0000 }, | ||
| 374 | { 0x40, 0x18, 0x0000, 0x1C00, 0x0000 }, | ||
| 375 | { 0x40, 0x18, 0x0000, 0x2100, 0x0000 }, | ||
| 376 | { 0x40, 0x18, 0x00C0, 0x228E, 0x0000 }, | ||
| 377 | { 0x40, 0x18, 0x0000, 0x3001, 0x0000 }, | ||
| 378 | { 0x40, 0x18, 0x0010, 0x3101, 0x0000 }, | ||
| 379 | { 0x40, 0x18, 0x0008, 0x3301, 0x0000 }, | ||
| 380 | { 0x40, 0x18, 0x0000, 0x3400, 0x0000 }, | ||
| 381 | { 0x40, 0x18, 0x0012, 0x3549, 0x0000 }, | ||
| 382 | { 0x40, 0x18, 0x0000, 0x3620, 0x0000 }, | ||
| 383 | { 0x40, 0x18, 0x0001, 0x3700, 0x0000 }, | ||
| 384 | { 0x40, 0x18, 0x0000, 0x4000, 0x0000 }, | ||
| 385 | { 0x40, 0x18, 0xFFFF, 0x41FF, 0x0000 }, | ||
| 386 | { 0x40, 0x18, 0xFFFF, 0x42FF, 0x0000 }, | ||
| 387 | { 0x40, 0x18, 0x0000, 0x500F, 0x0000 }, | ||
| 388 | { 0x40, 0x18, 0x2272, 0x5108, 0x0000 }, | ||
| 389 | { 0x40, 0x18, 0x2272, 0x5208, 0x0000 }, | ||
| 390 | { 0x40, 0x18, 0xFFFF, 0x53FF, 0x0000 }, | ||
| 391 | { 0x40, 0x18, 0xFFFF, 0x54FF, 0x0000 }, | ||
| 392 | { 0x40, 0x18, 0x0000, 0x6000, 0x0000 }, | ||
| 393 | { 0x40, 0x18, 0x0000, 0x6102, 0x0000 }, | ||
| 394 | { 0x40, 0x18, 0x0010, 0x6214, 0x0000 }, | ||
| 395 | { 0x40, 0x18, 0x0C80, 0x6300, 0x0000 }, | ||
| 396 | { 0x40, 0x18, 0x0000, 0x6401, 0x0000 }, | ||
| 397 | { 0x40, 0x18, 0x0680, 0x6551, 0x0000 }, | ||
| 398 | { 0x40, 0x18, 0xFFFF, 0x66FF, 0x0000 }, | ||
| 399 | { 0x40, 0x18, 0x0000, 0x6702, 0x0000 }, | ||
| 400 | { 0x40, 0x18, 0x0010, 0x6800, 0x0000 }, | ||
| 401 | { 0x40, 0x18, 0x0000, 0x6900, 0x0000 }, | ||
| 402 | { 0x40, 0x18, 0x0000, 0x6A00, 0x0000 }, | ||
| 403 | { 0x40, 0x18, 0x0000, 0x6B00, 0x0000 }, | ||
| 404 | { 0x40, 0x18, 0x0000, 0x6C00, 0x0000 }, | ||
| 405 | { 0x40, 0x18, 0x0000, 0x6D01, 0x0000 }, | ||
| 406 | { 0x40, 0x18, 0x0000, 0x6E00, 0x0000 }, | ||
| 407 | { 0x40, 0x18, 0x0000, 0x6F00, 0x0000 }, | ||
| 408 | { 0x40, 0x18, 0x0000, 0x7000, 0x0000 }, | ||
| 409 | { 0x40, 0x18, 0x0001, 0x7118, 0x0000 }, | ||
| 410 | { 0x40, 0x18, 0x0000, 0x2001, 0x0000 }, | ||
| 411 | { 0x40, 0x18, 0x0000, 0x1101, 0x0000 }, | ||
| 412 | { 0x40, 0x18, 0x0000, 0x1301, 0x0000 }, | ||
| 413 | { 0x40, 0x18, 0x0000, 0x1300, 0x0000 }, | ||
| 414 | { 0x40, 0x18, 0x0000, 0x1501, 0x0000 }, | ||
| 415 | { 0xC0, 0x11, 0x0000, 0x24C0, 0x0003 }, | ||
| 416 | { 0x40, 0x18, 0x0000, 0x3000, 0x0000 }, | ||
| 417 | { 0x40, 0x18, 0x0000, 0x3620, 0x0000 }, | ||
| 418 | { 0x40, 0x18, 0x0000, 0x1501, 0x0000 }, | ||
| 419 | { 0x40, 0x18, 0x0010, 0x6300, 0x0000 }, | ||
| 420 | { 0x40, 0x18, 0x0002, 0x01F0, 0x0000 }, | ||
| 421 | { 0x40, 0x01, 0x0003, 0x000F, 0x0000 } | ||
| 422 | }; | ||
| 423 | |||
| 424 | static const struct dtcs033_usb_requests dtcs033_stop_reqs[] = { | ||
| 425 | /* -- bRequest,wValue,wIndex,wLength */ | ||
| 426 | { 0x40, 0x01, 0x0001, 0x000F, 0x0000 }, | ||
| 427 | { 0x40, 0x01, 0x0000, 0x000F, 0x0000 }, | ||
| 428 | { 0x40, 0x18, 0x0000, 0x0003, 0x0000 } | ||
| 429 | }; | ||
| 430 | static int dtcs033_start(struct gspca_dev *gspca_dev) | ||
| 431 | { | ||
| 432 | return reg_reqs(gspca_dev, dtcs033_start_reqs, | ||
| 433 | ARRAY_SIZE(dtcs033_start_reqs)); | ||
| 434 | } | ||
| 435 | |||
| 436 | static void dtcs033_stopN(struct gspca_dev *gspca_dev) | ||
| 437 | { | ||
| 438 | reg_reqs(gspca_dev, dtcs033_stop_reqs, | ||
| 439 | ARRAY_SIZE(dtcs033_stop_reqs)); | ||
| 440 | return; | ||
| 441 | } | ||
diff --git a/drivers/media/usb/gspca/gl860/gl860-mi2020.c b/drivers/media/usb/gspca/gl860/gl860-mi2020.c index 2edda6b7d653..a785828d4b9d 100644 --- a/drivers/media/usb/gspca/gl860/gl860-mi2020.c +++ b/drivers/media/usb/gspca/gl860/gl860-mi2020.c | |||
| @@ -35,32 +35,34 @@ static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03}; | |||
| 35 | static u8 dat_hvflip6[] = {0x90, 0x00, 0x06}; | 35 | static u8 dat_hvflip6[] = {0x90, 0x00, 0x06}; |
| 36 | 36 | ||
| 37 | static struct idxdata tbl_middle_hvflip_low[] = { | 37 | static struct idxdata tbl_middle_hvflip_low[] = { |
| 38 | {0x33, "\x90\x00\x06"}, | 38 | {0x33, {0x90, 0x00, 0x06}}, |
| 39 | {6, "\xff\xff\xff"}, | 39 | {6, {0xff, 0xff, 0xff}}, |
| 40 | {0x33, "\x90\x00\x06"}, | 40 | {0x33, {0x90, 0x00, 0x06}}, |
| 41 | {6, "\xff\xff\xff"}, | 41 | {6, {0xff, 0xff, 0xff}}, |
| 42 | {0x33, "\x90\x00\x06"}, | 42 | {0x33, {0x90, 0x00, 0x06}}, |
| 43 | {6, "\xff\xff\xff"}, | 43 | {6, {0xff, 0xff, 0xff}}, |
| 44 | {0x33, "\x90\x00\x06"}, | 44 | {0x33, {0x90, 0x00, 0x06}}, |
| 45 | {6, "\xff\xff\xff"}, | 45 | {6, {0xff, 0xff, 0xff}}, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | static struct idxdata tbl_middle_hvflip_big[] = { | 48 | static struct idxdata tbl_middle_hvflip_big[] = { |
| 49 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa1\x20"}, | 49 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, |
| 50 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"}, | 50 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, |
| 51 | {102, "\xff\xff\xff"}, | 51 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, |
| 52 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x20"}, | 52 | {102, {0xff, 0xff, 0xff}}, |
| 53 | {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, | 53 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, |
| 54 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, | ||
| 55 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, | ||
| 54 | }; | 56 | }; |
| 55 | 57 | ||
| 56 | static struct idxdata tbl_end_hvflip[] = { | 58 | static struct idxdata tbl_end_hvflip[] = { |
| 57 | {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, | 59 | {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, |
| 58 | {6, "\xff\xff\xff"}, | 60 | {6, {0xff, 0xff, 0xff}}, |
| 59 | {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, | 61 | {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, |
| 60 | {6, "\xff\xff\xff"}, | 62 | {6, {0xff, 0xff, 0xff}}, |
| 61 | {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, | 63 | {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, |
| 62 | {6, "\xff\xff\xff"}, | 64 | {6, {0xff, 0xff, 0xff}}, |
| 63 | {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, | 65 | {0x33, {0x8c, 0xa1, 0x02}}, {0x33, {0x90, 0x00, 0x1f}}, |
| 64 | }; | 66 | }; |
| 65 | 67 | ||
| 66 | static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 }; | 68 | static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 }; |
| @@ -82,197 +84,267 @@ static struct validx tbl_common_0B[] = { | |||
| 82 | }; | 84 | }; |
| 83 | 85 | ||
| 84 | static struct idxdata tbl_common_3B[] = { | 86 | static struct idxdata tbl_common_3B[] = { |
| 85 | {0x33, "\x86\x25\x01"}, {0x33, "\x86\x25\x00"}, | 87 | {0x33, {0x86, 0x25, 0x01}}, {0x33, {0x86, 0x25, 0x00}}, |
| 86 | {2, "\xff\xff\xff"}, | 88 | {2, {0xff, 0xff, 0xff}}, |
| 87 | {0x30, "\x1a\x0a\xcc"}, {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"}, | 89 | {0x30, {0x1a, 0x0a, 0xcc}}, {0x32, {0x02, 0x00, 0x08}}, |
| 88 | {6, "\xff\xff\xff"}, /* 12 */ | 90 | {0x33, {0xf4, 0x03, 0x1d}}, |
| 89 | {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, | 91 | {6, {0xff, 0xff, 0xff}}, /* 12 */ |
| 90 | {2, "\xff\xff\xff"}, /* - */ | 92 | {0x34, {0x1e, 0x8f, 0x09}}, {0x34, {0x1c, 0x01, 0x28}}, |
| 91 | {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"}, | 93 | {0x34, {0x1e, 0x8f, 0x09}}, |
| 92 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"}, | 94 | {2, {0xff, 0xff, 0xff}}, /* - */ |
| 93 | {0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"}, | 95 | {0x34, {0x1e, 0x8f, 0x09}}, {0x32, {0x14, 0x06, 0xe6}}, |
| 94 | {0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"}, | 96 | {0x33, {0x8c, 0x22, 0x23}}, {0x33, {0x90, 0x00, 0x00}}, |
| 95 | {0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"}, | 97 | {0x33, {0x8c, 0xa2, 0x0f}}, {0x33, {0x90, 0x00, 0x0d}}, |
| 96 | {0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"}, | 98 | {0x33, {0x8c, 0xa2, 0x10}}, {0x33, {0x90, 0x00, 0x0b}}, |
| 97 | {0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"}, | 99 | {0x33, {0x8c, 0xa2, 0x11}}, {0x33, {0x90, 0x00, 0x07}}, |
| 98 | {0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"}, | 100 | {0x33, {0xf4, 0x03, 0x1d}}, {0x35, {0xa2, 0x00, 0xe2}}, |
| 99 | {0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, | 101 | {0x33, {0x8c, 0xab, 0x05}}, {0x33, {0x90, 0x00, 0x01}}, |
| 100 | {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, | 102 | {0x32, {0x6e, 0x00, 0x86}}, {0x32, {0x70, 0x0f, 0xaa}}, |
| 101 | {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, | 103 | {0x32, {0x72, 0x0f, 0xe4}}, {0x33, {0x8c, 0xa3, 0x4a}}, |
| 102 | {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"}, | 104 | {0x33, {0x90, 0x00, 0x5a}}, {0x33, {0x8c, 0xa3, 0x4b}}, |
| 103 | {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"}, | 105 | {0x33, {0x90, 0x00, 0xa6}}, {0x33, {0x8c, 0xa3, 0x61}}, |
| 104 | {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"}, | 106 | {0x33, {0x90, 0x00, 0xc8}}, {0x33, {0x8c, 0xa3, 0x62}}, |
| 105 | {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"}, | 107 | {0x33, {0x90, 0x00, 0xe1}}, {0x34, {0xce, 0x01, 0xa8}}, |
| 106 | {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"}, | 108 | {0x34, {0xd0, 0x66, 0x33}}, {0x34, {0xd2, 0x31, 0x9a}}, |
| 107 | {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"}, | 109 | {0x34, {0xd4, 0x94, 0x63}}, {0x34, {0xd6, 0x4b, 0x25}}, |
| 108 | {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"}, | 110 | {0x34, {0xd8, 0x26, 0x70}}, {0x34, {0xda, 0x72, 0x4c}}, |
| 109 | {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"}, | 111 | {0x34, {0xdc, 0xff, 0x04}}, {0x34, {0xde, 0x01, 0x5b}}, |
| 110 | {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"}, | 112 | {0x34, {0xe6, 0x01, 0x13}}, {0x34, {0xee, 0x0b, 0xf0}}, |
| 111 | {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"}, | 113 | {0x34, {0xf6, 0x0b, 0xa4}}, {0x35, {0x00, 0xf6, 0xe7}}, |
| 112 | {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"}, | 114 | {0x35, {0x08, 0x0d, 0xfd}}, {0x35, {0x10, 0x25, 0x63}}, |
| 113 | {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"}, | 115 | {0x35, {0x18, 0x35, 0x6c}}, {0x35, {0x20, 0x42, 0x7e}}, |
| 114 | {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"}, | 116 | {0x35, {0x28, 0x19, 0x44}}, {0x35, {0x30, 0x39, 0xd4}}, |
| 115 | {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"}, | 117 | {0x35, {0x38, 0xf5, 0xa8}}, {0x35, {0x4c, 0x07, 0x90}}, |
| 116 | {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"}, | 118 | {0x35, {0x44, 0x07, 0xb8}}, {0x35, {0x5c, 0x06, 0x88}}, |
| 117 | {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"}, | 119 | {0x35, {0x54, 0x07, 0xff}}, {0x34, {0xe0, 0x01, 0x52}}, |
| 118 | {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"}, | 120 | {0x34, {0xe8, 0x00, 0xcc}}, {0x34, {0xf0, 0x0d, 0x83}}, |
| 119 | {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"}, | 121 | {0x34, {0xf8, 0x0c, 0xb3}}, {0x35, {0x02, 0xfe, 0xba}}, |
| 120 | {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"}, | 122 | {0x35, {0x0a, 0x04, 0xe0}}, {0x35, {0x12, 0x1c, 0x63}}, |
| 121 | {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"}, | 123 | {0x35, {0x1a, 0x2b, 0x5a}}, {0x35, {0x22, 0x32, 0x5e}}, |
| 122 | {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"}, | 124 | {0x35, {0x2a, 0x0d, 0x28}}, {0x35, {0x32, 0x2c, 0x02}}, |
| 123 | {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"}, | 125 | {0x35, {0x3a, 0xf4, 0xfa}}, {0x35, {0x4e, 0x07, 0xef}}, |
| 124 | {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, | 126 | {0x35, {0x46, 0x07, 0x88}}, {0x35, {0x5e, 0x07, 0xc1}}, |
| 125 | {0x33, "\x78\x00\x00"}, | 127 | {0x35, {0x56, 0x04, 0x64}}, {0x34, {0xe4, 0x01, 0x15}}, |
| 126 | {2, "\xff\xff\xff"}, | 128 | {0x34, {0xec, 0x00, 0x82}}, {0x34, {0xf4, 0x0c, 0xce}}, |
| 127 | {0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"}, | 129 | {0x34, {0xfc, 0x0c, 0xba}}, {0x35, {0x06, 0x1f, 0x02}}, |
| 128 | {0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"}, | 130 | {0x35, {0x0e, 0x02, 0xe3}}, {0x35, {0x16, 0x1a, 0x50}}, |
| 129 | {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"}, | 131 | {0x35, {0x1e, 0x24, 0x39}}, {0x35, {0x26, 0x23, 0x4c}}, |
| 130 | {0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"}, | 132 | {0x35, {0x2e, 0xf9, 0x1b}}, {0x35, {0x36, 0x23, 0x19}}, |
| 131 | {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, {0x33, "\x8c\xa4\x04"}, | 133 | {0x35, {0x3e, 0x12, 0x08}}, {0x35, {0x52, 0x07, 0x22}}, |
| 132 | {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, {0x33, "\x90\x00\x00"}, | 134 | {0x35, {0x4a, 0x03, 0xd3}}, {0x35, {0x62, 0x06, 0x54}}, |
| 133 | {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0c"}, | 135 | {0x35, {0x5a, 0x04, 0x5d}}, {0x34, {0xe2, 0x01, 0x04}}, |
| 134 | {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, {0x33, "\x90\x00\x04"}, | 136 | {0x34, {0xea, 0x00, 0xa0}}, {0x34, {0xf2, 0x0c, 0xbc}}, |
| 135 | {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"}, {0x33, "\x8c\xa1\x03"}, | 137 | {0x34, {0xfa, 0x0c, 0x5b}}, {0x35, {0x04, 0x17, 0xf2}}, |
| 136 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"}, | 138 | {0x35, {0x0c, 0x02, 0x08}}, {0x35, {0x14, 0x28, 0x43}}, |
| 137 | {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x25"}, | 139 | {0x35, {0x1c, 0x28, 0x62}}, {0x35, {0x24, 0x2b, 0x60}}, |
| 138 | {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, | 140 | {0x35, {0x2c, 0x07, 0x33}}, {0x35, {0x34, 0x1f, 0xb0}}, |
| 139 | {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x47"}, | 141 | {0x35, {0x3c, 0xed, 0xcd}}, {0x35, {0x50, 0x00, 0x06}}, |
| 140 | {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x02\x84"}, | 142 | {0x35, {0x48, 0x07, 0xff}}, {0x35, {0x60, 0x05, 0x89}}, |
| 141 | {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"}, {0x33, "\x8c\x27\x07"}, | 143 | {0x35, {0x58, 0x07, 0xff}}, {0x35, {0x40, 0x00, 0xa0}}, |
| 142 | {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"}, {0x33, "\x90\x04\xb0"}, | 144 | {0x35, {0x42, 0x00, 0x00}}, {0x32, {0x10, 0x01, 0xfc}}, |
| 143 | {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x0f"}, | 145 | {0x33, {0x8c, 0xa1, 0x18}}, {0x33, {0x90, 0x00, 0x3c}}, |
| 144 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"}, {0x33, "\x90\x04\xbd"}, | 146 | {0x33, {0x78, 0x00, 0x00}}, |
| 145 | {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"}, {0x33, "\x8c\x27\x15"}, | 147 | {2, {0xff, 0xff, 0xff}}, |
| 146 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"}, | 148 | {0x35, {0xb8, 0x1f, 0x20}}, {0x33, {0x8c, 0xa2, 0x06}}, |
| 147 | {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"}, {0x33, "\x8c\x27\x1b"}, | 149 | {0x33, {0x90, 0x00, 0x10}}, {0x33, {0x8c, 0xa2, 0x07}}, |
| 148 | {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"}, {0x33, "\x90\x01\x02"}, | 150 | {0x33, {0x90, 0x00, 0x08}}, {0x33, {0x8c, 0xa2, 0x42}}, |
| 149 | {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"}, {0x33, "\x8c\x27\x21"}, | 151 | {0x33, {0x90, 0x00, 0x0b}}, {0x33, {0x8c, 0xa2, 0x4a}}, |
| 150 | {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"}, {0x33, "\x90\x02\x85"}, | 152 | {0x33, {0x90, 0x00, 0x8c}}, {0x35, {0xba, 0xfa, 0x08}}, |
| 151 | {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x27"}, | 153 | {0x33, {0x8c, 0xa2, 0x02}}, {0x33, {0x90, 0x00, 0x22}}, |
| 152 | {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"}, {0x33, "\x90\x20\x20"}, | 154 | {0x33, {0x8c, 0xa2, 0x03}}, {0x33, {0x90, 0x00, 0xbb}}, |
| 153 | {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"}, {0x33, "\x8c\x27\x2d"}, | 155 | {0x33, {0x8c, 0xa4, 0x04}}, {0x33, {0x90, 0x00, 0x80}}, |
| 154 | {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"}, {0x33, "\x90\x00\x04"}, | 156 | {0x33, {0x8c, 0xa7, 0x9d}}, {0x33, {0x90, 0x00, 0x00}}, |
| 155 | {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x33"}, | 157 | {0x33, {0x8c, 0xa7, 0x9e}}, {0x33, {0x90, 0x00, 0x00}}, |
| 156 | {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"}, {0x33, "\x90\x06\x4b"}, | 158 | {0x33, {0x8c, 0xa2, 0x0c}}, {0x33, {0x90, 0x00, 0x17}}, |
| 157 | {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x39"}, | 159 | {0x33, {0x8c, 0xa2, 0x15}}, {0x33, {0x90, 0x00, 0x04}}, |
| 158 | {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, | 160 | {0x33, {0x8c, 0xa2, 0x14}}, {0x33, {0x90, 0x00, 0x20}}, |
| 159 | {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x41"}, | 161 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x00}}, |
| 160 | {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"}, {0x33, "\x90\x04\xed"}, | 162 | {0x33, {0x8c, 0x27, 0x17}}, {0x33, {0x90, 0x21, 0x11}}, |
| 161 | {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x51"}, | 163 | {0x33, {0x8c, 0x27, 0x1b}}, {0x33, {0x90, 0x02, 0x4f}}, |
| 162 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"}, {0x33, "\x90\x03\x20"}, | 164 | {0x33, {0x8c, 0x27, 0x25}}, {0x33, {0x90, 0x06, 0x0f}}, |
| 163 | {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x57"}, | 165 | {0x33, {0x8c, 0x27, 0x39}}, {0x33, {0x90, 0x21, 0x11}}, |
| 164 | {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"}, {0x33, "\x90\x00\x00"}, | 166 | {0x33, {0x8c, 0x27, 0x3d}}, {0x33, {0x90, 0x01, 0x20}}, |
| 165 | {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x63"}, | 167 | {0x33, {0x8c, 0x27, 0x47}}, {0x33, {0x90, 0x09, 0x4c}}, |
| 166 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"}, {0x33, "\x90\x04\xb0"}, | 168 | {0x33, {0x8c, 0x27, 0x03}}, {0x33, {0x90, 0x02, 0x84}}, |
| 167 | {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\xa4\x08"}, | 169 | {0x33, {0x8c, 0x27, 0x05}}, {0x33, {0x90, 0x01, 0xe2}}, |
| 168 | {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"}, | 170 | {0x33, {0x8c, 0x27, 0x07}}, {0x33, {0x90, 0x06, 0x40}}, |
| 169 | {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"}, | 171 | {0x33, {0x8c, 0x27, 0x09}}, {0x33, {0x90, 0x04, 0xb0}}, |
| 170 | {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa1"}, | 172 | {0x33, {0x8c, 0x27, 0x0d}}, {0x33, {0x90, 0x00, 0x00}}, |
| 171 | {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"}, {0x33, "\x8c\x24\x15"}, | 173 | {0x33, {0x8c, 0x27, 0x0f}}, {0x33, {0x90, 0x00, 0x00}}, |
| 172 | {0x33, "\x90\x00\x6a"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\x80"}, | 174 | {0x33, {0x8c, 0x27, 0x11}}, {0x33, {0x90, 0x04, 0xbd}}, |
| 173 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, | 175 | {0x33, {0x8c, 0x27, 0x13}}, {0x33, {0x90, 0x06, 0x4d}}, |
| 174 | {2, "\xff\xff\xff"}, | 176 | {0x33, {0x8c, 0x27, 0x15}}, {0x33, {0x90, 0x00, 0x00}}, |
| 175 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, | 177 | {0x33, {0x8c, 0x27, 0x17}}, {0x33, {0x90, 0x21, 0x11}}, |
| 176 | {3, "\xff\xff\xff"}, | 178 | {0x33, {0x8c, 0x27, 0x19}}, {0x33, {0x90, 0x04, 0x6c}}, |
| 179 | {0x33, {0x8c, 0x27, 0x1b}}, {0x33, {0x90, 0x02, 0x4f}}, | ||
| 180 | {0x33, {0x8c, 0x27, 0x1d}}, {0x33, {0x90, 0x01, 0x02}}, | ||
| 181 | {0x33, {0x8c, 0x27, 0x1f}}, {0x33, {0x90, 0x02, 0x79}}, | ||
| 182 | {0x33, {0x8c, 0x27, 0x21}}, {0x33, {0x90, 0x01, 0x55}}, | ||
| 183 | {0x33, {0x8c, 0x27, 0x23}}, {0x33, {0x90, 0x02, 0x85}}, | ||
| 184 | {0x33, {0x8c, 0x27, 0x25}}, {0x33, {0x90, 0x06, 0x0f}}, | ||
| 185 | {0x33, {0x8c, 0x27, 0x27}}, {0x33, {0x90, 0x20, 0x20}}, | ||
| 186 | {0x33, {0x8c, 0x27, 0x29}}, {0x33, {0x90, 0x20, 0x20}}, | ||
| 187 | {0x33, {0x8c, 0x27, 0x2b}}, {0x33, {0x90, 0x10, 0x20}}, | ||
| 188 | {0x33, {0x8c, 0x27, 0x2d}}, {0x33, {0x90, 0x20, 0x07}}, | ||
| 189 | {0x33, {0x8c, 0x27, 0x2f}}, {0x33, {0x90, 0x00, 0x04}}, | ||
| 190 | {0x33, {0x8c, 0x27, 0x31}}, {0x33, {0x90, 0x00, 0x04}}, | ||
| 191 | {0x33, {0x8c, 0x27, 0x33}}, {0x33, {0x90, 0x04, 0xbb}}, | ||
| 192 | {0x33, {0x8c, 0x27, 0x35}}, {0x33, {0x90, 0x06, 0x4b}}, | ||
| 193 | {0x33, {0x8c, 0x27, 0x37}}, {0x33, {0x90, 0x00, 0x00}}, | ||
| 194 | {0x33, {0x8c, 0x27, 0x39}}, {0x33, {0x90, 0x21, 0x11}}, | ||
| 195 | {0x33, {0x8c, 0x27, 0x3b}}, {0x33, {0x90, 0x00, 0x24}}, | ||
| 196 | {0x33, {0x8c, 0x27, 0x3d}}, {0x33, {0x90, 0x01, 0x20}}, | ||
| 197 | {0x33, {0x8c, 0x27, 0x41}}, {0x33, {0x90, 0x01, 0x69}}, | ||
| 198 | {0x33, {0x8c, 0x27, 0x45}}, {0x33, {0x90, 0x04, 0xed}}, | ||
| 199 | {0x33, {0x8c, 0x27, 0x47}}, {0x33, {0x90, 0x09, 0x4c}}, | ||
| 200 | {0x33, {0x8c, 0x27, 0x51}}, {0x33, {0x90, 0x00, 0x00}}, | ||
| 201 | {0x33, {0x8c, 0x27, 0x53}}, {0x33, {0x90, 0x03, 0x20}}, | ||
| 202 | {0x33, {0x8c, 0x27, 0x55}}, {0x33, {0x90, 0x00, 0x00}}, | ||
| 203 | {0x33, {0x8c, 0x27, 0x57}}, {0x33, {0x90, 0x02, 0x58}}, | ||
| 204 | {0x33, {0x8c, 0x27, 0x5f}}, {0x33, {0x90, 0x00, 0x00}}, | ||
| 205 | {0x33, {0x8c, 0x27, 0x61}}, {0x33, {0x90, 0x06, 0x40}}, | ||
| 206 | {0x33, {0x8c, 0x27, 0x63}}, {0x33, {0x90, 0x00, 0x00}}, | ||
| 207 | {0x33, {0x8c, 0x27, 0x65}}, {0x33, {0x90, 0x04, 0xb0}}, | ||
| 208 | {0x33, {0x8c, 0x22, 0x2e}}, {0x33, {0x90, 0x00, 0xa1}}, | ||
| 209 | {0x33, {0x8c, 0xa4, 0x08}}, {0x33, {0x90, 0x00, 0x1f}}, | ||
| 210 | {0x33, {0x8c, 0xa4, 0x09}}, {0x33, {0x90, 0x00, 0x21}}, | ||
| 211 | {0x33, {0x8c, 0xa4, 0x0a}}, {0x33, {0x90, 0x00, 0x25}}, | ||
| 212 | {0x33, {0x8c, 0xa4, 0x0b}}, {0x33, {0x90, 0x00, 0x27}}, | ||
| 213 | {0x33, {0x8c, 0x24, 0x11}}, {0x33, {0x90, 0x00, 0xa1}}, | ||
| 214 | {0x33, {0x8c, 0x24, 0x13}}, {0x33, {0x90, 0x00, 0xc1}}, | ||
| 215 | {0x33, {0x8c, 0x24, 0x15}}, {0x33, {0x90, 0x00, 0x6a}}, | ||
| 216 | {0x33, {0x8c, 0x24, 0x17}}, {0x33, {0x90, 0x00, 0x80}}, | ||
| 217 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, | ||
| 218 | {2, {0xff, 0xff, 0xff}}, | ||
| 219 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, | ||
| 220 | {3, {0xff, 0xff, 0xff}}, | ||
| 177 | }; | 221 | }; |
| 178 | 222 | ||
| 179 | static struct idxdata tbl_init_post_alt_low1[] = { | 223 | static struct idxdata tbl_init_post_alt_low1[] = { |
| 180 | {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"}, | 224 | {0x33, {0x8c, 0x27, 0x15}}, {0x33, {0x90, 0x00, 0x25}}, |
| 181 | {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"}, | 225 | {0x33, {0x8c, 0x22, 0x2e}}, {0x33, {0x90, 0x00, 0x81}}, |
| 182 | {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"}, | 226 | {0x33, {0x8c, 0xa4, 0x08}}, {0x33, {0x90, 0x00, 0x17}}, |
| 183 | {0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"}, | 227 | {0x33, {0x8c, 0xa4, 0x09}}, {0x33, {0x90, 0x00, 0x1a}}, |
| 184 | {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"}, | 228 | {0x33, {0x8c, 0xa4, 0x0a}}, {0x33, {0x90, 0x00, 0x1d}}, |
| 185 | {0x33, "\x90\x00\x9b"}, | 229 | {0x33, {0x8c, 0xa4, 0x0b}}, {0x33, {0x90, 0x00, 0x20}}, |
| 230 | {0x33, {0x8c, 0x24, 0x11}}, {0x33, {0x90, 0x00, 0x81}}, | ||
| 231 | {0x33, {0x8c, 0x24, 0x13}}, {0x33, {0x90, 0x00, 0x9b}}, | ||
| 186 | }; | 232 | }; |
| 187 | 233 | ||
| 188 | static struct idxdata tbl_init_post_alt_low2[] = { | 234 | static struct idxdata tbl_init_post_alt_low2[] = { |
| 189 | {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"}, | 235 | {0x33, {0x8c, 0x27, 0x03}}, {0x33, {0x90, 0x03, 0x24}}, |
| 190 | {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, | 236 | {0x33, {0x8c, 0x27, 0x05}}, {0x33, {0x90, 0x02, 0x58}}, |
| 191 | {2, "\xff\xff\xff"}, | 237 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, |
| 192 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, | 238 | {2, {0xff, 0xff, 0xff}}, |
| 193 | {2, "\xff\xff\xff"}, | 239 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, |
| 240 | {2, {0xff, 0xff, 0xff}}, | ||
| 194 | }; | 241 | }; |
| 195 | 242 | ||
| 196 | static struct idxdata tbl_init_post_alt_low3[] = { | 243 | static struct idxdata tbl_init_post_alt_low3[] = { |
| 197 | {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, | 244 | {0x34, {0x1e, 0x8f, 0x09}}, {0x34, {0x1c, 0x01, 0x28}}, |
| 198 | {2, "\xff\xff\xff"}, | 245 | {0x34, {0x1e, 0x8f, 0x09}}, |
| 199 | {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"}, | 246 | {2, {0xff, 0xff, 0xff}}, |
| 200 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"}, | 247 | {0x34, {0x1e, 0x8f, 0x09}}, {0x32, {0x14, 0x06, 0xe6}}, |
| 201 | {0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, | 248 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, |
| 202 | {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"}, | 249 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, |
| 203 | {2, "\xff\xff\xff"}, | 250 | {0x33, {0x2e, 0x01, 0x00}}, {0x34, {0x04, 0x00, 0x2a}}, |
| 204 | {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"}, | 251 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, |
| 205 | {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, | 252 | {0x33, {0x8c, 0x27, 0x95}}, {0x33, {0x90, 0x01, 0x00}}, |
| 206 | {2, "\xff\xff\xff"}, | 253 | {2, {0xff, 0xff, 0xff}}, |
| 207 | {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, | 254 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, |
| 208 | {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"}, | 255 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, |
| 209 | {2, "\xff\xff\xff"}, | 256 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, |
| 210 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, | 257 | {2, {0xff, 0xff, 0xff}}, |
| 211 | {2, "\xff\xff\xff"}, | 258 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, |
| 212 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, | 259 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, |
| 213 | {2, "\xff\xff\xff"}, | 260 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, |
| 214 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, | 261 | {2, {0xff, 0xff, 0xff}}, |
| 215 | {2, "\xff\xff\xff"}, | 262 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, |
| 216 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, | 263 | {2, {0xff, 0xff, 0xff}}, |
| 264 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, | ||
| 265 | {2, {0xff, 0xff, 0xff}}, | ||
| 266 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, | ||
| 267 | {2, {0xff, 0xff, 0xff}}, | ||
| 268 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, | ||
| 217 | }; | 269 | }; |
| 218 | 270 | ||
| 219 | static struct idxdata tbl_init_post_alt_big[] = { | 271 | static struct idxdata tbl_init_post_alt_big[] = { |
| 220 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, | 272 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, |
| 221 | {2, "\xff\xff\xff"}, | 273 | {2, {0xff, 0xff, 0xff}}, |
| 222 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, | 274 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, |
| 223 | {2, "\xff\xff\xff"}, | 275 | {2, {0xff, 0xff, 0xff}}, |
| 224 | {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"}, | 276 | {0x34, {0x1e, 0x8f, 0x09}}, {0x34, {0x1c, 0x01, 0x28}}, |
| 225 | {2, "\xff\xff\xff"}, | 277 | {0x34, {0x1e, 0x8f, 0x09}}, |
| 226 | {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"}, | 278 | {2, {0xff, 0xff, 0xff}}, |
| 227 | {0x33, "\x90\x00\x05"}, | 279 | {0x34, {0x1e, 0x8f, 0x09}}, {0x32, {0x14, 0x06, 0xe6}}, |
| 228 | {2, "\xff\xff\xff"}, | 280 | {0x33, {0x8c, 0xa1, 0x03}}, |
| 229 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, | 281 | {0x33, {0x90, 0x00, 0x05}}, |
| 230 | {2, "\xff\xff\xff"}, | 282 | {2, {0xff, 0xff, 0xff}}, |
| 231 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"}, | 283 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, |
| 232 | {2, "\xff\xff\xff"}, | 284 | {2, {0xff, 0xff, 0xff}}, |
| 233 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"}, | 285 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x05}}, |
| 234 | {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"}, | 286 | {2, {0xff, 0xff, 0xff}}, |
| 235 | {0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"}, | 287 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x06}}, |
| 236 | {0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"}, | 288 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, |
| 237 | {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"}, | 289 | {0x33, {0x8c, 0xa1, 0x30}}, {0x33, {0x90, 0x00, 0x03}}, |
| 238 | {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, | 290 | {0x33, {0x8c, 0xa1, 0x31}}, {0x33, {0x90, 0x00, 0x02}}, |
| 239 | {0x33, "\x8c\x27\x97"}, {0x33, "\x90\x01\x00"}, | 291 | {0x33, {0x8c, 0xa1, 0x32}}, {0x33, {0x90, 0x00, 0x03}}, |
| 240 | {51, "\xff\xff\xff"}, | 292 | {0x33, {0x8c, 0xa1, 0x34}}, {0x33, {0x90, 0x00, 0x03}}, |
| 241 | {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, | 293 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, |
| 242 | {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"}, | 294 | {0x33, {0x2e, 0x01, 0x00}}, {0x34, {0x04, 0x00, 0x2a}}, |
| 243 | {51, "\xff\xff\xff"}, | 295 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, |
| 244 | {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"}, | 296 | {0x33, {0x8c, 0x27, 0x97}}, {0x33, {0x90, 0x01, 0x00}}, |
| 245 | {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"}, | 297 | {51, {0xff, 0xff, 0xff}}, |
| 246 | {51, "\xff\xff\xff"}, | 298 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x00}}, |
| 299 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x01}}, | ||
| 300 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x00}}, | ||
| 301 | {51, {0xff, 0xff, 0xff}}, | ||
| 302 | {0x33, {0x8c, 0xa1, 0x20}}, {0x33, {0x90, 0x00, 0x72}}, | ||
| 303 | {0x33, {0x8c, 0xa1, 0x03}}, {0x33, {0x90, 0x00, 0x02}}, | ||
| 304 | {0x33, {0x8c, 0xa7, 0x02}}, {0x33, {0x90, 0x00, 0x01}}, | ||
| 305 | {51, {0xff, 0xff, 0xff}}, | ||
| 247 | }; | 306 | }; |
| 248 | 307 | ||
| 249 | static struct idxdata tbl_init_post_alt_3B[] = { | 308 | static struct idxdata tbl_init_post_alt_3B[] = { |
| 250 | {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"}, | 309 | {0x32, {0x10, 0x01, 0xf8}}, {0x34, {0xce, 0x01, 0xa8}}, |
| 251 | {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"}, | 310 | {0x34, {0xd0, 0x66, 0x33}}, {0x34, {0xd2, 0x31, 0x9a}}, |
| 252 | {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"}, | 311 | {0x34, {0xd4, 0x94, 0x63}}, {0x34, {0xd6, 0x4b, 0x25}}, |
| 253 | {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"}, | 312 | {0x34, {0xd8, 0x26, 0x70}}, {0x34, {0xda, 0x72, 0x4c}}, |
| 254 | {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"}, | 313 | {0x34, {0xdc, 0xff, 0x04}}, {0x34, {0xde, 0x01, 0x5b}}, |
| 255 | {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"}, | 314 | {0x34, {0xe6, 0x01, 0x13}}, {0x34, {0xee, 0x0b, 0xf0}}, |
| 256 | {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"}, | 315 | {0x34, {0xf6, 0x0b, 0xa4}}, {0x35, {0x00, 0xf6, 0xe7}}, |
| 257 | {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"}, | 316 | {0x35, {0x08, 0x0d, 0xfd}}, {0x35, {0x10, 0x25, 0x63}}, |
| 258 | {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"}, | 317 | {0x35, {0x18, 0x35, 0x6c}}, {0x35, {0x20, 0x42, 0x7e}}, |
| 259 | {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"}, | 318 | {0x35, {0x28, 0x19, 0x44}}, {0x35, {0x30, 0x39, 0xd4}}, |
| 260 | {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"}, | 319 | {0x35, {0x38, 0xf5, 0xa8}}, {0x35, {0x4c, 0x07, 0x90}}, |
| 261 | {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"}, | 320 | {0x35, {0x44, 0x07, 0xb8}}, {0x35, {0x5c, 0x06, 0x88}}, |
| 262 | {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"}, | 321 | {0x35, {0x54, 0x07, 0xff}}, {0x34, {0xe0, 0x01, 0x52}}, |
| 263 | {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"}, | 322 | {0x34, {0xe8, 0x00, 0xcc}}, {0x34, {0xf0, 0x0d, 0x83}}, |
| 264 | {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"}, | 323 | {0x34, {0xf8, 0x0c, 0xb3}}, {0x35, {0x02, 0xfe, 0xba}}, |
| 265 | {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"}, | 324 | {0x35, {0x0a, 0x04, 0xe0}}, {0x35, {0x12, 0x1c, 0x63}}, |
| 266 | {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"}, | 325 | {0x35, {0x1a, 0x2b, 0x5a}}, {0x35, {0x22, 0x32, 0x5e}}, |
| 267 | {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"}, | 326 | {0x35, {0x2a, 0x0d, 0x28}}, {0x35, {0x32, 0x2c, 0x02}}, |
| 268 | {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"}, | 327 | {0x35, {0x3a, 0xf4, 0xfa}}, {0x35, {0x4e, 0x07, 0xef}}, |
| 269 | {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"}, | 328 | {0x35, {0x46, 0x07, 0x88}}, {0x35, {0x5e, 0x07, 0xc1}}, |
| 270 | {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"}, | 329 | {0x35, {0x56, 0x04, 0x64}}, {0x34, {0xe4, 0x01, 0x15}}, |
| 271 | {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"}, | 330 | {0x34, {0xec, 0x00, 0x82}}, {0x34, {0xf4, 0x0c, 0xce}}, |
| 272 | {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"}, | 331 | {0x34, {0xfc, 0x0c, 0xba}}, {0x35, {0x06, 0x1f, 0x02}}, |
| 273 | {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"}, | 332 | {0x35, {0x0e, 0x02, 0xe3}}, {0x35, {0x16, 0x1a, 0x50}}, |
| 274 | {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"}, | 333 | {0x35, {0x1e, 0x24, 0x39}}, {0x35, {0x26, 0x23, 0x4c}}, |
| 275 | {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"}, | 334 | {0x35, {0x2e, 0xf9, 0x1b}}, {0x35, {0x36, 0x23, 0x19}}, |
| 335 | {0x35, {0x3e, 0x12, 0x08}}, {0x35, {0x52, 0x07, 0x22}}, | ||
| 336 | {0x35, {0x4a, 0x03, 0xd3}}, {0x35, {0x62, 0x06, 0x54}}, | ||
| 337 | {0x35, {0x5a, 0x04, 0x5d}}, {0x34, {0xe2, 0x01, 0x04}}, | ||
| 338 | {0x34, {0xea, 0x00, 0xa0}}, {0x34, {0xf2, 0x0c, 0xbc}}, | ||
| 339 | {0x34, {0xfa, 0x0c, 0x5b}}, {0x35, {0x04, 0x17, 0xf2}}, | ||
| 340 | {0x35, {0x0c, 0x02, 0x08}}, {0x35, {0x14, 0x28, 0x43}}, | ||
| 341 | {0x35, {0x1c, 0x28, 0x62}}, {0x35, {0x24, 0x2b, 0x60}}, | ||
| 342 | {0x35, {0x2c, 0x07, 0x33}}, {0x35, {0x34, 0x1f, 0xb0}}, | ||
| 343 | {0x35, {0x3c, 0xed, 0xcd}}, {0x35, {0x50, 0x00, 0x06}}, | ||
| 344 | {0x35, {0x48, 0x07, 0xff}}, {0x35, {0x60, 0x05, 0x89}}, | ||
| 345 | {0x35, {0x58, 0x07, 0xff}}, {0x35, {0x40, 0x00, 0xa0}}, | ||
| 346 | {0x35, {0x42, 0x00, 0x00}}, {0x32, {0x10, 0x01, 0xfc}}, | ||
| 347 | {0x33, {0x8c, 0xa1, 0x18}}, {0x33, {0x90, 0x00, 0x3c}}, | ||
| 276 | }; | 348 | }; |
| 277 | 349 | ||
| 278 | static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81"; | 350 | static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81"; |
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index ea05f678b559..9623b6218214 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c | |||
| @@ -2910,7 +2910,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) | |||
| 2910 | v4l2_std_id vs; | 2910 | v4l2_std_id vs; |
| 2911 | vs = hdw->std_mask_cur; | 2911 | vs = hdw->std_mask_cur; |
| 2912 | v4l2_device_call_all(&hdw->v4l2_dev, 0, | 2912 | v4l2_device_call_all(&hdw->v4l2_dev, 0, |
| 2913 | core, s_std, vs); | 2913 | video, s_std, vs); |
| 2914 | pvr2_hdw_cx25840_vbi_hack(hdw); | 2914 | pvr2_hdw_cx25840_vbi_hack(hdw); |
| 2915 | } | 2915 | } |
| 2916 | hdw->tuner_signal_stale = !0; | 2916 | hdw->tuner_signal_stale = !0; |
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index 84a6720b1d00..a73b0bced96f 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c | |||
| @@ -681,12 +681,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 681 | return r; | 681 | return r; |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | static int stop_streaming(struct vb2_queue *vq) | 684 | static void stop_streaming(struct vb2_queue *vq) |
| 685 | { | 685 | { |
| 686 | struct pwc_device *pdev = vb2_get_drv_priv(vq); | 686 | struct pwc_device *pdev = vb2_get_drv_priv(vq); |
| 687 | 687 | ||
| 688 | if (mutex_lock_interruptible(&pdev->v4l2_lock)) | 688 | mutex_lock(&pdev->v4l2_lock); |
| 689 | return -ERESTARTSYS; | ||
| 690 | if (pdev->udev) { | 689 | if (pdev->udev) { |
| 691 | pwc_set_leds(pdev, 0, 0); | 690 | pwc_set_leds(pdev, 0, 0); |
| 692 | pwc_camera_power(pdev, 0); | 691 | pwc_camera_power(pdev, 0); |
| @@ -695,8 +694,6 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 695 | 694 | ||
| 696 | pwc_cleanup_queued_bufs(pdev); | 695 | pwc_cleanup_queued_bufs(pdev); |
| 697 | mutex_unlock(&pdev->v4l2_lock); | 696 | mutex_unlock(&pdev->v4l2_lock); |
| 698 | |||
| 699 | return 0; | ||
| 700 | } | 697 | } |
| 701 | 698 | ||
| 702 | static struct vb2_ops pwc_vb_queue_ops = { | 699 | static struct vb2_ops pwc_vb_queue_ops = { |
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 1d4ba2b80490..a44466bc7b86 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c | |||
| @@ -714,7 +714,7 @@ static void buffer_queue(struct vb2_buffer *vb) | |||
| 714 | } | 714 | } |
| 715 | 715 | ||
| 716 | static int start_streaming(struct vb2_queue *vq, unsigned int count); | 716 | static int start_streaming(struct vb2_queue *vq, unsigned int count); |
| 717 | static int stop_streaming(struct vb2_queue *vq); | 717 | static void stop_streaming(struct vb2_queue *vq); |
| 718 | 718 | ||
| 719 | static struct vb2_ops s2255_video_qops = { | 719 | static struct vb2_ops s2255_video_qops = { |
| 720 | .queue_setup = queue_setup, | 720 | .queue_setup = queue_setup, |
| @@ -1109,7 +1109,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | /* abort streaming and wait for last buffer */ | 1111 | /* abort streaming and wait for last buffer */ |
| 1112 | static int stop_streaming(struct vb2_queue *vq) | 1112 | static void stop_streaming(struct vb2_queue *vq) |
| 1113 | { | 1113 | { |
| 1114 | struct s2255_vc *vc = vb2_get_drv_priv(vq); | 1114 | struct s2255_vc *vc = vb2_get_drv_priv(vq); |
| 1115 | struct s2255_buffer *buf, *node; | 1115 | struct s2255_buffer *buf, *node; |
| @@ -1123,7 +1123,6 @@ static int stop_streaming(struct vb2_queue *vq) | |||
| 1123 | buf, buf->vb.v4l2_buf.index); | 1123 | buf, buf->vb.v4l2_buf.index); |
| 1124 | } | 1124 | } |
| 1125 | spin_unlock_irqrestore(&vc->qlock, flags); | 1125 | spin_unlock_irqrestore(&vc->qlock, flags); |
| 1126 | return 0; | ||
| 1127 | } | 1126 | } |
| 1128 | 1127 | ||
| 1129 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i) | 1128 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i) |
| @@ -1522,7 +1521,7 @@ static void s2255_destroy(struct s2255_dev *dev) | |||
| 1522 | /* board shutdown stops the read pipe if it is running */ | 1521 | /* board shutdown stops the read pipe if it is running */ |
| 1523 | s2255_board_shutdown(dev); | 1522 | s2255_board_shutdown(dev); |
| 1524 | /* make sure firmware still not trying to load */ | 1523 | /* make sure firmware still not trying to load */ |
| 1525 | del_timer(&dev->timer); /* only started in .probe and .open */ | 1524 | del_timer_sync(&dev->timer); /* only started in .probe and .open */ |
| 1526 | if (dev->fw_data->fw_urb) { | 1525 | if (dev->fw_data->fw_urb) { |
| 1527 | usb_kill_urb(dev->fw_data->fw_urb); | 1526 | usb_kill_urb(dev->fw_data->fw_urb); |
| 1528 | usb_free_urb(dev->fw_data->fw_urb); | 1527 | usb_free_urb(dev->fw_data->fw_urb); |
| @@ -2243,7 +2242,7 @@ static int s2255_probe(struct usb_interface *interface, | |||
| 2243 | dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL); | 2242 | dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL); |
| 2244 | if (dev->cmdbuf == NULL) { | 2243 | if (dev->cmdbuf == NULL) { |
| 2245 | s2255_dev_err(&interface->dev, "out of memory\n"); | 2244 | s2255_dev_err(&interface->dev, "out of memory\n"); |
| 2246 | return -ENOMEM; | 2245 | goto errorFWDATA1; |
| 2247 | } | 2246 | } |
| 2248 | 2247 | ||
| 2249 | atomic_set(&dev->num_channels, 0); | 2248 | atomic_set(&dev->num_channels, 0); |
| @@ -2352,7 +2351,7 @@ errorREQFW: | |||
| 2352 | errorFWDATA2: | 2351 | errorFWDATA2: |
| 2353 | usb_free_urb(dev->fw_data->fw_urb); | 2352 | usb_free_urb(dev->fw_data->fw_urb); |
| 2354 | errorFWURB: | 2353 | errorFWURB: |
| 2355 | del_timer(&dev->timer); | 2354 | del_timer_sync(&dev->timer); |
| 2356 | errorEP: | 2355 | errorEP: |
| 2357 | usb_put_dev(dev->udev); | 2356 | usb_put_dev(dev->udev); |
| 2358 | errorUDEV: | 2357 | errorUDEV: |
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c index 34a26e0cfe77..03504dcf3c52 100644 --- a/drivers/media/usb/stk1160/stk1160-core.c +++ b/drivers/media/usb/stk1160/stk1160-core.c | |||
| @@ -67,17 +67,25 @@ int stk1160_read_reg(struct stk1160 *dev, u16 reg, u8 *value) | |||
| 67 | { | 67 | { |
| 68 | int ret; | 68 | int ret; |
| 69 | int pipe = usb_rcvctrlpipe(dev->udev, 0); | 69 | int pipe = usb_rcvctrlpipe(dev->udev, 0); |
| 70 | u8 *buf; | ||
| 70 | 71 | ||
| 71 | *value = 0; | 72 | *value = 0; |
| 73 | |||
| 74 | buf = kmalloc(sizeof(u8), GFP_KERNEL); | ||
| 75 | if (!buf) | ||
| 76 | return -ENOMEM; | ||
| 72 | ret = usb_control_msg(dev->udev, pipe, 0x00, | 77 | ret = usb_control_msg(dev->udev, pipe, 0x00, |
| 73 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 78 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 74 | 0x00, reg, value, sizeof(u8), HZ); | 79 | 0x00, reg, buf, sizeof(u8), HZ); |
| 75 | if (ret < 0) { | 80 | if (ret < 0) { |
| 76 | stk1160_err("read failed on reg 0x%x (%d)\n", | 81 | stk1160_err("read failed on reg 0x%x (%d)\n", |
| 77 | reg, ret); | 82 | reg, ret); |
| 83 | kfree(buf); | ||
| 78 | return ret; | 84 | return ret; |
| 79 | } | 85 | } |
| 80 | 86 | ||
| 87 | *value = *buf; | ||
| 88 | kfree(buf); | ||
| 81 | return 0; | 89 | return 0; |
| 82 | } | 90 | } |
| 83 | 91 | ||
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index 37bc00f418f1..5461341a31cb 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c | |||
| @@ -406,7 +406,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 406 | 406 | ||
| 407 | stk1160_set_std(dev); | 407 | stk1160_set_std(dev); |
| 408 | 408 | ||
| 409 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, | 409 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, |
| 410 | dev->norm); | 410 | dev->norm); |
| 411 | 411 | ||
| 412 | return 0; | 412 | return 0; |
| @@ -583,10 +583,10 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | /* abort streaming and wait for last buffer */ | 585 | /* abort streaming and wait for last buffer */ |
| 586 | static int stop_streaming(struct vb2_queue *vq) | 586 | static void stop_streaming(struct vb2_queue *vq) |
| 587 | { | 587 | { |
| 588 | struct stk1160 *dev = vb2_get_drv_priv(vq); | 588 | struct stk1160 *dev = vb2_get_drv_priv(vq); |
| 589 | return stk1160_stop_streaming(dev); | 589 | stk1160_stop_streaming(dev); |
| 590 | } | 590 | } |
| 591 | 591 | ||
| 592 | static struct vb2_ops stk1160_video_qops = { | 592 | static struct vb2_ops stk1160_video_qops = { |
| @@ -682,7 +682,7 @@ int stk1160_video_register(struct stk1160 *dev) | |||
| 682 | dev->fmt = &format[0]; | 682 | dev->fmt = &format[0]; |
| 683 | stk1160_set_std(dev); | 683 | stk1160_set_std(dev); |
| 684 | 684 | ||
| 685 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, | 685 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, |
| 686 | dev->norm); | 686 | dev->norm); |
| 687 | 687 | ||
| 688 | video_set_drvdata(&dev->vdev, dev); | 688 | video_set_drvdata(&dev->vdev, dev); |
diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h index 05b05b160e1e..abdea484c998 100644 --- a/drivers/media/usb/stk1160/stk1160.h +++ b/drivers/media/usb/stk1160/stk1160.h | |||
| @@ -143,7 +143,6 @@ struct stk1160 { | |||
| 143 | int num_alt; | 143 | int num_alt; |
| 144 | 144 | ||
| 145 | struct stk1160_isoc_ctl isoc_ctl; | 145 | struct stk1160_isoc_ctl isoc_ctl; |
| 146 | char urb_buf[255]; /* urb control msg buffer */ | ||
| 147 | 146 | ||
| 148 | /* frame properties */ | 147 | /* frame properties */ |
| 149 | int width; /* current frame width */ | 148 | int width; /* current frame width */ |
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index 1ccaaddaa307..2e8c3afe4ec4 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c | |||
| @@ -1120,7 +1120,7 @@ static int tm6000_init_dev(struct tm6000_core *dev) | |||
| 1120 | tm6000_config_tuner(dev); | 1120 | tm6000_config_tuner(dev); |
| 1121 | 1121 | ||
| 1122 | /* Set video standard */ | 1122 | /* Set video standard */ |
| 1123 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | 1123 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, dev->norm); |
| 1124 | 1124 | ||
| 1125 | /* Set tuner frequency - also loads firmware on xc2028/xc3028 */ | 1125 | /* Set tuner frequency - also loads firmware on xc2028/xc3028 */ |
| 1126 | f.tuner = 0; | 1126 | f.tuner = 0; |
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index cc1aa14996ff..e6b3d5d83d43 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c | |||
| @@ -1071,7 +1071,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
| 1071 | if (rc < 0) | 1071 | if (rc < 0) |
| 1072 | return rc; | 1072 | return rc; |
| 1073 | 1073 | ||
| 1074 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | 1074 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, dev->norm); |
| 1075 | 1075 | ||
| 1076 | return 0; | 1076 | return 0; |
| 1077 | } | 1077 | } |
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 20365bd69d05..2967e808408b 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c | |||
| @@ -634,15 +634,12 @@ static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 634 | return usbtv_start(usbtv); | 634 | return usbtv_start(usbtv); |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | static int usbtv_stop_streaming(struct vb2_queue *vq) | 637 | static void usbtv_stop_streaming(struct vb2_queue *vq) |
| 638 | { | 638 | { |
| 639 | struct usbtv *usbtv = vb2_get_drv_priv(vq); | 639 | struct usbtv *usbtv = vb2_get_drv_priv(vq); |
| 640 | 640 | ||
| 641 | if (usbtv->udev == NULL) | 641 | if (usbtv->udev) |
| 642 | return -ENODEV; | 642 | usbtv_stop(usbtv); |
| 643 | |||
| 644 | usbtv_stop(usbtv); | ||
| 645 | return 0; | ||
| 646 | } | 643 | } |
| 647 | 644 | ||
| 648 | static struct vb2_ops usbtv_vb2_ops = { | 645 | static struct vb2_ops usbtv_vb2_ops = { |
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 5c9e3123ad2e..68bc9615660e 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c | |||
| @@ -597,7 +597,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) | |||
| 597 | 597 | ||
| 598 | usbvision->tvnorm_id = id; | 598 | usbvision->tvnorm_id = id; |
| 599 | 599 | ||
| 600 | call_all(usbvision, core, s_std, usbvision->tvnorm_id); | 600 | call_all(usbvision, video, s_std, usbvision->tvnorm_id); |
| 601 | /* propagate the change to the decoder */ | 601 | /* propagate the change to the decoder */ |
| 602 | usbvision_muxsel(usbvision, usbvision->ctl_input); | 602 | usbvision_muxsel(usbvision, usbvision->ctl_input); |
| 603 | 603 | ||
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 8d52baf5952b..9144a2f3ed82 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c | |||
| @@ -361,6 +361,14 @@ static int uvc_commit_video(struct uvc_streaming *stream, | |||
| 361 | * Clocks and timestamps | 361 | * Clocks and timestamps |
| 362 | */ | 362 | */ |
| 363 | 363 | ||
| 364 | static inline void uvc_video_get_ts(struct timespec *ts) | ||
| 365 | { | ||
| 366 | if (uvc_clock_param == CLOCK_MONOTONIC) | ||
| 367 | ktime_get_ts(ts); | ||
| 368 | else | ||
| 369 | ktime_get_real_ts(ts); | ||
| 370 | } | ||
| 371 | |||
| 364 | static void | 372 | static void |
| 365 | uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, | 373 | uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, |
| 366 | const __u8 *data, int len) | 374 | const __u8 *data, int len) |
| @@ -420,7 +428,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, | |||
| 420 | stream->clock.last_sof = dev_sof; | 428 | stream->clock.last_sof = dev_sof; |
| 421 | 429 | ||
| 422 | host_sof = usb_get_current_frame_number(stream->dev->udev); | 430 | host_sof = usb_get_current_frame_number(stream->dev->udev); |
| 423 | ktime_get_ts(&ts); | 431 | uvc_video_get_ts(&ts); |
| 424 | 432 | ||
| 425 | /* The UVC specification allows device implementations that can't obtain | 433 | /* The UVC specification allows device implementations that can't obtain |
| 426 | * the USB frame number to keep their own frame counters as long as they | 434 | * the USB frame number to keep their own frame counters as long as they |
| @@ -1011,10 +1019,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
| 1011 | return -ENODATA; | 1019 | return -ENODATA; |
| 1012 | } | 1020 | } |
| 1013 | 1021 | ||
| 1014 | if (uvc_clock_param == CLOCK_MONOTONIC) | 1022 | uvc_video_get_ts(&ts); |
| 1015 | ktime_get_ts(&ts); | ||
| 1016 | else | ||
| 1017 | ktime_get_real_ts(&ts); | ||
| 1018 | 1023 | ||
| 1019 | buf->buf.v4l2_buf.sequence = stream->sequence; | 1024 | buf->buf.v4l2_buf.sequence = stream->sequence; |
| 1020 | buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec; | 1025 | buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec; |
| @@ -1133,6 +1138,17 @@ static int uvc_video_encode_data(struct uvc_streaming *stream, | |||
| 1133 | */ | 1138 | */ |
| 1134 | 1139 | ||
| 1135 | /* | 1140 | /* |
| 1141 | * Set error flag for incomplete buffer. | ||
| 1142 | */ | ||
| 1143 | static void uvc_video_validate_buffer(const struct uvc_streaming *stream, | ||
| 1144 | struct uvc_buffer *buf) | ||
| 1145 | { | ||
| 1146 | if (buf->length != buf->bytesused && | ||
| 1147 | !(stream->cur_format->flags & UVC_FMT_FLAG_COMPRESSED)) | ||
| 1148 | buf->error = 1; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | /* | ||
| 1136 | * Completion handler for video URBs. | 1152 | * Completion handler for video URBs. |
| 1137 | */ | 1153 | */ |
| 1138 | static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, | 1154 | static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, |
| @@ -1156,9 +1172,11 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, | |||
| 1156 | do { | 1172 | do { |
| 1157 | ret = uvc_video_decode_start(stream, buf, mem, | 1173 | ret = uvc_video_decode_start(stream, buf, mem, |
| 1158 | urb->iso_frame_desc[i].actual_length); | 1174 | urb->iso_frame_desc[i].actual_length); |
| 1159 | if (ret == -EAGAIN) | 1175 | if (ret == -EAGAIN) { |
| 1176 | uvc_video_validate_buffer(stream, buf); | ||
| 1160 | buf = uvc_queue_next_buffer(&stream->queue, | 1177 | buf = uvc_queue_next_buffer(&stream->queue, |
| 1161 | buf); | 1178 | buf); |
| 1179 | } | ||
| 1162 | } while (ret == -EAGAIN); | 1180 | } while (ret == -EAGAIN); |
| 1163 | 1181 | ||
| 1164 | if (ret < 0) | 1182 | if (ret < 0) |
| @@ -1173,11 +1191,7 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, | |||
| 1173 | urb->iso_frame_desc[i].actual_length); | 1191 | urb->iso_frame_desc[i].actual_length); |
| 1174 | 1192 | ||
| 1175 | if (buf->state == UVC_BUF_STATE_READY) { | 1193 | if (buf->state == UVC_BUF_STATE_READY) { |
| 1176 | if (buf->length != buf->bytesused && | 1194 | uvc_video_validate_buffer(stream, buf); |
| 1177 | !(stream->cur_format->flags & | ||
| 1178 | UVC_FMT_FLAG_COMPRESSED)) | ||
| 1179 | buf->error = 1; | ||
| 1180 | |||
| 1181 | buf = uvc_queue_next_buffer(&stream->queue, buf); | 1195 | buf = uvc_queue_next_buffer(&stream->queue, buf); |
| 1182 | } | 1196 | } |
| 1183 | } | 1197 | } |
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index 2189bfb2e828..9ca0f8d59a14 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig | |||
| @@ -83,3 +83,7 @@ config VIDEOBUF2_DMA_SG | |||
| 83 | #depends on HAS_DMA | 83 | #depends on HAS_DMA |
| 84 | select VIDEOBUF2_CORE | 84 | select VIDEOBUF2_CORE |
| 85 | select VIDEOBUF2_MEMOPS | 85 | select VIDEOBUF2_MEMOPS |
| 86 | |||
| 87 | config VIDEOBUF2_DVB | ||
| 88 | tristate | ||
| 89 | select VIDEOBUF2_CORE | ||
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index c6ae7bad951e..63d29f27538c 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile | |||
| @@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o | |||
| 33 | obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o | 33 | obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o |
| 34 | obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o | 34 | obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o |
| 35 | obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o | 35 | obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o |
| 36 | obj-$(CONFIG_VIDEOBUF2_DVB) += videobuf2-dvb.o | ||
| 36 | 37 | ||
| 37 | ccflags-y += -I$(srctree)/drivers/media/dvb-core | 38 | ccflags-y += -I$(srctree)/drivers/media/dvb-core |
| 38 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends | 39 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends |
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 20c09229a08e..06c18ba16fa0 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c | |||
| @@ -1301,7 +1301,6 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg) | |||
| 1301 | 1301 | ||
| 1302 | static const struct v4l2_subdev_core_ops tuner_core_ops = { | 1302 | static const struct v4l2_subdev_core_ops tuner_core_ops = { |
| 1303 | .log_status = tuner_log_status, | 1303 | .log_status = tuner_log_status, |
| 1304 | .s_std = tuner_s_std, | ||
| 1305 | .s_power = tuner_s_power, | 1304 | .s_power = tuner_s_power, |
| 1306 | }; | 1305 | }; |
| 1307 | 1306 | ||
| @@ -1315,9 +1314,14 @@ static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { | |||
| 1315 | .s_config = tuner_s_config, | 1314 | .s_config = tuner_s_config, |
| 1316 | }; | 1315 | }; |
| 1317 | 1316 | ||
| 1317 | static const struct v4l2_subdev_video_ops tuner_video_ops = { | ||
| 1318 | .s_std = tuner_s_std, | ||
| 1319 | }; | ||
| 1320 | |||
| 1318 | static const struct v4l2_subdev_ops tuner_ops = { | 1321 | static const struct v4l2_subdev_ops tuner_ops = { |
| 1319 | .core = &tuner_core_ops, | 1322 | .core = &tuner_core_ops, |
| 1320 | .tuner = &tuner_tuner_ops, | 1323 | .tuner = &tuner_tuner_ops, |
| 1324 | .video = &tuner_video_ops, | ||
| 1321 | }; | 1325 | }; |
| 1322 | 1326 | ||
| 1323 | /* | 1327 | /* |
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 02d1b6327117..015f92aab44a 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c | |||
| @@ -158,7 +158,17 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, | |||
| 158 | /* Warn if we apparently re-register a subdev */ | 158 | /* Warn if we apparently re-register a subdev */ |
| 159 | WARN_ON(sd->v4l2_dev != NULL); | 159 | WARN_ON(sd->v4l2_dev != NULL); |
| 160 | 160 | ||
| 161 | if (!try_module_get(sd->owner)) | 161 | /* |
| 162 | * The reason to acquire the module here is to avoid unloading | ||
| 163 | * a module of sub-device which is registered to a media | ||
| 164 | * device. To make it possible to unload modules for media | ||
| 165 | * devices that also register sub-devices, do not | ||
| 166 | * try_module_get() such sub-device owners. | ||
| 167 | */ | ||
| 168 | sd->owner_v4l2_dev = v4l2_dev->dev && v4l2_dev->dev->driver && | ||
| 169 | sd->owner == v4l2_dev->dev->driver->owner; | ||
| 170 | |||
| 171 | if (!sd->owner_v4l2_dev && !try_module_get(sd->owner)) | ||
| 162 | return -ENODEV; | 172 | return -ENODEV; |
| 163 | 173 | ||
| 164 | sd->v4l2_dev = v4l2_dev; | 174 | sd->v4l2_dev = v4l2_dev; |
| @@ -192,7 +202,8 @@ error_unregister: | |||
| 192 | if (sd->internal_ops && sd->internal_ops->unregistered) | 202 | if (sd->internal_ops && sd->internal_ops->unregistered) |
| 193 | sd->internal_ops->unregistered(sd); | 203 | sd->internal_ops->unregistered(sd); |
| 194 | error_module: | 204 | error_module: |
| 195 | module_put(sd->owner); | 205 | if (!sd->owner_v4l2_dev) |
| 206 | module_put(sd->owner); | ||
| 196 | sd->v4l2_dev = NULL; | 207 | sd->v4l2_dev = NULL; |
| 197 | return err; | 208 | return err; |
| 198 | } | 209 | } |
| @@ -280,6 +291,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) | |||
| 280 | } | 291 | } |
| 281 | #endif | 292 | #endif |
| 282 | video_unregister_device(sd->devnode); | 293 | video_unregister_device(sd->devnode); |
| 283 | module_put(sd->owner); | 294 | if (!sd->owner_v4l2_dev) |
| 295 | module_put(sd->owner); | ||
| 284 | } | 296 | } |
| 285 | EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); | 297 | EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); |
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 48b20dfcc4d0..4ae54caadd03 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c | |||
| @@ -131,6 +131,17 @@ const struct v4l2_dv_timings v4l2_dv_timings_presets[] = { | |||
| 131 | V4L2_DV_BT_DMT_2560X1600P75, | 131 | V4L2_DV_BT_DMT_2560X1600P75, |
| 132 | V4L2_DV_BT_DMT_2560X1600P85, | 132 | V4L2_DV_BT_DMT_2560X1600P85, |
| 133 | V4L2_DV_BT_DMT_2560X1600P120_RB, | 133 | V4L2_DV_BT_DMT_2560X1600P120_RB, |
| 134 | V4L2_DV_BT_CEA_3840X2160P24, | ||
| 135 | V4L2_DV_BT_CEA_3840X2160P25, | ||
| 136 | V4L2_DV_BT_CEA_3840X2160P30, | ||
| 137 | V4L2_DV_BT_CEA_3840X2160P50, | ||
| 138 | V4L2_DV_BT_CEA_3840X2160P60, | ||
| 139 | V4L2_DV_BT_CEA_4096X2160P24, | ||
| 140 | V4L2_DV_BT_CEA_4096X2160P25, | ||
| 141 | V4L2_DV_BT_CEA_4096X2160P30, | ||
| 142 | V4L2_DV_BT_CEA_4096X2160P50, | ||
| 143 | V4L2_DV_BT_DMT_4096X2160P59_94_RB, | ||
| 144 | V4L2_DV_BT_CEA_4096X2160P60, | ||
| 134 | { } | 145 | { } |
| 135 | }; | 146 | }; |
| 136 | EXPORT_SYMBOL_GPL(v4l2_dv_timings_presets); | 147 | EXPORT_SYMBOL_GPL(v4l2_dv_timings_presets); |
diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index 86dcb5483c42..8761aab99de9 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c | |||
| @@ -318,3 +318,39 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, | |||
| 318 | return v4l2_event_unsubscribe(fh, sub); | 318 | return v4l2_event_unsubscribe(fh, sub); |
| 319 | } | 319 | } |
| 320 | EXPORT_SYMBOL_GPL(v4l2_event_subdev_unsubscribe); | 320 | EXPORT_SYMBOL_GPL(v4l2_event_subdev_unsubscribe); |
| 321 | |||
| 322 | static void v4l2_event_src_replace(struct v4l2_event *old, | ||
| 323 | const struct v4l2_event *new) | ||
| 324 | { | ||
| 325 | u32 old_changes = old->u.src_change.changes; | ||
| 326 | |||
| 327 | old->u.src_change = new->u.src_change; | ||
| 328 | old->u.src_change.changes |= old_changes; | ||
| 329 | } | ||
| 330 | |||
| 331 | static void v4l2_event_src_merge(const struct v4l2_event *old, | ||
| 332 | struct v4l2_event *new) | ||
| 333 | { | ||
| 334 | new->u.src_change.changes |= old->u.src_change.changes; | ||
| 335 | } | ||
| 336 | |||
| 337 | static const struct v4l2_subscribed_event_ops v4l2_event_src_ch_ops = { | ||
| 338 | .replace = v4l2_event_src_replace, | ||
| 339 | .merge = v4l2_event_src_merge, | ||
| 340 | }; | ||
| 341 | |||
| 342 | int v4l2_src_change_event_subscribe(struct v4l2_fh *fh, | ||
| 343 | const struct v4l2_event_subscription *sub) | ||
| 344 | { | ||
| 345 | if (sub->type == V4L2_EVENT_SOURCE_CHANGE) | ||
| 346 | return v4l2_event_subscribe(fh, sub, 0, &v4l2_event_src_ch_ops); | ||
| 347 | return -EINVAL; | ||
| 348 | } | ||
| 349 | EXPORT_SYMBOL_GPL(v4l2_src_change_event_subscribe); | ||
| 350 | |||
| 351 | int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd, | ||
| 352 | struct v4l2_fh *fh, struct v4l2_event_subscription *sub) | ||
| 353 | { | ||
| 354 | return v4l2_src_change_event_subscribe(fh, sub); | ||
| 355 | } | ||
| 356 | EXPORT_SYMBOL_GPL(v4l2_src_change_event_subdev_subscribe); | ||
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index d9113cc71c77..16bffd851bf9 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
| @@ -562,7 +562,7 @@ static void v4l_print_cropcap(const void *arg, bool write_only) | |||
| 562 | const struct v4l2_cropcap *p = arg; | 562 | const struct v4l2_cropcap *p = arg; |
| 563 | 563 | ||
| 564 | pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, " | 564 | pr_cont("type=%s, bounds wxh=%dx%d, x,y=%d,%d, " |
| 565 | "defrect wxh=%dx%d, x,y=%d,%d\n, " | 565 | "defrect wxh=%dx%d, x,y=%d,%d, " |
| 566 | "pixelaspect %d/%d\n", | 566 | "pixelaspect %d/%d\n", |
| 567 | prt_names(p->type, v4l2_type_names), | 567 | prt_names(p->type, v4l2_type_names), |
| 568 | p->bounds.width, p->bounds.height, | 568 | p->bounds.width, p->bounds.height, |
| @@ -2260,7 +2260,7 @@ done: | |||
| 2260 | } | 2260 | } |
| 2261 | 2261 | ||
| 2262 | static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, | 2262 | static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, |
| 2263 | void * __user *user_ptr, void ***kernel_ptr) | 2263 | void __user **user_ptr, void ***kernel_ptr) |
| 2264 | { | 2264 | { |
| 2265 | int ret = 0; | 2265 | int ret = 0; |
| 2266 | 2266 | ||
| @@ -2277,7 +2277,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, | |||
| 2277 | break; | 2277 | break; |
| 2278 | } | 2278 | } |
| 2279 | *user_ptr = (void __user *)buf->m.planes; | 2279 | *user_ptr = (void __user *)buf->m.planes; |
| 2280 | *kernel_ptr = (void *)&buf->m.planes; | 2280 | *kernel_ptr = (void **)&buf->m.planes; |
| 2281 | *array_size = sizeof(struct v4l2_plane) * buf->length; | 2281 | *array_size = sizeof(struct v4l2_plane) * buf->length; |
| 2282 | ret = 1; | 2282 | ret = 1; |
| 2283 | } | 2283 | } |
| @@ -2294,7 +2294,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, | |||
| 2294 | break; | 2294 | break; |
| 2295 | } | 2295 | } |
| 2296 | *user_ptr = (void __user *)edid->edid; | 2296 | *user_ptr = (void __user *)edid->edid; |
| 2297 | *kernel_ptr = (void *)&edid->edid; | 2297 | *kernel_ptr = (void **)&edid->edid; |
| 2298 | *array_size = edid->blocks * 128; | 2298 | *array_size = edid->blocks * 128; |
| 2299 | ret = 1; | 2299 | ret = 1; |
| 2300 | } | 2300 | } |
| @@ -2312,7 +2312,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, | |||
| 2312 | break; | 2312 | break; |
| 2313 | } | 2313 | } |
| 2314 | *user_ptr = (void __user *)ctrls->controls; | 2314 | *user_ptr = (void __user *)ctrls->controls; |
| 2315 | *kernel_ptr = (void *)&ctrls->controls; | 2315 | *kernel_ptr = (void **)&ctrls->controls; |
| 2316 | *array_size = sizeof(struct v4l2_ext_control) | 2316 | *array_size = sizeof(struct v4l2_ext_control) |
| 2317 | * ctrls->count; | 2317 | * ctrls->count; |
| 2318 | ret = 1; | 2318 | ret = 1; |
| @@ -2412,7 +2412,7 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
| 2412 | } | 2412 | } |
| 2413 | 2413 | ||
| 2414 | if (has_array_args) { | 2414 | if (has_array_args) { |
| 2415 | *kernel_ptr = user_ptr; | 2415 | *kernel_ptr = (void __force *)user_ptr; |
| 2416 | if (copy_to_user(user_ptr, mbuf, array_size)) | 2416 | if (copy_to_user(user_ptr, mbuf, array_size)) |
| 2417 | err = -EFAULT; | 2417 | err = -EFAULT; |
| 2418 | goto out_array_args; | 2418 | goto out_array_args; |
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index aea84ac5688a..058c1a6e8392 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c | |||
| @@ -305,11 +305,23 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 305 | fse); | 305 | fse); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | case VIDIOC_SUBDEV_G_FRAME_INTERVAL: | 308 | case VIDIOC_SUBDEV_G_FRAME_INTERVAL: { |
| 309 | struct v4l2_subdev_frame_interval *fi = arg; | ||
| 310 | |||
| 311 | if (fi->pad >= sd->entity.num_pads) | ||
| 312 | return -EINVAL; | ||
| 313 | |||
| 309 | return v4l2_subdev_call(sd, video, g_frame_interval, arg); | 314 | return v4l2_subdev_call(sd, video, g_frame_interval, arg); |
| 315 | } | ||
| 316 | |||
| 317 | case VIDIOC_SUBDEV_S_FRAME_INTERVAL: { | ||
| 318 | struct v4l2_subdev_frame_interval *fi = arg; | ||
| 319 | |||
| 320 | if (fi->pad >= sd->entity.num_pads) | ||
| 321 | return -EINVAL; | ||
| 310 | 322 | ||
| 311 | case VIDIOC_SUBDEV_S_FRAME_INTERVAL: | ||
| 312 | return v4l2_subdev_call(sd, video, s_frame_interval, arg); | 323 | return v4l2_subdev_call(sd, video, s_frame_interval, arg); |
| 324 | } | ||
| 313 | 325 | ||
| 314 | case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { | 326 | case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { |
| 315 | struct v4l2_subdev_frame_interval_enum *fie = arg; | 327 | struct v4l2_subdev_frame_interval_enum *fie = arg; |
| @@ -349,11 +361,54 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
| 349 | sd, pad, set_selection, subdev_fh, sel); | 361 | sd, pad, set_selection, subdev_fh, sel); |
| 350 | } | 362 | } |
| 351 | 363 | ||
| 352 | case VIDIOC_G_EDID: | 364 | case VIDIOC_G_EDID: { |
| 353 | return v4l2_subdev_call(sd, pad, get_edid, arg); | 365 | struct v4l2_subdev_edid *edid = arg; |
| 366 | |||
| 367 | if (edid->pad >= sd->entity.num_pads) | ||
| 368 | return -EINVAL; | ||
| 369 | if (edid->blocks && edid->edid == NULL) | ||
| 370 | return -EINVAL; | ||
| 371 | |||
| 372 | return v4l2_subdev_call(sd, pad, get_edid, edid); | ||
| 373 | } | ||
| 374 | |||
| 375 | case VIDIOC_S_EDID: { | ||
| 376 | struct v4l2_subdev_edid *edid = arg; | ||
| 377 | |||
| 378 | if (edid->pad >= sd->entity.num_pads) | ||
| 379 | return -EINVAL; | ||
| 380 | if (edid->blocks && edid->edid == NULL) | ||
| 381 | return -EINVAL; | ||
| 382 | |||
| 383 | return v4l2_subdev_call(sd, pad, set_edid, edid); | ||
| 384 | } | ||
| 385 | |||
| 386 | case VIDIOC_SUBDEV_DV_TIMINGS_CAP: { | ||
| 387 | struct v4l2_dv_timings_cap *cap = arg; | ||
| 388 | |||
| 389 | if (cap->pad >= sd->entity.num_pads) | ||
| 390 | return -EINVAL; | ||
| 391 | |||
| 392 | return v4l2_subdev_call(sd, pad, dv_timings_cap, cap); | ||
| 393 | } | ||
| 394 | |||
| 395 | case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: { | ||
| 396 | struct v4l2_enum_dv_timings *dvt = arg; | ||
| 397 | |||
| 398 | if (dvt->pad >= sd->entity.num_pads) | ||
| 399 | return -EINVAL; | ||
| 400 | |||
| 401 | return v4l2_subdev_call(sd, pad, enum_dv_timings, dvt); | ||
| 402 | } | ||
| 403 | |||
| 404 | case VIDIOC_SUBDEV_QUERY_DV_TIMINGS: | ||
| 405 | return v4l2_subdev_call(sd, video, query_dv_timings, arg); | ||
| 406 | |||
| 407 | case VIDIOC_SUBDEV_G_DV_TIMINGS: | ||
| 408 | return v4l2_subdev_call(sd, video, g_dv_timings, arg); | ||
| 354 | 409 | ||
| 355 | case VIDIOC_S_EDID: | 410 | case VIDIOC_SUBDEV_S_DV_TIMINGS: |
| 356 | return v4l2_subdev_call(sd, pad, set_edid, arg); | 411 | return v4l2_subdev_call(sd, video, s_dv_timings, arg); |
| 357 | #endif | 412 | #endif |
| 358 | default: | 413 | default: |
| 359 | return v4l2_subdev_call(sd, core, ioctl, cmd, arg); | 414 | return v4l2_subdev_call(sd, core, ioctl, cmd, arg); |
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c index 7e6b209b7002..bf80f0f7dfb8 100644 --- a/drivers/media/v4l2-core/videobuf-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c | |||
| @@ -305,7 +305,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
| 305 | /* Try to remap memory */ | 305 | /* Try to remap memory */ |
| 306 | size = vma->vm_end - vma->vm_start; | 306 | size = vma->vm_end - vma->vm_start; |
| 307 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 307 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 308 | retval = vm_iomap_memory(vma, vma->vm_start, size); | 308 | retval = vm_iomap_memory(vma, mem->dma_handle, size); |
| 309 | if (retval) { | 309 | if (retval) { |
| 310 | dev_err(q->dev, "mmap: remap failed with error %d. ", | 310 | dev_err(q->dev, "mmap: remap failed with error %d. ", |
| 311 | retval); | 311 | retval); |
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index f9059bb73840..349e659d75fb 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
| @@ -6,6 +6,9 @@ | |||
| 6 | * Author: Pawel Osciak <pawel@osciak.com> | 6 | * Author: Pawel Osciak <pawel@osciak.com> |
| 7 | * Marek Szyprowski <m.szyprowski@samsung.com> | 7 | * Marek Szyprowski <m.szyprowski@samsung.com> |
| 8 | * | 8 | * |
| 9 | * The vb2_thread implementation was based on code from videobuf-dvb.c: | ||
| 10 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs] | ||
| 11 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
| 11 | * the Free Software Foundation. | 14 | * the Free Software Foundation. |
| @@ -18,76 +21,154 @@ | |||
| 18 | #include <linux/poll.h> | 21 | #include <linux/poll.h> |
| 19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 20 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/freezer.h> | ||
| 25 | #include <linux/kthread.h> | ||
| 21 | 26 | ||
| 22 | #include <media/v4l2-dev.h> | 27 | #include <media/v4l2-dev.h> |
| 23 | #include <media/v4l2-fh.h> | 28 | #include <media/v4l2-fh.h> |
| 24 | #include <media/v4l2-event.h> | 29 | #include <media/v4l2-event.h> |
| 30 | #include <media/v4l2-common.h> | ||
| 25 | #include <media/videobuf2-core.h> | 31 | #include <media/videobuf2-core.h> |
| 26 | 32 | ||
| 27 | static int debug; | 33 | static int debug; |
| 28 | module_param(debug, int, 0644); | 34 | module_param(debug, int, 0644); |
| 29 | 35 | ||
| 30 | #define dprintk(level, fmt, arg...) \ | 36 | #define dprintk(level, fmt, arg...) \ |
| 31 | do { \ | 37 | do { \ |
| 32 | if (debug >= level) \ | 38 | if (debug >= level) \ |
| 33 | printk(KERN_DEBUG "vb2: " fmt, ## arg); \ | 39 | pr_debug("vb2: %s: " fmt, __func__, ## arg); \ |
| 34 | } while (0) | 40 | } while (0) |
| 35 | 41 | ||
| 36 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 42 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 37 | 43 | ||
| 38 | /* | 44 | /* |
| 39 | * If advanced debugging is on, then count how often each op is called, | 45 | * If advanced debugging is on, then count how often each op is called |
| 40 | * which can either be per-buffer or per-queue. | 46 | * successfully, which can either be per-buffer or per-queue. |
| 41 | * | 47 | * |
| 42 | * If the op failed then the 'fail_' variant is called to decrease the | 48 | * This makes it easy to check that the 'init' and 'cleanup' |
| 43 | * counter. That makes it easy to check that the 'init' and 'cleanup' | ||
| 44 | * (and variations thereof) stay balanced. | 49 | * (and variations thereof) stay balanced. |
| 45 | */ | 50 | */ |
| 46 | 51 | ||
| 52 | #define log_memop(vb, op) \ | ||
| 53 | dprintk(2, "call_memop(%p, %d, %s)%s\n", \ | ||
| 54 | (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \ | ||
| 55 | (vb)->vb2_queue->mem_ops->op ? "" : " (nop)") | ||
| 56 | |||
| 47 | #define call_memop(vb, op, args...) \ | 57 | #define call_memop(vb, op, args...) \ |
| 48 | ({ \ | 58 | ({ \ |
| 49 | struct vb2_queue *_q = (vb)->vb2_queue; \ | 59 | struct vb2_queue *_q = (vb)->vb2_queue; \ |
| 50 | dprintk(2, "call_memop(%p, %d, %s)%s\n", \ | 60 | int err; \ |
| 51 | _q, (vb)->v4l2_buf.index, #op, \ | 61 | \ |
| 52 | _q->mem_ops->op ? "" : " (nop)"); \ | 62 | log_memop(vb, op); \ |
| 63 | err = _q->mem_ops->op ? _q->mem_ops->op(args) : 0; \ | ||
| 64 | if (!err) \ | ||
| 65 | (vb)->cnt_mem_ ## op++; \ | ||
| 66 | err; \ | ||
| 67 | }) | ||
| 68 | |||
| 69 | #define call_ptr_memop(vb, op, args...) \ | ||
| 70 | ({ \ | ||
| 71 | struct vb2_queue *_q = (vb)->vb2_queue; \ | ||
| 72 | void *ptr; \ | ||
| 73 | \ | ||
| 74 | log_memop(vb, op); \ | ||
| 75 | ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL; \ | ||
| 76 | if (!IS_ERR_OR_NULL(ptr)) \ | ||
| 77 | (vb)->cnt_mem_ ## op++; \ | ||
| 78 | ptr; \ | ||
| 79 | }) | ||
| 80 | |||
| 81 | #define call_void_memop(vb, op, args...) \ | ||
| 82 | ({ \ | ||
| 83 | struct vb2_queue *_q = (vb)->vb2_queue; \ | ||
| 84 | \ | ||
| 85 | log_memop(vb, op); \ | ||
| 86 | if (_q->mem_ops->op) \ | ||
| 87 | _q->mem_ops->op(args); \ | ||
| 53 | (vb)->cnt_mem_ ## op++; \ | 88 | (vb)->cnt_mem_ ## op++; \ |
| 54 | _q->mem_ops->op ? _q->mem_ops->op(args) : 0; \ | ||
| 55 | }) | 89 | }) |
| 56 | #define fail_memop(vb, op) ((vb)->cnt_mem_ ## op--) | 90 | |
| 91 | #define log_qop(q, op) \ | ||
| 92 | dprintk(2, "call_qop(%p, %s)%s\n", q, #op, \ | ||
| 93 | (q)->ops->op ? "" : " (nop)") | ||
| 57 | 94 | ||
| 58 | #define call_qop(q, op, args...) \ | 95 | #define call_qop(q, op, args...) \ |
| 59 | ({ \ | 96 | ({ \ |
| 60 | dprintk(2, "call_qop(%p, %s)%s\n", q, #op, \ | 97 | int err; \ |
| 61 | (q)->ops->op ? "" : " (nop)"); \ | 98 | \ |
| 99 | log_qop(q, op); \ | ||
| 100 | err = (q)->ops->op ? (q)->ops->op(args) : 0; \ | ||
| 101 | if (!err) \ | ||
| 102 | (q)->cnt_ ## op++; \ | ||
| 103 | err; \ | ||
| 104 | }) | ||
| 105 | |||
| 106 | #define call_void_qop(q, op, args...) \ | ||
| 107 | ({ \ | ||
| 108 | log_qop(q, op); \ | ||
| 109 | if ((q)->ops->op) \ | ||
| 110 | (q)->ops->op(args); \ | ||
| 62 | (q)->cnt_ ## op++; \ | 111 | (q)->cnt_ ## op++; \ |
| 63 | (q)->ops->op ? (q)->ops->op(args) : 0; \ | ||
| 64 | }) | 112 | }) |
| 65 | #define fail_qop(q, op) ((q)->cnt_ ## op--) | 113 | |
| 114 | #define log_vb_qop(vb, op, args...) \ | ||
| 115 | dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \ | ||
| 116 | (vb)->vb2_queue, (vb)->v4l2_buf.index, #op, \ | ||
| 117 | (vb)->vb2_queue->ops->op ? "" : " (nop)") | ||
| 66 | 118 | ||
| 67 | #define call_vb_qop(vb, op, args...) \ | 119 | #define call_vb_qop(vb, op, args...) \ |
| 68 | ({ \ | 120 | ({ \ |
| 69 | struct vb2_queue *_q = (vb)->vb2_queue; \ | 121 | int err; \ |
| 70 | dprintk(2, "call_vb_qop(%p, %d, %s)%s\n", \ | 122 | \ |
| 71 | _q, (vb)->v4l2_buf.index, #op, \ | 123 | log_vb_qop(vb, op); \ |
| 72 | _q->ops->op ? "" : " (nop)"); \ | 124 | err = (vb)->vb2_queue->ops->op ? \ |
| 125 | (vb)->vb2_queue->ops->op(args) : 0; \ | ||
| 126 | if (!err) \ | ||
| 127 | (vb)->cnt_ ## op++; \ | ||
| 128 | err; \ | ||
| 129 | }) | ||
| 130 | |||
| 131 | #define call_void_vb_qop(vb, op, args...) \ | ||
| 132 | ({ \ | ||
| 133 | log_vb_qop(vb, op); \ | ||
| 134 | if ((vb)->vb2_queue->ops->op) \ | ||
| 135 | (vb)->vb2_queue->ops->op(args); \ | ||
| 73 | (vb)->cnt_ ## op++; \ | 136 | (vb)->cnt_ ## op++; \ |
| 74 | _q->ops->op ? _q->ops->op(args) : 0; \ | ||
| 75 | }) | 137 | }) |
| 76 | #define fail_vb_qop(vb, op) ((vb)->cnt_ ## op--) | ||
| 77 | 138 | ||
| 78 | #else | 139 | #else |
| 79 | 140 | ||
| 80 | #define call_memop(vb, op, args...) \ | 141 | #define call_memop(vb, op, args...) \ |
| 81 | ((vb)->vb2_queue->mem_ops->op ? (vb)->vb2_queue->mem_ops->op(args) : 0) | 142 | ((vb)->vb2_queue->mem_ops->op ? \ |
| 82 | #define fail_memop(vb, op) | 143 | (vb)->vb2_queue->mem_ops->op(args) : 0) |
| 144 | |||
| 145 | #define call_ptr_memop(vb, op, args...) \ | ||
| 146 | ((vb)->vb2_queue->mem_ops->op ? \ | ||
| 147 | (vb)->vb2_queue->mem_ops->op(args) : NULL) | ||
| 148 | |||
| 149 | #define call_void_memop(vb, op, args...) \ | ||
| 150 | do { \ | ||
| 151 | if ((vb)->vb2_queue->mem_ops->op) \ | ||
| 152 | (vb)->vb2_queue->mem_ops->op(args); \ | ||
| 153 | } while (0) | ||
| 83 | 154 | ||
| 84 | #define call_qop(q, op, args...) \ | 155 | #define call_qop(q, op, args...) \ |
| 85 | ((q)->ops->op ? (q)->ops->op(args) : 0) | 156 | ((q)->ops->op ? (q)->ops->op(args) : 0) |
| 86 | #define fail_qop(q, op) | 157 | |
| 158 | #define call_void_qop(q, op, args...) \ | ||
| 159 | do { \ | ||
| 160 | if ((q)->ops->op) \ | ||
| 161 | (q)->ops->op(args); \ | ||
| 162 | } while (0) | ||
| 87 | 163 | ||
| 88 | #define call_vb_qop(vb, op, args...) \ | 164 | #define call_vb_qop(vb, op, args...) \ |
| 89 | ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0) | 165 | ((vb)->vb2_queue->ops->op ? (vb)->vb2_queue->ops->op(args) : 0) |
| 90 | #define fail_vb_qop(vb, op) | 166 | |
| 167 | #define call_void_vb_qop(vb, op, args...) \ | ||
| 168 | do { \ | ||
| 169 | if ((vb)->vb2_queue->ops->op) \ | ||
| 170 | (vb)->vb2_queue->ops->op(args); \ | ||
| 171 | } while (0) | ||
| 91 | 172 | ||
| 92 | #endif | 173 | #endif |
| 93 | 174 | ||
| @@ -118,7 +199,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) | |||
| 118 | for (plane = 0; plane < vb->num_planes; ++plane) { | 199 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 119 | unsigned long size = PAGE_ALIGN(q->plane_sizes[plane]); | 200 | unsigned long size = PAGE_ALIGN(q->plane_sizes[plane]); |
| 120 | 201 | ||
| 121 | mem_priv = call_memop(vb, alloc, q->alloc_ctx[plane], | 202 | mem_priv = call_ptr_memop(vb, alloc, q->alloc_ctx[plane], |
| 122 | size, q->gfp_flags); | 203 | size, q->gfp_flags); |
| 123 | if (IS_ERR_OR_NULL(mem_priv)) | 204 | if (IS_ERR_OR_NULL(mem_priv)) |
| 124 | goto free; | 205 | goto free; |
| @@ -130,10 +211,9 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) | |||
| 130 | 211 | ||
| 131 | return 0; | 212 | return 0; |
| 132 | free: | 213 | free: |
| 133 | fail_memop(vb, alloc); | ||
| 134 | /* Free already allocated memory if one of the allocations failed */ | 214 | /* Free already allocated memory if one of the allocations failed */ |
| 135 | for (; plane > 0; --plane) { | 215 | for (; plane > 0; --plane) { |
| 136 | call_memop(vb, put, vb->planes[plane - 1].mem_priv); | 216 | call_void_memop(vb, put, vb->planes[plane - 1].mem_priv); |
| 137 | vb->planes[plane - 1].mem_priv = NULL; | 217 | vb->planes[plane - 1].mem_priv = NULL; |
| 138 | } | 218 | } |
| 139 | 219 | ||
| @@ -148,9 +228,9 @@ static void __vb2_buf_mem_free(struct vb2_buffer *vb) | |||
| 148 | unsigned int plane; | 228 | unsigned int plane; |
| 149 | 229 | ||
| 150 | for (plane = 0; plane < vb->num_planes; ++plane) { | 230 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 151 | call_memop(vb, put, vb->planes[plane].mem_priv); | 231 | call_void_memop(vb, put, vb->planes[plane].mem_priv); |
| 152 | vb->planes[plane].mem_priv = NULL; | 232 | vb->planes[plane].mem_priv = NULL; |
| 153 | dprintk(3, "Freed plane %d of buffer %d\n", plane, | 233 | dprintk(3, "freed plane %d of buffer %d\n", plane, |
| 154 | vb->v4l2_buf.index); | 234 | vb->v4l2_buf.index); |
| 155 | } | 235 | } |
| 156 | } | 236 | } |
| @@ -165,7 +245,7 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb) | |||
| 165 | 245 | ||
| 166 | for (plane = 0; plane < vb->num_planes; ++plane) { | 246 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 167 | if (vb->planes[plane].mem_priv) | 247 | if (vb->planes[plane].mem_priv) |
| 168 | call_memop(vb, put_userptr, vb->planes[plane].mem_priv); | 248 | call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv); |
| 169 | vb->planes[plane].mem_priv = NULL; | 249 | vb->planes[plane].mem_priv = NULL; |
| 170 | } | 250 | } |
| 171 | } | 251 | } |
| @@ -180,9 +260,9 @@ static void __vb2_plane_dmabuf_put(struct vb2_buffer *vb, struct vb2_plane *p) | |||
| 180 | return; | 260 | return; |
| 181 | 261 | ||
| 182 | if (p->dbuf_mapped) | 262 | if (p->dbuf_mapped) |
| 183 | call_memop(vb, unmap_dmabuf, p->mem_priv); | 263 | call_void_memop(vb, unmap_dmabuf, p->mem_priv); |
| 184 | 264 | ||
| 185 | call_memop(vb, detach_dmabuf, p->mem_priv); | 265 | call_void_memop(vb, detach_dmabuf, p->mem_priv); |
| 186 | dma_buf_put(p->dbuf); | 266 | dma_buf_put(p->dbuf); |
| 187 | memset(p, 0, sizeof(*p)); | 267 | memset(p, 0, sizeof(*p)); |
| 188 | } | 268 | } |
| @@ -245,7 +325,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) | |||
| 245 | for (plane = 0; plane < vb->num_planes; ++plane) { | 325 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 246 | vb->v4l2_planes[plane].m.mem_offset = off; | 326 | vb->v4l2_planes[plane].m.mem_offset = off; |
| 247 | 327 | ||
| 248 | dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n", | 328 | dprintk(3, "buffer %d, plane %d offset 0x%08lx\n", |
| 249 | buffer, plane, off); | 329 | buffer, plane, off); |
| 250 | 330 | ||
| 251 | off += vb->v4l2_planes[plane].length; | 331 | off += vb->v4l2_planes[plane].length; |
| @@ -272,7 +352,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
| 272 | /* Allocate videobuf buffer structures */ | 352 | /* Allocate videobuf buffer structures */ |
| 273 | vb = kzalloc(q->buf_struct_size, GFP_KERNEL); | 353 | vb = kzalloc(q->buf_struct_size, GFP_KERNEL); |
| 274 | if (!vb) { | 354 | if (!vb) { |
| 275 | dprintk(1, "Memory alloc for buffer struct failed\n"); | 355 | dprintk(1, "memory alloc for buffer struct failed\n"); |
| 276 | break; | 356 | break; |
| 277 | } | 357 | } |
| 278 | 358 | ||
| @@ -291,7 +371,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
| 291 | if (memory == V4L2_MEMORY_MMAP) { | 371 | if (memory == V4L2_MEMORY_MMAP) { |
| 292 | ret = __vb2_buf_mem_alloc(vb); | 372 | ret = __vb2_buf_mem_alloc(vb); |
| 293 | if (ret) { | 373 | if (ret) { |
| 294 | dprintk(1, "Failed allocating memory for " | 374 | dprintk(1, "failed allocating memory for " |
| 295 | "buffer %d\n", buffer); | 375 | "buffer %d\n", buffer); |
| 296 | kfree(vb); | 376 | kfree(vb); |
| 297 | break; | 377 | break; |
| @@ -303,9 +383,8 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
| 303 | */ | 383 | */ |
| 304 | ret = call_vb_qop(vb, buf_init, vb); | 384 | ret = call_vb_qop(vb, buf_init, vb); |
| 305 | if (ret) { | 385 | if (ret) { |
| 306 | dprintk(1, "Buffer %d %p initialization" | 386 | dprintk(1, "buffer %d %p initialization" |
| 307 | " failed\n", buffer, vb); | 387 | " failed\n", buffer, vb); |
| 308 | fail_vb_qop(vb, buf_init); | ||
| 309 | __vb2_buf_mem_free(vb); | 388 | __vb2_buf_mem_free(vb); |
| 310 | kfree(vb); | 389 | kfree(vb); |
| 311 | break; | 390 | break; |
| @@ -319,7 +398,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, | |||
| 319 | if (memory == V4L2_MEMORY_MMAP) | 398 | if (memory == V4L2_MEMORY_MMAP) |
| 320 | __setup_offsets(q, buffer); | 399 | __setup_offsets(q, buffer); |
| 321 | 400 | ||
| 322 | dprintk(1, "Allocated %d buffers, %d plane(s) each\n", | 401 | dprintk(1, "allocated %d buffers, %d plane(s) each\n", |
| 323 | buffer, num_planes); | 402 | buffer, num_planes); |
| 324 | 403 | ||
| 325 | return buffer; | 404 | return buffer; |
| @@ -371,7 +450,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) | |||
| 371 | if (q->bufs[buffer] == NULL) | 450 | if (q->bufs[buffer] == NULL) |
| 372 | continue; | 451 | continue; |
| 373 | if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) { | 452 | if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) { |
| 374 | dprintk(1, "reqbufs: preparing buffers, cannot free\n"); | 453 | dprintk(1, "preparing buffers, cannot free\n"); |
| 375 | return -EAGAIN; | 454 | return -EAGAIN; |
| 376 | } | 455 | } |
| 377 | } | 456 | } |
| @@ -382,7 +461,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) | |||
| 382 | struct vb2_buffer *vb = q->bufs[buffer]; | 461 | struct vb2_buffer *vb = q->bufs[buffer]; |
| 383 | 462 | ||
| 384 | if (vb && vb->planes[0].mem_priv) | 463 | if (vb && vb->planes[0].mem_priv) |
| 385 | call_vb_qop(vb, buf_cleanup, vb); | 464 | call_void_vb_qop(vb, buf_cleanup, vb); |
| 386 | } | 465 | } |
| 387 | 466 | ||
| 388 | /* Release video buffer memory */ | 467 | /* Release video buffer memory */ |
| @@ -476,13 +555,13 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer | |||
| 476 | 555 | ||
| 477 | /* Is memory for copying plane information present? */ | 556 | /* Is memory for copying plane information present? */ |
| 478 | if (NULL == b->m.planes) { | 557 | if (NULL == b->m.planes) { |
| 479 | dprintk(1, "Multi-planar buffer passed but " | 558 | dprintk(1, "multi-planar buffer passed but " |
| 480 | "planes array not provided\n"); | 559 | "planes array not provided\n"); |
| 481 | return -EINVAL; | 560 | return -EINVAL; |
| 482 | } | 561 | } |
| 483 | 562 | ||
| 484 | if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) { | 563 | if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) { |
| 485 | dprintk(1, "Incorrect planes array length, " | 564 | dprintk(1, "incorrect planes array length, " |
| 486 | "expected %d, got %d\n", vb->num_planes, b->length); | 565 | "expected %d, got %d\n", vb->num_planes, b->length); |
| 487 | return -EINVAL; | 566 | return -EINVAL; |
| 488 | } | 567 | } |
| @@ -656,12 +735,12 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 656 | int ret; | 735 | int ret; |
| 657 | 736 | ||
| 658 | if (b->type != q->type) { | 737 | if (b->type != q->type) { |
| 659 | dprintk(1, "querybuf: wrong buffer type\n"); | 738 | dprintk(1, "wrong buffer type\n"); |
| 660 | return -EINVAL; | 739 | return -EINVAL; |
| 661 | } | 740 | } |
| 662 | 741 | ||
| 663 | if (b->index >= q->num_buffers) { | 742 | if (b->index >= q->num_buffers) { |
| 664 | dprintk(1, "querybuf: buffer index out of range\n"); | 743 | dprintk(1, "buffer index out of range\n"); |
| 665 | return -EINVAL; | 744 | return -EINVAL; |
| 666 | } | 745 | } |
| 667 | vb = q->bufs[b->index]; | 746 | vb = q->bufs[b->index]; |
| @@ -721,12 +800,12 @@ static int __verify_memory_type(struct vb2_queue *q, | |||
| 721 | { | 800 | { |
| 722 | if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR && | 801 | if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR && |
| 723 | memory != V4L2_MEMORY_DMABUF) { | 802 | memory != V4L2_MEMORY_DMABUF) { |
| 724 | dprintk(1, "reqbufs: unsupported memory type\n"); | 803 | dprintk(1, "unsupported memory type\n"); |
| 725 | return -EINVAL; | 804 | return -EINVAL; |
| 726 | } | 805 | } |
| 727 | 806 | ||
| 728 | if (type != q->type) { | 807 | if (type != q->type) { |
| 729 | dprintk(1, "reqbufs: requested type is incorrect\n"); | 808 | dprintk(1, "requested type is incorrect\n"); |
| 730 | return -EINVAL; | 809 | return -EINVAL; |
| 731 | } | 810 | } |
| 732 | 811 | ||
| @@ -735,17 +814,17 @@ static int __verify_memory_type(struct vb2_queue *q, | |||
| 735 | * are available. | 814 | * are available. |
| 736 | */ | 815 | */ |
| 737 | if (memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) { | 816 | if (memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) { |
| 738 | dprintk(1, "reqbufs: MMAP for current setup unsupported\n"); | 817 | dprintk(1, "MMAP for current setup unsupported\n"); |
| 739 | return -EINVAL; | 818 | return -EINVAL; |
| 740 | } | 819 | } |
| 741 | 820 | ||
| 742 | if (memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) { | 821 | if (memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) { |
| 743 | dprintk(1, "reqbufs: USERPTR for current setup unsupported\n"); | 822 | dprintk(1, "USERPTR for current setup unsupported\n"); |
| 744 | return -EINVAL; | 823 | return -EINVAL; |
| 745 | } | 824 | } |
| 746 | 825 | ||
| 747 | if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) { | 826 | if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) { |
| 748 | dprintk(1, "reqbufs: DMABUF for current setup unsupported\n"); | 827 | dprintk(1, "DMABUF for current setup unsupported\n"); |
| 749 | return -EINVAL; | 828 | return -EINVAL; |
| 750 | } | 829 | } |
| 751 | 830 | ||
| @@ -754,8 +833,8 @@ static int __verify_memory_type(struct vb2_queue *q, | |||
| 754 | * create_bufs is called with count == 0, but count == 0 should still | 833 | * create_bufs is called with count == 0, but count == 0 should still |
| 755 | * do the memory and type validation. | 834 | * do the memory and type validation. |
| 756 | */ | 835 | */ |
| 757 | if (q->fileio) { | 836 | if (vb2_fileio_is_active(q)) { |
| 758 | dprintk(1, "reqbufs: file io in progress\n"); | 837 | dprintk(1, "file io in progress\n"); |
| 759 | return -EBUSY; | 838 | return -EBUSY; |
| 760 | } | 839 | } |
| 761 | return 0; | 840 | return 0; |
| @@ -790,7 +869,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
| 790 | int ret; | 869 | int ret; |
| 791 | 870 | ||
| 792 | if (q->streaming) { | 871 | if (q->streaming) { |
| 793 | dprintk(1, "reqbufs: streaming active\n"); | 872 | dprintk(1, "streaming active\n"); |
| 794 | return -EBUSY; | 873 | return -EBUSY; |
| 795 | } | 874 | } |
| 796 | 875 | ||
| @@ -800,7 +879,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
| 800 | * are not in use and can be freed. | 879 | * are not in use and can be freed. |
| 801 | */ | 880 | */ |
| 802 | if (q->memory == V4L2_MEMORY_MMAP && __buffers_in_use(q)) { | 881 | if (q->memory == V4L2_MEMORY_MMAP && __buffers_in_use(q)) { |
| 803 | dprintk(1, "reqbufs: memory in use, cannot free\n"); | 882 | dprintk(1, "memory in use, cannot free\n"); |
| 804 | return -EBUSY; | 883 | return -EBUSY; |
| 805 | } | 884 | } |
| 806 | 885 | ||
| @@ -826,7 +905,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
| 826 | * Make sure the requested values and current defaults are sane. | 905 | * Make sure the requested values and current defaults are sane. |
| 827 | */ | 906 | */ |
| 828 | num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); | 907 | num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); |
| 829 | num_buffers = max_t(unsigned int, req->count, q->min_buffers_needed); | 908 | num_buffers = max_t(unsigned int, num_buffers, q->min_buffers_needed); |
| 830 | memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); | 909 | memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); |
| 831 | memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); | 910 | memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); |
| 832 | q->memory = req->memory; | 911 | q->memory = req->memory; |
| @@ -837,15 +916,13 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
| 837 | */ | 916 | */ |
| 838 | ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes, | 917 | ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes, |
| 839 | q->plane_sizes, q->alloc_ctx); | 918 | q->plane_sizes, q->alloc_ctx); |
| 840 | if (ret) { | 919 | if (ret) |
| 841 | fail_qop(q, queue_setup); | ||
| 842 | return ret; | 920 | return ret; |
| 843 | } | ||
| 844 | 921 | ||
| 845 | /* Finally, allocate buffers and video memory */ | 922 | /* Finally, allocate buffers and video memory */ |
| 846 | allocated_buffers = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes); | 923 | allocated_buffers = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes); |
| 847 | if (allocated_buffers == 0) { | 924 | if (allocated_buffers == 0) { |
| 848 | dprintk(1, "Memory allocation failed\n"); | 925 | dprintk(1, "memory allocation failed\n"); |
| 849 | return -ENOMEM; | 926 | return -ENOMEM; |
| 850 | } | 927 | } |
| 851 | 928 | ||
| @@ -864,8 +941,6 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
| 864 | 941 | ||
| 865 | ret = call_qop(q, queue_setup, q, NULL, &num_buffers, | 942 | ret = call_qop(q, queue_setup, q, NULL, &num_buffers, |
| 866 | &num_planes, q->plane_sizes, q->alloc_ctx); | 943 | &num_planes, q->plane_sizes, q->alloc_ctx); |
| 867 | if (ret) | ||
| 868 | fail_qop(q, queue_setup); | ||
| 869 | 944 | ||
| 870 | if (!ret && allocated_buffers < num_buffers) | 945 | if (!ret && allocated_buffers < num_buffers) |
| 871 | ret = -ENOMEM; | 946 | ret = -ENOMEM; |
| @@ -931,8 +1006,7 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create | |||
| 931 | int ret; | 1006 | int ret; |
| 932 | 1007 | ||
| 933 | if (q->num_buffers == VIDEO_MAX_FRAME) { | 1008 | if (q->num_buffers == VIDEO_MAX_FRAME) { |
| 934 | dprintk(1, "%s(): maximum number of buffers already allocated\n", | 1009 | dprintk(1, "maximum number of buffers already allocated\n"); |
| 935 | __func__); | ||
| 936 | return -ENOBUFS; | 1010 | return -ENOBUFS; |
| 937 | } | 1011 | } |
| 938 | 1012 | ||
| @@ -950,16 +1024,14 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create | |||
| 950 | */ | 1024 | */ |
| 951 | ret = call_qop(q, queue_setup, q, &create->format, &num_buffers, | 1025 | ret = call_qop(q, queue_setup, q, &create->format, &num_buffers, |
| 952 | &num_planes, q->plane_sizes, q->alloc_ctx); | 1026 | &num_planes, q->plane_sizes, q->alloc_ctx); |
| 953 | if (ret) { | 1027 | if (ret) |
| 954 | fail_qop(q, queue_setup); | ||
| 955 | return ret; | 1028 | return ret; |
| 956 | } | ||
| 957 | 1029 | ||
| 958 | /* Finally, allocate buffers and video memory */ | 1030 | /* Finally, allocate buffers and video memory */ |
| 959 | allocated_buffers = __vb2_queue_alloc(q, create->memory, num_buffers, | 1031 | allocated_buffers = __vb2_queue_alloc(q, create->memory, num_buffers, |
| 960 | num_planes); | 1032 | num_planes); |
| 961 | if (allocated_buffers == 0) { | 1033 | if (allocated_buffers == 0) { |
| 962 | dprintk(1, "Memory allocation failed\n"); | 1034 | dprintk(1, "memory allocation failed\n"); |
| 963 | return -ENOMEM; | 1035 | return -ENOMEM; |
| 964 | } | 1036 | } |
| 965 | 1037 | ||
| @@ -975,8 +1047,6 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create | |||
| 975 | */ | 1047 | */ |
| 976 | ret = call_qop(q, queue_setup, q, &create->format, &num_buffers, | 1048 | ret = call_qop(q, queue_setup, q, &create->format, &num_buffers, |
| 977 | &num_planes, q->plane_sizes, q->alloc_ctx); | 1049 | &num_planes, q->plane_sizes, q->alloc_ctx); |
| 978 | if (ret) | ||
| 979 | fail_qop(q, queue_setup); | ||
| 980 | 1050 | ||
| 981 | if (!ret && allocated_buffers < num_buffers) | 1051 | if (!ret && allocated_buffers < num_buffers) |
| 982 | ret = -ENOMEM; | 1052 | ret = -ENOMEM; |
| @@ -1038,7 +1108,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no) | |||
| 1038 | if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) | 1108 | if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) |
| 1039 | return NULL; | 1109 | return NULL; |
| 1040 | 1110 | ||
| 1041 | return call_memop(vb, vaddr, vb->planes[plane_no].mem_priv); | 1111 | return call_ptr_memop(vb, vaddr, vb->planes[plane_no].mem_priv); |
| 1042 | 1112 | ||
| 1043 | } | 1113 | } |
| 1044 | EXPORT_SYMBOL_GPL(vb2_plane_vaddr); | 1114 | EXPORT_SYMBOL_GPL(vb2_plane_vaddr); |
| @@ -1059,7 +1129,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no) | |||
| 1059 | if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) | 1129 | if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) |
| 1060 | return NULL; | 1130 | return NULL; |
| 1061 | 1131 | ||
| 1062 | return call_memop(vb, cookie, vb->planes[plane_no].mem_priv); | 1132 | return call_ptr_memop(vb, cookie, vb->planes[plane_no].mem_priv); |
| 1063 | } | 1133 | } |
| 1064 | EXPORT_SYMBOL_GPL(vb2_plane_cookie); | 1134 | EXPORT_SYMBOL_GPL(vb2_plane_cookie); |
| 1065 | 1135 | ||
| @@ -1094,9 +1164,8 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 1094 | if (!q->start_streaming_called) { | 1164 | if (!q->start_streaming_called) { |
| 1095 | if (WARN_ON(state != VB2_BUF_STATE_QUEUED)) | 1165 | if (WARN_ON(state != VB2_BUF_STATE_QUEUED)) |
| 1096 | state = VB2_BUF_STATE_QUEUED; | 1166 | state = VB2_BUF_STATE_QUEUED; |
| 1097 | } else if (!WARN_ON(!q->start_streaming_called)) { | 1167 | } else if (WARN_ON(state != VB2_BUF_STATE_DONE && |
| 1098 | if (WARN_ON(state != VB2_BUF_STATE_DONE && | 1168 | state != VB2_BUF_STATE_ERROR)) { |
| 1099 | state != VB2_BUF_STATE_ERROR)) | ||
| 1100 | state = VB2_BUF_STATE_ERROR; | 1169 | state = VB2_BUF_STATE_ERROR; |
| 1101 | } | 1170 | } |
| 1102 | 1171 | ||
| @@ -1107,12 +1176,12 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 1107 | */ | 1176 | */ |
| 1108 | vb->cnt_buf_done++; | 1177 | vb->cnt_buf_done++; |
| 1109 | #endif | 1178 | #endif |
| 1110 | dprintk(4, "Done processing on buffer %d, state: %d\n", | 1179 | dprintk(4, "done processing on buffer %d, state: %d\n", |
| 1111 | vb->v4l2_buf.index, state); | 1180 | vb->v4l2_buf.index, state); |
| 1112 | 1181 | ||
| 1113 | /* sync buffers */ | 1182 | /* sync buffers */ |
| 1114 | for (plane = 0; plane < vb->num_planes; ++plane) | 1183 | for (plane = 0; plane < vb->num_planes; ++plane) |
| 1115 | call_memop(vb, finish, vb->planes[plane].mem_priv); | 1184 | call_void_memop(vb, finish, vb->planes[plane].mem_priv); |
| 1116 | 1185 | ||
| 1117 | /* Add the buffer to the done buffers list */ | 1186 | /* Add the buffer to the done buffers list */ |
| 1118 | spin_lock_irqsave(&q->done_lock, flags); | 1187 | spin_lock_irqsave(&q->done_lock, flags); |
| @@ -1143,15 +1212,30 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
| 1143 | if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { | 1212 | if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { |
| 1144 | /* Fill in driver-provided information for OUTPUT types */ | 1213 | /* Fill in driver-provided information for OUTPUT types */ |
| 1145 | if (V4L2_TYPE_IS_OUTPUT(b->type)) { | 1214 | if (V4L2_TYPE_IS_OUTPUT(b->type)) { |
| 1215 | bool bytesused_is_used; | ||
| 1216 | |||
| 1217 | /* Check if bytesused == 0 for all planes */ | ||
| 1218 | for (plane = 0; plane < vb->num_planes; ++plane) | ||
| 1219 | if (b->m.planes[plane].bytesused) | ||
| 1220 | break; | ||
| 1221 | bytesused_is_used = plane < vb->num_planes; | ||
| 1222 | |||
| 1146 | /* | 1223 | /* |
| 1147 | * Will have to go up to b->length when API starts | 1224 | * Will have to go up to b->length when API starts |
| 1148 | * accepting variable number of planes. | 1225 | * accepting variable number of planes. |
| 1226 | * | ||
| 1227 | * If bytesused_is_used is false, then fall back to the | ||
| 1228 | * full buffer size. In that case userspace clearly | ||
| 1229 | * never bothered to set it and it's a safe assumption | ||
| 1230 | * that they really meant to use the full plane sizes. | ||
| 1149 | */ | 1231 | */ |
| 1150 | for (plane = 0; plane < vb->num_planes; ++plane) { | 1232 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 1151 | v4l2_planes[plane].bytesused = | 1233 | struct v4l2_plane *pdst = &v4l2_planes[plane]; |
| 1152 | b->m.planes[plane].bytesused; | 1234 | struct v4l2_plane *psrc = &b->m.planes[plane]; |
| 1153 | v4l2_planes[plane].data_offset = | 1235 | |
| 1154 | b->m.planes[plane].data_offset; | 1236 | pdst->bytesused = bytesused_is_used ? |
| 1237 | psrc->bytesused : psrc->length; | ||
| 1238 | pdst->data_offset = psrc->data_offset; | ||
| 1155 | } | 1239 | } |
| 1156 | } | 1240 | } |
| 1157 | 1241 | ||
| @@ -1169,8 +1253,6 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
| 1169 | b->m.planes[plane].m.fd; | 1253 | b->m.planes[plane].m.fd; |
| 1170 | v4l2_planes[plane].length = | 1254 | v4l2_planes[plane].length = |
| 1171 | b->m.planes[plane].length; | 1255 | b->m.planes[plane].length; |
| 1172 | v4l2_planes[plane].data_offset = | ||
| 1173 | b->m.planes[plane].data_offset; | ||
| 1174 | } | 1256 | } |
| 1175 | } | 1257 | } |
| 1176 | } else { | 1258 | } else { |
| @@ -1179,11 +1261,15 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
| 1179 | * so fill in relevant v4l2_buffer struct fields instead. | 1261 | * so fill in relevant v4l2_buffer struct fields instead. |
| 1180 | * In videobuf we use our internal V4l2_planes struct for | 1262 | * In videobuf we use our internal V4l2_planes struct for |
| 1181 | * single-planar buffers as well, for simplicity. | 1263 | * single-planar buffers as well, for simplicity. |
| 1264 | * | ||
| 1265 | * If bytesused == 0, then fall back to the full buffer size | ||
| 1266 | * as that's a sensible default. | ||
| 1182 | */ | 1267 | */ |
| 1183 | if (V4L2_TYPE_IS_OUTPUT(b->type)) { | 1268 | if (V4L2_TYPE_IS_OUTPUT(b->type)) |
| 1184 | v4l2_planes[0].bytesused = b->bytesused; | 1269 | v4l2_planes[0].bytesused = |
| 1185 | v4l2_planes[0].data_offset = 0; | 1270 | b->bytesused ? b->bytesused : b->length; |
| 1186 | } | 1271 | else |
| 1272 | v4l2_planes[0].bytesused = 0; | ||
| 1187 | 1273 | ||
| 1188 | if (b->memory == V4L2_MEMORY_USERPTR) { | 1274 | if (b->memory == V4L2_MEMORY_USERPTR) { |
| 1189 | v4l2_planes[0].m.userptr = b->m.userptr; | 1275 | v4l2_planes[0].m.userptr = b->m.userptr; |
| @@ -1193,9 +1279,7 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
| 1193 | if (b->memory == V4L2_MEMORY_DMABUF) { | 1279 | if (b->memory == V4L2_MEMORY_DMABUF) { |
| 1194 | v4l2_planes[0].m.fd = b->m.fd; | 1280 | v4l2_planes[0].m.fd = b->m.fd; |
| 1195 | v4l2_planes[0].length = b->length; | 1281 | v4l2_planes[0].length = b->length; |
| 1196 | v4l2_planes[0].data_offset = 0; | ||
| 1197 | } | 1282 | } |
| 1198 | |||
| 1199 | } | 1283 | } |
| 1200 | 1284 | ||
| 1201 | /* Zero flags that the vb2 core handles */ | 1285 | /* Zero flags that the vb2 core handles */ |
| @@ -1226,6 +1310,15 @@ static void __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b | |||
| 1226 | } | 1310 | } |
| 1227 | 1311 | ||
| 1228 | /** | 1312 | /** |
| 1313 | * __qbuf_mmap() - handle qbuf of an MMAP buffer | ||
| 1314 | */ | ||
| 1315 | static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) | ||
| 1316 | { | ||
| 1317 | __fill_vb2_buffer(vb, b, vb->v4l2_planes); | ||
| 1318 | return call_vb_qop(vb, buf_prepare, vb); | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | /** | ||
| 1229 | * __qbuf_userptr() - handle qbuf of a USERPTR buffer | 1322 | * __qbuf_userptr() - handle qbuf of a USERPTR buffer |
| 1230 | */ | 1323 | */ |
| 1231 | static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) | 1324 | static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
| @@ -1238,6 +1331,7 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1238 | int write = !V4L2_TYPE_IS_OUTPUT(q->type); | 1331 | int write = !V4L2_TYPE_IS_OUTPUT(q->type); |
| 1239 | bool reacquired = vb->planes[0].mem_priv == NULL; | 1332 | bool reacquired = vb->planes[0].mem_priv == NULL; |
| 1240 | 1333 | ||
| 1334 | memset(planes, 0, sizeof(planes[0]) * vb->num_planes); | ||
| 1241 | /* Copy relevant information provided by the userspace */ | 1335 | /* Copy relevant information provided by the userspace */ |
| 1242 | __fill_vb2_buffer(vb, b, planes); | 1336 | __fill_vb2_buffer(vb, b, planes); |
| 1243 | 1337 | ||
| @@ -1248,12 +1342,12 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1248 | && vb->v4l2_planes[plane].length == planes[plane].length) | 1342 | && vb->v4l2_planes[plane].length == planes[plane].length) |
| 1249 | continue; | 1343 | continue; |
| 1250 | 1344 | ||
| 1251 | dprintk(3, "qbuf: userspace address for plane %d changed, " | 1345 | dprintk(3, "userspace address for plane %d changed, " |
| 1252 | "reacquiring memory\n", plane); | 1346 | "reacquiring memory\n", plane); |
| 1253 | 1347 | ||
| 1254 | /* Check if the provided plane buffer is large enough */ | 1348 | /* Check if the provided plane buffer is large enough */ |
| 1255 | if (planes[plane].length < q->plane_sizes[plane]) { | 1349 | if (planes[plane].length < q->plane_sizes[plane]) { |
| 1256 | dprintk(1, "qbuf: provided buffer size %u is less than " | 1350 | dprintk(1, "provided buffer size %u is less than " |
| 1257 | "setup size %u for plane %d\n", | 1351 | "setup size %u for plane %d\n", |
| 1258 | planes[plane].length, | 1352 | planes[plane].length, |
| 1259 | q->plane_sizes[plane], plane); | 1353 | q->plane_sizes[plane], plane); |
| @@ -1265,22 +1359,21 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1265 | if (vb->planes[plane].mem_priv) { | 1359 | if (vb->planes[plane].mem_priv) { |
| 1266 | if (!reacquired) { | 1360 | if (!reacquired) { |
| 1267 | reacquired = true; | 1361 | reacquired = true; |
| 1268 | call_vb_qop(vb, buf_cleanup, vb); | 1362 | call_void_vb_qop(vb, buf_cleanup, vb); |
| 1269 | } | 1363 | } |
| 1270 | call_memop(vb, put_userptr, vb->planes[plane].mem_priv); | 1364 | call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv); |
| 1271 | } | 1365 | } |
| 1272 | 1366 | ||
| 1273 | vb->planes[plane].mem_priv = NULL; | 1367 | vb->planes[plane].mem_priv = NULL; |
| 1274 | memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); | 1368 | memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); |
| 1275 | 1369 | ||
| 1276 | /* Acquire each plane's memory */ | 1370 | /* Acquire each plane's memory */ |
| 1277 | mem_priv = call_memop(vb, get_userptr, q->alloc_ctx[plane], | 1371 | mem_priv = call_ptr_memop(vb, get_userptr, q->alloc_ctx[plane], |
| 1278 | planes[plane].m.userptr, | 1372 | planes[plane].m.userptr, |
| 1279 | planes[plane].length, write); | 1373 | planes[plane].length, write); |
| 1280 | if (IS_ERR_OR_NULL(mem_priv)) { | 1374 | if (IS_ERR_OR_NULL(mem_priv)) { |
| 1281 | dprintk(1, "qbuf: failed acquiring userspace " | 1375 | dprintk(1, "failed acquiring userspace " |
| 1282 | "memory for plane %d\n", plane); | 1376 | "memory for plane %d\n", plane); |
| 1283 | fail_memop(vb, get_userptr); | ||
| 1284 | ret = mem_priv ? PTR_ERR(mem_priv) : -EINVAL; | 1377 | ret = mem_priv ? PTR_ERR(mem_priv) : -EINVAL; |
| 1285 | goto err; | 1378 | goto err; |
| 1286 | } | 1379 | } |
| @@ -1302,17 +1395,15 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1302 | */ | 1395 | */ |
| 1303 | ret = call_vb_qop(vb, buf_init, vb); | 1396 | ret = call_vb_qop(vb, buf_init, vb); |
| 1304 | if (ret) { | 1397 | if (ret) { |
| 1305 | dprintk(1, "qbuf: buffer initialization failed\n"); | 1398 | dprintk(1, "buffer initialization failed\n"); |
| 1306 | fail_vb_qop(vb, buf_init); | ||
| 1307 | goto err; | 1399 | goto err; |
| 1308 | } | 1400 | } |
| 1309 | } | 1401 | } |
| 1310 | 1402 | ||
| 1311 | ret = call_vb_qop(vb, buf_prepare, vb); | 1403 | ret = call_vb_qop(vb, buf_prepare, vb); |
| 1312 | if (ret) { | 1404 | if (ret) { |
| 1313 | dprintk(1, "qbuf: buffer preparation failed\n"); | 1405 | dprintk(1, "buffer preparation failed\n"); |
| 1314 | fail_vb_qop(vb, buf_prepare); | 1406 | call_void_vb_qop(vb, buf_cleanup, vb); |
| 1315 | call_vb_qop(vb, buf_cleanup, vb); | ||
| 1316 | goto err; | 1407 | goto err; |
| 1317 | } | 1408 | } |
| 1318 | 1409 | ||
| @@ -1321,7 +1412,7 @@ err: | |||
| 1321 | /* In case of errors, release planes that were already acquired */ | 1412 | /* In case of errors, release planes that were already acquired */ |
| 1322 | for (plane = 0; plane < vb->num_planes; ++plane) { | 1413 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 1323 | if (vb->planes[plane].mem_priv) | 1414 | if (vb->planes[plane].mem_priv) |
| 1324 | call_memop(vb, put_userptr, vb->planes[plane].mem_priv); | 1415 | call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv); |
| 1325 | vb->planes[plane].mem_priv = NULL; | 1416 | vb->planes[plane].mem_priv = NULL; |
| 1326 | vb->v4l2_planes[plane].m.userptr = 0; | 1417 | vb->v4l2_planes[plane].m.userptr = 0; |
| 1327 | vb->v4l2_planes[plane].length = 0; | 1418 | vb->v4l2_planes[plane].length = 0; |
| @@ -1331,20 +1422,6 @@ err: | |||
| 1331 | } | 1422 | } |
| 1332 | 1423 | ||
| 1333 | /** | 1424 | /** |
| 1334 | * __qbuf_mmap() - handle qbuf of an MMAP buffer | ||
| 1335 | */ | ||
| 1336 | static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b) | ||
| 1337 | { | ||
| 1338 | int ret; | ||
| 1339 | |||
| 1340 | __fill_vb2_buffer(vb, b, vb->v4l2_planes); | ||
| 1341 | ret = call_vb_qop(vb, buf_prepare, vb); | ||
| 1342 | if (ret) | ||
| 1343 | fail_vb_qop(vb, buf_prepare); | ||
| 1344 | return ret; | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | /** | ||
| 1348 | * __qbuf_dmabuf() - handle qbuf of a DMABUF buffer | 1425 | * __qbuf_dmabuf() - handle qbuf of a DMABUF buffer |
| 1349 | */ | 1426 | */ |
| 1350 | static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | 1427 | static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
| @@ -1357,6 +1434,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1357 | int write = !V4L2_TYPE_IS_OUTPUT(q->type); | 1434 | int write = !V4L2_TYPE_IS_OUTPUT(q->type); |
| 1358 | bool reacquired = vb->planes[0].mem_priv == NULL; | 1435 | bool reacquired = vb->planes[0].mem_priv == NULL; |
| 1359 | 1436 | ||
| 1437 | memset(planes, 0, sizeof(planes[0]) * vb->num_planes); | ||
| 1360 | /* Copy relevant information provided by the userspace */ | 1438 | /* Copy relevant information provided by the userspace */ |
| 1361 | __fill_vb2_buffer(vb, b, planes); | 1439 | __fill_vb2_buffer(vb, b, planes); |
| 1362 | 1440 | ||
| @@ -1364,7 +1442,7 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1364 | struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd); | 1442 | struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd); |
| 1365 | 1443 | ||
| 1366 | if (IS_ERR_OR_NULL(dbuf)) { | 1444 | if (IS_ERR_OR_NULL(dbuf)) { |
| 1367 | dprintk(1, "qbuf: invalid dmabuf fd for plane %d\n", | 1445 | dprintk(1, "invalid dmabuf fd for plane %d\n", |
| 1368 | plane); | 1446 | plane); |
| 1369 | ret = -EINVAL; | 1447 | ret = -EINVAL; |
| 1370 | goto err; | 1448 | goto err; |
| @@ -1374,9 +1452,8 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1374 | if (planes[plane].length == 0) | 1452 | if (planes[plane].length == 0) |
| 1375 | planes[plane].length = dbuf->size; | 1453 | planes[plane].length = dbuf->size; |
| 1376 | 1454 | ||
| 1377 | if (planes[plane].length < planes[plane].data_offset + | 1455 | if (planes[plane].length < q->plane_sizes[plane]) { |
| 1378 | q->plane_sizes[plane]) { | 1456 | dprintk(1, "invalid dmabuf length for plane %d\n", |
| 1379 | dprintk(1, "qbuf: invalid dmabuf length for plane %d\n", | ||
| 1380 | plane); | 1457 | plane); |
| 1381 | ret = -EINVAL; | 1458 | ret = -EINVAL; |
| 1382 | goto err; | 1459 | goto err; |
| @@ -1389,11 +1466,11 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1389 | continue; | 1466 | continue; |
| 1390 | } | 1467 | } |
| 1391 | 1468 | ||
| 1392 | dprintk(1, "qbuf: buffer for plane %d changed\n", plane); | 1469 | dprintk(1, "buffer for plane %d changed\n", plane); |
| 1393 | 1470 | ||
| 1394 | if (!reacquired) { | 1471 | if (!reacquired) { |
| 1395 | reacquired = true; | 1472 | reacquired = true; |
| 1396 | call_vb_qop(vb, buf_cleanup, vb); | 1473 | call_void_vb_qop(vb, buf_cleanup, vb); |
| 1397 | } | 1474 | } |
| 1398 | 1475 | ||
| 1399 | /* Release previously acquired memory if present */ | 1476 | /* Release previously acquired memory if present */ |
| @@ -1401,11 +1478,10 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1401 | memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); | 1478 | memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane)); |
| 1402 | 1479 | ||
| 1403 | /* Acquire each plane's memory */ | 1480 | /* Acquire each plane's memory */ |
| 1404 | mem_priv = call_memop(vb, attach_dmabuf, q->alloc_ctx[plane], | 1481 | mem_priv = call_ptr_memop(vb, attach_dmabuf, q->alloc_ctx[plane], |
| 1405 | dbuf, planes[plane].length, write); | 1482 | dbuf, planes[plane].length, write); |
| 1406 | if (IS_ERR(mem_priv)) { | 1483 | if (IS_ERR(mem_priv)) { |
| 1407 | dprintk(1, "qbuf: failed to attach dmabuf\n"); | 1484 | dprintk(1, "failed to attach dmabuf\n"); |
| 1408 | fail_memop(vb, attach_dmabuf); | ||
| 1409 | ret = PTR_ERR(mem_priv); | 1485 | ret = PTR_ERR(mem_priv); |
| 1410 | dma_buf_put(dbuf); | 1486 | dma_buf_put(dbuf); |
| 1411 | goto err; | 1487 | goto err; |
| @@ -1422,9 +1498,8 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1422 | for (plane = 0; plane < vb->num_planes; ++plane) { | 1498 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 1423 | ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv); | 1499 | ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv); |
| 1424 | if (ret) { | 1500 | if (ret) { |
| 1425 | dprintk(1, "qbuf: failed to map dmabuf for plane %d\n", | 1501 | dprintk(1, "failed to map dmabuf for plane %d\n", |
| 1426 | plane); | 1502 | plane); |
| 1427 | fail_memop(vb, map_dmabuf); | ||
| 1428 | goto err; | 1503 | goto err; |
| 1429 | } | 1504 | } |
| 1430 | vb->planes[plane].dbuf_mapped = 1; | 1505 | vb->planes[plane].dbuf_mapped = 1; |
| @@ -1444,17 +1519,15 @@ static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1444 | */ | 1519 | */ |
| 1445 | ret = call_vb_qop(vb, buf_init, vb); | 1520 | ret = call_vb_qop(vb, buf_init, vb); |
| 1446 | if (ret) { | 1521 | if (ret) { |
| 1447 | dprintk(1, "qbuf: buffer initialization failed\n"); | 1522 | dprintk(1, "buffer initialization failed\n"); |
| 1448 | fail_vb_qop(vb, buf_init); | ||
| 1449 | goto err; | 1523 | goto err; |
| 1450 | } | 1524 | } |
| 1451 | } | 1525 | } |
| 1452 | 1526 | ||
| 1453 | ret = call_vb_qop(vb, buf_prepare, vb); | 1527 | ret = call_vb_qop(vb, buf_prepare, vb); |
| 1454 | if (ret) { | 1528 | if (ret) { |
| 1455 | dprintk(1, "qbuf: buffer preparation failed\n"); | 1529 | dprintk(1, "buffer preparation failed\n"); |
| 1456 | fail_vb_qop(vb, buf_prepare); | 1530 | call_void_vb_qop(vb, buf_cleanup, vb); |
| 1457 | call_vb_qop(vb, buf_cleanup, vb); | ||
| 1458 | goto err; | 1531 | goto err; |
| 1459 | } | 1532 | } |
| 1460 | 1533 | ||
| @@ -1479,9 +1552,9 @@ static void __enqueue_in_driver(struct vb2_buffer *vb) | |||
| 1479 | 1552 | ||
| 1480 | /* sync buffers */ | 1553 | /* sync buffers */ |
| 1481 | for (plane = 0; plane < vb->num_planes; ++plane) | 1554 | for (plane = 0; plane < vb->num_planes; ++plane) |
| 1482 | call_memop(vb, prepare, vb->planes[plane].mem_priv); | 1555 | call_void_memop(vb, prepare, vb->planes[plane].mem_priv); |
| 1483 | 1556 | ||
| 1484 | call_vb_qop(vb, buf_queue, vb); | 1557 | call_void_vb_qop(vb, buf_queue, vb); |
| 1485 | } | 1558 | } |
| 1486 | 1559 | ||
| 1487 | static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) | 1560 | static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) |
| @@ -1492,10 +1565,22 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1492 | 1565 | ||
| 1493 | ret = __verify_length(vb, b); | 1566 | ret = __verify_length(vb, b); |
| 1494 | if (ret < 0) { | 1567 | if (ret < 0) { |
| 1495 | dprintk(1, "%s(): plane parameters verification failed: %d\n", | 1568 | dprintk(1, "plane parameters verification failed: %d\n", ret); |
| 1496 | __func__, ret); | ||
| 1497 | return ret; | 1569 | return ret; |
| 1498 | } | 1570 | } |
| 1571 | if (b->field == V4L2_FIELD_ALTERNATE && V4L2_TYPE_IS_OUTPUT(q->type)) { | ||
| 1572 | /* | ||
| 1573 | * If the format's field is ALTERNATE, then the buffer's field | ||
| 1574 | * should be either TOP or BOTTOM, not ALTERNATE since that | ||
| 1575 | * makes no sense. The driver has to know whether the | ||
| 1576 | * buffer represents a top or a bottom field in order to | ||
| 1577 | * program any DMA correctly. Using ALTERNATE is wrong, since | ||
| 1578 | * that just says that it is either a top or a bottom field, | ||
| 1579 | * but not which of the two it is. | ||
| 1580 | */ | ||
| 1581 | dprintk(1, "the field is incorrectly set to ALTERNATE for an output buffer\n"); | ||
| 1582 | return -EINVAL; | ||
| 1583 | } | ||
| 1499 | 1584 | ||
| 1500 | vb->state = VB2_BUF_STATE_PREPARING; | 1585 | vb->state = VB2_BUF_STATE_PREPARING; |
| 1501 | vb->v4l2_buf.timestamp.tv_sec = 0; | 1586 | vb->v4l2_buf.timestamp.tv_sec = 0; |
| @@ -1520,9 +1605,9 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1520 | * mmap_sem and then takes the driver's lock again. | 1605 | * mmap_sem and then takes the driver's lock again. |
| 1521 | */ | 1606 | */ |
| 1522 | mmap_sem = ¤t->mm->mmap_sem; | 1607 | mmap_sem = ¤t->mm->mmap_sem; |
| 1523 | call_qop(q, wait_prepare, q); | 1608 | call_void_qop(q, wait_prepare, q); |
| 1524 | down_read(mmap_sem); | 1609 | down_read(mmap_sem); |
| 1525 | call_qop(q, wait_finish, q); | 1610 | call_void_qop(q, wait_finish, q); |
| 1526 | 1611 | ||
| 1527 | ret = __qbuf_userptr(vb, b); | 1612 | ret = __qbuf_userptr(vb, b); |
| 1528 | 1613 | ||
| @@ -1537,7 +1622,7 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 1537 | } | 1622 | } |
| 1538 | 1623 | ||
| 1539 | if (ret) | 1624 | if (ret) |
| 1540 | dprintk(1, "qbuf: buffer preparation failed: %d\n", ret); | 1625 | dprintk(1, "buffer preparation failed: %d\n", ret); |
| 1541 | vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED; | 1626 | vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED; |
| 1542 | 1627 | ||
| 1543 | return ret; | 1628 | return ret; |
| @@ -1547,23 +1632,23 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b, | |||
| 1547 | const char *opname) | 1632 | const char *opname) |
| 1548 | { | 1633 | { |
| 1549 | if (b->type != q->type) { | 1634 | if (b->type != q->type) { |
| 1550 | dprintk(1, "%s(): invalid buffer type\n", opname); | 1635 | dprintk(1, "%s: invalid buffer type\n", opname); |
| 1551 | return -EINVAL; | 1636 | return -EINVAL; |
| 1552 | } | 1637 | } |
| 1553 | 1638 | ||
| 1554 | if (b->index >= q->num_buffers) { | 1639 | if (b->index >= q->num_buffers) { |
| 1555 | dprintk(1, "%s(): buffer index out of range\n", opname); | 1640 | dprintk(1, "%s: buffer index out of range\n", opname); |
| 1556 | return -EINVAL; | 1641 | return -EINVAL; |
| 1557 | } | 1642 | } |
| 1558 | 1643 | ||
| 1559 | if (q->bufs[b->index] == NULL) { | 1644 | if (q->bufs[b->index] == NULL) { |
| 1560 | /* Should never happen */ | 1645 | /* Should never happen */ |
| 1561 | dprintk(1, "%s(): buffer is NULL\n", opname); | 1646 | dprintk(1, "%s: buffer is NULL\n", opname); |
| 1562 | return -EINVAL; | 1647 | return -EINVAL; |
| 1563 | } | 1648 | } |
| 1564 | 1649 | ||
| 1565 | if (b->memory != q->memory) { | 1650 | if (b->memory != q->memory) { |
| 1566 | dprintk(1, "%s(): invalid memory type\n", opname); | 1651 | dprintk(1, "%s: invalid memory type\n", opname); |
| 1567 | return -EINVAL; | 1652 | return -EINVAL; |
| 1568 | } | 1653 | } |
| 1569 | 1654 | ||
| @@ -1590,8 +1675,8 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 1590 | struct vb2_buffer *vb; | 1675 | struct vb2_buffer *vb; |
| 1591 | int ret; | 1676 | int ret; |
| 1592 | 1677 | ||
| 1593 | if (q->fileio) { | 1678 | if (vb2_fileio_is_active(q)) { |
| 1594 | dprintk(1, "%s(): file io in progress\n", __func__); | 1679 | dprintk(1, "file io in progress\n"); |
| 1595 | return -EBUSY; | 1680 | return -EBUSY; |
| 1596 | } | 1681 | } |
| 1597 | 1682 | ||
| @@ -1601,7 +1686,7 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 1601 | 1686 | ||
| 1602 | vb = q->bufs[b->index]; | 1687 | vb = q->bufs[b->index]; |
| 1603 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { | 1688 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { |
| 1604 | dprintk(1, "%s(): invalid buffer state %d\n", __func__, | 1689 | dprintk(1, "invalid buffer state %d\n", |
| 1605 | vb->state); | 1690 | vb->state); |
| 1606 | return -EINVAL; | 1691 | return -EINVAL; |
| 1607 | } | 1692 | } |
| @@ -1611,7 +1696,7 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 1611 | /* Fill buffer information for the userspace */ | 1696 | /* Fill buffer information for the userspace */ |
| 1612 | __fill_v4l2_buffer(vb, b); | 1697 | __fill_v4l2_buffer(vb, b); |
| 1613 | 1698 | ||
| 1614 | dprintk(1, "%s() of buffer %d succeeded\n", __func__, vb->v4l2_buf.index); | 1699 | dprintk(1, "prepare of buffer %d succeeded\n", vb->v4l2_buf.index); |
| 1615 | } | 1700 | } |
| 1616 | return ret; | 1701 | return ret; |
| 1617 | } | 1702 | } |
| @@ -1647,8 +1732,7 @@ static int vb2_start_streaming(struct vb2_queue *q) | |||
| 1647 | if (!ret) | 1732 | if (!ret) |
| 1648 | return 0; | 1733 | return 0; |
| 1649 | 1734 | ||
| 1650 | fail_qop(q, start_streaming); | 1735 | dprintk(1, "driver refused to start streaming\n"); |
| 1651 | dprintk(1, "qbuf: driver refused to start streaming\n"); | ||
| 1652 | if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { | 1736 | if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { |
| 1653 | unsigned i; | 1737 | unsigned i; |
| 1654 | 1738 | ||
| @@ -1686,11 +1770,10 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 1686 | case VB2_BUF_STATE_PREPARED: | 1770 | case VB2_BUF_STATE_PREPARED: |
| 1687 | break; | 1771 | break; |
| 1688 | case VB2_BUF_STATE_PREPARING: | 1772 | case VB2_BUF_STATE_PREPARING: |
| 1689 | dprintk(1, "qbuf: buffer still being prepared\n"); | 1773 | dprintk(1, "buffer still being prepared\n"); |
| 1690 | return -EINVAL; | 1774 | return -EINVAL; |
| 1691 | default: | 1775 | default: |
| 1692 | dprintk(1, "%s(): invalid buffer state %d\n", __func__, | 1776 | dprintk(1, "invalid buffer state %d\n", vb->state); |
| 1693 | vb->state); | ||
| 1694 | return -EINVAL; | 1777 | return -EINVAL; |
| 1695 | } | 1778 | } |
| 1696 | 1779 | ||
| @@ -1737,7 +1820,7 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 1737 | return ret; | 1820 | return ret; |
| 1738 | } | 1821 | } |
| 1739 | 1822 | ||
| 1740 | dprintk(1, "%s() of buffer %d succeeded\n", __func__, vb->v4l2_buf.index); | 1823 | dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index); |
| 1741 | return 0; | 1824 | return 0; |
| 1742 | } | 1825 | } |
| 1743 | 1826 | ||
| @@ -1760,8 +1843,8 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
| 1760 | */ | 1843 | */ |
| 1761 | int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | 1844 | int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) |
| 1762 | { | 1845 | { |
| 1763 | if (q->fileio) { | 1846 | if (vb2_fileio_is_active(q)) { |
| 1764 | dprintk(1, "%s(): file io in progress\n", __func__); | 1847 | dprintk(1, "file io in progress\n"); |
| 1765 | return -EBUSY; | 1848 | return -EBUSY; |
| 1766 | } | 1849 | } |
| 1767 | 1850 | ||
| @@ -1790,7 +1873,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1790 | int ret; | 1873 | int ret; |
| 1791 | 1874 | ||
| 1792 | if (!q->streaming) { | 1875 | if (!q->streaming) { |
| 1793 | dprintk(1, "Streaming off, will not wait for buffers\n"); | 1876 | dprintk(1, "streaming off, will not wait for buffers\n"); |
| 1794 | return -EINVAL; | 1877 | return -EINVAL; |
| 1795 | } | 1878 | } |
| 1796 | 1879 | ||
| @@ -1802,7 +1885,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1802 | } | 1885 | } |
| 1803 | 1886 | ||
| 1804 | if (nonblocking) { | 1887 | if (nonblocking) { |
| 1805 | dprintk(1, "Nonblocking and no buffers to dequeue, " | 1888 | dprintk(1, "nonblocking and no buffers to dequeue, " |
| 1806 | "will not wait\n"); | 1889 | "will not wait\n"); |
| 1807 | return -EAGAIN; | 1890 | return -EAGAIN; |
| 1808 | } | 1891 | } |
| @@ -1812,12 +1895,12 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1812 | * become ready or for streamoff. Driver's lock is released to | 1895 | * become ready or for streamoff. Driver's lock is released to |
| 1813 | * allow streamoff or qbuf to be called while waiting. | 1896 | * allow streamoff or qbuf to be called while waiting. |
| 1814 | */ | 1897 | */ |
| 1815 | call_qop(q, wait_prepare, q); | 1898 | call_void_qop(q, wait_prepare, q); |
| 1816 | 1899 | ||
| 1817 | /* | 1900 | /* |
| 1818 | * All locks have been released, it is safe to sleep now. | 1901 | * All locks have been released, it is safe to sleep now. |
| 1819 | */ | 1902 | */ |
| 1820 | dprintk(3, "Will sleep waiting for buffers\n"); | 1903 | dprintk(3, "will sleep waiting for buffers\n"); |
| 1821 | ret = wait_event_interruptible(q->done_wq, | 1904 | ret = wait_event_interruptible(q->done_wq, |
| 1822 | !list_empty(&q->done_list) || !q->streaming); | 1905 | !list_empty(&q->done_list) || !q->streaming); |
| 1823 | 1906 | ||
| @@ -1825,9 +1908,9 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1825 | * We need to reevaluate both conditions again after reacquiring | 1908 | * We need to reevaluate both conditions again after reacquiring |
| 1826 | * the locks or return an error if one occurred. | 1909 | * the locks or return an error if one occurred. |
| 1827 | */ | 1910 | */ |
| 1828 | call_qop(q, wait_finish, q); | 1911 | call_void_qop(q, wait_finish, q); |
| 1829 | if (ret) { | 1912 | if (ret) { |
| 1830 | dprintk(1, "Sleep was interrupted\n"); | 1913 | dprintk(1, "sleep was interrupted\n"); |
| 1831 | return ret; | 1914 | return ret; |
| 1832 | } | 1915 | } |
| 1833 | } | 1916 | } |
| @@ -1882,7 +1965,7 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, | |||
| 1882 | int vb2_wait_for_all_buffers(struct vb2_queue *q) | 1965 | int vb2_wait_for_all_buffers(struct vb2_queue *q) |
| 1883 | { | 1966 | { |
| 1884 | if (!q->streaming) { | 1967 | if (!q->streaming) { |
| 1885 | dprintk(1, "Streaming off, will not wait for buffers\n"); | 1968 | dprintk(1, "streaming off, will not wait for buffers\n"); |
| 1886 | return -EINVAL; | 1969 | return -EINVAL; |
| 1887 | } | 1970 | } |
| 1888 | 1971 | ||
| @@ -1911,7 +1994,7 @@ static void __vb2_dqbuf(struct vb2_buffer *vb) | |||
| 1911 | for (i = 0; i < vb->num_planes; ++i) { | 1994 | for (i = 0; i < vb->num_planes; ++i) { |
| 1912 | if (!vb->planes[i].dbuf_mapped) | 1995 | if (!vb->planes[i].dbuf_mapped) |
| 1913 | continue; | 1996 | continue; |
| 1914 | call_memop(vb, unmap_dmabuf, vb->planes[i].mem_priv); | 1997 | call_void_memop(vb, unmap_dmabuf, vb->planes[i].mem_priv); |
| 1915 | vb->planes[i].dbuf_mapped = 0; | 1998 | vb->planes[i].dbuf_mapped = 0; |
| 1916 | } | 1999 | } |
| 1917 | } | 2000 | } |
| @@ -1922,7 +2005,7 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n | |||
| 1922 | int ret; | 2005 | int ret; |
| 1923 | 2006 | ||
| 1924 | if (b->type != q->type) { | 2007 | if (b->type != q->type) { |
| 1925 | dprintk(1, "dqbuf: invalid buffer type\n"); | 2008 | dprintk(1, "invalid buffer type\n"); |
| 1926 | return -EINVAL; | 2009 | return -EINVAL; |
| 1927 | } | 2010 | } |
| 1928 | ret = __vb2_get_done_vb(q, &vb, b, nonblocking); | 2011 | ret = __vb2_get_done_vb(q, &vb, b, nonblocking); |
| @@ -1931,17 +2014,17 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n | |||
| 1931 | 2014 | ||
| 1932 | switch (vb->state) { | 2015 | switch (vb->state) { |
| 1933 | case VB2_BUF_STATE_DONE: | 2016 | case VB2_BUF_STATE_DONE: |
| 1934 | dprintk(3, "dqbuf: Returning done buffer\n"); | 2017 | dprintk(3, "returning done buffer\n"); |
| 1935 | break; | 2018 | break; |
| 1936 | case VB2_BUF_STATE_ERROR: | 2019 | case VB2_BUF_STATE_ERROR: |
| 1937 | dprintk(3, "dqbuf: Returning done buffer with errors\n"); | 2020 | dprintk(3, "returning done buffer with errors\n"); |
| 1938 | break; | 2021 | break; |
| 1939 | default: | 2022 | default: |
| 1940 | dprintk(1, "dqbuf: Invalid buffer state\n"); | 2023 | dprintk(1, "invalid buffer state\n"); |
| 1941 | return -EINVAL; | 2024 | return -EINVAL; |
| 1942 | } | 2025 | } |
| 1943 | 2026 | ||
| 1944 | call_vb_qop(vb, buf_finish, vb); | 2027 | call_void_vb_qop(vb, buf_finish, vb); |
| 1945 | 2028 | ||
| 1946 | /* Fill buffer information for the userspace */ | 2029 | /* Fill buffer information for the userspace */ |
| 1947 | __fill_v4l2_buffer(vb, b); | 2030 | __fill_v4l2_buffer(vb, b); |
| @@ -1980,8 +2063,8 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n | |||
| 1980 | */ | 2063 | */ |
| 1981 | int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) | 2064 | int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) |
| 1982 | { | 2065 | { |
| 1983 | if (q->fileio) { | 2066 | if (vb2_fileio_is_active(q)) { |
| 1984 | dprintk(1, "dqbuf: file io in progress\n"); | 2067 | dprintk(1, "file io in progress\n"); |
| 1985 | return -EBUSY; | 2068 | return -EBUSY; |
| 1986 | } | 2069 | } |
| 1987 | return vb2_internal_dqbuf(q, b, nonblocking); | 2070 | return vb2_internal_dqbuf(q, b, nonblocking); |
| @@ -2003,10 +2086,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) | |||
| 2003 | * buffers. | 2086 | * buffers. |
| 2004 | */ | 2087 | */ |
| 2005 | if (q->start_streaming_called) | 2088 | if (q->start_streaming_called) |
| 2006 | call_qop(q, stop_streaming, q); | 2089 | call_void_qop(q, stop_streaming, q); |
| 2007 | q->streaming = 0; | ||
| 2008 | q->start_streaming_called = 0; | ||
| 2009 | q->queued_count = 0; | ||
| 2010 | 2090 | ||
| 2011 | if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { | 2091 | if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { |
| 2012 | for (i = 0; i < q->num_buffers; ++i) | 2092 | for (i = 0; i < q->num_buffers; ++i) |
| @@ -2016,6 +2096,10 @@ static void __vb2_queue_cancel(struct vb2_queue *q) | |||
| 2016 | WARN_ON(atomic_read(&q->owned_by_drv_count)); | 2096 | WARN_ON(atomic_read(&q->owned_by_drv_count)); |
| 2017 | } | 2097 | } |
| 2018 | 2098 | ||
| 2099 | q->streaming = 0; | ||
| 2100 | q->start_streaming_called = 0; | ||
| 2101 | q->queued_count = 0; | ||
| 2102 | |||
| 2019 | /* | 2103 | /* |
| 2020 | * Remove all buffers from videobuf's list... | 2104 | * Remove all buffers from videobuf's list... |
| 2021 | */ | 2105 | */ |
| @@ -2042,7 +2126,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) | |||
| 2042 | 2126 | ||
| 2043 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { | 2127 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { |
| 2044 | vb->state = VB2_BUF_STATE_PREPARED; | 2128 | vb->state = VB2_BUF_STATE_PREPARED; |
| 2045 | call_vb_qop(vb, buf_finish, vb); | 2129 | call_void_vb_qop(vb, buf_finish, vb); |
| 2046 | } | 2130 | } |
| 2047 | __vb2_dqbuf(vb); | 2131 | __vb2_dqbuf(vb); |
| 2048 | } | 2132 | } |
| @@ -2053,26 +2137,22 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | |||
| 2053 | int ret; | 2137 | int ret; |
| 2054 | 2138 | ||
| 2055 | if (type != q->type) { | 2139 | if (type != q->type) { |
| 2056 | dprintk(1, "streamon: invalid stream type\n"); | 2140 | dprintk(1, "invalid stream type\n"); |
| 2057 | return -EINVAL; | 2141 | return -EINVAL; |
| 2058 | } | 2142 | } |
| 2059 | 2143 | ||
| 2060 | if (q->streaming) { | 2144 | if (q->streaming) { |
| 2061 | dprintk(3, "streamon successful: already streaming\n"); | 2145 | dprintk(3, "already streaming\n"); |
| 2062 | return 0; | 2146 | return 0; |
| 2063 | } | 2147 | } |
| 2064 | 2148 | ||
| 2065 | if (!q->num_buffers) { | 2149 | if (!q->num_buffers) { |
| 2066 | dprintk(1, "streamon: no buffers have been allocated\n"); | 2150 | dprintk(1, "no buffers have been allocated\n"); |
| 2067 | return -EINVAL; | 2151 | return -EINVAL; |
| 2068 | } | 2152 | } |
| 2069 | 2153 | ||
| 2070 | if (!q->num_buffers) { | ||
| 2071 | dprintk(1, "streamon: no buffers have been allocated\n"); | ||
| 2072 | return -EINVAL; | ||
| 2073 | } | ||
| 2074 | if (q->num_buffers < q->min_buffers_needed) { | 2154 | if (q->num_buffers < q->min_buffers_needed) { |
| 2075 | dprintk(1, "streamon: need at least %u allocated buffers\n", | 2155 | dprintk(1, "need at least %u allocated buffers\n", |
| 2076 | q->min_buffers_needed); | 2156 | q->min_buffers_needed); |
| 2077 | return -EINVAL; | 2157 | return -EINVAL; |
| 2078 | } | 2158 | } |
| @@ -2091,7 +2171,7 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | |||
| 2091 | 2171 | ||
| 2092 | q->streaming = 1; | 2172 | q->streaming = 1; |
| 2093 | 2173 | ||
| 2094 | dprintk(3, "Streamon successful\n"); | 2174 | dprintk(3, "successful\n"); |
| 2095 | return 0; | 2175 | return 0; |
| 2096 | } | 2176 | } |
| 2097 | 2177 | ||
| @@ -2110,8 +2190,8 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | |||
| 2110 | */ | 2190 | */ |
| 2111 | int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | 2191 | int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) |
| 2112 | { | 2192 | { |
| 2113 | if (q->fileio) { | 2193 | if (vb2_fileio_is_active(q)) { |
| 2114 | dprintk(1, "streamon: file io in progress\n"); | 2194 | dprintk(1, "file io in progress\n"); |
| 2115 | return -EBUSY; | 2195 | return -EBUSY; |
| 2116 | } | 2196 | } |
| 2117 | return vb2_internal_streamon(q, type); | 2197 | return vb2_internal_streamon(q, type); |
| @@ -2121,7 +2201,7 @@ EXPORT_SYMBOL_GPL(vb2_streamon); | |||
| 2121 | static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) | 2201 | static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) |
| 2122 | { | 2202 | { |
| 2123 | if (type != q->type) { | 2203 | if (type != q->type) { |
| 2124 | dprintk(1, "streamoff: invalid stream type\n"); | 2204 | dprintk(1, "invalid stream type\n"); |
| 2125 | return -EINVAL; | 2205 | return -EINVAL; |
| 2126 | } | 2206 | } |
| 2127 | 2207 | ||
| @@ -2136,7 +2216,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) | |||
| 2136 | */ | 2216 | */ |
| 2137 | __vb2_queue_cancel(q); | 2217 | __vb2_queue_cancel(q); |
| 2138 | 2218 | ||
| 2139 | dprintk(3, "Streamoff successful\n"); | 2219 | dprintk(3, "successful\n"); |
| 2140 | return 0; | 2220 | return 0; |
| 2141 | } | 2221 | } |
| 2142 | 2222 | ||
| @@ -2157,8 +2237,8 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) | |||
| 2157 | */ | 2237 | */ |
| 2158 | int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) | 2238 | int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) |
| 2159 | { | 2239 | { |
| 2160 | if (q->fileio) { | 2240 | if (vb2_fileio_is_active(q)) { |
| 2161 | dprintk(1, "streamoff: file io in progress\n"); | 2241 | dprintk(1, "file io in progress\n"); |
| 2162 | return -EBUSY; | 2242 | return -EBUSY; |
| 2163 | } | 2243 | } |
| 2164 | return vb2_internal_streamoff(q, type); | 2244 | return vb2_internal_streamoff(q, type); |
| @@ -2211,22 +2291,22 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) | |||
| 2211 | struct dma_buf *dbuf; | 2291 | struct dma_buf *dbuf; |
| 2212 | 2292 | ||
| 2213 | if (q->memory != V4L2_MEMORY_MMAP) { | 2293 | if (q->memory != V4L2_MEMORY_MMAP) { |
| 2214 | dprintk(1, "Queue is not currently set up for mmap\n"); | 2294 | dprintk(1, "queue is not currently set up for mmap\n"); |
| 2215 | return -EINVAL; | 2295 | return -EINVAL; |
| 2216 | } | 2296 | } |
| 2217 | 2297 | ||
| 2218 | if (!q->mem_ops->get_dmabuf) { | 2298 | if (!q->mem_ops->get_dmabuf) { |
| 2219 | dprintk(1, "Queue does not support DMA buffer exporting\n"); | 2299 | dprintk(1, "queue does not support DMA buffer exporting\n"); |
| 2220 | return -EINVAL; | 2300 | return -EINVAL; |
| 2221 | } | 2301 | } |
| 2222 | 2302 | ||
| 2223 | if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) { | 2303 | if (eb->flags & ~(O_CLOEXEC | O_ACCMODE)) { |
| 2224 | dprintk(1, "Queue does support only O_CLOEXEC and access mode flags\n"); | 2304 | dprintk(1, "queue does support only O_CLOEXEC and access mode flags\n"); |
| 2225 | return -EINVAL; | 2305 | return -EINVAL; |
| 2226 | } | 2306 | } |
| 2227 | 2307 | ||
| 2228 | if (eb->type != q->type) { | 2308 | if (eb->type != q->type) { |
| 2229 | dprintk(1, "qbuf: invalid buffer type\n"); | 2309 | dprintk(1, "invalid buffer type\n"); |
| 2230 | return -EINVAL; | 2310 | return -EINVAL; |
| 2231 | } | 2311 | } |
| 2232 | 2312 | ||
| @@ -2242,13 +2322,17 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) | |||
| 2242 | return -EINVAL; | 2322 | return -EINVAL; |
| 2243 | } | 2323 | } |
| 2244 | 2324 | ||
| 2325 | if (vb2_fileio_is_active(q)) { | ||
| 2326 | dprintk(1, "expbuf: file io in progress\n"); | ||
| 2327 | return -EBUSY; | ||
| 2328 | } | ||
| 2329 | |||
| 2245 | vb_plane = &vb->planes[eb->plane]; | 2330 | vb_plane = &vb->planes[eb->plane]; |
| 2246 | 2331 | ||
| 2247 | dbuf = call_memop(vb, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE); | 2332 | dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE); |
| 2248 | if (IS_ERR_OR_NULL(dbuf)) { | 2333 | if (IS_ERR_OR_NULL(dbuf)) { |
| 2249 | dprintk(1, "Failed to export buffer %d, plane %d\n", | 2334 | dprintk(1, "failed to export buffer %d, plane %d\n", |
| 2250 | eb->index, eb->plane); | 2335 | eb->index, eb->plane); |
| 2251 | fail_memop(vb, get_dmabuf); | ||
| 2252 | return -EINVAL; | 2336 | return -EINVAL; |
| 2253 | } | 2337 | } |
| 2254 | 2338 | ||
| @@ -2291,12 +2375,12 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) | |||
| 2291 | { | 2375 | { |
| 2292 | unsigned long off = vma->vm_pgoff << PAGE_SHIFT; | 2376 | unsigned long off = vma->vm_pgoff << PAGE_SHIFT; |
| 2293 | struct vb2_buffer *vb; | 2377 | struct vb2_buffer *vb; |
| 2294 | unsigned int buffer, plane; | 2378 | unsigned int buffer = 0, plane = 0; |
| 2295 | int ret; | 2379 | int ret; |
| 2296 | unsigned long length; | 2380 | unsigned long length; |
| 2297 | 2381 | ||
| 2298 | if (q->memory != V4L2_MEMORY_MMAP) { | 2382 | if (q->memory != V4L2_MEMORY_MMAP) { |
| 2299 | dprintk(1, "Queue is not currently set up for mmap\n"); | 2383 | dprintk(1, "queue is not currently set up for mmap\n"); |
| 2300 | return -EINVAL; | 2384 | return -EINVAL; |
| 2301 | } | 2385 | } |
| 2302 | 2386 | ||
| @@ -2304,20 +2388,24 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) | |||
| 2304 | * Check memory area access mode. | 2388 | * Check memory area access mode. |
| 2305 | */ | 2389 | */ |
| 2306 | if (!(vma->vm_flags & VM_SHARED)) { | 2390 | if (!(vma->vm_flags & VM_SHARED)) { |
| 2307 | dprintk(1, "Invalid vma flags, VM_SHARED needed\n"); | 2391 | dprintk(1, "invalid vma flags, VM_SHARED needed\n"); |
| 2308 | return -EINVAL; | 2392 | return -EINVAL; |
| 2309 | } | 2393 | } |
| 2310 | if (V4L2_TYPE_IS_OUTPUT(q->type)) { | 2394 | if (V4L2_TYPE_IS_OUTPUT(q->type)) { |
| 2311 | if (!(vma->vm_flags & VM_WRITE)) { | 2395 | if (!(vma->vm_flags & VM_WRITE)) { |
| 2312 | dprintk(1, "Invalid vma flags, VM_WRITE needed\n"); | 2396 | dprintk(1, "invalid vma flags, VM_WRITE needed\n"); |
| 2313 | return -EINVAL; | 2397 | return -EINVAL; |
| 2314 | } | 2398 | } |
| 2315 | } else { | 2399 | } else { |
| 2316 | if (!(vma->vm_flags & VM_READ)) { | 2400 | if (!(vma->vm_flags & VM_READ)) { |
| 2317 | dprintk(1, "Invalid vma flags, VM_READ needed\n"); | 2401 | dprintk(1, "invalid vma flags, VM_READ needed\n"); |
| 2318 | return -EINVAL; | 2402 | return -EINVAL; |
| 2319 | } | 2403 | } |
| 2320 | } | 2404 | } |
| 2405 | if (vb2_fileio_is_active(q)) { | ||
| 2406 | dprintk(1, "mmap: file io in progress\n"); | ||
| 2407 | return -EBUSY; | ||
| 2408 | } | ||
| 2321 | 2409 | ||
| 2322 | /* | 2410 | /* |
| 2323 | * Find the plane corresponding to the offset passed by userspace. | 2411 | * Find the plane corresponding to the offset passed by userspace. |
| @@ -2341,12 +2429,10 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) | |||
| 2341 | } | 2429 | } |
| 2342 | 2430 | ||
| 2343 | ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma); | 2431 | ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma); |
| 2344 | if (ret) { | 2432 | if (ret) |
| 2345 | fail_memop(vb, mmap); | ||
| 2346 | return ret; | 2433 | return ret; |
| 2347 | } | ||
| 2348 | 2434 | ||
| 2349 | dprintk(3, "Buffer %d, plane %d successfully mapped\n", buffer, plane); | 2435 | dprintk(3, "buffer %d, plane %d successfully mapped\n", buffer, plane); |
| 2350 | return 0; | 2436 | return 0; |
| 2351 | } | 2437 | } |
| 2352 | EXPORT_SYMBOL_GPL(vb2_mmap); | 2438 | EXPORT_SYMBOL_GPL(vb2_mmap); |
| @@ -2364,7 +2450,7 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, | |||
| 2364 | int ret; | 2450 | int ret; |
| 2365 | 2451 | ||
| 2366 | if (q->memory != V4L2_MEMORY_MMAP) { | 2452 | if (q->memory != V4L2_MEMORY_MMAP) { |
| 2367 | dprintk(1, "Queue is not currently set up for mmap\n"); | 2453 | dprintk(1, "queue is not currently set up for mmap\n"); |
| 2368 | return -EINVAL; | 2454 | return -EINVAL; |
| 2369 | } | 2455 | } |
| 2370 | 2456 | ||
| @@ -2429,7 +2515,7 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) | |||
| 2429 | /* | 2515 | /* |
| 2430 | * Start file I/O emulator only if streaming API has not been used yet. | 2516 | * Start file I/O emulator only if streaming API has not been used yet. |
| 2431 | */ | 2517 | */ |
| 2432 | if (q->num_buffers == 0 && q->fileio == NULL) { | 2518 | if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) { |
| 2433 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && | 2519 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && |
| 2434 | (req_events & (POLLIN | POLLRDNORM))) { | 2520 | (req_events & (POLLIN | POLLRDNORM))) { |
| 2435 | if (__vb2_init_fileio(q, 1)) | 2521 | if (__vb2_init_fileio(q, 1)) |
| @@ -2574,6 +2660,7 @@ struct vb2_fileio_buf { | |||
| 2574 | */ | 2660 | */ |
| 2575 | struct vb2_fileio_data { | 2661 | struct vb2_fileio_data { |
| 2576 | struct v4l2_requestbuffers req; | 2662 | struct v4l2_requestbuffers req; |
| 2663 | struct v4l2_plane p; | ||
| 2577 | struct v4l2_buffer b; | 2664 | struct v4l2_buffer b; |
| 2578 | struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME]; | 2665 | struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME]; |
| 2579 | unsigned int cur_index; | 2666 | unsigned int cur_index; |
| @@ -2634,7 +2721,8 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
| 2634 | fileio->req.count = count; | 2721 | fileio->req.count = count; |
| 2635 | fileio->req.memory = V4L2_MEMORY_MMAP; | 2722 | fileio->req.memory = V4L2_MEMORY_MMAP; |
| 2636 | fileio->req.type = q->type; | 2723 | fileio->req.type = q->type; |
| 2637 | ret = vb2_reqbufs(q, &fileio->req); | 2724 | q->fileio = fileio; |
| 2725 | ret = __reqbufs(q, &fileio->req); | ||
| 2638 | if (ret) | 2726 | if (ret) |
| 2639 | goto err_kfree; | 2727 | goto err_kfree; |
| 2640 | 2728 | ||
| @@ -2663,16 +2751,24 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
| 2663 | * Read mode requires pre queuing of all buffers. | 2751 | * Read mode requires pre queuing of all buffers. |
| 2664 | */ | 2752 | */ |
| 2665 | if (read) { | 2753 | if (read) { |
| 2754 | bool is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type); | ||
| 2755 | |||
| 2666 | /* | 2756 | /* |
| 2667 | * Queue all buffers. | 2757 | * Queue all buffers. |
| 2668 | */ | 2758 | */ |
| 2669 | for (i = 0; i < q->num_buffers; i++) { | 2759 | for (i = 0; i < q->num_buffers; i++) { |
| 2670 | struct v4l2_buffer *b = &fileio->b; | 2760 | struct v4l2_buffer *b = &fileio->b; |
| 2761 | |||
| 2671 | memset(b, 0, sizeof(*b)); | 2762 | memset(b, 0, sizeof(*b)); |
| 2672 | b->type = q->type; | 2763 | b->type = q->type; |
| 2764 | if (is_multiplanar) { | ||
| 2765 | memset(&fileio->p, 0, sizeof(fileio->p)); | ||
| 2766 | b->m.planes = &fileio->p; | ||
| 2767 | b->length = 1; | ||
| 2768 | } | ||
| 2673 | b->memory = q->memory; | 2769 | b->memory = q->memory; |
| 2674 | b->index = i; | 2770 | b->index = i; |
| 2675 | ret = vb2_qbuf(q, b); | 2771 | ret = vb2_internal_qbuf(q, b); |
| 2676 | if (ret) | 2772 | if (ret) |
| 2677 | goto err_reqbufs; | 2773 | goto err_reqbufs; |
| 2678 | fileio->bufs[i].queued = 1; | 2774 | fileio->bufs[i].queued = 1; |
| @@ -2688,19 +2784,18 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
| 2688 | /* | 2784 | /* |
| 2689 | * Start streaming. | 2785 | * Start streaming. |
| 2690 | */ | 2786 | */ |
| 2691 | ret = vb2_streamon(q, q->type); | 2787 | ret = vb2_internal_streamon(q, q->type); |
| 2692 | if (ret) | 2788 | if (ret) |
| 2693 | goto err_reqbufs; | 2789 | goto err_reqbufs; |
| 2694 | 2790 | ||
| 2695 | q->fileio = fileio; | ||
| 2696 | |||
| 2697 | return ret; | 2791 | return ret; |
| 2698 | 2792 | ||
| 2699 | err_reqbufs: | 2793 | err_reqbufs: |
| 2700 | fileio->req.count = 0; | 2794 | fileio->req.count = 0; |
| 2701 | vb2_reqbufs(q, &fileio->req); | 2795 | __reqbufs(q, &fileio->req); |
| 2702 | 2796 | ||
| 2703 | err_kfree: | 2797 | err_kfree: |
| 2798 | q->fileio = NULL; | ||
| 2704 | kfree(fileio); | 2799 | kfree(fileio); |
| 2705 | return ret; | 2800 | return ret; |
| 2706 | } | 2801 | } |
| @@ -2738,9 +2833,18 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2738 | { | 2833 | { |
| 2739 | struct vb2_fileio_data *fileio; | 2834 | struct vb2_fileio_data *fileio; |
| 2740 | struct vb2_fileio_buf *buf; | 2835 | struct vb2_fileio_buf *buf; |
| 2836 | bool is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(q->type); | ||
| 2837 | /* | ||
| 2838 | * When using write() to write data to an output video node the vb2 core | ||
| 2839 | * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody | ||
| 2840 | * else is able to provide this information with the write() operation. | ||
| 2841 | */ | ||
| 2842 | bool set_timestamp = !read && | ||
| 2843 | (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) == | ||
| 2844 | V4L2_BUF_FLAG_TIMESTAMP_COPY; | ||
| 2741 | int ret, index; | 2845 | int ret, index; |
| 2742 | 2846 | ||
| 2743 | dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n", | 2847 | dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n", |
| 2744 | read ? "read" : "write", (long)*ppos, count, | 2848 | read ? "read" : "write", (long)*ppos, count, |
| 2745 | nonblock ? "non" : ""); | 2849 | nonblock ? "non" : ""); |
| 2746 | 2850 | ||
| @@ -2750,9 +2854,9 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2750 | /* | 2854 | /* |
| 2751 | * Initialize emulator on first call. | 2855 | * Initialize emulator on first call. |
| 2752 | */ | 2856 | */ |
| 2753 | if (!q->fileio) { | 2857 | if (!vb2_fileio_is_active(q)) { |
| 2754 | ret = __vb2_init_fileio(q, read); | 2858 | ret = __vb2_init_fileio(q, read); |
| 2755 | dprintk(3, "file io: vb2_init_fileio result: %d\n", ret); | 2859 | dprintk(3, "vb2_init_fileio result: %d\n", ret); |
| 2756 | if (ret) | 2860 | if (ret) |
| 2757 | return ret; | 2861 | return ret; |
| 2758 | } | 2862 | } |
| @@ -2769,8 +2873,13 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2769 | memset(&fileio->b, 0, sizeof(fileio->b)); | 2873 | memset(&fileio->b, 0, sizeof(fileio->b)); |
| 2770 | fileio->b.type = q->type; | 2874 | fileio->b.type = q->type; |
| 2771 | fileio->b.memory = q->memory; | 2875 | fileio->b.memory = q->memory; |
| 2876 | if (is_multiplanar) { | ||
| 2877 | memset(&fileio->p, 0, sizeof(fileio->p)); | ||
| 2878 | fileio->b.m.planes = &fileio->p; | ||
| 2879 | fileio->b.length = 1; | ||
| 2880 | } | ||
| 2772 | ret = vb2_internal_dqbuf(q, &fileio->b, nonblock); | 2881 | ret = vb2_internal_dqbuf(q, &fileio->b, nonblock); |
| 2773 | dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); | 2882 | dprintk(5, "vb2_dqbuf result: %d\n", ret); |
| 2774 | if (ret) | 2883 | if (ret) |
| 2775 | return ret; | 2884 | return ret; |
| 2776 | fileio->dq_count += 1; | 2885 | fileio->dq_count += 1; |
| @@ -2800,14 +2909,14 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2800 | /* | 2909 | /* |
| 2801 | * Transfer data to userspace. | 2910 | * Transfer data to userspace. |
| 2802 | */ | 2911 | */ |
| 2803 | dprintk(3, "file io: copying %zd bytes - buffer %d, offset %u\n", | 2912 | dprintk(3, "copying %zd bytes - buffer %d, offset %u\n", |
| 2804 | count, index, buf->pos); | 2913 | count, index, buf->pos); |
| 2805 | if (read) | 2914 | if (read) |
| 2806 | ret = copy_to_user(data, buf->vaddr + buf->pos, count); | 2915 | ret = copy_to_user(data, buf->vaddr + buf->pos, count); |
| 2807 | else | 2916 | else |
| 2808 | ret = copy_from_user(buf->vaddr + buf->pos, data, count); | 2917 | ret = copy_from_user(buf->vaddr + buf->pos, data, count); |
| 2809 | if (ret) { | 2918 | if (ret) { |
| 2810 | dprintk(3, "file io: error copying data\n"); | 2919 | dprintk(3, "error copying data\n"); |
| 2811 | return -EFAULT; | 2920 | return -EFAULT; |
| 2812 | } | 2921 | } |
| 2813 | 2922 | ||
| @@ -2827,7 +2936,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2827 | */ | 2936 | */ |
| 2828 | if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && | 2937 | if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && |
| 2829 | fileio->dq_count == 1) { | 2938 | fileio->dq_count == 1) { |
| 2830 | dprintk(3, "file io: read limit reached\n"); | 2939 | dprintk(3, "read limit reached\n"); |
| 2831 | return __vb2_cleanup_fileio(q); | 2940 | return __vb2_cleanup_fileio(q); |
| 2832 | } | 2941 | } |
| 2833 | 2942 | ||
| @@ -2839,8 +2948,16 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2839 | fileio->b.memory = q->memory; | 2948 | fileio->b.memory = q->memory; |
| 2840 | fileio->b.index = index; | 2949 | fileio->b.index = index; |
| 2841 | fileio->b.bytesused = buf->pos; | 2950 | fileio->b.bytesused = buf->pos; |
| 2951 | if (is_multiplanar) { | ||
| 2952 | memset(&fileio->p, 0, sizeof(fileio->p)); | ||
| 2953 | fileio->p.bytesused = buf->pos; | ||
| 2954 | fileio->b.m.planes = &fileio->p; | ||
| 2955 | fileio->b.length = 1; | ||
| 2956 | } | ||
| 2957 | if (set_timestamp) | ||
| 2958 | v4l2_get_timestamp(&fileio->b.timestamp); | ||
| 2842 | ret = vb2_internal_qbuf(q, &fileio->b); | 2959 | ret = vb2_internal_qbuf(q, &fileio->b); |
| 2843 | dprintk(5, "file io: vb2_dbuf result: %d\n", ret); | 2960 | dprintk(5, "vb2_dbuf result: %d\n", ret); |
| 2844 | if (ret) | 2961 | if (ret) |
| 2845 | return ret; | 2962 | return ret; |
| 2846 | 2963 | ||
| @@ -2890,6 +3007,147 @@ size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, | |||
| 2890 | } | 3007 | } |
| 2891 | EXPORT_SYMBOL_GPL(vb2_write); | 3008 | EXPORT_SYMBOL_GPL(vb2_write); |
| 2892 | 3009 | ||
| 3010 | struct vb2_threadio_data { | ||
| 3011 | struct task_struct *thread; | ||
| 3012 | vb2_thread_fnc fnc; | ||
| 3013 | void *priv; | ||
| 3014 | bool stop; | ||
| 3015 | }; | ||
| 3016 | |||
| 3017 | static int vb2_thread(void *data) | ||
| 3018 | { | ||
| 3019 | struct vb2_queue *q = data; | ||
| 3020 | struct vb2_threadio_data *threadio = q->threadio; | ||
| 3021 | struct vb2_fileio_data *fileio = q->fileio; | ||
| 3022 | bool set_timestamp = false; | ||
| 3023 | int prequeue = 0; | ||
| 3024 | int index = 0; | ||
| 3025 | int ret = 0; | ||
| 3026 | |||
| 3027 | if (V4L2_TYPE_IS_OUTPUT(q->type)) { | ||
| 3028 | prequeue = q->num_buffers; | ||
| 3029 | set_timestamp = | ||
| 3030 | (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) == | ||
| 3031 | V4L2_BUF_FLAG_TIMESTAMP_COPY; | ||
| 3032 | } | ||
| 3033 | |||
| 3034 | set_freezable(); | ||
| 3035 | |||
| 3036 | for (;;) { | ||
| 3037 | struct vb2_buffer *vb; | ||
| 3038 | |||
| 3039 | /* | ||
| 3040 | * Call vb2_dqbuf to get buffer back. | ||
| 3041 | */ | ||
| 3042 | memset(&fileio->b, 0, sizeof(fileio->b)); | ||
| 3043 | fileio->b.type = q->type; | ||
| 3044 | fileio->b.memory = q->memory; | ||
| 3045 | if (prequeue) { | ||
| 3046 | fileio->b.index = index++; | ||
| 3047 | prequeue--; | ||
| 3048 | } else { | ||
| 3049 | call_void_qop(q, wait_finish, q); | ||
| 3050 | ret = vb2_internal_dqbuf(q, &fileio->b, 0); | ||
| 3051 | call_void_qop(q, wait_prepare, q); | ||
| 3052 | dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); | ||
| 3053 | } | ||
| 3054 | if (threadio->stop) | ||
| 3055 | break; | ||
| 3056 | if (ret) | ||
| 3057 | break; | ||
| 3058 | try_to_freeze(); | ||
| 3059 | |||
| 3060 | vb = q->bufs[fileio->b.index]; | ||
| 3061 | if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) | ||
| 3062 | ret = threadio->fnc(vb, threadio->priv); | ||
| 3063 | if (ret) | ||
| 3064 | break; | ||
| 3065 | call_void_qop(q, wait_finish, q); | ||
| 3066 | if (set_timestamp) | ||
| 3067 | v4l2_get_timestamp(&fileio->b.timestamp); | ||
| 3068 | ret = vb2_internal_qbuf(q, &fileio->b); | ||
| 3069 | call_void_qop(q, wait_prepare, q); | ||
| 3070 | if (ret) | ||
| 3071 | break; | ||
| 3072 | } | ||
| 3073 | |||
| 3074 | /* Hmm, linux becomes *very* unhappy without this ... */ | ||
| 3075 | while (!kthread_should_stop()) { | ||
| 3076 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 3077 | schedule(); | ||
| 3078 | } | ||
| 3079 | return 0; | ||
| 3080 | } | ||
| 3081 | |||
| 3082 | /* | ||
| 3083 | * This function should not be used for anything else but the videobuf2-dvb | ||
| 3084 | * support. If you think you have another good use-case for this, then please | ||
| 3085 | * contact the linux-media mailinglist first. | ||
| 3086 | */ | ||
| 3087 | int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, | ||
| 3088 | const char *thread_name) | ||
| 3089 | { | ||
| 3090 | struct vb2_threadio_data *threadio; | ||
| 3091 | int ret = 0; | ||
| 3092 | |||
| 3093 | if (q->threadio) | ||
| 3094 | return -EBUSY; | ||
| 3095 | if (vb2_is_busy(q)) | ||
| 3096 | return -EBUSY; | ||
| 3097 | if (WARN_ON(q->fileio)) | ||
| 3098 | return -EBUSY; | ||
| 3099 | |||
| 3100 | threadio = kzalloc(sizeof(*threadio), GFP_KERNEL); | ||
| 3101 | if (threadio == NULL) | ||
| 3102 | return -ENOMEM; | ||
| 3103 | threadio->fnc = fnc; | ||
| 3104 | threadio->priv = priv; | ||
| 3105 | |||
| 3106 | ret = __vb2_init_fileio(q, !V4L2_TYPE_IS_OUTPUT(q->type)); | ||
| 3107 | dprintk(3, "file io: vb2_init_fileio result: %d\n", ret); | ||
| 3108 | if (ret) | ||
| 3109 | goto nomem; | ||
| 3110 | q->threadio = threadio; | ||
| 3111 | threadio->thread = kthread_run(vb2_thread, q, "vb2-%s", thread_name); | ||
| 3112 | if (IS_ERR(threadio->thread)) { | ||
| 3113 | ret = PTR_ERR(threadio->thread); | ||
| 3114 | threadio->thread = NULL; | ||
| 3115 | goto nothread; | ||
| 3116 | } | ||
| 3117 | return 0; | ||
| 3118 | |||
| 3119 | nothread: | ||
| 3120 | __vb2_cleanup_fileio(q); | ||
| 3121 | nomem: | ||
| 3122 | kfree(threadio); | ||
| 3123 | return ret; | ||
| 3124 | } | ||
| 3125 | EXPORT_SYMBOL_GPL(vb2_thread_start); | ||
| 3126 | |||
| 3127 | int vb2_thread_stop(struct vb2_queue *q) | ||
| 3128 | { | ||
| 3129 | struct vb2_threadio_data *threadio = q->threadio; | ||
| 3130 | struct vb2_fileio_data *fileio = q->fileio; | ||
| 3131 | int err; | ||
| 3132 | |||
| 3133 | if (threadio == NULL) | ||
| 3134 | return 0; | ||
| 3135 | call_void_qop(q, wait_finish, q); | ||
| 3136 | threadio->stop = true; | ||
| 3137 | vb2_internal_streamoff(q, q->type); | ||
| 3138 | call_void_qop(q, wait_prepare, q); | ||
| 3139 | q->fileio = NULL; | ||
| 3140 | fileio->req.count = 0; | ||
| 3141 | vb2_reqbufs(q, &fileio->req); | ||
| 3142 | kfree(fileio); | ||
| 3143 | err = kthread_stop(threadio->thread); | ||
| 3144 | threadio->thread = NULL; | ||
| 3145 | kfree(threadio); | ||
| 3146 | q->fileio = NULL; | ||
| 3147 | q->threadio = NULL; | ||
| 3148 | return err; | ||
| 3149 | } | ||
| 3150 | EXPORT_SYMBOL_GPL(vb2_thread_stop); | ||
| 2893 | 3151 | ||
| 2894 | /* | 3152 | /* |
| 2895 | * The following functions are not part of the vb2 core API, but are helper | 3153 | * The following functions are not part of the vb2 core API, but are helper |
| @@ -3116,7 +3374,7 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait) | |||
| 3116 | 3374 | ||
| 3117 | /* Try to be smart: only lock if polling might start fileio, | 3375 | /* Try to be smart: only lock if polling might start fileio, |
| 3118 | otherwise locking will only introduce unwanted delays. */ | 3376 | otherwise locking will only introduce unwanted delays. */ |
| 3119 | if (q->num_buffers == 0 && q->fileio == NULL) { | 3377 | if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) { |
| 3120 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && | 3378 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && |
| 3121 | (req_events & (POLLIN | POLLRDNORM))) | 3379 | (req_events & (POLLIN | POLLRDNORM))) |
| 3122 | must_lock = true; | 3380 | must_lock = true; |
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index c779f210d2c6..adefc31bb853 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c | |||
| @@ -211,7 +211,7 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, | |||
| 211 | ++num_pages_from_user, vaddr += PAGE_SIZE) { | 211 | ++num_pages_from_user, vaddr += PAGE_SIZE) { |
| 212 | unsigned long pfn; | 212 | unsigned long pfn; |
| 213 | 213 | ||
| 214 | if (follow_pfn(buf->vma, vaddr, &pfn)) { | 214 | if (follow_pfn(vma, vaddr, &pfn)) { |
| 215 | dprintk(1, "no page for address %lu\n", vaddr); | 215 | dprintk(1, "no page for address %lu\n", vaddr); |
| 216 | break; | 216 | break; |
| 217 | } | 217 | } |
diff --git a/drivers/media/v4l2-core/videobuf2-dvb.c b/drivers/media/v4l2-core/videobuf2-dvb.c new file mode 100644 index 000000000000..d09269846b7e --- /dev/null +++ b/drivers/media/v4l2-core/videobuf2-dvb.c | |||
| @@ -0,0 +1,336 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * some helper function for simple DVB cards which simply DMA the | ||
| 4 | * complete transport stream and let the computer sort everything else | ||
| 5 | * (i.e. we are using the software demux, ...). Also uses the | ||
| 6 | * video-buf to manage DMA buffers. | ||
| 7 | * | ||
| 8 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs] | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/device.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | |||
| 21 | #include <media/videobuf2-dvb.h> | ||
| 22 | |||
| 23 | /* ------------------------------------------------------------------ */ | ||
| 24 | |||
| 25 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | ||
| 26 | MODULE_LICENSE("GPL"); | ||
| 27 | |||
| 28 | /* ------------------------------------------------------------------ */ | ||
| 29 | |||
| 30 | static int dvb_fnc(struct vb2_buffer *vb, void *priv) | ||
| 31 | { | ||
| 32 | struct vb2_dvb *dvb = priv; | ||
| 33 | |||
| 34 | dvb_dmx_swfilter(&dvb->demux, vb2_plane_vaddr(vb, 0), | ||
| 35 | vb2_get_plane_payload(vb, 0)); | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | static int vb2_dvb_start_feed(struct dvb_demux_feed *feed) | ||
| 40 | { | ||
| 41 | struct dvb_demux *demux = feed->demux; | ||
| 42 | struct vb2_dvb *dvb = demux->priv; | ||
| 43 | int rc = 0; | ||
| 44 | |||
| 45 | if (!demux->dmx.frontend) | ||
| 46 | return -EINVAL; | ||
| 47 | |||
| 48 | mutex_lock(&dvb->lock); | ||
| 49 | dvb->nfeeds++; | ||
| 50 | |||
| 51 | if (!dvb->dvbq.threadio) { | ||
| 52 | rc = vb2_thread_start(&dvb->dvbq, dvb_fnc, dvb, dvb->name); | ||
| 53 | if (rc) | ||
| 54 | dvb->nfeeds--; | ||
| 55 | } | ||
| 56 | if (!rc) | ||
| 57 | rc = dvb->nfeeds; | ||
| 58 | mutex_unlock(&dvb->lock); | ||
| 59 | return rc; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int vb2_dvb_stop_feed(struct dvb_demux_feed *feed) | ||
| 63 | { | ||
| 64 | struct dvb_demux *demux = feed->demux; | ||
| 65 | struct vb2_dvb *dvb = demux->priv; | ||
| 66 | int err = 0; | ||
| 67 | |||
| 68 | mutex_lock(&dvb->lock); | ||
| 69 | dvb->nfeeds--; | ||
| 70 | if (0 == dvb->nfeeds) | ||
| 71 | err = vb2_thread_stop(&dvb->dvbq); | ||
| 72 | mutex_unlock(&dvb->lock); | ||
| 73 | return err; | ||
| 74 | } | ||
| 75 | |||
| 76 | static int vb2_dvb_register_adapter(struct vb2_dvb_frontends *fe, | ||
| 77 | struct module *module, | ||
| 78 | void *adapter_priv, | ||
| 79 | struct device *device, | ||
| 80 | char *adapter_name, | ||
| 81 | short *adapter_nr, | ||
| 82 | int mfe_shared) | ||
| 83 | { | ||
| 84 | int result; | ||
| 85 | |||
| 86 | mutex_init(&fe->lock); | ||
| 87 | |||
| 88 | /* register adapter */ | ||
| 89 | result = dvb_register_adapter(&fe->adapter, adapter_name, module, | ||
| 90 | device, adapter_nr); | ||
| 91 | if (result < 0) { | ||
| 92 | pr_warn("%s: dvb_register_adapter failed (errno = %d)\n", | ||
| 93 | adapter_name, result); | ||
| 94 | } | ||
| 95 | fe->adapter.priv = adapter_priv; | ||
| 96 | fe->adapter.mfe_shared = mfe_shared; | ||
| 97 | |||
| 98 | return result; | ||
| 99 | } | ||
| 100 | |||
| 101 | static int vb2_dvb_register_frontend(struct dvb_adapter *adapter, | ||
| 102 | struct vb2_dvb *dvb) | ||
| 103 | { | ||
| 104 | int result; | ||
| 105 | |||
| 106 | /* register frontend */ | ||
| 107 | result = dvb_register_frontend(adapter, dvb->frontend); | ||
| 108 | if (result < 0) { | ||
| 109 | pr_warn("%s: dvb_register_frontend failed (errno = %d)\n", | ||
| 110 | dvb->name, result); | ||
| 111 | goto fail_frontend; | ||
| 112 | } | ||
| 113 | |||
| 114 | /* register demux stuff */ | ||
| 115 | dvb->demux.dmx.capabilities = | ||
| 116 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
| 117 | DMX_MEMORY_BASED_FILTERING; | ||
| 118 | dvb->demux.priv = dvb; | ||
| 119 | dvb->demux.filternum = 256; | ||
| 120 | dvb->demux.feednum = 256; | ||
| 121 | dvb->demux.start_feed = vb2_dvb_start_feed; | ||
| 122 | dvb->demux.stop_feed = vb2_dvb_stop_feed; | ||
| 123 | result = dvb_dmx_init(&dvb->demux); | ||
| 124 | if (result < 0) { | ||
| 125 | pr_warn("%s: dvb_dmx_init failed (errno = %d)\n", | ||
| 126 | dvb->name, result); | ||
| 127 | goto fail_dmx; | ||
| 128 | } | ||
| 129 | |||
| 130 | dvb->dmxdev.filternum = 256; | ||
| 131 | dvb->dmxdev.demux = &dvb->demux.dmx; | ||
| 132 | dvb->dmxdev.capabilities = 0; | ||
| 133 | result = dvb_dmxdev_init(&dvb->dmxdev, adapter); | ||
| 134 | |||
| 135 | if (result < 0) { | ||
| 136 | pr_warn("%s: dvb_dmxdev_init failed (errno = %d)\n", | ||
| 137 | dvb->name, result); | ||
| 138 | goto fail_dmxdev; | ||
| 139 | } | ||
| 140 | |||
| 141 | dvb->fe_hw.source = DMX_FRONTEND_0; | ||
| 142 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
| 143 | if (result < 0) { | ||
| 144 | pr_warn("%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", | ||
| 145 | dvb->name, result); | ||
| 146 | goto fail_fe_hw; | ||
| 147 | } | ||
| 148 | |||
| 149 | dvb->fe_mem.source = DMX_MEMORY_FE; | ||
| 150 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
| 151 | if (result < 0) { | ||
| 152 | pr_warn("%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", | ||
| 153 | dvb->name, result); | ||
| 154 | goto fail_fe_mem; | ||
| 155 | } | ||
| 156 | |||
| 157 | result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
| 158 | if (result < 0) { | ||
| 159 | pr_warn("%s: connect_frontend failed (errno = %d)\n", | ||
| 160 | dvb->name, result); | ||
| 161 | goto fail_fe_conn; | ||
| 162 | } | ||
| 163 | |||
| 164 | /* register network adapter */ | ||
| 165 | result = dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx); | ||
| 166 | if (result < 0) { | ||
| 167 | pr_warn("%s: dvb_net_init failed (errno = %d)\n", | ||
| 168 | dvb->name, result); | ||
| 169 | goto fail_fe_conn; | ||
| 170 | } | ||
| 171 | return 0; | ||
| 172 | |||
| 173 | fail_fe_conn: | ||
| 174 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
| 175 | fail_fe_mem: | ||
| 176 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
| 177 | fail_fe_hw: | ||
| 178 | dvb_dmxdev_release(&dvb->dmxdev); | ||
| 179 | fail_dmxdev: | ||
| 180 | dvb_dmx_release(&dvb->demux); | ||
| 181 | fail_dmx: | ||
| 182 | dvb_unregister_frontend(dvb->frontend); | ||
| 183 | fail_frontend: | ||
| 184 | dvb_frontend_detach(dvb->frontend); | ||
| 185 | dvb->frontend = NULL; | ||
| 186 | |||
| 187 | return result; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* ------------------------------------------------------------------ */ | ||
| 191 | /* Register a single adapter and one or more frontends */ | ||
| 192 | int vb2_dvb_register_bus(struct vb2_dvb_frontends *f, | ||
| 193 | struct module *module, | ||
| 194 | void *adapter_priv, | ||
| 195 | struct device *device, | ||
| 196 | short *adapter_nr, | ||
| 197 | int mfe_shared) | ||
| 198 | { | ||
| 199 | struct list_head *list, *q; | ||
| 200 | struct vb2_dvb_frontend *fe; | ||
| 201 | int res; | ||
| 202 | |||
| 203 | fe = vb2_dvb_get_frontend(f, 1); | ||
| 204 | if (!fe) { | ||
| 205 | pr_warn("Unable to register the adapter which has no frontends\n"); | ||
| 206 | return -EINVAL; | ||
| 207 | } | ||
| 208 | |||
| 209 | /* Bring up the adapter */ | ||
| 210 | res = vb2_dvb_register_adapter(f, module, adapter_priv, device, | ||
| 211 | fe->dvb.name, adapter_nr, mfe_shared); | ||
| 212 | if (res < 0) { | ||
| 213 | pr_warn("vb2_dvb_register_adapter failed (errno = %d)\n", res); | ||
| 214 | return res; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* Attach all of the frontends to the adapter */ | ||
| 218 | mutex_lock(&f->lock); | ||
| 219 | list_for_each_safe(list, q, &f->felist) { | ||
| 220 | fe = list_entry(list, struct vb2_dvb_frontend, felist); | ||
| 221 | res = vb2_dvb_register_frontend(&f->adapter, &fe->dvb); | ||
| 222 | if (res < 0) { | ||
| 223 | pr_warn("%s: vb2_dvb_register_frontend failed (errno = %d)\n", | ||
| 224 | fe->dvb.name, res); | ||
| 225 | goto err; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | mutex_unlock(&f->lock); | ||
| 229 | return 0; | ||
| 230 | |||
| 231 | err: | ||
| 232 | mutex_unlock(&f->lock); | ||
| 233 | vb2_dvb_unregister_bus(f); | ||
| 234 | return res; | ||
| 235 | } | ||
| 236 | EXPORT_SYMBOL(vb2_dvb_register_bus); | ||
| 237 | |||
| 238 | void vb2_dvb_unregister_bus(struct vb2_dvb_frontends *f) | ||
| 239 | { | ||
| 240 | vb2_dvb_dealloc_frontends(f); | ||
| 241 | |||
| 242 | dvb_unregister_adapter(&f->adapter); | ||
| 243 | } | ||
| 244 | EXPORT_SYMBOL(vb2_dvb_unregister_bus); | ||
| 245 | |||
| 246 | struct vb2_dvb_frontend *vb2_dvb_get_frontend( | ||
| 247 | struct vb2_dvb_frontends *f, int id) | ||
| 248 | { | ||
| 249 | struct list_head *list, *q; | ||
| 250 | struct vb2_dvb_frontend *fe, *ret = NULL; | ||
| 251 | |||
| 252 | mutex_lock(&f->lock); | ||
| 253 | |||
| 254 | list_for_each_safe(list, q, &f->felist) { | ||
| 255 | fe = list_entry(list, struct vb2_dvb_frontend, felist); | ||
| 256 | if (fe->id == id) { | ||
| 257 | ret = fe; | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | mutex_unlock(&f->lock); | ||
| 263 | |||
| 264 | return ret; | ||
| 265 | } | ||
| 266 | EXPORT_SYMBOL(vb2_dvb_get_frontend); | ||
| 267 | |||
| 268 | int vb2_dvb_find_frontend(struct vb2_dvb_frontends *f, | ||
| 269 | struct dvb_frontend *p) | ||
| 270 | { | ||
| 271 | struct list_head *list, *q; | ||
| 272 | struct vb2_dvb_frontend *fe = NULL; | ||
| 273 | int ret = 0; | ||
| 274 | |||
| 275 | mutex_lock(&f->lock); | ||
| 276 | |||
| 277 | list_for_each_safe(list, q, &f->felist) { | ||
| 278 | fe = list_entry(list, struct vb2_dvb_frontend, felist); | ||
| 279 | if (fe->dvb.frontend == p) { | ||
| 280 | ret = fe->id; | ||
| 281 | break; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | |||
| 285 | mutex_unlock(&f->lock); | ||
| 286 | |||
| 287 | return ret; | ||
| 288 | } | ||
| 289 | EXPORT_SYMBOL(vb2_dvb_find_frontend); | ||
| 290 | |||
| 291 | struct vb2_dvb_frontend *vb2_dvb_alloc_frontend( | ||
| 292 | struct vb2_dvb_frontends *f, int id) | ||
| 293 | { | ||
| 294 | struct vb2_dvb_frontend *fe; | ||
| 295 | |||
| 296 | fe = kzalloc(sizeof(struct vb2_dvb_frontend), GFP_KERNEL); | ||
| 297 | if (fe == NULL) | ||
| 298 | return NULL; | ||
| 299 | |||
| 300 | fe->id = id; | ||
| 301 | mutex_init(&fe->dvb.lock); | ||
| 302 | |||
| 303 | mutex_lock(&f->lock); | ||
| 304 | list_add_tail(&fe->felist, &f->felist); | ||
| 305 | mutex_unlock(&f->lock); | ||
| 306 | return fe; | ||
| 307 | } | ||
| 308 | EXPORT_SYMBOL(vb2_dvb_alloc_frontend); | ||
| 309 | |||
| 310 | void vb2_dvb_dealloc_frontends(struct vb2_dvb_frontends *f) | ||
| 311 | { | ||
| 312 | struct list_head *list, *q; | ||
| 313 | struct vb2_dvb_frontend *fe; | ||
| 314 | |||
| 315 | mutex_lock(&f->lock); | ||
| 316 | list_for_each_safe(list, q, &f->felist) { | ||
| 317 | fe = list_entry(list, struct vb2_dvb_frontend, felist); | ||
| 318 | if (fe->dvb.net.dvbdev) { | ||
| 319 | dvb_net_release(&fe->dvb.net); | ||
| 320 | fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, | ||
| 321 | &fe->dvb.fe_mem); | ||
| 322 | fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, | ||
| 323 | &fe->dvb.fe_hw); | ||
| 324 | dvb_dmxdev_release(&fe->dvb.dmxdev); | ||
| 325 | dvb_dmx_release(&fe->dvb.demux); | ||
| 326 | dvb_unregister_frontend(fe->dvb.frontend); | ||
| 327 | } | ||
| 328 | if (fe->dvb.frontend) | ||
| 329 | /* always allocated, may have been reset */ | ||
| 330 | dvb_frontend_detach(fe->dvb.frontend); | ||
| 331 | list_del(list); /* remove list entry */ | ||
| 332 | kfree(fe); /* free frontend allocation */ | ||
| 333 | } | ||
| 334 | mutex_unlock(&f->lock); | ||
| 335 | } | ||
| 336 | EXPORT_SYMBOL(vb2_dvb_dealloc_frontends); | ||
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index e4a69454ebeb..e6f6278e97d6 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c | |||
| @@ -249,7 +249,7 @@ static void as102_free_usb_stream_buffer(struct as102_dev_t *dev) | |||
| 249 | 249 | ||
| 250 | static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) | 250 | static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) |
| 251 | { | 251 | { |
| 252 | int i, ret = 0; | 252 | int i; |
| 253 | 253 | ||
| 254 | dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev, | 254 | dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev, |
| 255 | MAX_STREAM_URB * AS102_USB_BUF_SIZE, | 255 | MAX_STREAM_URB * AS102_USB_BUF_SIZE, |
| @@ -280,7 +280,7 @@ static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) | |||
| 280 | 280 | ||
| 281 | dev->stream_urb[i] = urb; | 281 | dev->stream_urb[i] = urb; |
| 282 | } | 282 | } |
| 283 | return ret; | 283 | return 0; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static void as102_usb_stop_stream(struct as102_dev_t *dev) | 286 | static void as102_usb_stop_stream(struct as102_dev_t *dev) |
| @@ -458,7 +458,6 @@ exit: | |||
| 458 | 458 | ||
| 459 | static int as102_release(struct inode *inode, struct file *file) | 459 | static int as102_release(struct inode *inode, struct file *file) |
| 460 | { | 460 | { |
| 461 | int ret = 0; | ||
| 462 | struct as102_dev_t *dev = NULL; | 461 | struct as102_dev_t *dev = NULL; |
| 463 | 462 | ||
| 464 | dev = file->private_data; | 463 | dev = file->private_data; |
| @@ -467,7 +466,7 @@ static int as102_release(struct inode *inode, struct file *file) | |||
| 467 | kref_put(&dev->kref, as102_usb_release); | 466 | kref_put(&dev->kref, as102_usb_release); |
| 468 | } | 467 | } |
| 469 | 468 | ||
| 470 | return ret; | 469 | return 0; |
| 471 | } | 470 | } |
| 472 | 471 | ||
| 473 | MODULE_DEVICE_TABLE(usb, as102_usb_id_table); | 472 | MODULE_DEVICE_TABLE(usb, as102_usb_id_table); |
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h index 68f6fe43a5b5..2632a806c4a8 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h | |||
| @@ -87,8 +87,6 @@ struct vpfe_fh { | |||
| 87 | struct vpfe_video_device *video; | 87 | struct vpfe_video_device *video; |
| 88 | /* Indicates whether this file handle is doing IO */ | 88 | /* Indicates whether this file handle is doing IO */ |
| 89 | u8 io_allowed; | 89 | u8 io_allowed; |
| 90 | /* Used to keep track priority of this instance */ | ||
| 91 | enum v4l2_priority prio; | ||
| 92 | }; | 90 | }; |
| 93 | 91 | ||
| 94 | void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus, | 92 | void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus, |
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index acc8184c46cd..d95c427043d4 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c | |||
| @@ -415,7 +415,6 @@ static int vpfe_open(struct file *file) | |||
| 415 | video->usrs++; | 415 | video->usrs++; |
| 416 | /* Set io_allowed member to false */ | 416 | /* Set io_allowed member to false */ |
| 417 | handle->io_allowed = 0; | 417 | handle->io_allowed = 0; |
| 418 | v4l2_prio_open(&video->prio, &handle->prio); | ||
| 419 | handle->video = video; | 418 | handle->video = video; |
| 420 | file->private_data = &handle->vfh; | 419 | file->private_data = &handle->vfh; |
| 421 | mutex_unlock(&video->lock); | 420 | mutex_unlock(&video->lock); |
| @@ -532,8 +531,8 @@ static int vpfe_release(struct file *file) | |||
| 532 | } | 531 | } |
| 533 | /* Decrement device users counter */ | 532 | /* Decrement device users counter */ |
| 534 | video->usrs--; | 533 | video->usrs--; |
| 535 | /* Close the priority */ | 534 | v4l2_fh_del(&fh->vfh); |
| 536 | v4l2_prio_close(&video->prio, fh->prio); | 535 | v4l2_fh_exit(&fh->vfh); |
| 537 | /* If this is the last file handle */ | 536 | /* If this is the last file handle */ |
| 538 | if (!video->usrs) | 537 | if (!video->usrs) |
| 539 | video->initialized = 0; | 538 | video->initialized = 0; |
| @@ -945,7 +944,7 @@ static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id) | |||
| 945 | goto unlock_out; | 944 | goto unlock_out; |
| 946 | } | 945 | } |
| 947 | ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, | 946 | ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id, |
| 948 | core, s_std, std_id); | 947 | video, s_std, std_id); |
| 949 | if (ret < 0) { | 948 | if (ret < 0) { |
| 950 | v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n"); | 949 | v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n"); |
| 951 | video->stdid = V4L2_STD_UNKNOWN; | 950 | video->stdid = V4L2_STD_UNKNOWN; |
| @@ -987,8 +986,10 @@ vpfe_enum_dv_timings(struct file *file, void *fh, | |||
| 987 | struct vpfe_device *vpfe_dev = video->vpfe_dev; | 986 | struct vpfe_device *vpfe_dev = video->vpfe_dev; |
| 988 | struct v4l2_subdev *subdev = video->current_ext_subdev->subdev; | 987 | struct v4l2_subdev *subdev = video->current_ext_subdev->subdev; |
| 989 | 988 | ||
| 989 | timings->pad = 0; | ||
| 990 | |||
| 990 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_dv_timings\n"); | 991 | v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_dv_timings\n"); |
| 991 | return v4l2_subdev_call(subdev, video, enum_dv_timings, timings); | 992 | return v4l2_subdev_call(subdev, pad, enum_dv_timings, timings); |
| 992 | } | 993 | } |
| 993 | 994 | ||
| 994 | /* | 995 | /* |
| @@ -1219,8 +1220,16 @@ static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 1219 | video->state = VPFE_VIDEO_BUFFER_QUEUED; | 1220 | video->state = VPFE_VIDEO_BUFFER_QUEUED; |
| 1220 | 1221 | ||
| 1221 | ret = vpfe_start_capture(video); | 1222 | ret = vpfe_start_capture(video); |
| 1222 | if (ret) | 1223 | if (ret) { |
| 1224 | struct vpfe_cap_buffer *buf, *tmp; | ||
| 1225 | |||
| 1226 | vb2_buffer_done(&video->cur_frm->vb, VB2_BUF_STATE_QUEUED); | ||
| 1227 | list_for_each_entry_safe(buf, tmp, &video->dma_queue, list) { | ||
| 1228 | list_del(&buf->list); | ||
| 1229 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); | ||
| 1230 | } | ||
| 1223 | goto unlock_out; | 1231 | goto unlock_out; |
| 1232 | } | ||
| 1224 | 1233 | ||
| 1225 | mutex_unlock(&video->lock); | 1234 | mutex_unlock(&video->lock); |
| 1226 | 1235 | ||
| @@ -1242,7 +1251,7 @@ static int vpfe_buffer_init(struct vb2_buffer *vb) | |||
| 1242 | } | 1251 | } |
| 1243 | 1252 | ||
| 1244 | /* abort streaming and wait for last buffer */ | 1253 | /* abort streaming and wait for last buffer */ |
| 1245 | static int vpfe_stop_streaming(struct vb2_queue *vq) | 1254 | static void vpfe_stop_streaming(struct vb2_queue *vq) |
| 1246 | { | 1255 | { |
| 1247 | struct vpfe_fh *fh = vb2_get_drv_priv(vq); | 1256 | struct vpfe_fh *fh = vb2_get_drv_priv(vq); |
| 1248 | struct vpfe_video_device *video = fh->video; | 1257 | struct vpfe_video_device *video = fh->video; |
| @@ -1265,7 +1274,6 @@ static int vpfe_stop_streaming(struct vb2_queue *vq) | |||
| 1265 | list_del(&video->next_frm->list); | 1274 | list_del(&video->next_frm->list); |
| 1266 | vb2_buffer_done(&video->next_frm->vb, VB2_BUF_STATE_ERROR); | 1275 | vb2_buffer_done(&video->next_frm->vb, VB2_BUF_STATE_ERROR); |
| 1267 | } | 1276 | } |
| 1268 | return 0; | ||
| 1269 | } | 1277 | } |
| 1270 | 1278 | ||
| 1271 | static void vpfe_buf_cleanup(struct vb2_buffer *vb) | 1279 | static void vpfe_buf_cleanup(struct vb2_buffer *vb) |
| @@ -1590,8 +1598,6 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name) | |||
| 1590 | snprintf(video->video_dev.name, sizeof(video->video_dev.name), | 1598 | snprintf(video->video_dev.name, sizeof(video->video_dev.name), |
| 1591 | "DAVINCI VIDEO %s %s", name, direction); | 1599 | "DAVINCI VIDEO %s %s", name, direction); |
| 1592 | 1600 | ||
| 1593 | /* Initialize prio member of device object */ | ||
| 1594 | v4l2_prio_init(&video->prio); | ||
| 1595 | spin_lock_init(&video->irqlock); | 1601 | spin_lock_init(&video->irqlock); |
| 1596 | spin_lock_init(&video->dma_queue_lock); | 1602 | spin_lock_init(&video->dma_queue_lock); |
| 1597 | mutex_init(&video->lock); | 1603 | mutex_init(&video->lock); |
| @@ -1600,6 +1606,7 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name) | |||
| 1600 | if (ret < 0) | 1606 | if (ret < 0) |
| 1601 | return ret; | 1607 | return ret; |
| 1602 | 1608 | ||
| 1609 | set_bit(V4L2_FL_USE_FH_PRIO, &video->video_dev.flags); | ||
| 1603 | video_set_drvdata(&video->video_dev, video); | 1610 | video_set_drvdata(&video->video_dev, video); |
| 1604 | 1611 | ||
| 1605 | return 0; | 1612 | return 0; |
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.h b/drivers/staging/media/davinci_vpfe/vpfe_video.h index ca9a70245233..1b1b6c4a56b7 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.h +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.h | |||
| @@ -102,8 +102,6 @@ struct vpfe_video_device { | |||
| 102 | * user has selected | 102 | * user has selected |
| 103 | */ | 103 | */ |
| 104 | enum v4l2_memory memory; | 104 | enum v4l2_memory memory; |
| 105 | /* Used to keep track of state of the priority */ | ||
| 106 | struct v4l2_prio_state prio; | ||
| 107 | /* number of open instances of the channel */ | 105 | /* number of open instances of the channel */ |
| 108 | u32 usrs; | 106 | u32 usrs; |
| 109 | /* flag to indicate whether decoder is initialized */ | 107 | /* flag to indicate whether decoder is initialized */ |
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c index afbc2e519606..40580228a6c7 100644 --- a/drivers/staging/media/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c | |||
| @@ -262,7 +262,7 @@ dt3155_buf_prepare(struct vb2_buffer *vb) | |||
| 262 | return 0; | 262 | return 0; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | static int | 265 | static void |
| 266 | dt3155_stop_streaming(struct vb2_queue *q) | 266 | dt3155_stop_streaming(struct vb2_queue *q) |
| 267 | { | 267 | { |
| 268 | struct dt3155_priv *pd = vb2_get_drv_priv(q); | 268 | struct dt3155_priv *pd = vb2_get_drv_priv(q); |
| @@ -276,7 +276,6 @@ dt3155_stop_streaming(struct vb2_queue *q) | |||
| 276 | } | 276 | } |
| 277 | spin_unlock_irq(&pd->lock); | 277 | spin_unlock_irq(&pd->lock); |
| 278 | msleep(45); /* irq hendler will stop the hardware */ | 278 | msleep(45); /* irq hendler will stop the hardware */ |
| 279 | return 0; | ||
| 280 | } | 279 | } |
| 281 | 280 | ||
| 282 | static void | 281 | static void |
| @@ -907,8 +906,10 @@ dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 907 | if (!pd) | 906 | if (!pd) |
| 908 | return -ENOMEM; | 907 | return -ENOMEM; |
| 909 | pd->vdev = video_device_alloc(); | 908 | pd->vdev = video_device_alloc(); |
| 910 | if (!pd->vdev) | 909 | if (!pd->vdev) { |
| 910 | err = -ENOMEM; | ||
| 911 | goto err_video_device_alloc; | 911 | goto err_video_device_alloc; |
| 912 | } | ||
| 912 | *pd->vdev = dt3155_vdev; | 913 | *pd->vdev = dt3155_vdev; |
| 913 | pci_set_drvdata(pdev, pd); /* for use in dt3155_remove() */ | 914 | pci_set_drvdata(pdev, pd); /* for use in dt3155_remove() */ |
| 914 | video_set_drvdata(pd->vdev, pd); /* for use in video_fops */ | 915 | video_set_drvdata(pd->vdev, pd); /* for use in video_fops */ |
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c index b397aa3c0f44..da7b5493e13e 100644 --- a/drivers/staging/media/go7007/go7007-v4l2.c +++ b/drivers/staging/media/go7007/go7007-v4l2.c | |||
| @@ -516,7 +516,7 @@ static int go7007_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 516 | return ret; | 516 | return ret; |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | static int go7007_stop_streaming(struct vb2_queue *q) | 519 | static void go7007_stop_streaming(struct vb2_queue *q) |
| 520 | { | 520 | { |
| 521 | struct go7007 *go = vb2_get_drv_priv(q); | 521 | struct go7007 *go = vb2_get_drv_priv(q); |
| 522 | unsigned long flags; | 522 | unsigned long flags; |
| @@ -538,7 +538,6 @@ static int go7007_stop_streaming(struct vb2_queue *q) | |||
| 538 | /* Turn on Capture LED */ | 538 | /* Turn on Capture LED */ |
| 539 | if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) | 539 | if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) |
| 540 | go7007_write_addr(go, 0x3c82, 0x000d); | 540 | go7007_write_addr(go, 0x3c82, 0x000d); |
| 541 | return 0; | ||
| 542 | } | 541 | } |
| 543 | 542 | ||
| 544 | static struct vb2_ops go7007_video_qops = { | 543 | static struct vb2_ops go7007_video_qops = { |
| @@ -666,7 +665,7 @@ static int go7007_s_std(struct go7007 *go) | |||
| 666 | go->sensor_framerate = 30000; | 665 | go->sensor_framerate = 30000; |
| 667 | } | 666 | } |
| 668 | 667 | ||
| 669 | call_all(&go->v4l2_dev, core, s_std, go->std); | 668 | call_all(&go->v4l2_dev, video, s_std, go->std); |
| 670 | set_capture_size(go, NULL, 0); | 669 | set_capture_size(go, NULL, 0); |
| 671 | return 0; | 670 | return 0; |
| 672 | } | 671 | } |
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c index 696a80756691..eaa2b0990a1b 100644 --- a/drivers/staging/media/go7007/s2250-board.c +++ b/drivers/staging/media/go7007/s2250-board.c | |||
| @@ -474,7 +474,6 @@ static const struct v4l2_ctrl_ops s2250_ctrl_ops = { | |||
| 474 | 474 | ||
| 475 | static const struct v4l2_subdev_core_ops s2250_core_ops = { | 475 | static const struct v4l2_subdev_core_ops s2250_core_ops = { |
| 476 | .log_status = s2250_log_status, | 476 | .log_status = s2250_log_status, |
| 477 | .s_std = s2250_s_std, | ||
| 478 | }; | 477 | }; |
| 479 | 478 | ||
| 480 | static const struct v4l2_subdev_audio_ops s2250_audio_ops = { | 479 | static const struct v4l2_subdev_audio_ops s2250_audio_ops = { |
| @@ -482,6 +481,7 @@ static const struct v4l2_subdev_audio_ops s2250_audio_ops = { | |||
| 482 | }; | 481 | }; |
| 483 | 482 | ||
| 484 | static const struct v4l2_subdev_video_ops s2250_video_ops = { | 483 | static const struct v4l2_subdev_video_ops s2250_video_ops = { |
| 484 | .s_std = s2250_s_std, | ||
| 485 | .s_routing = s2250_s_video_routing, | 485 | .s_routing = s2250_s_video_routing, |
| 486 | .s_mbus_fmt = s2250_s_mbus_fmt, | 486 | .s_mbus_fmt = s2250_s_mbus_fmt, |
| 487 | }; | 487 | }; |
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c index 6e2ca338cdd9..e40f7fbfc0a5 100644 --- a/drivers/staging/media/go7007/saa7134-go7007.c +++ b/drivers/staging/media/go7007/saa7134-go7007.c | |||
| @@ -434,11 +434,15 @@ static const struct v4l2_subdev_core_ops saa7134_go7007_core_ops = { | |||
| 434 | .g_ctrl = saa7134_go7007_g_ctrl, | 434 | .g_ctrl = saa7134_go7007_g_ctrl, |
| 435 | .s_ctrl = saa7134_go7007_s_ctrl, | 435 | .s_ctrl = saa7134_go7007_s_ctrl, |
| 436 | .queryctrl = saa7134_go7007_queryctrl, | 436 | .queryctrl = saa7134_go7007_queryctrl, |
| 437 | }; | ||
| 438 | |||
| 439 | static const struct v4l2_subdev_video_ops saa7134_go7007_video_ops = { | ||
| 437 | .s_std = saa7134_go7007_s_std, | 440 | .s_std = saa7134_go7007_s_std, |
| 438 | }; | 441 | }; |
| 439 | 442 | ||
| 440 | static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = { | 443 | static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = { |
| 441 | .core = &saa7134_go7007_core_ops, | 444 | .core = &saa7134_go7007_core_ops, |
| 445 | .video = &saa7134_go7007_video_ops, | ||
| 442 | }; | 446 | }; |
| 443 | 447 | ||
| 444 | /* --------------------------------------------------------------------------*/ | 448 | /* --------------------------------------------------------------------------*/ |
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c index 65d351f99da2..08d0d096b881 100644 --- a/drivers/staging/media/msi3101/sdr-msi3101.c +++ b/drivers/staging/media/msi3101/sdr-msi3101.c | |||
| @@ -1074,14 +1074,13 @@ static int msi3101_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 1074 | return ret; | 1074 | return ret; |
| 1075 | } | 1075 | } |
| 1076 | 1076 | ||
| 1077 | static int msi3101_stop_streaming(struct vb2_queue *vq) | 1077 | static void msi3101_stop_streaming(struct vb2_queue *vq) |
| 1078 | { | 1078 | { |
| 1079 | struct msi3101_state *s = vb2_get_drv_priv(vq); | 1079 | struct msi3101_state *s = vb2_get_drv_priv(vq); |
| 1080 | int ret; | 1080 | |
| 1081 | dev_dbg(&s->udev->dev, "%s:\n", __func__); | 1081 | dev_dbg(&s->udev->dev, "%s:\n", __func__); |
| 1082 | 1082 | ||
| 1083 | if (mutex_lock_interruptible(&s->v4l2_lock)) | 1083 | mutex_lock(&s->v4l2_lock); |
| 1084 | return -ERESTARTSYS; | ||
| 1085 | 1084 | ||
| 1086 | if (s->udev) | 1085 | if (s->udev) |
| 1087 | msi3101_isoc_cleanup(s); | 1086 | msi3101_isoc_cleanup(s); |
| @@ -1090,22 +1089,15 @@ static int msi3101_stop_streaming(struct vb2_queue *vq) | |||
| 1090 | 1089 | ||
| 1091 | /* according to tests, at least 700us delay is required */ | 1090 | /* according to tests, at least 700us delay is required */ |
| 1092 | msleep(20); | 1091 | msleep(20); |
| 1093 | ret = msi3101_ctrl_msg(s, CMD_STOP_STREAMING, 0); | 1092 | if (!msi3101_ctrl_msg(s, CMD_STOP_STREAMING, 0)) { |
| 1094 | if (ret) | 1093 | /* sleep USB IF / ADC */ |
| 1095 | goto err_sleep_tuner; | 1094 | msi3101_ctrl_msg(s, CMD_WREG, 0x01000003); |
| 1096 | 1095 | } | |
| 1097 | /* sleep USB IF / ADC */ | ||
| 1098 | ret = msi3101_ctrl_msg(s, CMD_WREG, 0x01000003); | ||
| 1099 | if (ret) | ||
| 1100 | goto err_sleep_tuner; | ||
| 1101 | 1096 | ||
| 1102 | err_sleep_tuner: | ||
| 1103 | /* sleep tuner */ | 1097 | /* sleep tuner */ |
| 1104 | ret = v4l2_subdev_call(s->v4l2_subdev, core, s_power, 0); | 1098 | v4l2_subdev_call(s->v4l2_subdev, core, s_power, 0); |
| 1105 | 1099 | ||
| 1106 | mutex_unlock(&s->v4l2_lock); | 1100 | mutex_unlock(&s->v4l2_lock); |
| 1107 | |||
| 1108 | return ret; | ||
| 1109 | } | 1101 | } |
| 1110 | 1102 | ||
| 1111 | static struct vb2_ops msi3101_vb2_ops = { | 1103 | static struct vb2_ops msi3101_vb2_ops = { |
diff --git a/drivers/staging/media/omap24xx/tcm825x.c b/drivers/staging/media/omap24xx/tcm825x.c index f4dd32df2353..3367ccd1d1e8 100644 --- a/drivers/staging/media/omap24xx/tcm825x.c +++ b/drivers/staging/media/omap24xx/tcm825x.c | |||
| @@ -89,10 +89,10 @@ static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; | |||
| 89 | 89 | ||
| 90 | /* Our own specific controls */ | 90 | /* Our own specific controls */ |
| 91 | #define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE | 91 | #define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE |
| 92 | #define V4L2_CID_H_EDGE_EN V4L2_CID_PRIVATE_BASE + 1 | 92 | #define V4L2_CID_H_EDGE_EN (V4L2_CID_PRIVATE_BASE + 1) |
| 93 | #define V4L2_CID_V_EDGE_EN V4L2_CID_PRIVATE_BASE + 2 | 93 | #define V4L2_CID_V_EDGE_EN (V4L2_CID_PRIVATE_BASE + 2) |
| 94 | #define V4L2_CID_LENS V4L2_CID_PRIVATE_BASE + 3 | 94 | #define V4L2_CID_LENS (V4L2_CID_PRIVATE_BASE + 3) |
| 95 | #define V4L2_CID_MAX_EXPOSURE_TIME V4L2_CID_PRIVATE_BASE + 4 | 95 | #define V4L2_CID_MAX_EXPOSURE_TIME (V4L2_CID_PRIVATE_BASE + 4) |
| 96 | #define V4L2_CID_LAST_PRIV V4L2_CID_MAX_EXPOSURE_TIME | 96 | #define V4L2_CID_LAST_PRIV V4L2_CID_MAX_EXPOSURE_TIME |
| 97 | 97 | ||
| 98 | /* Video controls */ | 98 | /* Video controls */ |
| @@ -914,8 +914,8 @@ static int __init tcm825x_init(void) | |||
| 914 | 914 | ||
| 915 | rval = i2c_add_driver(&tcm825x_i2c_driver); | 915 | rval = i2c_add_driver(&tcm825x_i2c_driver); |
| 916 | if (rval) | 916 | if (rval) |
| 917 | printk(KERN_INFO "%s: failed registering " TCM825X_NAME "\n", | 917 | pr_info("%s: failed registering " TCM825X_NAME "\n", |
| 918 | __func__); | 918 | __func__); |
| 919 | 919 | ||
| 920 | return rval; | 920 | return rval; |
| 921 | } | 921 | } |
diff --git a/drivers/staging/media/omap24xx/tcm825x.h b/drivers/staging/media/omap24xx/tcm825x.h index 9970fb1c596a..8a29636d1ad4 100644 --- a/drivers/staging/media/omap24xx/tcm825x.h +++ b/drivers/staging/media/omap24xx/tcm825x.h | |||
| @@ -21,8 +21,8 @@ | |||
| 21 | 21 | ||
| 22 | #define TCM825X_NAME "tcm825x" | 22 | #define TCM825X_NAME "tcm825x" |
| 23 | 23 | ||
| 24 | #define TCM825X_MASK(x) x & 0x00ff | 24 | #define TCM825X_MASK(x) (x & 0x00ff) |
| 25 | #define TCM825X_ADDR(x) (x & 0xff00) >> 8 | 25 | #define TCM825X_ADDR(x) ((x & 0xff00) >> 8) |
| 26 | 26 | ||
| 27 | /* The TCM825X I2C sensor chip has a fixed slave address of 0x3d. */ | 27 | /* The TCM825X I2C sensor chip has a fixed slave address of 0x3d. */ |
| 28 | #define TCM825X_I2C_ADDR 0x3d | 28 | #define TCM825X_I2C_ADDR 0x3d |
diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig index b9fe753969bd..78b0fba7047e 100644 --- a/drivers/staging/media/omap4iss/Kconfig +++ b/drivers/staging/media/omap4iss/Kconfig | |||
| @@ -4,9 +4,3 @@ config VIDEO_OMAP4 | |||
| 4 | select VIDEOBUF2_DMA_CONTIG | 4 | select VIDEOBUF2_DMA_CONTIG |
| 5 | ---help--- | 5 | ---help--- |
| 6 | Driver for an OMAP 4 ISS controller. | 6 | Driver for an OMAP 4 ISS controller. |
| 7 | |||
| 8 | config VIDEO_OMAP4_DEBUG | ||
| 9 | bool "OMAP 4 Camera debug messages" | ||
| 10 | depends on VIDEO_OMAP4 | ||
| 11 | ---help--- | ||
| 12 | Enable debug messages on OMAP 4 ISS controller driver. | ||
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 61fbfcd13582..2e422dde074e 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c | |||
| @@ -204,7 +204,7 @@ void omap4iss_configure_bridge(struct iss_device *iss, | |||
| 204 | iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val); | 204 | iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | #if defined(DEBUG) && defined(ISS_ISR_DEBUG) | 207 | #ifdef ISS_ISR_DEBUG |
| 208 | static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus) | 208 | static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus) |
| 209 | { | 209 | { |
| 210 | static const char * const name[] = { | 210 | static const char * const name[] = { |
| @@ -347,14 +347,14 @@ static irqreturn_t iss_isr(int irq, void *_iss) | |||
| 347 | omap4iss_resizer_isr(&iss->resizer, | 347 | omap4iss_resizer_isr(&iss->resizer, |
| 348 | isp_irqstatus & resizer_events); | 348 | isp_irqstatus & resizer_events); |
| 349 | 349 | ||
| 350 | #if defined(DEBUG) && defined(ISS_ISR_DEBUG) | 350 | #ifdef ISS_ISR_DEBUG |
| 351 | iss_isp_isr_dbg(iss, isp_irqstatus); | 351 | iss_isp_isr_dbg(iss, isp_irqstatus); |
| 352 | #endif | 352 | #endif |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | omap4iss_flush(iss); | 355 | omap4iss_flush(iss); |
| 356 | 356 | ||
| 357 | #if defined(DEBUG) && defined(ISS_ISR_DEBUG) | 357 | #ifdef ISS_ISR_DEBUG |
| 358 | iss_isr_dbg(iss, irqstatus); | 358 | iss_isr_dbg(iss, irqstatus); |
| 359 | #endif | 359 | #endif |
| 360 | 360 | ||
| @@ -734,18 +734,17 @@ static int iss_pipeline_is_last(struct media_entity *me) | |||
| 734 | 734 | ||
| 735 | static int iss_reset(struct iss_device *iss) | 735 | static int iss_reset(struct iss_device *iss) |
| 736 | { | 736 | { |
| 737 | unsigned long timeout = 0; | 737 | unsigned int timeout; |
| 738 | 738 | ||
| 739 | iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG, | 739 | iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG, |
| 740 | ISS_HL_SYSCONFIG_SOFTRESET); | 740 | ISS_HL_SYSCONFIG_SOFTRESET); |
| 741 | 741 | ||
| 742 | while (iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) & | 742 | timeout = iss_poll_condition_timeout( |
| 743 | ISS_HL_SYSCONFIG_SOFTRESET) { | 743 | !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) & |
| 744 | if (timeout++ > 100) { | 744 | ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 100); |
| 745 | dev_alert(iss->dev, "cannot reset ISS\n"); | 745 | if (timeout) { |
| 746 | return -ETIMEDOUT; | 746 | dev_err(iss->dev, "ISS reset timeout\n"); |
| 747 | } | 747 | return -ETIMEDOUT; |
| 748 | usleep_range(10, 10); | ||
| 749 | } | 748 | } |
| 750 | 749 | ||
| 751 | iss->crashed = 0; | 750 | iss->crashed = 0; |
| @@ -754,7 +753,7 @@ static int iss_reset(struct iss_device *iss) | |||
| 754 | 753 | ||
| 755 | static int iss_isp_reset(struct iss_device *iss) | 754 | static int iss_isp_reset(struct iss_device *iss) |
| 756 | { | 755 | { |
| 757 | unsigned long timeout = 0; | 756 | unsigned int timeout; |
| 758 | 757 | ||
| 759 | /* Fist, ensure that the ISP is IDLE (no transactions happening) */ | 758 | /* Fist, ensure that the ISP is IDLE (no transactions happening) */ |
| 760 | iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, | 759 | iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, |
| @@ -763,29 +762,24 @@ static int iss_isp_reset(struct iss_device *iss) | |||
| 763 | 762 | ||
| 764 | iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY); | 763 | iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY); |
| 765 | 764 | ||
| 766 | for (;;) { | 765 | timeout = iss_poll_condition_timeout( |
| 767 | if (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) & | 766 | iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) & |
| 768 | ISP5_CTRL_MSTANDBY_WAIT) | 767 | ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500); |
| 769 | break; | 768 | if (timeout) { |
| 770 | if (timeout++ > 1000) { | 769 | dev_err(iss->dev, "ISP5 standby timeout\n"); |
| 771 | dev_alert(iss->dev, "cannot set ISP5 to standby\n"); | 770 | return -ETIMEDOUT; |
| 772 | return -ETIMEDOUT; | ||
| 773 | } | ||
| 774 | usleep_range(1000, 1500); | ||
| 775 | } | 771 | } |
| 776 | 772 | ||
| 777 | /* Now finally, do the reset */ | 773 | /* Now finally, do the reset */ |
| 778 | iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, | 774 | iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, |
| 779 | ISP5_SYSCONFIG_SOFTRESET); | 775 | ISP5_SYSCONFIG_SOFTRESET); |
| 780 | 776 | ||
| 781 | timeout = 0; | 777 | timeout = iss_poll_condition_timeout( |
| 782 | while (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) & | 778 | !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) & |
| 783 | ISP5_SYSCONFIG_SOFTRESET) { | 779 | ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500); |
| 784 | if (timeout++ > 1000) { | 780 | if (timeout) { |
| 785 | dev_alert(iss->dev, "cannot reset ISP5\n"); | 781 | dev_err(iss->dev, "ISP5 reset timeout\n"); |
| 786 | return -ETIMEDOUT; | 782 | return -ETIMEDOUT; |
| 787 | } | ||
| 788 | usleep_range(1000, 1500); | ||
| 789 | } | 783 | } |
| 790 | 784 | ||
| 791 | return 0; | 785 | return 0; |
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h index 346db9233171..05cd9bf3b41f 100644 --- a/drivers/staging/media/omap4iss/iss.h +++ b/drivers/staging/media/omap4iss/iss.h | |||
| @@ -233,4 +233,18 @@ void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res, | |||
| 233 | iss_reg_write(iss, res, offset, (v & ~clr) | set); | 233 | iss_reg_write(iss, res, offset, (v & ~clr) | set); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | #define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival) \ | ||
| 237 | ({ \ | ||
| 238 | unsigned long __timeout = jiffies + usecs_to_jiffies(timeout); \ | ||
| 239 | unsigned int __min_ival = (min_ival); \ | ||
| 240 | unsigned int __max_ival = (max_ival); \ | ||
| 241 | bool __cond; \ | ||
| 242 | while (!(__cond = (cond))) { \ | ||
| 243 | if (time_after(jiffies, __timeout)) \ | ||
| 244 | break; \ | ||
| 245 | usleep_range(__min_ival, __max_ival); \ | ||
| 246 | } \ | ||
| 247 | !__cond; \ | ||
| 248 | }) | ||
| 249 | |||
| 236 | #endif /* _OMAP4_ISS_H_ */ | 250 | #endif /* _OMAP4_ISS_H_ */ |
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 61fc350eb251..bf8a65726107 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c | |||
| @@ -487,9 +487,7 @@ static void csi2_irq_status_set(struct iss_csi2_device *csi2, int enable) | |||
| 487 | */ | 487 | */ |
| 488 | int omap4iss_csi2_reset(struct iss_csi2_device *csi2) | 488 | int omap4iss_csi2_reset(struct iss_csi2_device *csi2) |
| 489 | { | 489 | { |
| 490 | u8 soft_reset_retries = 0; | 490 | unsigned int timeout; |
| 491 | u32 reg; | ||
| 492 | int i; | ||
| 493 | 491 | ||
| 494 | if (!csi2->available) | 492 | if (!csi2->available) |
| 495 | return -ENODEV; | 493 | return -ENODEV; |
| @@ -500,37 +498,22 @@ int omap4iss_csi2_reset(struct iss_csi2_device *csi2) | |||
| 500 | iss_reg_set(csi2->iss, csi2->regs1, CSI2_SYSCONFIG, | 498 | iss_reg_set(csi2->iss, csi2->regs1, CSI2_SYSCONFIG, |
| 501 | CSI2_SYSCONFIG_SOFT_RESET); | 499 | CSI2_SYSCONFIG_SOFT_RESET); |
| 502 | 500 | ||
| 503 | do { | 501 | timeout = iss_poll_condition_timeout( |
| 504 | reg = iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS) | 502 | iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS) & |
| 505 | & CSI2_SYSSTATUS_RESET_DONE; | 503 | CSI2_SYSSTATUS_RESET_DONE, 500, 100, 200); |
| 506 | if (reg == CSI2_SYSSTATUS_RESET_DONE) | 504 | if (timeout) { |
| 507 | break; | 505 | dev_err(csi2->iss->dev, "CSI2: Soft reset timeout!\n"); |
| 508 | soft_reset_retries++; | ||
| 509 | if (soft_reset_retries < 5) | ||
| 510 | usleep_range(100, 100); | ||
| 511 | } while (soft_reset_retries < 5); | ||
| 512 | |||
| 513 | if (soft_reset_retries == 5) { | ||
| 514 | dev_err(csi2->iss->dev, | ||
| 515 | "CSI2: Soft reset try count exceeded!\n"); | ||
| 516 | return -EBUSY; | 506 | return -EBUSY; |
| 517 | } | 507 | } |
| 518 | 508 | ||
| 519 | iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_CFG, | 509 | iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_CFG, |
| 520 | CSI2_COMPLEXIO_CFG_RESET_CTRL); | 510 | CSI2_COMPLEXIO_CFG_RESET_CTRL); |
| 521 | 511 | ||
| 522 | i = 100; | 512 | timeout = iss_poll_condition_timeout( |
| 523 | do { | 513 | iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1) & |
| 524 | reg = iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1) | 514 | REGISTER1_RESET_DONE_CTRLCLK, 10000, 100, 500); |
| 525 | & REGISTER1_RESET_DONE_CTRLCLK; | 515 | if (timeout) { |
| 526 | if (reg == REGISTER1_RESET_DONE_CTRLCLK) | 516 | dev_err(csi2->iss->dev, "CSI2: CSI2_96M_FCLK reset timeout!\n"); |
| 527 | break; | ||
| 528 | usleep_range(100, 100); | ||
| 529 | } while (--i > 0); | ||
| 530 | |||
| 531 | if (i == 0) { | ||
| 532 | dev_err(csi2->iss->dev, | ||
| 533 | "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n"); | ||
| 534 | return -EBUSY; | 517 | return -EBUSY; |
| 535 | } | 518 | } |
| 536 | 519 | ||
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h index 878e4a3082e7..9dccdb154e1a 100644 --- a/drivers/staging/media/omap4iss/iss_video.h +++ b/drivers/staging/media/omap4iss/iss_video.h | |||
| @@ -140,7 +140,7 @@ enum iss_video_dmaqueue_flags { | |||
| 140 | * if there was no buffer previously queued. | 140 | * if there was no buffer previously queued. |
| 141 | */ | 141 | */ |
| 142 | struct iss_video_operations { | 142 | struct iss_video_operations { |
| 143 | int(*queue)(struct iss_video *video, struct iss_buffer *buffer); | 143 | int (*queue)(struct iss_video *video, struct iss_buffer *buffer); |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
| 146 | struct iss_video { | 146 | struct iss_video { |
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c index 104ee8af79af..093df6b6ae35 100644 --- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c +++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | |||
| @@ -1032,13 +1032,12 @@ err: | |||
| 1032 | return ret; | 1032 | return ret; |
| 1033 | } | 1033 | } |
| 1034 | 1034 | ||
| 1035 | static int rtl2832_sdr_stop_streaming(struct vb2_queue *vq) | 1035 | static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq) |
| 1036 | { | 1036 | { |
| 1037 | struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq); | 1037 | struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq); |
| 1038 | dev_dbg(&s->udev->dev, "%s:\n", __func__); | 1038 | dev_dbg(&s->udev->dev, "%s:\n", __func__); |
| 1039 | 1039 | ||
| 1040 | if (mutex_lock_interruptible(&s->v4l2_lock)) | 1040 | mutex_lock(&s->v4l2_lock); |
| 1041 | return -ERESTARTSYS; | ||
| 1042 | 1041 | ||
| 1043 | rtl2832_sdr_kill_urbs(s); | 1042 | rtl2832_sdr_kill_urbs(s); |
| 1044 | rtl2832_sdr_free_urbs(s); | 1043 | rtl2832_sdr_free_urbs(s); |
| @@ -1053,8 +1052,6 @@ static int rtl2832_sdr_stop_streaming(struct vb2_queue *vq) | |||
| 1053 | s->d->props->power_ctrl(s->d, 0); | 1052 | s->d->props->power_ctrl(s->d, 0); |
| 1054 | 1053 | ||
| 1055 | mutex_unlock(&s->v4l2_lock); | 1054 | mutex_unlock(&s->v4l2_lock); |
| 1056 | |||
| 1057 | return 0; | ||
| 1058 | } | 1055 | } |
| 1059 | 1056 | ||
| 1060 | static struct vb2_ops rtl2832_sdr_vb2_ops = { | 1057 | static struct vb2_ops rtl2832_sdr_vb2_ops = { |
diff --git a/drivers/staging/media/sn9c102/sn9c102.h b/drivers/staging/media/sn9c102/sn9c102.h index 8a917f060503..37ca7225fcf7 100644 --- a/drivers/staging/media/sn9c102/sn9c102.h +++ b/drivers/staging/media/sn9c102/sn9c102.h | |||
| @@ -53,7 +53,7 @@ enum sn9c102_frame_state { | |||
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | struct sn9c102_frame_t { | 55 | struct sn9c102_frame_t { |
| 56 | void* bufmem; | 56 | void *bufmem; |
| 57 | struct v4l2_buffer buf; | 57 | struct v4l2_buffer buf; |
| 58 | enum sn9c102_frame_state state; | 58 | enum sn9c102_frame_state state; |
| 59 | struct list_head frame; | 59 | struct list_head frame; |
| @@ -99,17 +99,17 @@ static DEFINE_MUTEX(sn9c102_sysfs_lock); | |||
| 99 | static DECLARE_RWSEM(sn9c102_dev_lock); | 99 | static DECLARE_RWSEM(sn9c102_dev_lock); |
| 100 | 100 | ||
| 101 | struct sn9c102_device { | 101 | struct sn9c102_device { |
| 102 | struct video_device* v4ldev; | 102 | struct video_device *v4ldev; |
| 103 | 103 | ||
| 104 | struct v4l2_device v4l2_dev; | 104 | struct v4l2_device v4l2_dev; |
| 105 | 105 | ||
| 106 | enum sn9c102_bridge bridge; | 106 | enum sn9c102_bridge bridge; |
| 107 | struct sn9c102_sensor sensor; | 107 | struct sn9c102_sensor sensor; |
| 108 | 108 | ||
| 109 | struct usb_device* usbdev; | 109 | struct usb_device *usbdev; |
| 110 | struct urb* urb[SN9C102_URBS]; | 110 | struct urb *urb[SN9C102_URBS]; |
| 111 | void* transfer_buffer[SN9C102_URBS]; | 111 | void *transfer_buffer[SN9C102_URBS]; |
| 112 | u8* control_buffer; | 112 | u8 *control_buffer; |
| 113 | 113 | ||
| 114 | struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES]; | 114 | struct sn9c102_frame_t *frame_current, frame[SN9C102_MAX_FRAMES]; |
| 115 | struct list_head inqueue, outqueue; | 115 | struct list_head inqueue, outqueue; |
| @@ -139,28 +139,28 @@ struct sn9c102_device { | |||
| 139 | /*****************************************************************************/ | 139 | /*****************************************************************************/ |
| 140 | 140 | ||
| 141 | struct sn9c102_device* | 141 | struct sn9c102_device* |
| 142 | sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id) | 142 | sn9c102_match_id(struct sn9c102_device *cam, const struct usb_device_id *id) |
| 143 | { | 143 | { |
| 144 | return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL; | 144 | return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | 147 | ||
| 148 | void | 148 | void |
| 149 | sn9c102_attach_sensor(struct sn9c102_device* cam, | 149 | sn9c102_attach_sensor(struct sn9c102_device *cam, |
| 150 | const struct sn9c102_sensor* sensor) | 150 | const struct sn9c102_sensor *sensor) |
| 151 | { | 151 | { |
| 152 | memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor)); | 152 | memcpy(&cam->sensor, sensor, sizeof(struct sn9c102_sensor)); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | 155 | ||
| 156 | enum sn9c102_bridge | 156 | enum sn9c102_bridge |
| 157 | sn9c102_get_bridge(struct sn9c102_device* cam) | 157 | sn9c102_get_bridge(struct sn9c102_device *cam) |
| 158 | { | 158 | { |
| 159 | return cam->bridge; | 159 | return cam->bridge; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | 162 | ||
| 163 | struct sn9c102_sensor* sn9c102_get_sensor(struct sn9c102_device* cam) | 163 | struct sn9c102_sensor *sn9c102_get_sensor(struct sn9c102_device *cam) |
| 164 | { | 164 | { |
| 165 | return &cam->sensor; | 165 | return &cam->sensor; |
| 166 | } | 166 | } |
| @@ -198,9 +198,9 @@ do { \ | |||
| 198 | } \ | 198 | } \ |
| 199 | } while (0) | 199 | } while (0) |
| 200 | #else | 200 | #else |
| 201 | # define DBG(level, fmt, args...) do {;} while(0) | 201 | # define DBG(level, fmt, args...) do { ; } while (0) |
| 202 | # define V4LDBG(level, name, cmd) do {;} while(0) | 202 | # define V4LDBG(level, name, cmd) do { ; } while (0) |
| 203 | # define KDBG(level, fmt, args...) do {;} while(0) | 203 | # define KDBG(level, fmt, args...) do { ; } while (0) |
| 204 | #endif | 204 | #endif |
| 205 | 205 | ||
| 206 | #undef PDBG | 206 | #undef PDBG |
| @@ -209,6 +209,6 @@ dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ | |||
| 209 | __LINE__ , ## args) | 209 | __LINE__ , ## args) |
| 210 | 210 | ||
| 211 | #undef PDBGG | 211 | #undef PDBGG |
| 212 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ | 212 | #define PDBGG(fmt, args...) do { ; } while (0) /* placeholder */ |
| 213 | 213 | ||
| 214 | #endif /* _SN9C102_H_ */ | 214 | #endif /* _SN9C102_H_ */ |
diff --git a/drivers/staging/media/sn9c102/sn9c102_core.c b/drivers/staging/media/sn9c102/sn9c102_core.c index 71f594f5aa71..98b30579b0ac 100644 --- a/drivers/staging/media/sn9c102/sn9c102_core.c +++ b/drivers/staging/media/sn9c102/sn9c102_core.c | |||
| @@ -139,15 +139,15 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device *) = { | |||
| 139 | /*****************************************************************************/ | 139 | /*****************************************************************************/ |
| 140 | 140 | ||
| 141 | static u32 | 141 | static u32 |
| 142 | sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, | 142 | sn9c102_request_buffers(struct sn9c102_device *cam, u32 count, |
| 143 | enum sn9c102_io_method io) | 143 | enum sn9c102_io_method io) |
| 144 | { | 144 | { |
| 145 | struct v4l2_pix_format* p = &(cam->sensor.pix_format); | 145 | struct v4l2_pix_format *p = &(cam->sensor.pix_format); |
| 146 | struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); | 146 | struct v4l2_rect *r = &(cam->sensor.cropcap.bounds); |
| 147 | size_t imagesize = cam->module_param.force_munmap || io == IO_READ ? | 147 | size_t imagesize = cam->module_param.force_munmap || io == IO_READ ? |
| 148 | (p->width * p->height * p->priv) / 8 : | 148 | (p->width * p->height * p->priv) / 8 : |
| 149 | (r->width * r->height * p->priv) / 8; | 149 | (r->width * r->height * p->priv) / 8; |
| 150 | void* buff = NULL; | 150 | void *buff = NULL; |
| 151 | u32 i; | 151 | u32 i; |
| 152 | 152 | ||
| 153 | if (count > SN9C102_MAX_FRAMES) | 153 | if (count > SN9C102_MAX_FRAMES) |
| @@ -180,7 +180,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, | |||
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | 182 | ||
| 183 | static void sn9c102_release_buffers(struct sn9c102_device* cam) | 183 | static void sn9c102_release_buffers(struct sn9c102_device *cam) |
| 184 | { | 184 | { |
| 185 | if (cam->nbuffers) { | 185 | if (cam->nbuffers) { |
| 186 | vfree(cam->frame[0].bufmem); | 186 | vfree(cam->frame[0].bufmem); |
| @@ -190,7 +190,7 @@ static void sn9c102_release_buffers(struct sn9c102_device* cam) | |||
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | 192 | ||
| 193 | static void sn9c102_empty_framequeues(struct sn9c102_device* cam) | 193 | static void sn9c102_empty_framequeues(struct sn9c102_device *cam) |
| 194 | { | 194 | { |
| 195 | u32 i; | 195 | u32 i; |
| 196 | 196 | ||
| @@ -204,7 +204,7 @@ static void sn9c102_empty_framequeues(struct sn9c102_device* cam) | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | 206 | ||
| 207 | static void sn9c102_requeue_outqueue(struct sn9c102_device* cam) | 207 | static void sn9c102_requeue_outqueue(struct sn9c102_device *cam) |
| 208 | { | 208 | { |
| 209 | struct sn9c102_frame_t *i; | 209 | struct sn9c102_frame_t *i; |
| 210 | 210 | ||
| @@ -217,7 +217,7 @@ static void sn9c102_requeue_outqueue(struct sn9c102_device* cam) | |||
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | 219 | ||
| 220 | static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) | 220 | static void sn9c102_queue_unusedframes(struct sn9c102_device *cam) |
| 221 | { | 221 | { |
| 222 | unsigned long lock_flags; | 222 | unsigned long lock_flags; |
| 223 | u32 i; | 223 | u32 i; |
| @@ -237,11 +237,11 @@ static void sn9c102_queue_unusedframes(struct sn9c102_device* cam) | |||
| 237 | Write a sequence of count value/register pairs. Returns -1 after the first | 237 | Write a sequence of count value/register pairs. Returns -1 after the first |
| 238 | failed write, or 0 for no errors. | 238 | failed write, or 0 for no errors. |
| 239 | */ | 239 | */ |
| 240 | int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2], | 240 | int sn9c102_write_regs(struct sn9c102_device *cam, const u8 valreg[][2], |
| 241 | int count) | 241 | int count) |
| 242 | { | 242 | { |
| 243 | struct usb_device* udev = cam->usbdev; | 243 | struct usb_device *udev = cam->usbdev; |
| 244 | u8* buff = cam->control_buffer; | 244 | u8 *buff = cam->control_buffer; |
| 245 | int i, res; | 245 | int i, res; |
| 246 | 246 | ||
| 247 | for (i = 0; i < count; i++) { | 247 | for (i = 0; i < count; i++) { |
| @@ -273,10 +273,10 @@ int sn9c102_write_regs(struct sn9c102_device* cam, const u8 valreg[][2], | |||
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | 275 | ||
| 276 | int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) | 276 | int sn9c102_write_reg(struct sn9c102_device *cam, u8 value, u16 index) |
| 277 | { | 277 | { |
| 278 | struct usb_device* udev = cam->usbdev; | 278 | struct usb_device *udev = cam->usbdev; |
| 279 | u8* buff = cam->control_buffer; | 279 | u8 *buff = cam->control_buffer; |
| 280 | int res; | 280 | int res; |
| 281 | 281 | ||
| 282 | if (index >= ARRAY_SIZE(cam->reg)) | 282 | if (index >= ARRAY_SIZE(cam->reg)) |
| @@ -299,10 +299,10 @@ int sn9c102_write_reg(struct sn9c102_device* cam, u8 value, u16 index) | |||
| 299 | 299 | ||
| 300 | 300 | ||
| 301 | /* NOTE: with the SN9C10[123] reading some registers always returns 0 */ | 301 | /* NOTE: with the SN9C10[123] reading some registers always returns 0 */ |
| 302 | int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) | 302 | int sn9c102_read_reg(struct sn9c102_device *cam, u16 index) |
| 303 | { | 303 | { |
| 304 | struct usb_device* udev = cam->usbdev; | 304 | struct usb_device *udev = cam->usbdev; |
| 305 | u8* buff = cam->control_buffer; | 305 | u8 *buff = cam->control_buffer; |
| 306 | int res; | 306 | int res; |
| 307 | 307 | ||
| 308 | res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, | 308 | res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, 0xc1, |
| @@ -315,7 +315,7 @@ int sn9c102_read_reg(struct sn9c102_device* cam, u16 index) | |||
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | 317 | ||
| 318 | int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index) | 318 | int sn9c102_pread_reg(struct sn9c102_device *cam, u16 index) |
| 319 | { | 319 | { |
| 320 | if (index >= ARRAY_SIZE(cam->reg)) | 320 | if (index >= ARRAY_SIZE(cam->reg)) |
| 321 | return -1; | 321 | return -1; |
| @@ -325,8 +325,8 @@ int sn9c102_pread_reg(struct sn9c102_device* cam, u16 index) | |||
| 325 | 325 | ||
| 326 | 326 | ||
| 327 | static int | 327 | static int |
| 328 | sn9c102_i2c_wait(struct sn9c102_device* cam, | 328 | sn9c102_i2c_wait(struct sn9c102_device *cam, |
| 329 | const struct sn9c102_sensor* sensor) | 329 | const struct sn9c102_sensor *sensor) |
| 330 | { | 330 | { |
| 331 | int i, r; | 331 | int i, r; |
| 332 | 332 | ||
| @@ -346,8 +346,8 @@ sn9c102_i2c_wait(struct sn9c102_device* cam, | |||
| 346 | 346 | ||
| 347 | 347 | ||
| 348 | static int | 348 | static int |
| 349 | sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, | 349 | sn9c102_i2c_detect_read_error(struct sn9c102_device *cam, |
| 350 | const struct sn9c102_sensor* sensor) | 350 | const struct sn9c102_sensor *sensor) |
| 351 | { | 351 | { |
| 352 | int r , err = 0; | 352 | int r , err = 0; |
| 353 | 353 | ||
| @@ -368,22 +368,23 @@ sn9c102_i2c_detect_read_error(struct sn9c102_device* cam, | |||
| 368 | 368 | ||
| 369 | 369 | ||
| 370 | static int | 370 | static int |
| 371 | sn9c102_i2c_detect_write_error(struct sn9c102_device* cam, | 371 | sn9c102_i2c_detect_write_error(struct sn9c102_device *cam, |
| 372 | const struct sn9c102_sensor* sensor) | 372 | const struct sn9c102_sensor *sensor) |
| 373 | { | 373 | { |
| 374 | int r; | 374 | int r; |
| 375 | |||
| 375 | r = sn9c102_read_reg(cam, 0x08); | 376 | r = sn9c102_read_reg(cam, 0x08); |
| 376 | return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0; | 377 | return (r < 0 || (r >= 0 && (r & 0x08))) ? -EIO : 0; |
| 377 | } | 378 | } |
| 378 | 379 | ||
| 379 | 380 | ||
| 380 | int | 381 | int |
| 381 | sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, | 382 | sn9c102_i2c_try_raw_read(struct sn9c102_device *cam, |
| 382 | const struct sn9c102_sensor* sensor, u8 data0, | 383 | const struct sn9c102_sensor *sensor, u8 data0, |
| 383 | u8 data1, u8 n, u8 buffer[]) | 384 | u8 data1, u8 n, u8 buffer[]) |
| 384 | { | 385 | { |
| 385 | struct usb_device* udev = cam->usbdev; | 386 | struct usb_device *udev = cam->usbdev; |
| 386 | u8* data = cam->control_buffer; | 387 | u8 *data = cam->control_buffer; |
| 387 | int i = 0, err = 0, res; | 388 | int i = 0, err = 0, res; |
| 388 | 389 | ||
| 389 | /* Write cycle */ | 390 | /* Write cycle */ |
| @@ -437,12 +438,12 @@ sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, | |||
| 437 | 438 | ||
| 438 | 439 | ||
| 439 | int | 440 | int |
| 440 | sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, | 441 | sn9c102_i2c_try_raw_write(struct sn9c102_device *cam, |
| 441 | const struct sn9c102_sensor* sensor, u8 n, u8 data0, | 442 | const struct sn9c102_sensor *sensor, u8 n, u8 data0, |
| 442 | u8 data1, u8 data2, u8 data3, u8 data4, u8 data5) | 443 | u8 data1, u8 data2, u8 data3, u8 data4, u8 data5) |
| 443 | { | 444 | { |
| 444 | struct usb_device* udev = cam->usbdev; | 445 | struct usb_device *udev = cam->usbdev; |
| 445 | u8* data = cam->control_buffer; | 446 | u8 *data = cam->control_buffer; |
| 446 | int err = 0, res; | 447 | int err = 0, res; |
| 447 | 448 | ||
| 448 | /* Write cycle. It usually is address + value */ | 449 | /* Write cycle. It usually is address + value */ |
| @@ -476,16 +477,16 @@ sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, | |||
| 476 | 477 | ||
| 477 | 478 | ||
| 478 | int | 479 | int |
| 479 | sn9c102_i2c_try_read(struct sn9c102_device* cam, | 480 | sn9c102_i2c_try_read(struct sn9c102_device *cam, |
| 480 | const struct sn9c102_sensor* sensor, u8 address) | 481 | const struct sn9c102_sensor *sensor, u8 address) |
| 481 | { | 482 | { |
| 482 | return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id, | 483 | return sn9c102_i2c_try_raw_read(cam, sensor, sensor->i2c_slave_id, |
| 483 | address, 1, NULL); | 484 | address, 1, NULL); |
| 484 | } | 485 | } |
| 485 | 486 | ||
| 486 | 487 | ||
| 487 | static int sn9c102_i2c_try_write(struct sn9c102_device* cam, | 488 | static int sn9c102_i2c_try_write(struct sn9c102_device *cam, |
| 488 | const struct sn9c102_sensor* sensor, | 489 | const struct sn9c102_sensor *sensor, |
| 489 | u8 address, u8 value) | 490 | u8 address, u8 value) |
| 490 | { | 491 | { |
| 491 | return sn9c102_i2c_try_raw_write(cam, sensor, 3, | 492 | return sn9c102_i2c_try_raw_write(cam, sensor, 3, |
| @@ -494,20 +495,20 @@ static int sn9c102_i2c_try_write(struct sn9c102_device* cam, | |||
| 494 | } | 495 | } |
| 495 | 496 | ||
| 496 | 497 | ||
| 497 | int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address) | 498 | int sn9c102_i2c_read(struct sn9c102_device *cam, u8 address) |
| 498 | { | 499 | { |
| 499 | return sn9c102_i2c_try_read(cam, &cam->sensor, address); | 500 | return sn9c102_i2c_try_read(cam, &cam->sensor, address); |
| 500 | } | 501 | } |
| 501 | 502 | ||
| 502 | 503 | ||
| 503 | int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value) | 504 | int sn9c102_i2c_write(struct sn9c102_device *cam, u8 address, u8 value) |
| 504 | { | 505 | { |
| 505 | return sn9c102_i2c_try_write(cam, &cam->sensor, address, value); | 506 | return sn9c102_i2c_try_write(cam, &cam->sensor, address, value); |
| 506 | } | 507 | } |
| 507 | 508 | ||
| 508 | /*****************************************************************************/ | 509 | /*****************************************************************************/ |
| 509 | 510 | ||
| 510 | static size_t sn9c102_sof_length(struct sn9c102_device* cam) | 511 | static size_t sn9c102_sof_length(struct sn9c102_device *cam) |
| 511 | { | 512 | { |
| 512 | switch (cam->bridge) { | 513 | switch (cam->bridge) { |
| 513 | case BRIDGE_SN9C101: | 514 | case BRIDGE_SN9C101: |
| @@ -525,7 +526,7 @@ static size_t sn9c102_sof_length(struct sn9c102_device* cam) | |||
| 525 | 526 | ||
| 526 | 527 | ||
| 527 | static void* | 528 | static void* |
| 528 | sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | 529 | sn9c102_find_sof_header(struct sn9c102_device *cam, void *mem, size_t len) |
| 529 | { | 530 | { |
| 530 | static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; | 531 | static const char marker[6] = {0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96}; |
| 531 | const char *m = mem; | 532 | const char *m = mem; |
| @@ -547,7 +548,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
| 547 | } | 548 | } |
| 548 | 549 | ||
| 549 | /* Search for the SOF marker (fixed part) in the header */ | 550 | /* Search for the SOF marker (fixed part) in the header */ |
| 550 | for (j = 0, b=cam->sof.bytesread; j+b < sizeof(marker); j++) { | 551 | for (j = 0, b = cam->sof.bytesread; j+b < sizeof(marker); j++) { |
| 551 | if (unlikely(i+j == len)) | 552 | if (unlikely(i+j == len)) |
| 552 | return NULL; | 553 | return NULL; |
| 553 | if (*(m+i+j) == marker[cam->sof.bytesread]) { | 554 | if (*(m+i+j) == marker[cam->sof.bytesread]) { |
| @@ -570,7 +571,7 @@ sn9c102_find_sof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
| 570 | 571 | ||
| 571 | 572 | ||
| 572 | static void* | 573 | static void* |
| 573 | sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) | 574 | sn9c102_find_eof_header(struct sn9c102_device *cam, void *mem, size_t len) |
| 574 | { | 575 | { |
| 575 | static const u8 eof_header[4][4] = { | 576 | static const u8 eof_header[4][4] = { |
| 576 | {0x00, 0x00, 0x00, 0x00}, | 577 | {0x00, 0x00, 0x00, 0x00}, |
| @@ -600,7 +601,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len) | |||
| 600 | 601 | ||
| 601 | 602 | ||
| 602 | static void | 603 | static void |
| 603 | sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f) | 604 | sn9c102_write_jpegheader(struct sn9c102_device *cam, struct sn9c102_frame_t *f) |
| 604 | { | 605 | { |
| 605 | static const u8 jpeg_header[589] = { | 606 | static const u8 jpeg_header[589] = { |
| 606 | 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05, | 607 | 0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x06, 0x04, 0x05, |
| @@ -687,8 +688,8 @@ sn9c102_write_jpegheader(struct sn9c102_device* cam, struct sn9c102_frame_t* f) | |||
| 687 | 688 | ||
| 688 | static void sn9c102_urb_complete(struct urb *urb) | 689 | static void sn9c102_urb_complete(struct urb *urb) |
| 689 | { | 690 | { |
| 690 | struct sn9c102_device* cam = urb->context; | 691 | struct sn9c102_device *cam = urb->context; |
| 691 | struct sn9c102_frame_t** f; | 692 | struct sn9c102_frame_t **f; |
| 692 | size_t imagesize, soflen; | 693 | size_t imagesize, soflen; |
| 693 | u8 i; | 694 | u8 i; |
| 694 | int err = 0; | 695 | int err = 0; |
| @@ -787,7 +788,7 @@ end_of_frame: | |||
| 787 | 788 | ||
| 788 | b = (*f)->buf.bytesused; | 789 | b = (*f)->buf.bytesused; |
| 789 | (*f)->state = F_DONE; | 790 | (*f)->state = F_DONE; |
| 790 | (*f)->buf.sequence= ++cam->frame_count; | 791 | (*f)->buf.sequence = ++cam->frame_count; |
| 791 | 792 | ||
| 792 | spin_lock(&cam->queue_lock); | 793 | spin_lock(&cam->queue_lock); |
| 793 | list_move_tail(&(*f)->frame, | 794 | list_move_tail(&(*f)->frame, |
| @@ -796,7 +797,7 @@ end_of_frame: | |||
| 796 | (*f) = list_entry( | 797 | (*f) = list_entry( |
| 797 | cam->inqueue.next, | 798 | cam->inqueue.next, |
| 798 | struct sn9c102_frame_t, | 799 | struct sn9c102_frame_t, |
| 799 | frame ); | 800 | frame); |
| 800 | else | 801 | else |
| 801 | (*f) = NULL; | 802 | (*f) = NULL; |
| 802 | spin_unlock(&cam->queue_lock); | 803 | spin_unlock(&cam->queue_lock); |
| @@ -883,11 +884,11 @@ resubmit_urb: | |||
| 883 | } | 884 | } |
| 884 | 885 | ||
| 885 | 886 | ||
| 886 | static int sn9c102_start_transfer(struct sn9c102_device* cam) | 887 | static int sn9c102_start_transfer(struct sn9c102_device *cam) |
| 887 | { | 888 | { |
| 888 | struct usb_device *udev = cam->usbdev; | 889 | struct usb_device *udev = cam->usbdev; |
| 889 | struct urb* urb; | 890 | struct urb *urb; |
| 890 | struct usb_host_interface* altsetting = usb_altnum_to_altsetting( | 891 | struct usb_host_interface *altsetting = usb_altnum_to_altsetting( |
| 891 | usb_ifnum_to_if(udev, 0), | 892 | usb_ifnum_to_if(udev, 0), |
| 892 | SN9C102_ALTERNATE_SETTING); | 893 | SN9C102_ALTERNATE_SETTING); |
| 893 | const unsigned int psz = le16_to_cpu(altsetting-> | 894 | const unsigned int psz = le16_to_cpu(altsetting-> |
| @@ -971,7 +972,7 @@ free_buffers: | |||
| 971 | } | 972 | } |
| 972 | 973 | ||
| 973 | 974 | ||
| 974 | static int sn9c102_stop_transfer(struct sn9c102_device* cam) | 975 | static int sn9c102_stop_transfer(struct sn9c102_device *cam) |
| 975 | { | 976 | { |
| 976 | struct usb_device *udev = cam->usbdev; | 977 | struct usb_device *udev = cam->usbdev; |
| 977 | s8 i; | 978 | s8 i; |
| @@ -994,7 +995,7 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam) | |||
| 994 | } | 995 | } |
| 995 | 996 | ||
| 996 | 997 | ||
| 997 | static int sn9c102_stream_interrupt(struct sn9c102_device* cam) | 998 | static int sn9c102_stream_interrupt(struct sn9c102_device *cam) |
| 998 | { | 999 | { |
| 999 | cam->stream = STREAM_INTERRUPT; | 1000 | cam->stream = STREAM_INTERRUPT; |
| 1000 | wait_event_timeout(cam->wait_stream, | 1001 | wait_event_timeout(cam->wait_stream, |
| @@ -1017,10 +1018,10 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) | |||
| 1017 | /*****************************************************************************/ | 1018 | /*****************************************************************************/ |
| 1018 | 1019 | ||
| 1019 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1020 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 1020 | static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count) | 1021 | static u16 sn9c102_strtou16(const char *buff, size_t len, ssize_t *count) |
| 1021 | { | 1022 | { |
| 1022 | char str[7]; | 1023 | char str[7]; |
| 1023 | char* endp; | 1024 | char *endp; |
| 1024 | unsigned long val; | 1025 | unsigned long val; |
| 1025 | 1026 | ||
| 1026 | if (len < 6) { | 1027 | if (len < 6) { |
| @@ -1048,10 +1049,10 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count) | |||
| 1048 | NOTE 2: buffers are PAGE_SIZE long | 1049 | NOTE 2: buffers are PAGE_SIZE long |
| 1049 | */ | 1050 | */ |
| 1050 | 1051 | ||
| 1051 | static ssize_t sn9c102_show_reg(struct device* cd, | 1052 | static ssize_t sn9c102_show_reg(struct device *cd, |
| 1052 | struct device_attribute *attr, char* buf) | 1053 | struct device_attribute *attr, char *buf) |
| 1053 | { | 1054 | { |
| 1054 | struct sn9c102_device* cam; | 1055 | struct sn9c102_device *cam; |
| 1055 | ssize_t count; | 1056 | ssize_t count; |
| 1056 | 1057 | ||
| 1057 | if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) | 1058 | if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) |
| @@ -1072,10 +1073,10 @@ static ssize_t sn9c102_show_reg(struct device* cd, | |||
| 1072 | 1073 | ||
| 1073 | 1074 | ||
| 1074 | static ssize_t | 1075 | static ssize_t |
| 1075 | sn9c102_store_reg(struct device* cd, struct device_attribute *attr, | 1076 | sn9c102_store_reg(struct device *cd, struct device_attribute *attr, |
| 1076 | const char* buf, size_t len) | 1077 | const char *buf, size_t len) |
| 1077 | { | 1078 | { |
| 1078 | struct sn9c102_device* cam; | 1079 | struct sn9c102_device *cam; |
| 1079 | u16 index; | 1080 | u16 index; |
| 1080 | ssize_t count; | 1081 | ssize_t count; |
| 1081 | 1082 | ||
| @@ -1105,10 +1106,10 @@ sn9c102_store_reg(struct device* cd, struct device_attribute *attr, | |||
| 1105 | } | 1106 | } |
| 1106 | 1107 | ||
| 1107 | 1108 | ||
| 1108 | static ssize_t sn9c102_show_val(struct device* cd, | 1109 | static ssize_t sn9c102_show_val(struct device *cd, |
| 1109 | struct device_attribute *attr, char* buf) | 1110 | struct device_attribute *attr, char *buf) |
| 1110 | { | 1111 | { |
| 1111 | struct sn9c102_device* cam; | 1112 | struct sn9c102_device *cam; |
| 1112 | ssize_t count; | 1113 | ssize_t count; |
| 1113 | int val; | 1114 | int val; |
| 1114 | 1115 | ||
| @@ -1138,10 +1139,10 @@ static ssize_t sn9c102_show_val(struct device* cd, | |||
| 1138 | 1139 | ||
| 1139 | 1140 | ||
| 1140 | static ssize_t | 1141 | static ssize_t |
| 1141 | sn9c102_store_val(struct device* cd, struct device_attribute *attr, | 1142 | sn9c102_store_val(struct device *cd, struct device_attribute *attr, |
| 1142 | const char* buf, size_t len) | 1143 | const char *buf, size_t len) |
| 1143 | { | 1144 | { |
| 1144 | struct sn9c102_device* cam; | 1145 | struct sn9c102_device *cam; |
| 1145 | u16 value; | 1146 | u16 value; |
| 1146 | ssize_t count; | 1147 | ssize_t count; |
| 1147 | int err; | 1148 | int err; |
| @@ -1177,10 +1178,10 @@ sn9c102_store_val(struct device* cd, struct device_attribute *attr, | |||
| 1177 | } | 1178 | } |
| 1178 | 1179 | ||
| 1179 | 1180 | ||
| 1180 | static ssize_t sn9c102_show_i2c_reg(struct device* cd, | 1181 | static ssize_t sn9c102_show_i2c_reg(struct device *cd, |
| 1181 | struct device_attribute *attr, char* buf) | 1182 | struct device_attribute *attr, char *buf) |
| 1182 | { | 1183 | { |
| 1183 | struct sn9c102_device* cam; | 1184 | struct sn9c102_device *cam; |
| 1184 | ssize_t count; | 1185 | ssize_t count; |
| 1185 | 1186 | ||
| 1186 | if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) | 1187 | if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) |
| @@ -1203,10 +1204,10 @@ static ssize_t sn9c102_show_i2c_reg(struct device* cd, | |||
| 1203 | 1204 | ||
| 1204 | 1205 | ||
| 1205 | static ssize_t | 1206 | static ssize_t |
| 1206 | sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr, | 1207 | sn9c102_store_i2c_reg(struct device *cd, struct device_attribute *attr, |
| 1207 | const char* buf, size_t len) | 1208 | const char *buf, size_t len) |
| 1208 | { | 1209 | { |
| 1209 | struct sn9c102_device* cam; | 1210 | struct sn9c102_device *cam; |
| 1210 | u16 index; | 1211 | u16 index; |
| 1211 | ssize_t count; | 1212 | ssize_t count; |
| 1212 | 1213 | ||
| @@ -1236,10 +1237,10 @@ sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr, | |||
| 1236 | } | 1237 | } |
| 1237 | 1238 | ||
| 1238 | 1239 | ||
| 1239 | static ssize_t sn9c102_show_i2c_val(struct device* cd, | 1240 | static ssize_t sn9c102_show_i2c_val(struct device *cd, |
| 1240 | struct device_attribute *attr, char* buf) | 1241 | struct device_attribute *attr, char *buf) |
| 1241 | { | 1242 | { |
| 1242 | struct sn9c102_device* cam; | 1243 | struct sn9c102_device *cam; |
| 1243 | ssize_t count; | 1244 | ssize_t count; |
| 1244 | int val; | 1245 | int val; |
| 1245 | 1246 | ||
| @@ -1274,10 +1275,10 @@ static ssize_t sn9c102_show_i2c_val(struct device* cd, | |||
| 1274 | 1275 | ||
| 1275 | 1276 | ||
| 1276 | static ssize_t | 1277 | static ssize_t |
| 1277 | sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr, | 1278 | sn9c102_store_i2c_val(struct device *cd, struct device_attribute *attr, |
| 1278 | const char* buf, size_t len) | 1279 | const char *buf, size_t len) |
| 1279 | { | 1280 | { |
| 1280 | struct sn9c102_device* cam; | 1281 | struct sn9c102_device *cam; |
| 1281 | u16 value; | 1282 | u16 value; |
| 1282 | ssize_t count; | 1283 | ssize_t count; |
| 1283 | int err; | 1284 | int err; |
| @@ -1319,10 +1320,10 @@ sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr, | |||
| 1319 | 1320 | ||
| 1320 | 1321 | ||
| 1321 | static ssize_t | 1322 | static ssize_t |
| 1322 | sn9c102_store_green(struct device* cd, struct device_attribute *attr, | 1323 | sn9c102_store_green(struct device *cd, struct device_attribute *attr, |
| 1323 | const char* buf, size_t len) | 1324 | const char *buf, size_t len) |
| 1324 | { | 1325 | { |
| 1325 | struct sn9c102_device* cam; | 1326 | struct sn9c102_device *cam; |
| 1326 | enum sn9c102_bridge bridge; | 1327 | enum sn9c102_bridge bridge; |
| 1327 | ssize_t res = 0; | 1328 | ssize_t res = 0; |
| 1328 | u16 value; | 1329 | u16 value; |
| @@ -1350,7 +1351,8 @@ sn9c102_store_green(struct device* cd, struct device_attribute *attr, | |||
| 1350 | case BRIDGE_SN9C102: | 1351 | case BRIDGE_SN9C102: |
| 1351 | if (value > 0x0f) | 1352 | if (value > 0x0f) |
| 1352 | return -EINVAL; | 1353 | return -EINVAL; |
| 1353 | if ((res = sn9c102_store_reg(cd, attr, "0x11", 4)) >= 0) | 1354 | res = sn9c102_store_reg(cd, attr, "0x11", 4); |
| 1355 | if (res >= 0) | ||
| 1354 | res = sn9c102_store_val(cd, attr, buf, len); | 1356 | res = sn9c102_store_val(cd, attr, buf, len); |
| 1355 | break; | 1357 | break; |
| 1356 | case BRIDGE_SN9C103: | 1358 | case BRIDGE_SN9C103: |
| @@ -1358,7 +1360,8 @@ sn9c102_store_green(struct device* cd, struct device_attribute *attr, | |||
| 1358 | case BRIDGE_SN9C120: | 1360 | case BRIDGE_SN9C120: |
| 1359 | if (value > 0x7f) | 1361 | if (value > 0x7f) |
| 1360 | return -EINVAL; | 1362 | return -EINVAL; |
| 1361 | if ((res = sn9c102_store_reg(cd, attr, "0x07", 4)) >= 0) | 1363 | res = sn9c102_store_reg(cd, attr, "0x07", 4); |
| 1364 | if (res >= 0) | ||
| 1362 | res = sn9c102_store_val(cd, attr, buf, len); | 1365 | res = sn9c102_store_val(cd, attr, buf, len); |
| 1363 | break; | 1366 | break; |
| 1364 | } | 1367 | } |
| @@ -1368,8 +1371,8 @@ sn9c102_store_green(struct device* cd, struct device_attribute *attr, | |||
| 1368 | 1371 | ||
| 1369 | 1372 | ||
| 1370 | static ssize_t | 1373 | static ssize_t |
| 1371 | sn9c102_store_blue(struct device* cd, struct device_attribute *attr, | 1374 | sn9c102_store_blue(struct device *cd, struct device_attribute *attr, |
| 1372 | const char* buf, size_t len) | 1375 | const char *buf, size_t len) |
| 1373 | { | 1376 | { |
| 1374 | ssize_t res = 0; | 1377 | ssize_t res = 0; |
| 1375 | u16 value; | 1378 | u16 value; |
| @@ -1379,7 +1382,8 @@ sn9c102_store_blue(struct device* cd, struct device_attribute *attr, | |||
| 1379 | if (!count || value > 0x7f) | 1382 | if (!count || value > 0x7f) |
| 1380 | return -EINVAL; | 1383 | return -EINVAL; |
| 1381 | 1384 | ||
| 1382 | if ((res = sn9c102_store_reg(cd, attr, "0x06", 4)) >= 0) | 1385 | res = sn9c102_store_reg(cd, attr, "0x06", 4); |
| 1386 | if (res >= 0) | ||
| 1383 | res = sn9c102_store_val(cd, attr, buf, len); | 1387 | res = sn9c102_store_val(cd, attr, buf, len); |
| 1384 | 1388 | ||
| 1385 | return res; | 1389 | return res; |
| @@ -1387,8 +1391,8 @@ sn9c102_store_blue(struct device* cd, struct device_attribute *attr, | |||
| 1387 | 1391 | ||
| 1388 | 1392 | ||
| 1389 | static ssize_t | 1393 | static ssize_t |
| 1390 | sn9c102_store_red(struct device* cd, struct device_attribute *attr, | 1394 | sn9c102_store_red(struct device *cd, struct device_attribute *attr, |
| 1391 | const char* buf, size_t len) | 1395 | const char *buf, size_t len) |
| 1392 | { | 1396 | { |
| 1393 | ssize_t res = 0; | 1397 | ssize_t res = 0; |
| 1394 | u16 value; | 1398 | u16 value; |
| @@ -1397,19 +1401,19 @@ sn9c102_store_red(struct device* cd, struct device_attribute *attr, | |||
| 1397 | value = sn9c102_strtou16(buf, len, &count); | 1401 | value = sn9c102_strtou16(buf, len, &count); |
| 1398 | if (!count || value > 0x7f) | 1402 | if (!count || value > 0x7f) |
| 1399 | return -EINVAL; | 1403 | return -EINVAL; |
| 1400 | 1404 | res = sn9c102_store_reg(cd, attr, "0x05", 4); | |
| 1401 | if ((res = sn9c102_store_reg(cd, attr, "0x05", 4)) >= 0) | 1405 | if (res >= 0) |
| 1402 | res = sn9c102_store_val(cd, attr, buf, len); | 1406 | res = sn9c102_store_val(cd, attr, buf, len); |
| 1403 | 1407 | ||
| 1404 | return res; | 1408 | return res; |
| 1405 | } | 1409 | } |
| 1406 | 1410 | ||
| 1407 | 1411 | ||
| 1408 | static ssize_t sn9c102_show_frame_header(struct device* cd, | 1412 | static ssize_t sn9c102_show_frame_header(struct device *cd, |
| 1409 | struct device_attribute *attr, | 1413 | struct device_attribute *attr, |
| 1410 | char* buf) | 1414 | char *buf) |
| 1411 | { | 1415 | { |
| 1412 | struct sn9c102_device* cam; | 1416 | struct sn9c102_device *cam; |
| 1413 | ssize_t count; | 1417 | ssize_t count; |
| 1414 | 1418 | ||
| 1415 | cam = video_get_drvdata(container_of(cd, struct video_device, dev)); | 1419 | cam = video_get_drvdata(container_of(cd, struct video_device, dev)); |
| @@ -1437,7 +1441,7 @@ static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red); | |||
| 1437 | static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL); | 1441 | static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL); |
| 1438 | 1442 | ||
| 1439 | 1443 | ||
| 1440 | static int sn9c102_create_sysfs(struct sn9c102_device* cam) | 1444 | static int sn9c102_create_sysfs(struct sn9c102_device *cam) |
| 1441 | { | 1445 | { |
| 1442 | struct device *dev = &(cam->v4ldev->dev); | 1446 | struct device *dev = &(cam->v4ldev->dev); |
| 1443 | int err = 0; | 1447 | int err = 0; |
| @@ -1498,7 +1502,7 @@ err_out: | |||
| 1498 | /*****************************************************************************/ | 1502 | /*****************************************************************************/ |
| 1499 | 1503 | ||
| 1500 | static int | 1504 | static int |
| 1501 | sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix) | 1505 | sn9c102_set_pix_format(struct sn9c102_device *cam, struct v4l2_pix_format *pix) |
| 1502 | { | 1506 | { |
| 1503 | int err = 0; | 1507 | int err = 0; |
| 1504 | 1508 | ||
| @@ -1538,8 +1542,8 @@ sn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix) | |||
| 1538 | 1542 | ||
| 1539 | 1543 | ||
| 1540 | static int | 1544 | static int |
| 1541 | sn9c102_set_compression(struct sn9c102_device* cam, | 1545 | sn9c102_set_compression(struct sn9c102_device *cam, |
| 1542 | struct v4l2_jpegcompression* compression) | 1546 | struct v4l2_jpegcompression *compression) |
| 1543 | { | 1547 | { |
| 1544 | int i, err = 0; | 1548 | int i, err = 0; |
| 1545 | 1549 | ||
| @@ -1586,7 +1590,7 @@ sn9c102_set_compression(struct sn9c102_device* cam, | |||
| 1586 | } | 1590 | } |
| 1587 | 1591 | ||
| 1588 | 1592 | ||
| 1589 | static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale) | 1593 | static int sn9c102_set_scale(struct sn9c102_device *cam, u8 scale) |
| 1590 | { | 1594 | { |
| 1591 | u8 r = 0; | 1595 | u8 r = 0; |
| 1592 | int err = 0; | 1596 | int err = 0; |
| @@ -1609,9 +1613,9 @@ static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale) | |||
| 1609 | } | 1613 | } |
| 1610 | 1614 | ||
| 1611 | 1615 | ||
| 1612 | static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect) | 1616 | static int sn9c102_set_crop(struct sn9c102_device *cam, struct v4l2_rect *rect) |
| 1613 | { | 1617 | { |
| 1614 | struct sn9c102_sensor* s = &cam->sensor; | 1618 | struct sn9c102_sensor *s = &cam->sensor; |
| 1615 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left), | 1619 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left), |
| 1616 | v_start = (u8)(rect->top - s->cropcap.bounds.top), | 1620 | v_start = (u8)(rect->top - s->cropcap.bounds.top), |
| 1617 | h_size = (u8)(rect->width / 16), | 1621 | h_size = (u8)(rect->width / 16), |
| @@ -1632,12 +1636,12 @@ static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect) | |||
| 1632 | } | 1636 | } |
| 1633 | 1637 | ||
| 1634 | 1638 | ||
| 1635 | static int sn9c102_init(struct sn9c102_device* cam) | 1639 | static int sn9c102_init(struct sn9c102_device *cam) |
| 1636 | { | 1640 | { |
| 1637 | struct sn9c102_sensor* s = &cam->sensor; | 1641 | struct sn9c102_sensor *s = &cam->sensor; |
| 1638 | struct v4l2_control ctrl; | 1642 | struct v4l2_control ctrl; |
| 1639 | struct v4l2_queryctrl *qctrl; | 1643 | struct v4l2_queryctrl *qctrl; |
| 1640 | struct v4l2_rect* rect; | 1644 | struct v4l2_rect *rect; |
| 1641 | u8 i = 0; | 1645 | u8 i = 0; |
| 1642 | int err = 0; | 1646 | int err = 0; |
| 1643 | 1647 | ||
| @@ -1669,7 +1673,7 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
| 1669 | cam->bridge == BRIDGE_SN9C102 || | 1673 | cam->bridge == BRIDGE_SN9C102 || |
| 1670 | cam->bridge == BRIDGE_SN9C103) { | 1674 | cam->bridge == BRIDGE_SN9C103) { |
| 1671 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG) | 1675 | if (s->pix_format.pixelformat == V4L2_PIX_FMT_JPEG) |
| 1672 | s->pix_format.pixelformat= V4L2_PIX_FMT_SBGGR8; | 1676 | s->pix_format.pixelformat = V4L2_PIX_FMT_SBGGR8; |
| 1673 | cam->compression.quality = cam->reg[0x17] & 0x01 ? | 1677 | cam->compression.quality = cam->reg[0x17] & 0x01 ? |
| 1674 | 0 : 1; | 1678 | 0 : 1; |
| 1675 | } else { | 1679 | } else { |
| @@ -1761,7 +1765,7 @@ static void sn9c102_release_resources(struct kref *kref) | |||
| 1761 | 1765 | ||
| 1762 | static int sn9c102_open(struct file *filp) | 1766 | static int sn9c102_open(struct file *filp) |
| 1763 | { | 1767 | { |
| 1764 | struct sn9c102_device* cam; | 1768 | struct sn9c102_device *cam; |
| 1765 | int err = 0; | 1769 | int err = 0; |
| 1766 | 1770 | ||
| 1767 | /* | 1771 | /* |
| @@ -1873,7 +1877,7 @@ out: | |||
| 1873 | 1877 | ||
| 1874 | static int sn9c102_release(struct file *filp) | 1878 | static int sn9c102_release(struct file *filp) |
| 1875 | { | 1879 | { |
| 1876 | struct sn9c102_device* cam; | 1880 | struct sn9c102_device *cam; |
| 1877 | 1881 | ||
| 1878 | down_write(&sn9c102_dev_lock); | 1882 | down_write(&sn9c102_dev_lock); |
| 1879 | 1883 | ||
| @@ -1895,10 +1899,10 @@ static int sn9c102_release(struct file *filp) | |||
| 1895 | 1899 | ||
| 1896 | 1900 | ||
| 1897 | static ssize_t | 1901 | static ssize_t |
| 1898 | sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | 1902 | sn9c102_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) |
| 1899 | { | 1903 | { |
| 1900 | struct sn9c102_device *cam = video_drvdata(filp); | 1904 | struct sn9c102_device *cam = video_drvdata(filp); |
| 1901 | struct sn9c102_frame_t* f, * i; | 1905 | struct sn9c102_frame_t *f, *i; |
| 1902 | unsigned long lock_flags; | 1906 | unsigned long lock_flags; |
| 1903 | long timeout; | 1907 | long timeout; |
| 1904 | int err = 0; | 1908 | int err = 0; |
| @@ -1927,7 +1931,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
| 1927 | } | 1931 | } |
| 1928 | 1932 | ||
| 1929 | if (cam->io == IO_NONE) { | 1933 | if (cam->io == IO_NONE) { |
| 1930 | if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) { | 1934 | if (!sn9c102_request_buffers(cam, cam->nreadbuffers, IO_READ)) { |
| 1931 | DBG(1, "read() failed, not enough memory"); | 1935 | DBG(1, "read() failed, not enough memory"); |
| 1932 | mutex_unlock(&cam->fileop_mutex); | 1936 | mutex_unlock(&cam->fileop_mutex); |
| 1933 | return -ENOMEM; | 1937 | return -ENOMEM; |
| @@ -1954,17 +1958,17 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
| 1954 | } | 1958 | } |
| 1955 | if (!cam->module_param.frame_timeout) { | 1959 | if (!cam->module_param.frame_timeout) { |
| 1956 | err = wait_event_interruptible | 1960 | err = wait_event_interruptible |
| 1957 | ( cam->wait_frame, | 1961 | (cam->wait_frame, |
| 1958 | (!list_empty(&cam->outqueue)) || | 1962 | (!list_empty(&cam->outqueue)) || |
| 1959 | (cam->state & DEV_DISCONNECTED) || | 1963 | (cam->state & DEV_DISCONNECTED) || |
| 1960 | (cam->state & DEV_MISCONFIGURED) ); | 1964 | (cam->state & DEV_MISCONFIGURED)); |
| 1961 | if (err) { | 1965 | if (err) { |
| 1962 | mutex_unlock(&cam->fileop_mutex); | 1966 | mutex_unlock(&cam->fileop_mutex); |
| 1963 | return err; | 1967 | return err; |
| 1964 | } | 1968 | } |
| 1965 | } else { | 1969 | } else { |
| 1966 | timeout = wait_event_interruptible_timeout | 1970 | timeout = wait_event_interruptible_timeout |
| 1967 | ( cam->wait_frame, | 1971 | (cam->wait_frame, |
| 1968 | (!list_empty(&cam->outqueue)) || | 1972 | (!list_empty(&cam->outqueue)) || |
| 1969 | (cam->state & DEV_DISCONNECTED) || | 1973 | (cam->state & DEV_DISCONNECTED) || |
| 1970 | (cam->state & DEV_MISCONFIGURED), | 1974 | (cam->state & DEV_MISCONFIGURED), |
| @@ -2024,7 +2028,7 @@ exit: | |||
| 2024 | static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) | 2028 | static unsigned int sn9c102_poll(struct file *filp, poll_table *wait) |
| 2025 | { | 2029 | { |
| 2026 | struct sn9c102_device *cam = video_drvdata(filp); | 2030 | struct sn9c102_device *cam = video_drvdata(filp); |
| 2027 | struct sn9c102_frame_t* f; | 2031 | struct sn9c102_frame_t *f; |
| 2028 | unsigned long lock_flags; | 2032 | unsigned long lock_flags; |
| 2029 | unsigned int mask = 0; | 2033 | unsigned int mask = 0; |
| 2030 | 2034 | ||
| @@ -2076,17 +2080,17 @@ error: | |||
| 2076 | } | 2080 | } |
| 2077 | 2081 | ||
| 2078 | 2082 | ||
| 2079 | static void sn9c102_vm_open(struct vm_area_struct* vma) | 2083 | static void sn9c102_vm_open(struct vm_area_struct *vma) |
| 2080 | { | 2084 | { |
| 2081 | struct sn9c102_frame_t* f = vma->vm_private_data; | 2085 | struct sn9c102_frame_t *f = vma->vm_private_data; |
| 2082 | f->vma_use_count++; | 2086 | f->vma_use_count++; |
| 2083 | } | 2087 | } |
| 2084 | 2088 | ||
| 2085 | 2089 | ||
| 2086 | static void sn9c102_vm_close(struct vm_area_struct* vma) | 2090 | static void sn9c102_vm_close(struct vm_area_struct *vma) |
| 2087 | { | 2091 | { |
| 2088 | /* NOTE: buffers are not freed here */ | 2092 | /* NOTE: buffers are not freed here */ |
| 2089 | struct sn9c102_frame_t* f = vma->vm_private_data; | 2093 | struct sn9c102_frame_t *f = vma->vm_private_data; |
| 2090 | f->vma_use_count--; | 2094 | f->vma_use_count--; |
| 2091 | } | 2095 | } |
| 2092 | 2096 | ||
| @@ -2097,7 +2101,7 @@ static const struct vm_operations_struct sn9c102_vm_ops = { | |||
| 2097 | }; | 2101 | }; |
| 2098 | 2102 | ||
| 2099 | 2103 | ||
| 2100 | static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) | 2104 | static int sn9c102_mmap(struct file *filp, struct vm_area_struct *vma) |
| 2101 | { | 2105 | { |
| 2102 | struct sn9c102_device *cam = video_drvdata(filp); | 2106 | struct sn9c102_device *cam = video_drvdata(filp); |
| 2103 | unsigned long size = vma->vm_end - vma->vm_start, | 2107 | unsigned long size = vma->vm_end - vma->vm_start, |
| @@ -2166,7 +2170,7 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) | |||
| 2166 | /*****************************************************************************/ | 2170 | /*****************************************************************************/ |
| 2167 | 2171 | ||
| 2168 | static int | 2172 | static int |
| 2169 | sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) | 2173 | sn9c102_vidioc_querycap(struct sn9c102_device *cam, void __user *arg) |
| 2170 | { | 2174 | { |
| 2171 | struct v4l2_capability cap = { | 2175 | struct v4l2_capability cap = { |
| 2172 | .driver = "sn9c102", | 2176 | .driver = "sn9c102", |
| @@ -2188,7 +2192,7 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) | |||
| 2188 | 2192 | ||
| 2189 | 2193 | ||
| 2190 | static int | 2194 | static int |
| 2191 | sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) | 2195 | sn9c102_vidioc_enuminput(struct sn9c102_device *cam, void __user *arg) |
| 2192 | { | 2196 | { |
| 2193 | struct v4l2_input i; | 2197 | struct v4l2_input i; |
| 2194 | 2198 | ||
| @@ -2211,7 +2215,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) | |||
| 2211 | 2215 | ||
| 2212 | 2216 | ||
| 2213 | static int | 2217 | static int |
| 2214 | sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg) | 2218 | sn9c102_vidioc_g_input(struct sn9c102_device *cam, void __user *arg) |
| 2215 | { | 2219 | { |
| 2216 | int index = 0; | 2220 | int index = 0; |
| 2217 | 2221 | ||
| @@ -2223,7 +2227,7 @@ sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg) | |||
| 2223 | 2227 | ||
| 2224 | 2228 | ||
| 2225 | static int | 2229 | static int |
| 2226 | sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg) | 2230 | sn9c102_vidioc_s_input(struct sn9c102_device *cam, void __user *arg) |
| 2227 | { | 2231 | { |
| 2228 | int index; | 2232 | int index; |
| 2229 | 2233 | ||
| @@ -2238,9 +2242,9 @@ sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg) | |||
| 2238 | 2242 | ||
| 2239 | 2243 | ||
| 2240 | static int | 2244 | static int |
| 2241 | sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg) | 2245 | sn9c102_vidioc_query_ctrl(struct sn9c102_device *cam, void __user *arg) |
| 2242 | { | 2246 | { |
| 2243 | struct sn9c102_sensor* s = &cam->sensor; | 2247 | struct sn9c102_sensor *s = &cam->sensor; |
| 2244 | struct v4l2_queryctrl qc; | 2248 | struct v4l2_queryctrl qc; |
| 2245 | u8 i; | 2249 | u8 i; |
| 2246 | 2250 | ||
| @@ -2260,9 +2264,9 @@ sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg) | |||
| 2260 | 2264 | ||
| 2261 | 2265 | ||
| 2262 | static int | 2266 | static int |
| 2263 | sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg) | 2267 | sn9c102_vidioc_g_ctrl(struct sn9c102_device *cam, void __user *arg) |
| 2264 | { | 2268 | { |
| 2265 | struct sn9c102_sensor* s = &cam->sensor; | 2269 | struct sn9c102_sensor *s = &cam->sensor; |
| 2266 | struct v4l2_control ctrl; | 2270 | struct v4l2_control ctrl; |
| 2267 | int err = 0; | 2271 | int err = 0; |
| 2268 | u8 i; | 2272 | u8 i; |
| @@ -2295,9 +2299,9 @@ exit: | |||
| 2295 | 2299 | ||
| 2296 | 2300 | ||
| 2297 | static int | 2301 | static int |
| 2298 | sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) | 2302 | sn9c102_vidioc_s_ctrl(struct sn9c102_device *cam, void __user *arg) |
| 2299 | { | 2303 | { |
| 2300 | struct sn9c102_sensor* s = &cam->sensor; | 2304 | struct sn9c102_sensor *s = &cam->sensor; |
| 2301 | struct v4l2_control ctrl; | 2305 | struct v4l2_control ctrl; |
| 2302 | u8 i; | 2306 | u8 i; |
| 2303 | int err = 0; | 2307 | int err = 0; |
| @@ -2335,9 +2339,9 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg) | |||
| 2335 | 2339 | ||
| 2336 | 2340 | ||
| 2337 | static int | 2341 | static int |
| 2338 | sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg) | 2342 | sn9c102_vidioc_cropcap(struct sn9c102_device *cam, void __user *arg) |
| 2339 | { | 2343 | { |
| 2340 | struct v4l2_cropcap* cc = &(cam->sensor.cropcap); | 2344 | struct v4l2_cropcap *cc = &(cam->sensor.cropcap); |
| 2341 | 2345 | ||
| 2342 | cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 2346 | cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 2343 | cc->pixelaspect.numerator = 1; | 2347 | cc->pixelaspect.numerator = 1; |
| @@ -2351,9 +2355,9 @@ sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg) | |||
| 2351 | 2355 | ||
| 2352 | 2356 | ||
| 2353 | static int | 2357 | static int |
| 2354 | sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg) | 2358 | sn9c102_vidioc_g_crop(struct sn9c102_device *cam, void __user *arg) |
| 2355 | { | 2359 | { |
| 2356 | struct sn9c102_sensor* s = &cam->sensor; | 2360 | struct sn9c102_sensor *s = &cam->sensor; |
| 2357 | struct v4l2_crop crop = { | 2361 | struct v4l2_crop crop = { |
| 2358 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, | 2362 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, |
| 2359 | }; | 2363 | }; |
| @@ -2368,13 +2372,13 @@ sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg) | |||
| 2368 | 2372 | ||
| 2369 | 2373 | ||
| 2370 | static int | 2374 | static int |
| 2371 | sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) | 2375 | sn9c102_vidioc_s_crop(struct sn9c102_device *cam, void __user *arg) |
| 2372 | { | 2376 | { |
| 2373 | struct sn9c102_sensor* s = &cam->sensor; | 2377 | struct sn9c102_sensor *s = &cam->sensor; |
| 2374 | struct v4l2_crop crop; | 2378 | struct v4l2_crop crop; |
| 2375 | struct v4l2_rect* rect; | 2379 | struct v4l2_rect *rect; |
| 2376 | struct v4l2_rect* bounds = &(s->cropcap.bounds); | 2380 | struct v4l2_rect *bounds = &(s->cropcap.bounds); |
| 2377 | struct v4l2_pix_format* pix_format = &(s->pix_format); | 2381 | struct v4l2_pix_format *pix_format = &(s->pix_format); |
| 2378 | u8 scale; | 2382 | u8 scale; |
| 2379 | const enum sn9c102_stream_state stream = cam->stream; | 2383 | const enum sn9c102_stream_state stream = cam->stream; |
| 2380 | const u32 nbuffers = cam->nbuffers; | 2384 | const u32 nbuffers = cam->nbuffers; |
| @@ -2482,7 +2486,7 @@ sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg) | |||
| 2482 | 2486 | ||
| 2483 | 2487 | ||
| 2484 | static int | 2488 | static int |
| 2485 | sn9c102_vidioc_enum_framesizes(struct sn9c102_device* cam, void __user * arg) | 2489 | sn9c102_vidioc_enum_framesizes(struct sn9c102_device *cam, void __user *arg) |
| 2486 | { | 2490 | { |
| 2487 | struct v4l2_frmsizeenum frmsize; | 2491 | struct v4l2_frmsizeenum frmsize; |
| 2488 | 2492 | ||
| @@ -2523,7 +2527,7 @@ sn9c102_vidioc_enum_framesizes(struct sn9c102_device* cam, void __user * arg) | |||
| 2523 | 2527 | ||
| 2524 | 2528 | ||
| 2525 | static int | 2529 | static int |
| 2526 | sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg) | 2530 | sn9c102_vidioc_enum_fmt(struct sn9c102_device *cam, void __user *arg) |
| 2527 | { | 2531 | { |
| 2528 | struct v4l2_fmtdesc fmtd; | 2532 | struct v4l2_fmtdesc fmtd; |
| 2529 | 2533 | ||
| @@ -2565,10 +2569,10 @@ sn9c102_vidioc_enum_fmt(struct sn9c102_device* cam, void __user * arg) | |||
| 2565 | 2569 | ||
| 2566 | 2570 | ||
| 2567 | static int | 2571 | static int |
| 2568 | sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) | 2572 | sn9c102_vidioc_g_fmt(struct sn9c102_device *cam, void __user *arg) |
| 2569 | { | 2573 | { |
| 2570 | struct v4l2_format format; | 2574 | struct v4l2_format format; |
| 2571 | struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format); | 2575 | struct v4l2_pix_format *pfmt = &(cam->sensor.pix_format); |
| 2572 | 2576 | ||
| 2573 | if (copy_from_user(&format, arg, sizeof(format))) | 2577 | if (copy_from_user(&format, arg, sizeof(format))) |
| 2574 | return -EFAULT; | 2578 | return -EFAULT; |
| @@ -2593,14 +2597,14 @@ sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg) | |||
| 2593 | 2597 | ||
| 2594 | 2598 | ||
| 2595 | static int | 2599 | static int |
| 2596 | sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | 2600 | sn9c102_vidioc_try_s_fmt(struct sn9c102_device *cam, unsigned int cmd, |
| 2597 | void __user * arg) | 2601 | void __user *arg) |
| 2598 | { | 2602 | { |
| 2599 | struct sn9c102_sensor* s = &cam->sensor; | 2603 | struct sn9c102_sensor *s = &cam->sensor; |
| 2600 | struct v4l2_format format; | 2604 | struct v4l2_format format; |
| 2601 | struct v4l2_pix_format* pix; | 2605 | struct v4l2_pix_format *pix; |
| 2602 | struct v4l2_pix_format* pfmt = &(s->pix_format); | 2606 | struct v4l2_pix_format *pfmt = &(s->pix_format); |
| 2603 | struct v4l2_rect* bounds = &(s->cropcap.bounds); | 2607 | struct v4l2_rect *bounds = &(s->cropcap.bounds); |
| 2604 | struct v4l2_rect rect; | 2608 | struct v4l2_rect rect; |
| 2605 | u8 scale; | 2609 | u8 scale; |
| 2606 | const enum sn9c102_stream_state stream = cam->stream; | 2610 | const enum sn9c102_stream_state stream = cam->stream; |
| @@ -2742,7 +2746,7 @@ sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd, | |||
| 2742 | 2746 | ||
| 2743 | 2747 | ||
| 2744 | static int | 2748 | static int |
| 2745 | sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg) | 2749 | sn9c102_vidioc_g_jpegcomp(struct sn9c102_device *cam, void __user *arg) |
| 2746 | { | 2750 | { |
| 2747 | if (copy_to_user(arg, &cam->compression, sizeof(cam->compression))) | 2751 | if (copy_to_user(arg, &cam->compression, sizeof(cam->compression))) |
| 2748 | return -EFAULT; | 2752 | return -EFAULT; |
| @@ -2752,7 +2756,7 @@ sn9c102_vidioc_g_jpegcomp(struct sn9c102_device* cam, void __user * arg) | |||
| 2752 | 2756 | ||
| 2753 | 2757 | ||
| 2754 | static int | 2758 | static int |
| 2755 | sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg) | 2759 | sn9c102_vidioc_s_jpegcomp(struct sn9c102_device *cam, void __user *arg) |
| 2756 | { | 2760 | { |
| 2757 | struct v4l2_jpegcompression jc; | 2761 | struct v4l2_jpegcompression jc; |
| 2758 | const enum sn9c102_stream_state stream = cam->stream; | 2762 | const enum sn9c102_stream_state stream = cam->stream; |
| @@ -2788,7 +2792,7 @@ sn9c102_vidioc_s_jpegcomp(struct sn9c102_device* cam, void __user * arg) | |||
| 2788 | 2792 | ||
| 2789 | 2793 | ||
| 2790 | static int | 2794 | static int |
| 2791 | sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg) | 2795 | sn9c102_vidioc_reqbufs(struct sn9c102_device *cam, void __user *arg) |
| 2792 | { | 2796 | { |
| 2793 | struct v4l2_requestbuffers rb; | 2797 | struct v4l2_requestbuffers rb; |
| 2794 | u32 i; | 2798 | u32 i; |
| @@ -2839,7 +2843,7 @@ sn9c102_vidioc_reqbufs(struct sn9c102_device* cam, void __user * arg) | |||
| 2839 | 2843 | ||
| 2840 | 2844 | ||
| 2841 | static int | 2845 | static int |
| 2842 | sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg) | 2846 | sn9c102_vidioc_querybuf(struct sn9c102_device *cam, void __user *arg) |
| 2843 | { | 2847 | { |
| 2844 | struct v4l2_buffer b; | 2848 | struct v4l2_buffer b; |
| 2845 | 2849 | ||
| @@ -2868,7 +2872,7 @@ sn9c102_vidioc_querybuf(struct sn9c102_device* cam, void __user * arg) | |||
| 2868 | 2872 | ||
| 2869 | 2873 | ||
| 2870 | static int | 2874 | static int |
| 2871 | sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg) | 2875 | sn9c102_vidioc_qbuf(struct sn9c102_device *cam, void __user *arg) |
| 2872 | { | 2876 | { |
| 2873 | struct v4l2_buffer b; | 2877 | struct v4l2_buffer b; |
| 2874 | unsigned long lock_flags; | 2878 | unsigned long lock_flags; |
| @@ -2896,8 +2900,8 @@ sn9c102_vidioc_qbuf(struct sn9c102_device* cam, void __user * arg) | |||
| 2896 | 2900 | ||
| 2897 | 2901 | ||
| 2898 | static int | 2902 | static int |
| 2899 | sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, | 2903 | sn9c102_vidioc_dqbuf(struct sn9c102_device *cam, struct file *filp, |
| 2900 | void __user * arg) | 2904 | void __user *arg) |
| 2901 | { | 2905 | { |
| 2902 | struct v4l2_buffer b; | 2906 | struct v4l2_buffer b; |
| 2903 | struct sn9c102_frame_t *f; | 2907 | struct sn9c102_frame_t *f; |
| @@ -2918,20 +2922,20 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, | |||
| 2918 | return -EAGAIN; | 2922 | return -EAGAIN; |
| 2919 | if (!cam->module_param.frame_timeout) { | 2923 | if (!cam->module_param.frame_timeout) { |
| 2920 | err = wait_event_interruptible | 2924 | err = wait_event_interruptible |
| 2921 | ( cam->wait_frame, | 2925 | (cam->wait_frame, |
| 2922 | (!list_empty(&cam->outqueue)) || | 2926 | (!list_empty(&cam->outqueue)) || |
| 2923 | (cam->state & DEV_DISCONNECTED) || | 2927 | (cam->state & DEV_DISCONNECTED) || |
| 2924 | (cam->state & DEV_MISCONFIGURED) ); | 2928 | (cam->state & DEV_MISCONFIGURED)); |
| 2925 | if (err) | 2929 | if (err) |
| 2926 | return err; | 2930 | return err; |
| 2927 | } else { | 2931 | } else { |
| 2928 | timeout = wait_event_interruptible_timeout | 2932 | timeout = wait_event_interruptible_timeout |
| 2929 | ( cam->wait_frame, | 2933 | (cam->wait_frame, |
| 2930 | (!list_empty(&cam->outqueue)) || | 2934 | (!list_empty(&cam->outqueue)) || |
| 2931 | (cam->state & DEV_DISCONNECTED) || | 2935 | (cam->state & DEV_DISCONNECTED) || |
| 2932 | (cam->state & DEV_MISCONFIGURED), | 2936 | (cam->state & DEV_MISCONFIGURED), |
| 2933 | cam->module_param.frame_timeout * | 2937 | cam->module_param.frame_timeout * |
| 2934 | 1000 * msecs_to_jiffies(1) ); | 2938 | 1000 * msecs_to_jiffies(1)); |
| 2935 | if (timeout < 0) | 2939 | if (timeout < 0) |
| 2936 | return timeout; | 2940 | return timeout; |
| 2937 | else if (timeout == 0 && | 2941 | else if (timeout == 0 && |
| @@ -2967,7 +2971,7 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp, | |||
| 2967 | 2971 | ||
| 2968 | 2972 | ||
| 2969 | static int | 2973 | static int |
| 2970 | sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg) | 2974 | sn9c102_vidioc_streamon(struct sn9c102_device *cam, void __user *arg) |
| 2971 | { | 2975 | { |
| 2972 | int type; | 2976 | int type; |
| 2973 | 2977 | ||
| @@ -2986,7 +2990,7 @@ sn9c102_vidioc_streamon(struct sn9c102_device* cam, void __user * arg) | |||
| 2986 | 2990 | ||
| 2987 | 2991 | ||
| 2988 | static int | 2992 | static int |
| 2989 | sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg) | 2993 | sn9c102_vidioc_streamoff(struct sn9c102_device *cam, void __user *arg) |
| 2990 | { | 2994 | { |
| 2991 | int type, err; | 2995 | int type, err; |
| 2992 | 2996 | ||
| @@ -3011,7 +3015,7 @@ sn9c102_vidioc_streamoff(struct sn9c102_device* cam, void __user * arg) | |||
| 3011 | 3015 | ||
| 3012 | 3016 | ||
| 3013 | static int | 3017 | static int |
| 3014 | sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg) | 3018 | sn9c102_vidioc_g_parm(struct sn9c102_device *cam, void __user *arg) |
| 3015 | { | 3019 | { |
| 3016 | struct v4l2_streamparm sp; | 3020 | struct v4l2_streamparm sp; |
| 3017 | 3021 | ||
| @@ -3032,7 +3036,7 @@ sn9c102_vidioc_g_parm(struct sn9c102_device* cam, void __user * arg) | |||
| 3032 | 3036 | ||
| 3033 | 3037 | ||
| 3034 | static int | 3038 | static int |
| 3035 | sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg) | 3039 | sn9c102_vidioc_s_parm(struct sn9c102_device *cam, void __user *arg) |
| 3036 | { | 3040 | { |
| 3037 | struct v4l2_streamparm sp; | 3041 | struct v4l2_streamparm sp; |
| 3038 | 3042 | ||
| @@ -3060,7 +3064,7 @@ sn9c102_vidioc_s_parm(struct sn9c102_device* cam, void __user * arg) | |||
| 3060 | 3064 | ||
| 3061 | 3065 | ||
| 3062 | static int | 3066 | static int |
| 3063 | sn9c102_vidioc_enumaudio(struct sn9c102_device* cam, void __user * arg) | 3067 | sn9c102_vidioc_enumaudio(struct sn9c102_device *cam, void __user *arg) |
| 3064 | { | 3068 | { |
| 3065 | struct v4l2_audio audio; | 3069 | struct v4l2_audio audio; |
| 3066 | 3070 | ||
| @@ -3085,7 +3089,7 @@ sn9c102_vidioc_enumaudio(struct sn9c102_device* cam, void __user * arg) | |||
| 3085 | 3089 | ||
| 3086 | 3090 | ||
| 3087 | static int | 3091 | static int |
| 3088 | sn9c102_vidioc_g_audio(struct sn9c102_device* cam, void __user * arg) | 3092 | sn9c102_vidioc_g_audio(struct sn9c102_device *cam, void __user *arg) |
| 3089 | { | 3093 | { |
| 3090 | struct v4l2_audio audio; | 3094 | struct v4l2_audio audio; |
| 3091 | 3095 | ||
| @@ -3106,7 +3110,7 @@ sn9c102_vidioc_g_audio(struct sn9c102_device* cam, void __user * arg) | |||
| 3106 | 3110 | ||
| 3107 | 3111 | ||
| 3108 | static int | 3112 | static int |
| 3109 | sn9c102_vidioc_s_audio(struct sn9c102_device* cam, void __user * arg) | 3113 | sn9c102_vidioc_s_audio(struct sn9c102_device *cam, void __user *arg) |
| 3110 | { | 3114 | { |
| 3111 | struct v4l2_audio audio; | 3115 | struct v4l2_audio audio; |
| 3112 | 3116 | ||
| @@ -3266,10 +3270,10 @@ static const struct v4l2_file_operations sn9c102_fops = { | |||
| 3266 | 3270 | ||
| 3267 | /* It exists a single interface only. We do not need to validate anything. */ | 3271 | /* It exists a single interface only. We do not need to validate anything. */ |
| 3268 | static int | 3272 | static int |
| 3269 | sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | 3273 | sn9c102_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| 3270 | { | 3274 | { |
| 3271 | struct usb_device *udev = interface_to_usbdev(intf); | 3275 | struct usb_device *udev = interface_to_usbdev(intf); |
| 3272 | struct sn9c102_device* cam; | 3276 | struct sn9c102_device *cam; |
| 3273 | static unsigned int dev_nr; | 3277 | static unsigned int dev_nr; |
| 3274 | unsigned int i; | 3278 | unsigned int i; |
| 3275 | int err = 0, r; | 3279 | int err = 0, r; |
| @@ -3419,9 +3423,9 @@ fail: | |||
| 3419 | } | 3423 | } |
| 3420 | 3424 | ||
| 3421 | 3425 | ||
| 3422 | static void sn9c102_usb_disconnect(struct usb_interface* intf) | 3426 | static void sn9c102_usb_disconnect(struct usb_interface *intf) |
| 3423 | { | 3427 | { |
| 3424 | struct sn9c102_device* cam; | 3428 | struct sn9c102_device *cam; |
| 3425 | 3429 | ||
| 3426 | down_write(&sn9c102_dev_lock); | 3430 | down_write(&sn9c102_dev_lock); |
| 3427 | 3431 | ||
diff --git a/drivers/staging/media/sn9c102/sn9c102_devtable.h b/drivers/staging/media/sn9c102/sn9c102_devtable.h index 4ba569258498..b187a8a304eb 100644 --- a/drivers/staging/media/sn9c102/sn9c102_devtable.h +++ b/drivers/staging/media/sn9c102/sn9c102_devtable.h | |||
| @@ -129,17 +129,17 @@ static const struct usb_device_id sn9c102_id_table[] = { | |||
| 129 | initialization of the SN9C1XX chip. | 129 | initialization of the SN9C1XX chip. |
| 130 | Functions must return 0 on success, the appropriate error otherwise. | 130 | Functions must return 0 on success, the appropriate error otherwise. |
| 131 | */ | 131 | */ |
| 132 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); | 132 | extern int sn9c102_probe_hv7131d(struct sn9c102_device *cam); |
| 133 | extern int sn9c102_probe_hv7131r(struct sn9c102_device* cam); | 133 | extern int sn9c102_probe_hv7131r(struct sn9c102_device *cam); |
| 134 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); | 134 | extern int sn9c102_probe_mi0343(struct sn9c102_device *cam); |
| 135 | extern int sn9c102_probe_mi0360(struct sn9c102_device* cam); | 135 | extern int sn9c102_probe_mi0360(struct sn9c102_device *cam); |
| 136 | extern int sn9c102_probe_mt9v111(struct sn9c102_device *cam); | 136 | extern int sn9c102_probe_mt9v111(struct sn9c102_device *cam); |
| 137 | extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); | 137 | extern int sn9c102_probe_ov7630(struct sn9c102_device *cam); |
| 138 | extern int sn9c102_probe_ov7660(struct sn9c102_device* cam); | 138 | extern int sn9c102_probe_ov7660(struct sn9c102_device *cam); |
| 139 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); | 139 | extern int sn9c102_probe_pas106b(struct sn9c102_device *cam); |
| 140 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); | 140 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device *cam); |
| 141 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); | 141 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device *cam); |
| 142 | extern int sn9c102_probe_tas5110d(struct sn9c102_device* cam); | 142 | extern int sn9c102_probe_tas5110d(struct sn9c102_device *cam); |
| 143 | extern int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam); | 143 | extern int sn9c102_probe_tas5130d1b(struct sn9c102_device *cam); |
| 144 | 144 | ||
| 145 | #endif /* _SN9C102_DEVTABLE_H_ */ | 145 | #endif /* _SN9C102_DEVTABLE_H_ */ |
diff --git a/drivers/staging/media/sn9c102/sn9c102_hv7131d.c b/drivers/staging/media/sn9c102/sn9c102_hv7131d.c index 468072176527..f1d94f0190c6 100644 --- a/drivers/staging/media/sn9c102/sn9c102_hv7131d.c +++ b/drivers/staging/media/sn9c102/sn9c102_hv7131d.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int hv7131d_init(struct sn9c102_device* cam) | 26 | static int hv7131d_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err; | 28 | int err; |
| 29 | 29 | ||
| @@ -39,8 +39,8 @@ static int hv7131d_init(struct sn9c102_device* cam) | |||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | static int hv7131d_get_ctrl(struct sn9c102_device* cam, | 42 | static int hv7131d_get_ctrl(struct sn9c102_device *cam, |
| 43 | struct v4l2_control* ctrl) | 43 | struct v4l2_control *ctrl) |
| 44 | { | 44 | { |
| 45 | switch (ctrl->id) { | 45 | switch (ctrl->id) { |
| 46 | case V4L2_CID_EXPOSURE: | 46 | case V4L2_CID_EXPOSURE: |
| @@ -88,8 +88,8 @@ static int hv7131d_get_ctrl(struct sn9c102_device* cam, | |||
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | 90 | ||
| 91 | static int hv7131d_set_ctrl(struct sn9c102_device* cam, | 91 | static int hv7131d_set_ctrl(struct sn9c102_device *cam, |
| 92 | const struct v4l2_control* ctrl) | 92 | const struct v4l2_control *ctrl) |
| 93 | { | 93 | { |
| 94 | int err = 0; | 94 | int err = 0; |
| 95 | 95 | ||
| @@ -121,10 +121,10 @@ static int hv7131d_set_ctrl(struct sn9c102_device* cam, | |||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | 123 | ||
| 124 | static int hv7131d_set_crop(struct sn9c102_device* cam, | 124 | static int hv7131d_set_crop(struct sn9c102_device *cam, |
| 125 | const struct v4l2_rect* rect) | 125 | const struct v4l2_rect *rect) |
| 126 | { | 126 | { |
| 127 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 127 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 128 | int err = 0; | 128 | int err = 0; |
| 129 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2, | 129 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 2, |
| 130 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2; | 130 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2; |
| @@ -136,8 +136,8 @@ static int hv7131d_set_crop(struct sn9c102_device* cam, | |||
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | 138 | ||
| 139 | static int hv7131d_set_pix_format(struct sn9c102_device* cam, | 139 | static int hv7131d_set_pix_format(struct sn9c102_device *cam, |
| 140 | const struct v4l2_pix_format* pix) | 140 | const struct v4l2_pix_format *pix) |
| 141 | { | 141 | { |
| 142 | int err = 0; | 142 | int err = 0; |
| 143 | 143 | ||
| @@ -248,7 +248,7 @@ static const struct sn9c102_sensor hv7131d = { | |||
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | 250 | ||
| 251 | int sn9c102_probe_hv7131d(struct sn9c102_device* cam) | 251 | int sn9c102_probe_hv7131d(struct sn9c102_device *cam) |
| 252 | { | 252 | { |
| 253 | int r0 = 0, r1 = 0, err; | 253 | int r0 = 0, r1 = 0, err; |
| 254 | 254 | ||
diff --git a/drivers/staging/media/sn9c102/sn9c102_hv7131r.c b/drivers/staging/media/sn9c102/sn9c102_hv7131r.c index 26a91115b831..51b24e000e88 100644 --- a/drivers/staging/media/sn9c102/sn9c102_hv7131r.c +++ b/drivers/staging/media/sn9c102/sn9c102_hv7131r.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int hv7131r_init(struct sn9c102_device* cam) | 26 | static int hv7131r_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err = 0; | 28 | int err = 0; |
| 29 | 29 | ||
| @@ -137,8 +137,8 @@ static int hv7131r_init(struct sn9c102_device* cam) | |||
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | 139 | ||
| 140 | static int hv7131r_get_ctrl(struct sn9c102_device* cam, | 140 | static int hv7131r_get_ctrl(struct sn9c102_device *cam, |
| 141 | struct v4l2_control* ctrl) | 141 | struct v4l2_control *ctrl) |
| 142 | { | 142 | { |
| 143 | switch (ctrl->id) { | 143 | switch (ctrl->id) { |
| 144 | case V4L2_CID_GAIN: | 144 | case V4L2_CID_GAIN: |
| @@ -176,8 +176,8 @@ static int hv7131r_get_ctrl(struct sn9c102_device* cam, | |||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | 178 | ||
| 179 | static int hv7131r_set_ctrl(struct sn9c102_device* cam, | 179 | static int hv7131r_set_ctrl(struct sn9c102_device *cam, |
| 180 | const struct v4l2_control* ctrl) | 180 | const struct v4l2_control *ctrl) |
| 181 | { | 181 | { |
| 182 | int err = 0; | 182 | int err = 0; |
| 183 | 183 | ||
| @@ -197,6 +197,7 @@ static int hv7131r_set_ctrl(struct sn9c102_device* cam, | |||
| 197 | case V4L2_CID_BLACK_LEVEL: | 197 | case V4L2_CID_BLACK_LEVEL: |
| 198 | { | 198 | { |
| 199 | int r = sn9c102_i2c_read(cam, 0x01); | 199 | int r = sn9c102_i2c_read(cam, 0x01); |
| 200 | |||
| 200 | if (r < 0) | 201 | if (r < 0) |
| 201 | return -EIO; | 202 | return -EIO; |
| 202 | err += sn9c102_i2c_write(cam, 0x01, | 203 | err += sn9c102_i2c_write(cam, 0x01, |
| @@ -211,10 +212,10 @@ static int hv7131r_set_ctrl(struct sn9c102_device* cam, | |||
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | 214 | ||
| 214 | static int hv7131r_set_crop(struct sn9c102_device* cam, | 215 | static int hv7131r_set_crop(struct sn9c102_device *cam, |
| 215 | const struct v4l2_rect* rect) | 216 | const struct v4l2_rect *rect) |
| 216 | { | 217 | { |
| 217 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 218 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 218 | int err = 0; | 219 | int err = 0; |
| 219 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, | 220 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, |
| 220 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | 221 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; |
| @@ -226,8 +227,8 @@ static int hv7131r_set_crop(struct sn9c102_device* cam, | |||
| 226 | } | 227 | } |
| 227 | 228 | ||
| 228 | 229 | ||
| 229 | static int hv7131r_set_pix_format(struct sn9c102_device* cam, | 230 | static int hv7131r_set_pix_format(struct sn9c102_device *cam, |
| 230 | const struct v4l2_pix_format* pix) | 231 | const struct v4l2_pix_format *pix) |
| 231 | { | 232 | { |
| 232 | int err = 0; | 233 | int err = 0; |
| 233 | 234 | ||
| @@ -347,7 +348,7 @@ static const struct sn9c102_sensor hv7131r = { | |||
| 347 | }; | 348 | }; |
| 348 | 349 | ||
| 349 | 350 | ||
| 350 | int sn9c102_probe_hv7131r(struct sn9c102_device* cam) | 351 | int sn9c102_probe_hv7131r(struct sn9c102_device *cam) |
| 351 | { | 352 | { |
| 352 | int devid, err; | 353 | int devid, err; |
| 353 | 354 | ||
diff --git a/drivers/staging/media/sn9c102/sn9c102_mi0343.c b/drivers/staging/media/sn9c102/sn9c102_mi0343.c index 1f5b09bec89c..b20fdb6541d3 100644 --- a/drivers/staging/media/sn9c102/sn9c102_mi0343.c +++ b/drivers/staging/media/sn9c102/sn9c102_mi0343.c | |||
| @@ -23,9 +23,9 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int mi0343_init(struct sn9c102_device* cam) | 26 | static int mi0343_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 28 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 29 | int err = 0; | 29 | int err = 0; |
| 30 | 30 | ||
| 31 | err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, | 31 | err = sn9c102_write_const_regs(cam, {0x00, 0x10}, {0x00, 0x11}, |
| @@ -52,10 +52,10 @@ static int mi0343_init(struct sn9c102_device* cam) | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | static int mi0343_get_ctrl(struct sn9c102_device* cam, | 55 | static int mi0343_get_ctrl(struct sn9c102_device *cam, |
| 56 | struct v4l2_control* ctrl) | 56 | struct v4l2_control *ctrl) |
| 57 | { | 57 | { |
| 58 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 58 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 59 | u8 data[2]; | 59 | u8 data[2]; |
| 60 | 60 | ||
| 61 | switch (ctrl->id) { | 61 | switch (ctrl->id) { |
| @@ -119,10 +119,10 @@ static int mi0343_get_ctrl(struct sn9c102_device* cam, | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | 121 | ||
| 122 | static int mi0343_set_ctrl(struct sn9c102_device* cam, | 122 | static int mi0343_set_ctrl(struct sn9c102_device *cam, |
| 123 | const struct v4l2_control* ctrl) | 123 | const struct v4l2_control *ctrl) |
| 124 | { | 124 | { |
| 125 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 125 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 126 | u16 reg = 0; | 126 | u16 reg = 0; |
| 127 | int err = 0; | 127 | int err = 0; |
| 128 | 128 | ||
| @@ -189,10 +189,10 @@ static int mi0343_set_ctrl(struct sn9c102_device* cam, | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | 191 | ||
| 192 | static int mi0343_set_crop(struct sn9c102_device* cam, | 192 | static int mi0343_set_crop(struct sn9c102_device *cam, |
| 193 | const struct v4l2_rect* rect) | 193 | const struct v4l2_rect *rect) |
| 194 | { | 194 | { |
| 195 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 195 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 196 | int err = 0; | 196 | int err = 0; |
| 197 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0, | 197 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 0, |
| 198 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2; | 198 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 2; |
| @@ -204,10 +204,10 @@ static int mi0343_set_crop(struct sn9c102_device* cam, | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | 206 | ||
| 207 | static int mi0343_set_pix_format(struct sn9c102_device* cam, | 207 | static int mi0343_set_pix_format(struct sn9c102_device *cam, |
| 208 | const struct v4l2_pix_format* pix) | 208 | const struct v4l2_pix_format *pix) |
| 209 | { | 209 | { |
| 210 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 210 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 211 | int err = 0; | 211 | int err = 0; |
| 212 | 212 | ||
| 213 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { | 213 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) { |
| @@ -331,7 +331,7 @@ static const struct sn9c102_sensor mi0343 = { | |||
| 331 | }; | 331 | }; |
| 332 | 332 | ||
| 333 | 333 | ||
| 334 | int sn9c102_probe_mi0343(struct sn9c102_device* cam) | 334 | int sn9c102_probe_mi0343(struct sn9c102_device *cam) |
| 335 | { | 335 | { |
| 336 | u8 data[2]; | 336 | u8 data[2]; |
| 337 | 337 | ||
diff --git a/drivers/staging/media/sn9c102/sn9c102_mi0360.c b/drivers/staging/media/sn9c102/sn9c102_mi0360.c index d973fc1973d9..5f21d1b43e32 100644 --- a/drivers/staging/media/sn9c102/sn9c102_mi0360.c +++ b/drivers/staging/media/sn9c102/sn9c102_mi0360.c | |||
| @@ -23,9 +23,9 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int mi0360_init(struct sn9c102_device* cam) | 26 | static int mi0360_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 28 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 29 | int err = 0; | 29 | int err = 0; |
| 30 | 30 | ||
| 31 | switch (sn9c102_get_bridge(cam)) { | 31 | switch (sn9c102_get_bridge(cam)) { |
| @@ -147,10 +147,10 @@ static int mi0360_init(struct sn9c102_device* cam) | |||
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | 149 | ||
| 150 | static int mi0360_get_ctrl(struct sn9c102_device* cam, | 150 | static int mi0360_get_ctrl(struct sn9c102_device *cam, |
| 151 | struct v4l2_control* ctrl) | 151 | struct v4l2_control *ctrl) |
| 152 | { | 152 | { |
| 153 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 153 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 154 | u8 data[2]; | 154 | u8 data[2]; |
| 155 | 155 | ||
| 156 | switch (ctrl->id) { | 156 | switch (ctrl->id) { |
| @@ -204,10 +204,10 @@ static int mi0360_get_ctrl(struct sn9c102_device* cam, | |||
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | 206 | ||
| 207 | static int mi0360_set_ctrl(struct sn9c102_device* cam, | 207 | static int mi0360_set_ctrl(struct sn9c102_device *cam, |
| 208 | const struct v4l2_control* ctrl) | 208 | const struct v4l2_control *ctrl) |
| 209 | { | 209 | { |
| 210 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 210 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 211 | int err = 0; | 211 | int err = 0; |
| 212 | 212 | ||
| 213 | switch (ctrl->id) { | 213 | switch (ctrl->id) { |
| @@ -259,10 +259,10 @@ static int mi0360_set_ctrl(struct sn9c102_device* cam, | |||
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | 261 | ||
| 262 | static int mi0360_set_crop(struct sn9c102_device* cam, | 262 | static int mi0360_set_crop(struct sn9c102_device *cam, |
| 263 | const struct v4l2_rect* rect) | 263 | const struct v4l2_rect *rect) |
| 264 | { | 264 | { |
| 265 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 265 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 266 | int err = 0; | 266 | int err = 0; |
| 267 | u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | 267 | u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; |
| 268 | 268 | ||
| @@ -285,10 +285,10 @@ static int mi0360_set_crop(struct sn9c102_device* cam, | |||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | 287 | ||
| 288 | static int mi0360_set_pix_format(struct sn9c102_device* cam, | 288 | static int mi0360_set_pix_format(struct sn9c102_device *cam, |
| 289 | const struct v4l2_pix_format* pix) | 289 | const struct v4l2_pix_format *pix) |
| 290 | { | 290 | { |
| 291 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 291 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 292 | int err = 0; | 292 | int err = 0; |
| 293 | 293 | ||
| 294 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { | 294 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { |
| @@ -418,7 +418,7 @@ static const struct sn9c102_sensor mi0360 = { | |||
| 418 | }; | 418 | }; |
| 419 | 419 | ||
| 420 | 420 | ||
| 421 | int sn9c102_probe_mi0360(struct sn9c102_device* cam) | 421 | int sn9c102_probe_mi0360(struct sn9c102_device *cam) |
| 422 | { | 422 | { |
| 423 | 423 | ||
| 424 | u8 data[2]; | 424 | u8 data[2]; |
diff --git a/drivers/staging/media/sn9c102/sn9c102_ov7630.c b/drivers/staging/media/sn9c102/sn9c102_ov7630.c index d3a1bd8d5648..9ec304dc4705 100644 --- a/drivers/staging/media/sn9c102/sn9c102_ov7630.c +++ b/drivers/staging/media/sn9c102/sn9c102_ov7630.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int ov7630_init(struct sn9c102_device* cam) | 26 | static int ov7630_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err = 0; | 28 | int err = 0; |
| 29 | 29 | ||
| @@ -252,8 +252,8 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | 254 | ||
| 255 | static int ov7630_get_ctrl(struct sn9c102_device* cam, | 255 | static int ov7630_get_ctrl(struct sn9c102_device *cam, |
| 256 | struct v4l2_control* ctrl) | 256 | struct v4l2_control *ctrl) |
| 257 | { | 257 | { |
| 258 | enum sn9c102_bridge bridge = sn9c102_get_bridge(cam); | 258 | enum sn9c102_bridge bridge = sn9c102_get_bridge(cam); |
| 259 | int err = 0; | 259 | int err = 0; |
| @@ -330,8 +330,8 @@ static int ov7630_get_ctrl(struct sn9c102_device* cam, | |||
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | 332 | ||
| 333 | static int ov7630_set_ctrl(struct sn9c102_device* cam, | 333 | static int ov7630_set_ctrl(struct sn9c102_device *cam, |
| 334 | const struct v4l2_control* ctrl) | 334 | const struct v4l2_control *ctrl) |
| 335 | { | 335 | { |
| 336 | enum sn9c102_bridge bridge = sn9c102_get_bridge(cam); | 336 | enum sn9c102_bridge bridge = sn9c102_get_bridge(cam); |
| 337 | int err = 0; | 337 | int err = 0; |
| @@ -385,10 +385,10 @@ static int ov7630_set_ctrl(struct sn9c102_device* cam, | |||
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | 387 | ||
| 388 | static int ov7630_set_crop(struct sn9c102_device* cam, | 388 | static int ov7630_set_crop(struct sn9c102_device *cam, |
| 389 | const struct v4l2_rect* rect) | 389 | const struct v4l2_rect *rect) |
| 390 | { | 390 | { |
| 391 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 391 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 392 | int err = 0; | 392 | int err = 0; |
| 393 | u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | 393 | u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; |
| 394 | 394 | ||
| @@ -413,8 +413,8 @@ static int ov7630_set_crop(struct sn9c102_device* cam, | |||
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | 415 | ||
| 416 | static int ov7630_set_pix_format(struct sn9c102_device* cam, | 416 | static int ov7630_set_pix_format(struct sn9c102_device *cam, |
| 417 | const struct v4l2_pix_format* pix) | 417 | const struct v4l2_pix_format *pix) |
| 418 | { | 418 | { |
| 419 | int err = 0; | 419 | int err = 0; |
| 420 | 420 | ||
| @@ -594,7 +594,7 @@ static const struct sn9c102_sensor ov7630 = { | |||
| 594 | }; | 594 | }; |
| 595 | 595 | ||
| 596 | 596 | ||
| 597 | int sn9c102_probe_ov7630(struct sn9c102_device* cam) | 597 | int sn9c102_probe_ov7630(struct sn9c102_device *cam) |
| 598 | { | 598 | { |
| 599 | int pid, ver, err = 0; | 599 | int pid, ver, err = 0; |
| 600 | 600 | ||
diff --git a/drivers/staging/media/sn9c102/sn9c102_ov7660.c b/drivers/staging/media/sn9c102/sn9c102_ov7660.c index 530157a234e6..ac07805d122e 100644 --- a/drivers/staging/media/sn9c102/sn9c102_ov7660.c +++ b/drivers/staging/media/sn9c102/sn9c102_ov7660.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int ov7660_init(struct sn9c102_device* cam) | 26 | static int ov7660_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err = 0; | 28 | int err = 0; |
| 29 | 29 | ||
| @@ -271,8 +271,8 @@ static int ov7660_init(struct sn9c102_device* cam) | |||
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | 273 | ||
| 274 | static int ov7660_get_ctrl(struct sn9c102_device* cam, | 274 | static int ov7660_get_ctrl(struct sn9c102_device *cam, |
| 275 | struct v4l2_control* ctrl) | 275 | struct v4l2_control *ctrl) |
| 276 | { | 276 | { |
| 277 | int err = 0; | 277 | int err = 0; |
| 278 | 278 | ||
| @@ -332,8 +332,8 @@ static int ov7660_get_ctrl(struct sn9c102_device* cam, | |||
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | 334 | ||
| 335 | static int ov7660_set_ctrl(struct sn9c102_device* cam, | 335 | static int ov7660_set_ctrl(struct sn9c102_device *cam, |
| 336 | const struct v4l2_control* ctrl) | 336 | const struct v4l2_control *ctrl) |
| 337 | { | 337 | { |
| 338 | int err = 0; | 338 | int err = 0; |
| 339 | 339 | ||
| @@ -371,10 +371,10 @@ static int ov7660_set_ctrl(struct sn9c102_device* cam, | |||
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | 373 | ||
| 374 | static int ov7660_set_crop(struct sn9c102_device* cam, | 374 | static int ov7660_set_crop(struct sn9c102_device *cam, |
| 375 | const struct v4l2_rect* rect) | 375 | const struct v4l2_rect *rect) |
| 376 | { | 376 | { |
| 377 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 377 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 378 | int err = 0; | 378 | int err = 0; |
| 379 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, | 379 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, |
| 380 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | 380 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; |
| @@ -386,8 +386,8 @@ static int ov7660_set_crop(struct sn9c102_device* cam, | |||
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | 388 | ||
| 389 | static int ov7660_set_pix_format(struct sn9c102_device* cam, | 389 | static int ov7660_set_pix_format(struct sn9c102_device *cam, |
| 390 | const struct v4l2_pix_format* pix) | 390 | const struct v4l2_pix_format *pix) |
| 391 | { | 391 | { |
| 392 | int r0, err = 0; | 392 | int r0, err = 0; |
| 393 | 393 | ||
| @@ -525,7 +525,7 @@ static const struct sn9c102_sensor ov7660 = { | |||
| 525 | }; | 525 | }; |
| 526 | 526 | ||
| 527 | 527 | ||
| 528 | int sn9c102_probe_ov7660(struct sn9c102_device* cam) | 528 | int sn9c102_probe_ov7660(struct sn9c102_device *cam) |
| 529 | { | 529 | { |
| 530 | int pid, ver, err; | 530 | int pid, ver, err; |
| 531 | 531 | ||
diff --git a/drivers/staging/media/sn9c102/sn9c102_pas106b.c b/drivers/staging/media/sn9c102/sn9c102_pas106b.c index 47bd82de80f9..895931ecac48 100644 --- a/drivers/staging/media/sn9c102/sn9c102_pas106b.c +++ b/drivers/staging/media/sn9c102/sn9c102_pas106b.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include "sn9c102_devtable.h" | 24 | #include "sn9c102_devtable.h" |
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | static int pas106b_init(struct sn9c102_device* cam) | 27 | static int pas106b_init(struct sn9c102_device *cam) |
| 28 | { | 28 | { |
| 29 | int err = 0; | 29 | int err = 0; |
| 30 | 30 | ||
| @@ -48,8 +48,8 @@ static int pas106b_init(struct sn9c102_device* cam) | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | static int pas106b_get_ctrl(struct sn9c102_device* cam, | 51 | static int pas106b_get_ctrl(struct sn9c102_device *cam, |
| 52 | struct v4l2_control* ctrl) | 52 | struct v4l2_control *ctrl) |
| 53 | { | 53 | { |
| 54 | switch (ctrl->id) { | 54 | switch (ctrl->id) { |
| 55 | case V4L2_CID_EXPOSURE: | 55 | case V4L2_CID_EXPOSURE: |
| @@ -103,8 +103,8 @@ static int pas106b_get_ctrl(struct sn9c102_device* cam, | |||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | 105 | ||
| 106 | static int pas106b_set_ctrl(struct sn9c102_device* cam, | 106 | static int pas106b_set_ctrl(struct sn9c102_device *cam, |
| 107 | const struct v4l2_control* ctrl) | 107 | const struct v4l2_control *ctrl) |
| 108 | { | 108 | { |
| 109 | int err = 0; | 109 | int err = 0; |
| 110 | 110 | ||
| @@ -141,10 +141,10 @@ static int pas106b_set_ctrl(struct sn9c102_device* cam, | |||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | 143 | ||
| 144 | static int pas106b_set_crop(struct sn9c102_device* cam, | 144 | static int pas106b_set_crop(struct sn9c102_device *cam, |
| 145 | const struct v4l2_rect* rect) | 145 | const struct v4l2_rect *rect) |
| 146 | { | 146 | { |
| 147 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 147 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 148 | int err = 0; | 148 | int err = 0; |
| 149 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4, | 149 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4, |
| 150 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; | 150 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; |
| @@ -156,8 +156,8 @@ static int pas106b_set_crop(struct sn9c102_device* cam, | |||
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | 158 | ||
| 159 | static int pas106b_set_pix_format(struct sn9c102_device* cam, | 159 | static int pas106b_set_pix_format(struct sn9c102_device *cam, |
| 160 | const struct v4l2_pix_format* pix) | 160 | const struct v4l2_pix_format *pix) |
| 161 | { | 161 | { |
| 162 | int err = 0; | 162 | int err = 0; |
| 163 | 163 | ||
| @@ -278,7 +278,7 @@ static const struct sn9c102_sensor pas106b = { | |||
| 278 | }; | 278 | }; |
| 279 | 279 | ||
| 280 | 280 | ||
| 281 | int sn9c102_probe_pas106b(struct sn9c102_device* cam) | 281 | int sn9c102_probe_pas106b(struct sn9c102_device *cam) |
| 282 | { | 282 | { |
| 283 | int r0 = 0, r1 = 0; | 283 | int r0 = 0, r1 = 0; |
| 284 | unsigned int pid = 0; | 284 | unsigned int pid = 0; |
diff --git a/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c b/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c index cbfacc2dad84..f9e31ae2ad9f 100644 --- a/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c +++ b/drivers/staging/media/sn9c102/sn9c102_pas202bcb.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include "sn9c102_devtable.h" | 28 | #include "sn9c102_devtable.h" |
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | static int pas202bcb_init(struct sn9c102_device* cam) | 31 | static int pas202bcb_init(struct sn9c102_device *cam) |
| 32 | { | 32 | { |
| 33 | int err = 0; | 33 | int err = 0; |
| 34 | 34 | ||
| @@ -78,8 +78,8 @@ static int pas202bcb_init(struct sn9c102_device* cam) | |||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | 80 | ||
| 81 | static int pas202bcb_get_ctrl(struct sn9c102_device* cam, | 81 | static int pas202bcb_get_ctrl(struct sn9c102_device *cam, |
| 82 | struct v4l2_control* ctrl) | 82 | struct v4l2_control *ctrl) |
| 83 | { | 83 | { |
| 84 | switch (ctrl->id) { | 84 | switch (ctrl->id) { |
| 85 | case V4L2_CID_EXPOSURE: | 85 | case V4L2_CID_EXPOSURE: |
| @@ -126,8 +126,8 @@ static int pas202bcb_get_ctrl(struct sn9c102_device* cam, | |||
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | 128 | ||
| 129 | static int pas202bcb_set_pix_format(struct sn9c102_device* cam, | 129 | static int pas202bcb_set_pix_format(struct sn9c102_device *cam, |
| 130 | const struct v4l2_pix_format* pix) | 130 | const struct v4l2_pix_format *pix) |
| 131 | { | 131 | { |
| 132 | int err = 0; | 132 | int err = 0; |
| 133 | 133 | ||
| @@ -140,8 +140,8 @@ static int pas202bcb_set_pix_format(struct sn9c102_device* cam, | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | 142 | ||
| 143 | static int pas202bcb_set_ctrl(struct sn9c102_device* cam, | 143 | static int pas202bcb_set_ctrl(struct sn9c102_device *cam, |
| 144 | const struct v4l2_control* ctrl) | 144 | const struct v4l2_control *ctrl) |
| 145 | { | 145 | { |
| 146 | int err = 0; | 146 | int err = 0; |
| 147 | 147 | ||
| @@ -174,10 +174,10 @@ static int pas202bcb_set_ctrl(struct sn9c102_device* cam, | |||
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | 176 | ||
| 177 | static int pas202bcb_set_crop(struct sn9c102_device* cam, | 177 | static int pas202bcb_set_crop(struct sn9c102_device *cam, |
| 178 | const struct v4l2_rect* rect) | 178 | const struct v4l2_rect *rect) |
| 179 | { | 179 | { |
| 180 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 180 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 181 | int err = 0; | 181 | int err = 0; |
| 182 | u8 h_start = 0, | 182 | u8 h_start = 0, |
| 183 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; | 183 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 3; |
| @@ -299,7 +299,7 @@ static const struct sn9c102_sensor pas202bcb = { | |||
| 299 | }; | 299 | }; |
| 300 | 300 | ||
| 301 | 301 | ||
| 302 | int sn9c102_probe_pas202bcb(struct sn9c102_device* cam) | 302 | int sn9c102_probe_pas202bcb(struct sn9c102_device *cam) |
| 303 | { | 303 | { |
| 304 | int r0 = 0, r1 = 0, err = 0; | 304 | int r0 = 0, r1 = 0, err = 0; |
| 305 | unsigned int pid = 0; | 305 | unsigned int pid = 0; |
diff --git a/drivers/staging/media/sn9c102/sn9c102_sensor.h b/drivers/staging/media/sn9c102/sn9c102_sensor.h index 3679970dba2c..9f59c815d48b 100644 --- a/drivers/staging/media/sn9c102/sn9c102_sensor.h +++ b/drivers/staging/media/sn9c102/sn9c102_sensor.h | |||
| @@ -62,19 +62,19 @@ enum sn9c102_bridge { | |||
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | /* Return the bridge name */ | 64 | /* Return the bridge name */ |
| 65 | enum sn9c102_bridge sn9c102_get_bridge(struct sn9c102_device* cam); | 65 | enum sn9c102_bridge sn9c102_get_bridge(struct sn9c102_device *cam); |
| 66 | 66 | ||
| 67 | /* Return a pointer the sensor struct attached to the camera */ | 67 | /* Return a pointer the sensor struct attached to the camera */ |
| 68 | struct sn9c102_sensor* sn9c102_get_sensor(struct sn9c102_device* cam); | 68 | struct sn9c102_sensor *sn9c102_get_sensor(struct sn9c102_device *cam); |
| 69 | 69 | ||
| 70 | /* Identify a device */ | 70 | /* Identify a device */ |
| 71 | extern struct sn9c102_device* | 71 | extern struct sn9c102_device* |
| 72 | sn9c102_match_id(struct sn9c102_device* cam, const struct usb_device_id *id); | 72 | sn9c102_match_id(struct sn9c102_device *cam, const struct usb_device_id *id); |
| 73 | 73 | ||
| 74 | /* Attach a probed sensor to the camera. */ | 74 | /* Attach a probed sensor to the camera. */ |
| 75 | extern void | 75 | extern void |
| 76 | sn9c102_attach_sensor(struct sn9c102_device* cam, | 76 | sn9c102_attach_sensor(struct sn9c102_device *cam, |
| 77 | const struct sn9c102_sensor* sensor); | 77 | const struct sn9c102_sensor *sensor); |
| 78 | 78 | ||
| 79 | /* | 79 | /* |
| 80 | Read/write routines: they always return -1 on error, 0 or the read value | 80 | Read/write routines: they always return -1 on error, 0 or the read value |
| @@ -99,12 +99,12 @@ extern int sn9c102_i2c_try_read(struct sn9c102_device*, | |||
| 99 | version returns 0 on success, while the read version returns the first read | 99 | version returns 0 on success, while the read version returns the first read |
| 100 | byte. | 100 | byte. |
| 101 | */ | 101 | */ |
| 102 | extern int sn9c102_i2c_try_raw_write(struct sn9c102_device* cam, | 102 | extern int sn9c102_i2c_try_raw_write(struct sn9c102_device *cam, |
| 103 | const struct sn9c102_sensor* sensor, u8 n, | 103 | const struct sn9c102_sensor *sensor, u8 n, |
| 104 | u8 data0, u8 data1, u8 data2, u8 data3, | 104 | u8 data0, u8 data1, u8 data2, u8 data3, |
| 105 | u8 data4, u8 data5); | 105 | u8 data4, u8 data5); |
| 106 | extern int sn9c102_i2c_try_raw_read(struct sn9c102_device* cam, | 106 | extern int sn9c102_i2c_try_raw_read(struct sn9c102_device *cam, |
| 107 | const struct sn9c102_sensor* sensor, | 107 | const struct sn9c102_sensor *sensor, |
| 108 | u8 data0, u8 data1, u8 n, u8 buffer[]); | 108 | u8 data0, u8 data1, u8 n, u8 buffer[]); |
| 109 | 109 | ||
| 110 | /* To be used after the sensor struct has been attached to the camera struct */ | 110 | /* To be used after the sensor struct has been attached to the camera struct */ |
| @@ -174,7 +174,7 @@ struct sn9c102_sensor { | |||
| 174 | they must return 0 on success, the proper error otherwise. | 174 | they must return 0 on success, the proper error otherwise. |
| 175 | */ | 175 | */ |
| 176 | 176 | ||
| 177 | int (*init)(struct sn9c102_device* cam); | 177 | int (*init)(struct sn9c102_device *cam); |
| 178 | /* | 178 | /* |
| 179 | This function will be called after the sensor has been attached. | 179 | This function will be called after the sensor has been attached. |
| 180 | It should be used to initialize the sensor only, but may also | 180 | It should be used to initialize the sensor only, but may also |
| @@ -195,9 +195,9 @@ struct sn9c102_sensor { | |||
| 195 | V4L2 API. Menu type controls are not handled by this interface. | 195 | V4L2 API. Menu type controls are not handled by this interface. |
| 196 | */ | 196 | */ |
| 197 | 197 | ||
| 198 | int (*get_ctrl)(struct sn9c102_device* cam, struct v4l2_control* ctrl); | 198 | int (*get_ctrl)(struct sn9c102_device *cam, struct v4l2_control *ctrl); |
| 199 | int (*set_ctrl)(struct sn9c102_device* cam, | 199 | int (*set_ctrl)(struct sn9c102_device *cam, |
| 200 | const struct v4l2_control* ctrl); | 200 | const struct v4l2_control *ctrl); |
| 201 | /* | 201 | /* |
| 202 | You must implement at least the set_ctrl method if you have defined | 202 | You must implement at least the set_ctrl method if you have defined |
| 203 | the list above. The returned value must follow the V4L2 | 203 | the list above. The returned value must follow the V4L2 |
| @@ -240,8 +240,8 @@ struct sn9c102_sensor { | |||
| 240 | will be ignored. | 240 | will be ignored. |
| 241 | */ | 241 | */ |
| 242 | 242 | ||
| 243 | int (*set_crop)(struct sn9c102_device* cam, | 243 | int (*set_crop)(struct sn9c102_device *cam, |
| 244 | const struct v4l2_rect* rect); | 244 | const struct v4l2_rect *rect); |
| 245 | /* | 245 | /* |
| 246 | To be called on VIDIOC_C_SETCROP. The core module always calls a | 246 | To be called on VIDIOC_C_SETCROP. The core module always calls a |
| 247 | default routine which configures the appropriate SN9C1XX regs (also | 247 | default routine which configures the appropriate SN9C1XX regs (also |
| @@ -276,8 +276,8 @@ struct sn9c102_sensor { | |||
| 276 | matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR). | 276 | matches the RGB bayer sequence (i.e. BGBGBG...GRGRGR). |
| 277 | */ | 277 | */ |
| 278 | 278 | ||
| 279 | int (*set_pix_format)(struct sn9c102_device* cam, | 279 | int (*set_pix_format)(struct sn9c102_device *cam, |
| 280 | const struct v4l2_pix_format* pix); | 280 | const struct v4l2_pix_format *pix); |
| 281 | /* | 281 | /* |
| 282 | To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to | 282 | To be called on VIDIOC_S_FMT, when switching from the SBGGR8 to |
| 283 | SN9C10X pixel format or viceversa. On error return the corresponding | 283 | SN9C10X pixel format or viceversa. On error return the corresponding |
diff --git a/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c b/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c index 04cdfdde8564..6a00b626d347 100644 --- a/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c +++ b/drivers/staging/media/sn9c102/sn9c102_tas5110c1b.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int tas5110c1b_init(struct sn9c102_device* cam) | 26 | static int tas5110c1b_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err = 0; | 28 | int err = 0; |
| 29 | 29 | ||
| @@ -38,8 +38,8 @@ static int tas5110c1b_init(struct sn9c102_device* cam) | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, | 41 | static int tas5110c1b_set_ctrl(struct sn9c102_device *cam, |
| 42 | const struct v4l2_control* ctrl) | 42 | const struct v4l2_control *ctrl) |
| 43 | { | 43 | { |
| 44 | int err = 0; | 44 | int err = 0; |
| 45 | 45 | ||
| @@ -55,10 +55,10 @@ static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | static int tas5110c1b_set_crop(struct sn9c102_device* cam, | 58 | static int tas5110c1b_set_crop(struct sn9c102_device *cam, |
| 59 | const struct v4l2_rect* rect) | 59 | const struct v4l2_rect *rect) |
| 60 | { | 60 | { |
| 61 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 61 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 62 | int err = 0; | 62 | int err = 0; |
| 63 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69, | 63 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69, |
| 64 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9; | 64 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9; |
| @@ -75,8 +75,8 @@ static int tas5110c1b_set_crop(struct sn9c102_device* cam, | |||
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | 77 | ||
| 78 | static int tas5110c1b_set_pix_format(struct sn9c102_device* cam, | 78 | static int tas5110c1b_set_pix_format(struct sn9c102_device *cam, |
| 79 | const struct v4l2_pix_format* pix) | 79 | const struct v4l2_pix_format *pix) |
| 80 | { | 80 | { |
| 81 | int err = 0; | 81 | int err = 0; |
| 82 | 82 | ||
| @@ -135,7 +135,7 @@ static const struct sn9c102_sensor tas5110c1b = { | |||
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | 137 | ||
| 138 | int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam) | 138 | int sn9c102_probe_tas5110c1b(struct sn9c102_device *cam) |
| 139 | { | 139 | { |
| 140 | const struct usb_device_id tas5110c1b_id_table[] = { | 140 | const struct usb_device_id tas5110c1b_id_table[] = { |
| 141 | { USB_DEVICE(0x0c45, 0x6001), }, | 141 | { USB_DEVICE(0x0c45, 0x6001), }, |
diff --git a/drivers/staging/media/sn9c102/sn9c102_tas5110d.c b/drivers/staging/media/sn9c102/sn9c102_tas5110d.c index 9372e6f9fcff..eefbf8670c3e 100644 --- a/drivers/staging/media/sn9c102/sn9c102_tas5110d.c +++ b/drivers/staging/media/sn9c102/sn9c102_tas5110d.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int tas5110d_init(struct sn9c102_device* cam) | 26 | static int tas5110d_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err; | 28 | int err; |
| 29 | 29 | ||
| @@ -37,10 +37,10 @@ static int tas5110d_init(struct sn9c102_device* cam) | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | static int tas5110d_set_crop(struct sn9c102_device* cam, | 40 | static int tas5110d_set_crop(struct sn9c102_device *cam, |
| 41 | const struct v4l2_rect* rect) | 41 | const struct v4l2_rect *rect) |
| 42 | { | 42 | { |
| 43 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 43 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 44 | int err = 0; | 44 | int err = 0; |
| 45 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69, | 45 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 69, |
| 46 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9; | 46 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 9; |
| @@ -55,8 +55,8 @@ static int tas5110d_set_crop(struct sn9c102_device* cam, | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | static int tas5110d_set_pix_format(struct sn9c102_device* cam, | 58 | static int tas5110d_set_pix_format(struct sn9c102_device *cam, |
| 59 | const struct v4l2_pix_format* pix) | 59 | const struct v4l2_pix_format *pix) |
| 60 | { | 60 | { |
| 61 | int err = 0; | 61 | int err = 0; |
| 62 | 62 | ||
| @@ -103,7 +103,7 @@ static const struct sn9c102_sensor tas5110d = { | |||
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | 105 | ||
| 106 | int sn9c102_probe_tas5110d(struct sn9c102_device* cam) | 106 | int sn9c102_probe_tas5110d(struct sn9c102_device *cam) |
| 107 | { | 107 | { |
| 108 | const struct usb_device_id tas5110d_id_table[] = { | 108 | const struct usb_device_id tas5110d_id_table[] = { |
| 109 | { USB_DEVICE(0x0c45, 0x6007), }, | 109 | { USB_DEVICE(0x0c45, 0x6007), }, |
diff --git a/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c b/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c index a30bbc4389f5..725de857de45 100644 --- a/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c +++ b/drivers/staging/media/sn9c102/sn9c102_tas5130d1b.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "sn9c102_devtable.h" | 23 | #include "sn9c102_devtable.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | static int tas5130d1b_init(struct sn9c102_device* cam) | 26 | static int tas5130d1b_init(struct sn9c102_device *cam) |
| 27 | { | 27 | { |
| 28 | int err; | 28 | int err; |
| 29 | 29 | ||
| @@ -36,8 +36,8 @@ static int tas5130d1b_init(struct sn9c102_device* cam) | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | 39 | static int tas5130d1b_set_ctrl(struct sn9c102_device *cam, |
| 40 | const struct v4l2_control* ctrl) | 40 | const struct v4l2_control *ctrl) |
| 41 | { | 41 | { |
| 42 | int err = 0; | 42 | int err = 0; |
| 43 | 43 | ||
| @@ -56,10 +56,10 @@ static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | 58 | ||
| 59 | static int tas5130d1b_set_crop(struct sn9c102_device* cam, | 59 | static int tas5130d1b_set_crop(struct sn9c102_device *cam, |
| 60 | const struct v4l2_rect* rect) | 60 | const struct v4l2_rect *rect) |
| 61 | { | 61 | { |
| 62 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 62 | struct sn9c102_sensor *s = sn9c102_get_sensor(cam); |
| 63 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104, | 63 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104, |
| 64 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12; | 64 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12; |
| 65 | int err = 0; | 65 | int err = 0; |
| @@ -76,8 +76,8 @@ static int tas5130d1b_set_crop(struct sn9c102_device* cam, | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | 78 | ||
| 79 | static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, | 79 | static int tas5130d1b_set_pix_format(struct sn9c102_device *cam, |
| 80 | const struct v4l2_pix_format* pix) | 80 | const struct v4l2_pix_format *pix) |
| 81 | { | 81 | { |
| 82 | int err = 0; | 82 | int err = 0; |
| 83 | 83 | ||
| @@ -146,7 +146,7 @@ static const struct sn9c102_sensor tas5130d1b = { | |||
| 146 | }; | 146 | }; |
| 147 | 147 | ||
| 148 | 148 | ||
| 149 | int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam) | 149 | int sn9c102_probe_tas5130d1b(struct sn9c102_device *cam) |
| 150 | { | 150 | { |
| 151 | const struct usb_device_id tas5130d1b_id_table[] = { | 151 | const struct usb_device_id tas5130d1b_id_table[] = { |
| 152 | { USB_DEVICE(0x0c45, 0x6024), }, | 152 | { USB_DEVICE(0x0c45, 0x6024), }, |
diff --git a/drivers/staging/media/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig index 9a4296c2e3ab..6a1906fa1117 100644 --- a/drivers/staging/media/solo6x10/Kconfig +++ b/drivers/staging/media/solo6x10/Kconfig | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | config SOLO6X10 | 1 | config SOLO6X10 |
| 2 | tristate "Softlogic 6x10 MPEG codec cards" | 2 | tristate "Bluecherry / Softlogic 6x10 capture cards (MPEG-4/H.264)" |
| 3 | depends on PCI && VIDEO_DEV && SND && I2C | 3 | depends on PCI && VIDEO_DEV && SND && I2C |
| 4 | select FONT_SUPPORT | 4 | select FONT_SUPPORT |
| 5 | select FONT_8x16 | 5 | select FONT_8x16 |
| @@ -8,5 +8,11 @@ config SOLO6X10 | |||
| 8 | select SND_PCM | 8 | select SND_PCM |
| 9 | select FONT_8x16 | 9 | select FONT_8x16 |
| 10 | ---help--- | 10 | ---help--- |
| 11 | This driver supports the Softlogic based MPEG-4 and h.264 codec | 11 | This driver supports the Bluecherry H.264 and MPEG-4 hardware |
| 12 | cards. | 12 | compression capture cards and other Softlogic-based ones. |
| 13 | |||
| 14 | Following cards have been tested: | ||
| 15 | * Bluecherry BC-H16480A (PCIe, 16 port, H.264) | ||
| 16 | * Bluecherry BC-H04120A (PCIe, 4 port, H.264) | ||
| 17 | * Bluecherry BC-H04120A-MPCI (Mini-PCI, 4 port, H.264) | ||
| 18 | * Bluecherry BC-04120A (PCIe, 4 port, MPEG-4) | ||
diff --git a/drivers/staging/media/solo6x10/solo6x10-enc.c b/drivers/staging/media/solo6x10/solo6x10-enc.c index 94d5735abf85..2db53b68c62f 100644 --- a/drivers/staging/media/solo6x10/solo6x10-enc.c +++ b/drivers/staging/media/solo6x10/solo6x10-enc.c | |||
| @@ -134,51 +134,48 @@ static void solo_capture_config(struct solo_dev *solo_dev) | |||
| 134 | kfree(buf); | 134 | kfree(buf); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | #define SOLO_OSD_WRITE_SIZE (16 * OSD_TEXT_MAX) | ||
| 138 | |||
| 137 | /* Should be called with enable_lock held */ | 139 | /* Should be called with enable_lock held */ |
| 138 | int solo_osd_print(struct solo_enc_dev *solo_enc) | 140 | int solo_osd_print(struct solo_enc_dev *solo_enc) |
| 139 | { | 141 | { |
| 140 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 142 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
| 141 | unsigned char *str = solo_enc->osd_text; | 143 | unsigned char *str = solo_enc->osd_text; |
| 142 | u8 *buf = solo_enc->osd_buf; | 144 | u8 *buf = solo_enc->osd_buf; |
| 143 | u32 reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH); | 145 | u32 reg; |
| 144 | const struct font_desc *vga = find_font("VGA8x16"); | 146 | const struct font_desc *vga = find_font("VGA8x16"); |
| 145 | const unsigned char *vga_data; | 147 | const unsigned char *vga_data; |
| 146 | int len; | ||
| 147 | int i, j; | 148 | int i, j; |
| 148 | 149 | ||
| 149 | if (WARN_ON_ONCE(!vga)) | 150 | if (WARN_ON_ONCE(!vga)) |
| 150 | return -ENODEV; | 151 | return -ENODEV; |
| 151 | 152 | ||
| 152 | len = strlen(str); | 153 | reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH); |
| 153 | 154 | if (!*str) { | |
| 154 | if (len == 0) { | ||
| 155 | /* Disable OSD on this channel */ | 155 | /* Disable OSD on this channel */ |
| 156 | reg &= ~(1 << solo_enc->ch); | 156 | reg &= ~(1 << solo_enc->ch); |
| 157 | solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); | 157 | goto out; |
| 158 | return 0; | ||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | memset(buf, 0, SOLO_EOSD_EXT_SIZE_MAX); | 160 | memset(buf, 0, SOLO_OSD_WRITE_SIZE); |
| 162 | vga_data = (const unsigned char *)vga->data; | 161 | vga_data = (const unsigned char *)vga->data; |
| 163 | 162 | ||
| 164 | for (i = 0; i < len; i++) { | 163 | for (i = 0; *str; i++, str++) { |
| 165 | unsigned char c = str[i]; | ||
| 166 | |||
| 167 | for (j = 0; j < 16; j++) { | 164 | for (j = 0; j < 16; j++) { |
| 168 | buf[(j * 2) + (i % 2) + (i / 2 * 32)] = | 165 | buf[(j << 1) | (i & 1) | ((i & ~1) << 4)] = |
| 169 | bitrev8(vga_data[(c * 16) + j]); | 166 | bitrev8(vga_data[(*str << 4) | j]); |
| 170 | } | 167 | } |
| 171 | } | 168 | } |
| 172 | 169 | ||
| 173 | solo_p2m_dma(solo_dev, 1, buf, | 170 | solo_p2m_dma(solo_dev, 1, buf, |
| 174 | SOLO_EOSD_EXT_ADDR + | 171 | SOLO_EOSD_EXT_ADDR_CHAN(solo_dev, solo_enc->ch), |
| 175 | (solo_enc->ch * SOLO_EOSD_EXT_SIZE(solo_dev)), | 172 | SOLO_OSD_WRITE_SIZE, 0, 0); |
| 176 | SOLO_EOSD_EXT_SIZE(solo_dev), 0, 0); | ||
| 177 | 173 | ||
| 178 | /* Enable OSD on this channel */ | 174 | /* Enable OSD on this channel */ |
| 179 | reg |= (1 << solo_enc->ch); | 175 | reg |= (1 << solo_enc->ch); |
| 180 | solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); | ||
| 181 | 176 | ||
| 177 | out: | ||
| 178 | solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); | ||
| 182 | return 0; | 179 | return 0; |
| 183 | } | 180 | } |
| 184 | 181 | ||
diff --git a/drivers/staging/media/solo6x10/solo6x10-offsets.h b/drivers/staging/media/solo6x10/solo6x10-offsets.h index f005dca501f1..13eeb4470dcf 100644 --- a/drivers/staging/media/solo6x10/solo6x10-offsets.h +++ b/drivers/staging/media/solo6x10/solo6x10-offsets.h | |||
| @@ -35,6 +35,8 @@ | |||
| 35 | #define SOLO_EOSD_EXT_SIZE_MAX 0x20000 | 35 | #define SOLO_EOSD_EXT_SIZE_MAX 0x20000 |
| 36 | #define SOLO_EOSD_EXT_AREA(__solo) \ | 36 | #define SOLO_EOSD_EXT_AREA(__solo) \ |
| 37 | (SOLO_EOSD_EXT_SIZE(__solo) * 32) | 37 | (SOLO_EOSD_EXT_SIZE(__solo) * 32) |
| 38 | #define SOLO_EOSD_EXT_ADDR_CHAN(__solo, ch) \ | ||
| 39 | (SOLO_EOSD_EXT_ADDR + SOLO_EOSD_EXT_SIZE(__solo) * (ch)) | ||
| 38 | 40 | ||
| 39 | #define SOLO_MOTION_EXT_ADDR(__solo) \ | 41 | #define SOLO_MOTION_EXT_ADDR(__solo) \ |
| 40 | (SOLO_EOSD_EXT_ADDR + SOLO_EOSD_EXT_AREA(__solo)) | 42 | (SOLO_EOSD_EXT_ADDR + SOLO_EOSD_EXT_AREA(__solo)) |
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c index 2cbe088f1697..b8ff113c20f4 100644 --- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c | |||
| @@ -745,14 +745,13 @@ static int solo_enc_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 745 | return solo_ring_start(solo_enc->solo_dev); | 745 | return solo_ring_start(solo_enc->solo_dev); |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | static int solo_enc_stop_streaming(struct vb2_queue *q) | 748 | static void solo_enc_stop_streaming(struct vb2_queue *q) |
| 749 | { | 749 | { |
| 750 | struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); | 750 | struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); |
| 751 | 751 | ||
| 752 | solo_enc_off(solo_enc); | 752 | solo_enc_off(solo_enc); |
| 753 | INIT_LIST_HEAD(&solo_enc->vidq_active); | 753 | INIT_LIST_HEAD(&solo_enc->vidq_active); |
| 754 | solo_ring_stop(solo_enc->solo_dev); | 754 | solo_ring_stop(solo_enc->solo_dev); |
| 755 | return 0; | ||
| 756 | } | 755 | } |
| 757 | 756 | ||
| 758 | static struct vb2_ops solo_enc_video_qops = { | 757 | static struct vb2_ops solo_enc_video_qops = { |
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2.c b/drivers/staging/media/solo6x10/solo6x10-v4l2.c index 1815f765d033..5d0100eb38e6 100644 --- a/drivers/staging/media/solo6x10/solo6x10-v4l2.c +++ b/drivers/staging/media/solo6x10/solo6x10-v4l2.c | |||
| @@ -336,13 +336,12 @@ static int solo_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 336 | return solo_start_thread(solo_dev); | 336 | return solo_start_thread(solo_dev); |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | static int solo_stop_streaming(struct vb2_queue *q) | 339 | static void solo_stop_streaming(struct vb2_queue *q) |
| 340 | { | 340 | { |
| 341 | struct solo_dev *solo_dev = vb2_get_drv_priv(q); | 341 | struct solo_dev *solo_dev = vb2_get_drv_priv(q); |
| 342 | 342 | ||
| 343 | solo_stop_thread(solo_dev); | 343 | solo_stop_thread(solo_dev); |
| 344 | INIT_LIST_HEAD(&solo_dev->vidq_active); | 344 | INIT_LIST_HEAD(&solo_dev->vidq_active); |
| 345 | return 0; | ||
| 346 | } | 345 | } |
| 347 | 346 | ||
| 348 | static void solo_buf_queue(struct vb2_buffer *vb) | 347 | static void solo_buf_queue(struct vb2_buffer *vb) |
diff --git a/include/linux/platform_data/mipi-csis.h b/include/linux/platform_data/mipi-csis.h deleted file mode 100644 index c2fd9024717c..000000000000 --- a/include/linux/platform_data/mipi-csis.h +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd. | ||
| 3 | * | ||
| 4 | * Samsung S5P/Exynos SoC series MIPI CSIS device support | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __PLAT_SAMSUNG_MIPI_CSIS_H_ | ||
| 12 | #define __PLAT_SAMSUNG_MIPI_CSIS_H_ __FILE__ | ||
| 13 | |||
| 14 | /** | ||
| 15 | * struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver | ||
| 16 | * @clk_rate: bus clock frequency | ||
| 17 | * @wclk_source: CSI wrapper clock selection: 0 - bus clock, 1 - ext. SCLK_CAM | ||
| 18 | * @lanes: number of data lanes used | ||
| 19 | * @hs_settle: HS-RX settle time | ||
| 20 | */ | ||
| 21 | struct s5p_platform_mipi_csis { | ||
| 22 | unsigned long clk_rate; | ||
| 23 | u8 wclk_source; | ||
| 24 | u8 lanes; | ||
| 25 | u8 hs_settle; | ||
| 26 | }; | ||
| 27 | |||
| 28 | #endif /* __PLAT_SAMSUNG_MIPI_CSIS_H_ */ | ||
diff --git a/include/media/adv7604.h b/include/media/adv7604.h index d262a3a922bd..c6b39372eed7 100644 --- a/include/media/adv7604.h +++ b/include/media/adv7604.h | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #ifndef _ADV7604_ | 21 | #ifndef _ADV7604_ |
| 22 | #define _ADV7604_ | 22 | #define _ADV7604_ |
| 23 | 23 | ||
| 24 | #include <linux/types.h> | ||
| 25 | |||
| 24 | /* Analog input muxing modes (AFE register 0x02, [2:0]) */ | 26 | /* Analog input muxing modes (AFE register 0x02, [2:0]) */ |
| 25 | enum adv7604_ain_sel { | 27 | enum adv7604_ain_sel { |
| 26 | ADV7604_AIN1_2_3_NC_SYNC_1_2 = 0, | 28 | ADV7604_AIN1_2_3_NC_SYNC_1_2 = 0, |
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h index 8dffffedbb59..637749a91432 100644 --- a/include/media/davinci/vpbe_display.h +++ b/include/media/davinci/vpbe_display.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | /* Header files */ | 16 | /* Header files */ |
| 17 | #include <linux/videodev2.h> | 17 | #include <linux/videodev2.h> |
| 18 | #include <media/v4l2-common.h> | 18 | #include <media/v4l2-common.h> |
| 19 | #include <media/v4l2-fh.h> | ||
| 19 | #include <media/videobuf2-dma-contig.h> | 20 | #include <media/videobuf2-dma-contig.h> |
| 20 | #include <media/davinci/vpbe_types.h> | 21 | #include <media/davinci/vpbe_types.h> |
| 21 | #include <media/davinci/vpbe_osd.h> | 22 | #include <media/davinci/vpbe_osd.h> |
| @@ -94,8 +95,6 @@ struct vpbe_layer { | |||
| 94 | * has selected | 95 | * has selected |
| 95 | */ | 96 | */ |
| 96 | enum v4l2_memory memory; | 97 | enum v4l2_memory memory; |
| 97 | /* Used to keep track of state of the priority */ | ||
| 98 | struct v4l2_prio_state prio; | ||
| 99 | /* Used to store pixel format */ | 98 | /* Used to store pixel format */ |
| 100 | struct v4l2_pix_format pix_fmt; | 99 | struct v4l2_pix_format pix_fmt; |
| 101 | enum v4l2_field buf_field; | 100 | enum v4l2_field buf_field; |
| @@ -134,14 +133,13 @@ struct vpbe_display { | |||
| 134 | 133 | ||
| 135 | /* File handle structure */ | 134 | /* File handle structure */ |
| 136 | struct vpbe_fh { | 135 | struct vpbe_fh { |
| 136 | struct v4l2_fh fh; | ||
| 137 | /* vpbe device structure */ | 137 | /* vpbe device structure */ |
| 138 | struct vpbe_display *disp_dev; | 138 | struct vpbe_display *disp_dev; |
| 139 | /* pointer to layer object for opened device */ | 139 | /* pointer to layer object for opened device */ |
| 140 | struct vpbe_layer *layer; | 140 | struct vpbe_layer *layer; |
| 141 | /* Indicates whether this file handle is doing IO */ | 141 | /* Indicates whether this file handle is doing IO */ |
| 142 | unsigned char io_allowed; | 142 | unsigned char io_allowed; |
| 143 | /* Used to keep track priority of this instance */ | ||
| 144 | enum v4l2_priority prio; | ||
| 145 | }; | 143 | }; |
| 146 | 144 | ||
| 147 | struct buf_config_params { | 145 | struct buf_config_params { |
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h index cc973ed845a7..288772e6900a 100644 --- a/include/media/davinci/vpfe_capture.h +++ b/include/media/davinci/vpfe_capture.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
| 27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
| 28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
| 29 | #include <media/v4l2-fh.h> | ||
| 29 | #include <media/v4l2-ioctl.h> | 30 | #include <media/v4l2-ioctl.h> |
| 30 | #include <media/v4l2-device.h> | 31 | #include <media/v4l2-device.h> |
| 31 | #include <media/videobuf-dma-contig.h> | 32 | #include <media/videobuf-dma-contig.h> |
| @@ -110,8 +111,6 @@ struct vpfe_device { | |||
| 110 | struct v4l2_device v4l2_dev; | 111 | struct v4l2_device v4l2_dev; |
| 111 | /* parent device */ | 112 | /* parent device */ |
| 112 | struct device *pdev; | 113 | struct device *pdev; |
| 113 | /* Used to keep track of state of the priority */ | ||
| 114 | struct v4l2_prio_state prio; | ||
| 115 | /* number of open instances of the channel */ | 114 | /* number of open instances of the channel */ |
| 116 | u32 usrs; | 115 | u32 usrs; |
| 117 | /* Indicates id of the field which is being displayed */ | 116 | /* Indicates id of the field which is being displayed */ |
| @@ -174,11 +173,10 @@ struct vpfe_device { | |||
| 174 | 173 | ||
| 175 | /* File handle structure */ | 174 | /* File handle structure */ |
| 176 | struct vpfe_fh { | 175 | struct vpfe_fh { |
| 176 | struct v4l2_fh fh; | ||
| 177 | struct vpfe_device *vpfe_dev; | 177 | struct vpfe_device *vpfe_dev; |
| 178 | /* Indicates whether this file handle is doing IO */ | 178 | /* Indicates whether this file handle is doing IO */ |
| 179 | u8 io_allowed; | 179 | u8 io_allowed; |
| 180 | /* Used to keep track priority of this instance */ | ||
| 181 | enum v4l2_priority prio; | ||
| 182 | }; | 180 | }; |
| 183 | 181 | ||
| 184 | struct vpfe_config_params { | 182 | struct vpfe_config_params { |
diff --git a/include/media/s5p_fimc.h b/include/media/exynos-fimc.h index b975c285c8a9..aa44660e2041 100644 --- a/include/media/s5p_fimc.h +++ b/include/media/exynos-fimc.h | |||
| @@ -61,41 +61,20 @@ enum fimc_bus_type { | |||
| 61 | #define GRP_ID_FLITE (1 << 13) | 61 | #define GRP_ID_FLITE (1 << 13) |
| 62 | #define GRP_ID_FIMC_IS (1 << 14) | 62 | #define GRP_ID_FIMC_IS (1 << 14) |
| 63 | 63 | ||
| 64 | struct i2c_board_info; | ||
| 65 | |||
| 66 | /** | 64 | /** |
| 67 | * struct fimc_source_info - video source description required for the host | 65 | * struct fimc_source_info - video source description required for the host |
| 68 | * interface configuration | 66 | * interface configuration |
| 69 | * | 67 | * |
| 70 | * @board_info: pointer to I2C subdevice's board info | ||
| 71 | * @clk_frequency: frequency of the clock the host interface provides to sensor | ||
| 72 | * @fimc_bus_type: FIMC camera input type | 68 | * @fimc_bus_type: FIMC camera input type |
| 73 | * @sensor_bus_type: image sensor bus type, MIPI, ITU-R BT.601 etc. | 69 | * @sensor_bus_type: image sensor bus type, MIPI, ITU-R BT.601 etc. |
| 74 | * @flags: the parallel sensor bus flags defining signals polarity (V4L2_MBUS_*) | 70 | * @flags: the parallel sensor bus flags defining signals polarity (V4L2_MBUS_*) |
| 75 | * @i2c_bus_num: i2c control bus id the sensor is attached to | ||
| 76 | * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) | 71 | * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) |
| 77 | * @clk_id: index of the SoC peripheral clock for sensors | ||
| 78 | */ | 72 | */ |
| 79 | struct fimc_source_info { | 73 | struct fimc_source_info { |
| 80 | struct i2c_board_info *board_info; | ||
| 81 | unsigned long clk_frequency; | ||
| 82 | enum fimc_bus_type fimc_bus_type; | 74 | enum fimc_bus_type fimc_bus_type; |
| 83 | enum fimc_bus_type sensor_bus_type; | 75 | enum fimc_bus_type sensor_bus_type; |
| 84 | u16 flags; | 76 | u16 flags; |
| 85 | u16 i2c_bus_num; | ||
| 86 | u16 mux_id; | 77 | u16 mux_id; |
| 87 | u8 clk_id; | ||
| 88 | }; | ||
| 89 | |||
| 90 | /** | ||
| 91 | * struct s5p_platform_fimc - camera host interface platform data | ||
| 92 | * | ||
| 93 | * @source_info: properties of an image source for the host interface setup | ||
| 94 | * @num_clients: the number of attached image sources | ||
| 95 | */ | ||
| 96 | struct s5p_platform_fimc { | ||
| 97 | struct fimc_source_info *source_info; | ||
| 98 | int num_clients; | ||
| 99 | }; | 78 | }; |
| 100 | 79 | ||
| 101 | /* | 80 | /* |
diff --git a/include/media/media-device.h b/include/media/media-device.h index 12155a9596c4..6e6db78f1ee2 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h | |||
| @@ -87,7 +87,9 @@ struct media_device { | |||
| 87 | /* media_devnode to media_device */ | 87 | /* media_devnode to media_device */ |
| 88 | #define to_media_device(node) container_of(node, struct media_device, devnode) | 88 | #define to_media_device(node) container_of(node, struct media_device, devnode) |
| 89 | 89 | ||
| 90 | int __must_check media_device_register(struct media_device *mdev); | 90 | int __must_check __media_device_register(struct media_device *mdev, |
| 91 | struct module *owner); | ||
| 92 | #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE) | ||
| 91 | void media_device_unregister(struct media_device *mdev); | 93 | void media_device_unregister(struct media_device *mdev); |
| 92 | 94 | ||
| 93 | int __must_check media_device_register_entity(struct media_device *mdev, | 95 | int __must_check media_device_register_entity(struct media_device *mdev, |
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 3446af279fca..0dc7060f9625 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h | |||
| @@ -82,7 +82,8 @@ struct media_devnode { | |||
| 82 | /* dev to media_devnode */ | 82 | /* dev to media_devnode */ |
| 83 | #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) | 83 | #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) |
| 84 | 84 | ||
| 85 | int __must_check media_devnode_register(struct media_devnode *mdev); | 85 | int __must_check media_devnode_register(struct media_devnode *mdev, |
| 86 | struct module *owner); | ||
| 86 | void media_devnode_unregister(struct media_devnode *mdev); | 87 | void media_devnode_unregister(struct media_devnode *mdev); |
| 87 | 88 | ||
| 88 | static inline struct media_devnode *media_devnode_data(struct file *filp) | 89 | static inline struct media_devnode *media_devnode_data(struct file *filp) |
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index c9b1593923f6..ffb69da3ce9e 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h | |||
| @@ -120,6 +120,14 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); | |||
| 120 | int __must_check | 120 | int __must_check |
| 121 | v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); | 121 | v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); |
| 122 | 122 | ||
| 123 | /* Send a notification to v4l2_device. */ | ||
| 124 | static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, | ||
| 125 | unsigned int notification, void *arg) | ||
| 126 | { | ||
| 127 | if (sd && sd->v4l2_dev && sd->v4l2_dev->notify) | ||
| 128 | sd->v4l2_dev->notify(sd, notification, arg); | ||
| 129 | } | ||
| 130 | |||
| 123 | /* Iterate over all subdevs. */ | 131 | /* Iterate over all subdevs. */ |
| 124 | #define v4l2_device_for_each_subdev(sd, v4l2_dev) \ | 132 | #define v4l2_device_for_each_subdev(sd, v4l2_dev) \ |
| 125 | list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) | 133 | list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) |
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h index be05d019de25..1ab9045e52e3 100644 --- a/include/media/v4l2-event.h +++ b/include/media/v4l2-event.h | |||
| @@ -132,4 +132,8 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, | |||
| 132 | void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); | 132 | void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); |
| 133 | int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, | 133 | int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, |
| 134 | struct v4l2_event_subscription *sub); | 134 | struct v4l2_event_subscription *sub); |
| 135 | int v4l2_src_change_event_subscribe(struct v4l2_fh *fh, | ||
| 136 | const struct v4l2_event_subscription *sub); | ||
| 137 | int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd, | ||
| 138 | struct v4l2_fh *fh, struct v4l2_event_subscription *sub); | ||
| 135 | #endif /* V4L2_EVENT_H */ | 139 | #endif /* V4L2_EVENT_H */ |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 28f4d8c3cf7d..9fab013eea86 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
| @@ -159,8 +159,6 @@ struct v4l2_subdev_core_ops { | |||
| 159 | int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); | 159 | int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); |
| 160 | int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); | 160 | int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); |
| 161 | int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); | 161 | int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); |
| 162 | int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm); | ||
| 163 | int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm); | ||
| 164 | long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); | 162 | long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); |
| 165 | #ifdef CONFIG_COMPAT | 163 | #ifdef CONFIG_COMPAT |
| 166 | long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, | 164 | long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, |
| @@ -234,15 +232,18 @@ struct v4l2_subdev_audio_ops { | |||
| 234 | 232 | ||
| 235 | /* Indicates the @length field specifies maximum data length. */ | 233 | /* Indicates the @length field specifies maximum data length. */ |
| 236 | #define V4L2_MBUS_FRAME_DESC_FL_LEN_MAX (1U << 0) | 234 | #define V4L2_MBUS_FRAME_DESC_FL_LEN_MAX (1U << 0) |
| 237 | /* Indicates user defined data format, i.e. non standard frame format. */ | 235 | /* |
| 236 | * Indicates that the format does not have line offsets, i.e. the | ||
| 237 | * receiver should use 1D DMA. | ||
| 238 | */ | ||
| 238 | #define V4L2_MBUS_FRAME_DESC_FL_BLOB (1U << 1) | 239 | #define V4L2_MBUS_FRAME_DESC_FL_BLOB (1U << 1) |
| 239 | 240 | ||
| 240 | /** | 241 | /** |
| 241 | * struct v4l2_mbus_frame_desc_entry - media bus frame description structure | 242 | * struct v4l2_mbus_frame_desc_entry - media bus frame description structure |
| 242 | * @flags: V4L2_MBUS_FRAME_DESC_FL_* flags | 243 | * @flags: V4L2_MBUS_FRAME_DESC_FL_* flags |
| 243 | * @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set | 244 | * @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set |
| 244 | * @length: number of octets per frame, valid for compressed or unspecified | 245 | * @length: number of octets per frame, valid if V4L2_MBUS_FRAME_DESC_FL_BLOB |
| 245 | * formats | 246 | * is set |
| 246 | */ | 247 | */ |
| 247 | struct v4l2_mbus_frame_desc_entry { | 248 | struct v4l2_mbus_frame_desc_entry { |
| 248 | u16 flags; | 249 | u16 flags; |
| @@ -269,8 +270,11 @@ struct v4l2_mbus_frame_desc { | |||
| 269 | g_std_output: get current standard for video OUTPUT devices. This is ignored | 270 | g_std_output: get current standard for video OUTPUT devices. This is ignored |
| 270 | by video input devices. | 271 | by video input devices. |
| 271 | 272 | ||
| 272 | g_tvnorms_output: get v4l2_std_id with all standards supported by video | 273 | g_tvnorms: get v4l2_std_id with all standards supported by the video |
| 273 | OUTPUT device. This is ignored by video input devices. | 274 | CAPTURE device. This is ignored by video output devices. |
| 275 | |||
| 276 | g_tvnorms_output: get v4l2_std_id with all standards supported by the video | ||
| 277 | OUTPUT device. This is ignored by video capture devices. | ||
| 274 | 278 | ||
| 275 | s_crystal_freq: sets the frequency of the crystal used to generate the | 279 | s_crystal_freq: sets the frequency of the crystal used to generate the |
| 276 | clocks in Hz. An extra flags field allows device specific configuration | 280 | clocks in Hz. An extra flags field allows device specific configuration |
| @@ -310,9 +314,12 @@ struct v4l2_mbus_frame_desc { | |||
| 310 | struct v4l2_subdev_video_ops { | 314 | struct v4l2_subdev_video_ops { |
| 311 | int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); | 315 | int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); |
| 312 | int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags); | 316 | int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags); |
| 317 | int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm); | ||
| 318 | int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm); | ||
| 313 | int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); | 319 | int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); |
| 314 | int (*g_std_output)(struct v4l2_subdev *sd, v4l2_std_id *std); | 320 | int (*g_std_output)(struct v4l2_subdev *sd, v4l2_std_id *std); |
| 315 | int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); | 321 | int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); |
| 322 | int (*g_tvnorms)(struct v4l2_subdev *sd, v4l2_std_id *std); | ||
| 316 | int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std); | 323 | int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std); |
| 317 | int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); | 324 | int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); |
| 318 | int (*s_stream)(struct v4l2_subdev *sd, int enable); | 325 | int (*s_stream)(struct v4l2_subdev *sd, int enable); |
| @@ -510,6 +517,10 @@ struct v4l2_subdev_pad_ops { | |||
| 510 | struct v4l2_subdev_selection *sel); | 517 | struct v4l2_subdev_selection *sel); |
| 511 | int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); | 518 | int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); |
| 512 | int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); | 519 | int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_edid *edid); |
| 520 | int (*dv_timings_cap)(struct v4l2_subdev *sd, | ||
| 521 | struct v4l2_dv_timings_cap *cap); | ||
| 522 | int (*enum_dv_timings)(struct v4l2_subdev *sd, | ||
| 523 | struct v4l2_enum_dv_timings *timings); | ||
| 513 | #ifdef CONFIG_MEDIA_CONTROLLER | 524 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 514 | int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link, | 525 | int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link, |
| 515 | struct v4l2_subdev_format *source_fmt, | 526 | struct v4l2_subdev_format *source_fmt, |
| @@ -584,6 +595,7 @@ struct v4l2_subdev { | |||
| 584 | #endif | 595 | #endif |
| 585 | struct list_head list; | 596 | struct list_head list; |
| 586 | struct module *owner; | 597 | struct module *owner; |
| 598 | bool owner_v4l2_dev; | ||
| 587 | u32 flags; | 599 | u32 flags; |
| 588 | struct v4l2_device *v4l2_dev; | 600 | struct v4l2_device *v4l2_dev; |
| 589 | const struct v4l2_subdev_ops *ops; | 601 | const struct v4l2_subdev_ops *ops; |
| @@ -685,17 +697,12 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, | |||
| 685 | /* Call an ops of a v4l2_subdev, doing the right checks against | 697 | /* Call an ops of a v4l2_subdev, doing the right checks against |
| 686 | NULL pointers. | 698 | NULL pointers. |
| 687 | 699 | ||
| 688 | Example: err = v4l2_subdev_call(sd, core, s_std, norm); | 700 | Example: err = v4l2_subdev_call(sd, video, s_std, norm); |
| 689 | */ | 701 | */ |
| 690 | #define v4l2_subdev_call(sd, o, f, args...) \ | 702 | #define v4l2_subdev_call(sd, o, f, args...) \ |
| 691 | (!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \ | 703 | (!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \ |
| 692 | (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD)) | 704 | (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD)) |
| 693 | 705 | ||
| 694 | /* Send a notification to v4l2_device. */ | ||
| 695 | #define v4l2_subdev_notify(sd, notification, arg) \ | ||
| 696 | ((!(sd) || !(sd)->v4l2_dev || !(sd)->v4l2_dev->notify) ? -ENODEV : \ | ||
| 697 | (sd)->v4l2_dev->notify((sd), (notification), (arg))) | ||
| 698 | |||
| 699 | #define v4l2_subdev_has_op(sd, o, f) \ | 706 | #define v4l2_subdev_has_op(sd, o, f) \ |
| 700 | ((sd)->ops->o && (sd)->ops->o->f) | 707 | ((sd)->ops->o && (sd)->ops->o->f) |
| 701 | 708 | ||
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index af4621109726..bca25dc53f9d 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | struct vb2_alloc_ctx; | 21 | struct vb2_alloc_ctx; |
| 22 | struct vb2_fileio_data; | 22 | struct vb2_fileio_data; |
| 23 | struct vb2_threadio_data; | ||
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| 25 | * struct vb2_mem_ops - memory handling/memory allocator operations | 26 | * struct vb2_mem_ops - memory handling/memory allocator operations |
| @@ -323,7 +324,7 @@ struct vb2_ops { | |||
| 323 | void (*buf_cleanup)(struct vb2_buffer *vb); | 324 | void (*buf_cleanup)(struct vb2_buffer *vb); |
| 324 | 325 | ||
| 325 | int (*start_streaming)(struct vb2_queue *q, unsigned int count); | 326 | int (*start_streaming)(struct vb2_queue *q, unsigned int count); |
| 326 | int (*stop_streaming)(struct vb2_queue *q); | 327 | void (*stop_streaming)(struct vb2_queue *q); |
| 327 | 328 | ||
| 328 | void (*buf_queue)(struct vb2_buffer *vb); | 329 | void (*buf_queue)(struct vb2_buffer *vb); |
| 329 | }; | 330 | }; |
| @@ -375,6 +376,7 @@ struct v4l2_fh; | |||
| 375 | * @start_streaming_called: start_streaming() was called successfully and we | 376 | * @start_streaming_called: start_streaming() was called successfully and we |
| 376 | * started streaming. | 377 | * started streaming. |
| 377 | * @fileio: file io emulator internal data, used only if emulator is active | 378 | * @fileio: file io emulator internal data, used only if emulator is active |
| 379 | * @threadio: thread io internal data, used only if thread is active | ||
| 378 | */ | 380 | */ |
| 379 | struct vb2_queue { | 381 | struct vb2_queue { |
| 380 | enum v4l2_buf_type type; | 382 | enum v4l2_buf_type type; |
| @@ -411,6 +413,7 @@ struct vb2_queue { | |||
| 411 | unsigned int start_streaming_called:1; | 413 | unsigned int start_streaming_called:1; |
| 412 | 414 | ||
| 413 | struct vb2_fileio_data *fileio; | 415 | struct vb2_fileio_data *fileio; |
| 416 | struct vb2_threadio_data *threadio; | ||
| 414 | 417 | ||
| 415 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 418 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 416 | /* | 419 | /* |
| @@ -461,6 +464,35 @@ size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, | |||
| 461 | loff_t *ppos, int nonblock); | 464 | loff_t *ppos, int nonblock); |
| 462 | size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, | 465 | size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, |
| 463 | loff_t *ppos, int nonblock); | 466 | loff_t *ppos, int nonblock); |
| 467 | /** | ||
| 468 | * vb2_thread_fnc - callback function for use with vb2_thread | ||
| 469 | * | ||
| 470 | * This is called whenever a buffer is dequeued in the thread. | ||
| 471 | */ | ||
| 472 | typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv); | ||
| 473 | |||
| 474 | /** | ||
| 475 | * vb2_thread_start() - start a thread for the given queue. | ||
| 476 | * @q: videobuf queue | ||
| 477 | * @fnc: callback function | ||
| 478 | * @priv: priv pointer passed to the callback function | ||
| 479 | * @thread_name:the name of the thread. This will be prefixed with "vb2-". | ||
| 480 | * | ||
| 481 | * This starts a thread that will queue and dequeue until an error occurs | ||
| 482 | * or @vb2_thread_stop is called. | ||
| 483 | * | ||
| 484 | * This function should not be used for anything else but the videobuf2-dvb | ||
| 485 | * support. If you think you have another good use-case for this, then please | ||
| 486 | * contact the linux-media mailinglist first. | ||
| 487 | */ | ||
| 488 | int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, | ||
| 489 | const char *thread_name); | ||
| 490 | |||
| 491 | /** | ||
| 492 | * vb2_thread_stop() - stop the thread for the given queue. | ||
| 493 | * @q: videobuf queue | ||
| 494 | */ | ||
| 495 | int vb2_thread_stop(struct vb2_queue *q); | ||
| 464 | 496 | ||
| 465 | /** | 497 | /** |
| 466 | * vb2_is_streaming() - return streaming status of the queue | 498 | * vb2_is_streaming() - return streaming status of the queue |
| @@ -472,6 +504,23 @@ static inline bool vb2_is_streaming(struct vb2_queue *q) | |||
| 472 | } | 504 | } |
| 473 | 505 | ||
| 474 | /** | 506 | /** |
| 507 | * vb2_fileio_is_active() - return true if fileio is active. | ||
| 508 | * @q: videobuf queue | ||
| 509 | * | ||
| 510 | * This returns true if read() or write() is used to stream the data | ||
| 511 | * as opposed to stream I/O. This is almost never an important distinction, | ||
| 512 | * except in rare cases. One such case is that using read() or write() to | ||
| 513 | * stream a format using V4L2_FIELD_ALTERNATE is not allowed since there | ||
| 514 | * is no way you can pass the field information of each buffer to/from | ||
| 515 | * userspace. A driver that supports this field format should check for | ||
| 516 | * this in the queue_setup op and reject it if this function returns true. | ||
| 517 | */ | ||
| 518 | static inline bool vb2_fileio_is_active(struct vb2_queue *q) | ||
| 519 | { | ||
| 520 | return q->fileio; | ||
| 521 | } | ||
| 522 | |||
| 523 | /** | ||
| 475 | * vb2_is_busy() - return busy status of the queue | 524 | * vb2_is_busy() - return busy status of the queue |
| 476 | * @q: videobuf queue | 525 | * @q: videobuf queue |
| 477 | * | 526 | * |
diff --git a/include/media/videobuf2-dvb.h b/include/media/videobuf2-dvb.h new file mode 100644 index 000000000000..8f61456f1394 --- /dev/null +++ b/include/media/videobuf2-dvb.h | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | #ifndef _VIDEOBUF2_DVB_H_ | ||
| 2 | #define _VIDEOBUF2_DVB_H_ | ||
| 3 | |||
| 4 | #include <dvbdev.h> | ||
| 5 | #include <dmxdev.h> | ||
| 6 | #include <dvb_demux.h> | ||
| 7 | #include <dvb_net.h> | ||
| 8 | #include <dvb_frontend.h> | ||
| 9 | #include <media/videobuf2-core.h> | ||
| 10 | |||
| 11 | struct vb2_dvb { | ||
| 12 | /* filling that the job of the driver */ | ||
| 13 | char *name; | ||
| 14 | struct dvb_frontend *frontend; | ||
| 15 | struct vb2_queue dvbq; | ||
| 16 | |||
| 17 | /* video-buf-dvb state info */ | ||
| 18 | struct mutex lock; | ||
| 19 | int nfeeds; | ||
| 20 | |||
| 21 | /* vb2_dvb_(un)register manages this */ | ||
| 22 | struct dvb_demux demux; | ||
| 23 | struct dmxdev dmxdev; | ||
| 24 | struct dmx_frontend fe_hw; | ||
| 25 | struct dmx_frontend fe_mem; | ||
| 26 | struct dvb_net net; | ||
| 27 | }; | ||
| 28 | |||
| 29 | struct vb2_dvb_frontend { | ||
| 30 | struct list_head felist; | ||
| 31 | int id; | ||
| 32 | struct vb2_dvb dvb; | ||
| 33 | }; | ||
| 34 | |||
| 35 | struct vb2_dvb_frontends { | ||
| 36 | struct list_head felist; | ||
| 37 | struct mutex lock; | ||
| 38 | struct dvb_adapter adapter; | ||
| 39 | int active_fe_id; /* Indicates which frontend in the felist is in use */ | ||
| 40 | int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */ | ||
| 41 | }; | ||
| 42 | |||
| 43 | int vb2_dvb_register_bus(struct vb2_dvb_frontends *f, | ||
| 44 | struct module *module, | ||
| 45 | void *adapter_priv, | ||
| 46 | struct device *device, | ||
| 47 | short *adapter_nr, | ||
| 48 | int mfe_shared); | ||
| 49 | |||
| 50 | void vb2_dvb_unregister_bus(struct vb2_dvb_frontends *f); | ||
| 51 | |||
| 52 | struct vb2_dvb_frontend *vb2_dvb_alloc_frontend(struct vb2_dvb_frontends *f, int id); | ||
| 53 | void vb2_dvb_dealloc_frontends(struct vb2_dvb_frontends *f); | ||
| 54 | |||
| 55 | struct vb2_dvb_frontend *vb2_dvb_get_frontend(struct vb2_dvb_frontends *f, int id); | ||
| 56 | int vb2_dvb_find_frontend(struct vb2_dvb_frontends *f, struct dvb_frontend *p); | ||
| 57 | |||
| 58 | #endif /* _VIDEOBUF2_DVB_H_ */ | ||
diff --git a/include/uapi/linux/v4l2-common.h b/include/uapi/linux/v4l2-common.h index 9bf508ad0957..2f6f8cafe773 100644 --- a/include/uapi/linux/v4l2-common.h +++ b/include/uapi/linux/v4l2-common.h | |||
| @@ -75,7 +75,7 @@ struct v4l2_edid { | |||
| 75 | __u32 start_block; | 75 | __u32 start_block; |
| 76 | __u32 blocks; | 76 | __u32 blocks; |
| 77 | __u32 reserved[5]; | 77 | __u32 reserved[5]; |
| 78 | __u8 __user *edid; | 78 | __u8 *edid; |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | #endif /* __V4L2_COMMON__ */ | 81 | #endif /* __V4L2_COMMON__ */ |
diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h index b6a5fe00a470..6c8f159e416e 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h | |||
| @@ -173,6 +173,76 @@ | |||
| 173 | V4L2_DV_FL_CAN_REDUCE_FPS) \ | 173 | V4L2_DV_FL_CAN_REDUCE_FPS) \ |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | #define V4L2_DV_BT_CEA_3840X2160P24 { \ | ||
| 177 | .type = V4L2_DV_BT_656_1120, \ | ||
| 178 | V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 179 | 297000000, 1276, 88, 296, 8, 10, 72, 0, 0, 0, \ | ||
| 180 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ | ||
| 181 | } | ||
| 182 | |||
| 183 | #define V4L2_DV_BT_CEA_3840X2160P25 { \ | ||
| 184 | .type = V4L2_DV_BT_656_1120, \ | ||
| 185 | V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 186 | 297000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ | ||
| 187 | V4L2_DV_BT_STD_CEA861, 0) \ | ||
| 188 | } | ||
| 189 | |||
| 190 | #define V4L2_DV_BT_CEA_3840X2160P30 { \ | ||
| 191 | .type = V4L2_DV_BT_656_1120, \ | ||
| 192 | V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 193 | 297000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ | ||
| 194 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ | ||
| 195 | } | ||
| 196 | |||
| 197 | #define V4L2_DV_BT_CEA_3840X2160P50 { \ | ||
| 198 | .type = V4L2_DV_BT_656_1120, \ | ||
| 199 | V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 200 | 594000000, 1056, 88, 296, 8, 10, 72, 0, 0, 0, \ | ||
| 201 | V4L2_DV_BT_STD_CEA861, 0) \ | ||
| 202 | } | ||
| 203 | |||
| 204 | #define V4L2_DV_BT_CEA_3840X2160P60 { \ | ||
| 205 | .type = V4L2_DV_BT_656_1120, \ | ||
| 206 | V4L2_INIT_BT_TIMINGS(3840, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 207 | 594000000, 176, 88, 296, 8, 10, 72, 0, 0, 0, \ | ||
| 208 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ | ||
| 209 | } | ||
| 210 | |||
| 211 | #define V4L2_DV_BT_CEA_4096X2160P24 { \ | ||
| 212 | .type = V4L2_DV_BT_656_1120, \ | ||
| 213 | V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 214 | 297000000, 1020, 88, 296, 8, 10, 72, 0, 0, 0, \ | ||
| 215 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ | ||
| 216 | } | ||
| 217 | |||
| 218 | #define V4L2_DV_BT_CEA_4096X2160P25 { \ | ||
| 219 | .type = V4L2_DV_BT_656_1120, \ | ||
| 220 | V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 221 | 297000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ | ||
| 222 | V4L2_DV_BT_STD_CEA861, 0) \ | ||
| 223 | } | ||
| 224 | |||
| 225 | #define V4L2_DV_BT_CEA_4096X2160P30 { \ | ||
| 226 | .type = V4L2_DV_BT_656_1120, \ | ||
| 227 | V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 228 | 297000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ | ||
| 229 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ | ||
| 230 | } | ||
| 231 | |||
| 232 | #define V4L2_DV_BT_CEA_4096X2160P50 { \ | ||
| 233 | .type = V4L2_DV_BT_656_1120, \ | ||
| 234 | V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 235 | 594000000, 968, 88, 128, 8, 10, 72, 0, 0, 0, \ | ||
| 236 | V4L2_DV_BT_STD_CEA861, 0) \ | ||
| 237 | } | ||
| 238 | |||
| 239 | #define V4L2_DV_BT_CEA_4096X2160P60 { \ | ||
| 240 | .type = V4L2_DV_BT_656_1120, \ | ||
| 241 | V4L2_INIT_BT_TIMINGS(4096, 2160, 0, V4L2_DV_HSYNC_POS_POL, \ | ||
| 242 | 594000000, 88, 88, 128, 8, 10, 72, 0, 0, 0, \ | ||
| 243 | V4L2_DV_BT_STD_CEA861, V4L2_DV_FL_CAN_REDUCE_FPS) \ | ||
| 244 | } | ||
| 245 | |||
| 176 | 246 | ||
| 177 | /* VESA Discrete Monitor Timings as per version 1.0, revision 12 */ | 247 | /* VESA Discrete Monitor Timings as per version 1.0, revision 12 */ |
| 178 | 248 | ||
diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h index b5c3aab6e82c..1445e858854f 100644 --- a/include/uapi/linux/v4l2-mediabus.h +++ b/include/uapi/linux/v4l2-mediabus.h | |||
| @@ -52,7 +52,7 @@ enum v4l2_mbus_pixelcode { | |||
| 52 | V4L2_MBUS_FMT_RGB888_2X12_LE = 0x100c, | 52 | V4L2_MBUS_FMT_RGB888_2X12_LE = 0x100c, |
| 53 | V4L2_MBUS_FMT_ARGB8888_1X32 = 0x100d, | 53 | V4L2_MBUS_FMT_ARGB8888_1X32 = 0x100d, |
| 54 | 54 | ||
| 55 | /* YUV (including grey) - next is 0x2018 */ | 55 | /* YUV (including grey) - next is 0x2024 */ |
| 56 | V4L2_MBUS_FMT_Y8_1X8 = 0x2001, | 56 | V4L2_MBUS_FMT_Y8_1X8 = 0x2001, |
| 57 | V4L2_MBUS_FMT_UV8_1X8 = 0x2015, | 57 | V4L2_MBUS_FMT_UV8_1X8 = 0x2015, |
| 58 | V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, | 58 | V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, |
| @@ -64,6 +64,8 @@ enum v4l2_mbus_pixelcode { | |||
| 64 | V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008, | 64 | V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008, |
| 65 | V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009, | 65 | V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009, |
| 66 | V4L2_MBUS_FMT_Y10_1X10 = 0x200a, | 66 | V4L2_MBUS_FMT_Y10_1X10 = 0x200a, |
| 67 | V4L2_MBUS_FMT_UYVY10_2X10 = 0x2018, | ||
| 68 | V4L2_MBUS_FMT_VYUY10_2X10 = 0x2019, | ||
| 67 | V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, | 69 | V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, |
| 68 | V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, | 70 | V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, |
| 69 | V4L2_MBUS_FMT_Y12_1X12 = 0x2013, | 71 | V4L2_MBUS_FMT_Y12_1X12 = 0x2013, |
| @@ -72,10 +74,20 @@ enum v4l2_mbus_pixelcode { | |||
| 72 | V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, | 74 | V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, |
| 73 | V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, | 75 | V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012, |
| 74 | V4L2_MBUS_FMT_YDYUYDYV8_1X16 = 0x2014, | 76 | V4L2_MBUS_FMT_YDYUYDYV8_1X16 = 0x2014, |
| 77 | V4L2_MBUS_FMT_UYVY10_1X20 = 0x201a, | ||
| 78 | V4L2_MBUS_FMT_VYUY10_1X20 = 0x201b, | ||
| 75 | V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, | 79 | V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, |
| 76 | V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, | 80 | V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, |
| 77 | V4L2_MBUS_FMT_YUV10_1X30 = 0x2016, | 81 | V4L2_MBUS_FMT_YUV10_1X30 = 0x2016, |
| 78 | V4L2_MBUS_FMT_AYUV8_1X32 = 0x2017, | 82 | V4L2_MBUS_FMT_AYUV8_1X32 = 0x2017, |
| 83 | V4L2_MBUS_FMT_UYVY12_2X12 = 0x201c, | ||
| 84 | V4L2_MBUS_FMT_VYUY12_2X12 = 0x201d, | ||
| 85 | V4L2_MBUS_FMT_YUYV12_2X12 = 0x201e, | ||
| 86 | V4L2_MBUS_FMT_YVYU12_2X12 = 0x201f, | ||
| 87 | V4L2_MBUS_FMT_UYVY12_1X24 = 0x2020, | ||
| 88 | V4L2_MBUS_FMT_VYUY12_1X24 = 0x2021, | ||
| 89 | V4L2_MBUS_FMT_YUYV12_1X24 = 0x2022, | ||
| 90 | V4L2_MBUS_FMT_YVYU12_1X24 = 0x2023, | ||
| 79 | 91 | ||
| 80 | /* Bayer - next is 0x3019 */ | 92 | /* Bayer - next is 0x3019 */ |
| 81 | V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, | 93 | V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, |
diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index 87e05159f637..a619cdd300ac 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h | |||
| @@ -151,26 +151,24 @@ struct v4l2_subdev_selection { | |||
| 151 | /* Backwards compatibility define --- to be removed */ | 151 | /* Backwards compatibility define --- to be removed */ |
| 152 | #define v4l2_subdev_edid v4l2_edid | 152 | #define v4l2_subdev_edid v4l2_edid |
| 153 | 153 | ||
| 154 | #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) | 154 | #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) |
| 155 | #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) | 155 | #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) |
| 156 | #define VIDIOC_SUBDEV_G_FRAME_INTERVAL \ | 156 | #define VIDIOC_SUBDEV_G_FRAME_INTERVAL _IOWR('V', 21, struct v4l2_subdev_frame_interval) |
| 157 | _IOWR('V', 21, struct v4l2_subdev_frame_interval) | 157 | #define VIDIOC_SUBDEV_S_FRAME_INTERVAL _IOWR('V', 22, struct v4l2_subdev_frame_interval) |
| 158 | #define VIDIOC_SUBDEV_S_FRAME_INTERVAL \ | 158 | #define VIDIOC_SUBDEV_ENUM_MBUS_CODE _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum) |
| 159 | _IOWR('V', 22, struct v4l2_subdev_frame_interval) | 159 | #define VIDIOC_SUBDEV_ENUM_FRAME_SIZE _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) |
| 160 | #define VIDIOC_SUBDEV_ENUM_MBUS_CODE \ | 160 | #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) |
| 161 | _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum) | 161 | #define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) |
| 162 | #define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \ | 162 | #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) |
| 163 | _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) | 163 | #define VIDIOC_SUBDEV_G_SELECTION _IOWR('V', 61, struct v4l2_subdev_selection) |
| 164 | #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ | 164 | #define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection) |
| 165 | _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) | 165 | /* The following ioctls are identical to the ioctls in videodev2.h */ |
| 166 | #define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) | 166 | #define VIDIOC_SUBDEV_G_EDID _IOWR('V', 40, struct v4l2_edid) |
| 167 | #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) | 167 | #define VIDIOC_SUBDEV_S_EDID _IOWR('V', 41, struct v4l2_edid) |
| 168 | #define VIDIOC_SUBDEV_G_SELECTION \ | 168 | #define VIDIOC_SUBDEV_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) |
| 169 | _IOWR('V', 61, struct v4l2_subdev_selection) | 169 | #define VIDIOC_SUBDEV_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) |
| 170 | #define VIDIOC_SUBDEV_S_SELECTION \ | 170 | #define VIDIOC_SUBDEV_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) |
| 171 | _IOWR('V', 62, struct v4l2_subdev_selection) | 171 | #define VIDIOC_SUBDEV_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) |
| 172 | /* These two G/S_EDID ioctls are identical to the ioctls in videodev2.h */ | 172 | #define VIDIOC_SUBDEV_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) |
| 173 | #define VIDIOC_SUBDEV_G_EDID _IOWR('V', 40, struct v4l2_edid) | ||
| 174 | #define VIDIOC_SUBDEV_S_EDID _IOWR('V', 41, struct v4l2_edid) | ||
| 175 | 173 | ||
| 176 | #endif | 174 | #endif |
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index ea468ee8fe21..168ff507bf75 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h | |||
| @@ -649,7 +649,6 @@ struct v4l2_plane { | |||
| 649 | * @length: size in bytes of the buffer (NOT its payload) for single-plane | 649 | * @length: size in bytes of the buffer (NOT its payload) for single-plane |
| 650 | * buffers (when type != *_MPLANE); number of elements in the | 650 | * buffers (when type != *_MPLANE); number of elements in the |
| 651 | * planes array for multi-plane buffers | 651 | * planes array for multi-plane buffers |
| 652 | * @input: input number from which the video data has has been captured | ||
| 653 | * | 652 | * |
| 654 | * Contains data exchanged by application and driver using one of the Streaming | 653 | * Contains data exchanged by application and driver using one of the Streaming |
| 655 | * I/O methods. | 654 | * I/O methods. |
| @@ -1107,12 +1106,15 @@ struct v4l2_dv_timings { | |||
| 1107 | 1106 | ||
| 1108 | /** struct v4l2_enum_dv_timings - DV timings enumeration | 1107 | /** struct v4l2_enum_dv_timings - DV timings enumeration |
| 1109 | * @index: enumeration index | 1108 | * @index: enumeration index |
| 1109 | * @pad: the pad number for which to enumerate timings (used with | ||
| 1110 | * v4l-subdev nodes only) | ||
| 1110 | * @reserved: must be zeroed | 1111 | * @reserved: must be zeroed |
| 1111 | * @timings: the timings for the given index | 1112 | * @timings: the timings for the given index |
| 1112 | */ | 1113 | */ |
| 1113 | struct v4l2_enum_dv_timings { | 1114 | struct v4l2_enum_dv_timings { |
| 1114 | __u32 index; | 1115 | __u32 index; |
| 1115 | __u32 reserved[3]; | 1116 | __u32 pad; |
| 1117 | __u32 reserved[2]; | ||
| 1116 | struct v4l2_dv_timings timings; | 1118 | struct v4l2_dv_timings timings; |
| 1117 | }; | 1119 | }; |
| 1118 | 1120 | ||
| @@ -1150,11 +1152,14 @@ struct v4l2_bt_timings_cap { | |||
| 1150 | 1152 | ||
| 1151 | /** struct v4l2_dv_timings_cap - DV timings capabilities | 1153 | /** struct v4l2_dv_timings_cap - DV timings capabilities |
| 1152 | * @type: the type of the timings (same as in struct v4l2_dv_timings) | 1154 | * @type: the type of the timings (same as in struct v4l2_dv_timings) |
| 1155 | * @pad: the pad number for which to query capabilities (used with | ||
| 1156 | * v4l-subdev nodes only) | ||
| 1153 | * @bt: the BT656/1120 timings capabilities | 1157 | * @bt: the BT656/1120 timings capabilities |
| 1154 | */ | 1158 | */ |
| 1155 | struct v4l2_dv_timings_cap { | 1159 | struct v4l2_dv_timings_cap { |
| 1156 | __u32 type; | 1160 | __u32 type; |
| 1157 | __u32 reserved[3]; | 1161 | __u32 pad; |
| 1162 | __u32 reserved[2]; | ||
| 1158 | union { | 1163 | union { |
| 1159 | struct v4l2_bt_timings_cap bt; | 1164 | struct v4l2_bt_timings_cap bt; |
| 1160 | __u32 raw_data[32]; | 1165 | __u32 raw_data[32]; |
| @@ -1765,6 +1770,7 @@ struct v4l2_streamparm { | |||
| 1765 | #define V4L2_EVENT_EOS 2 | 1770 | #define V4L2_EVENT_EOS 2 |
| 1766 | #define V4L2_EVENT_CTRL 3 | 1771 | #define V4L2_EVENT_CTRL 3 |
| 1767 | #define V4L2_EVENT_FRAME_SYNC 4 | 1772 | #define V4L2_EVENT_FRAME_SYNC 4 |
| 1773 | #define V4L2_EVENT_SOURCE_CHANGE 5 | ||
| 1768 | #define V4L2_EVENT_PRIVATE_START 0x08000000 | 1774 | #define V4L2_EVENT_PRIVATE_START 0x08000000 |
| 1769 | 1775 | ||
| 1770 | /* Payload for V4L2_EVENT_VSYNC */ | 1776 | /* Payload for V4L2_EVENT_VSYNC */ |
| @@ -1796,12 +1802,19 @@ struct v4l2_event_frame_sync { | |||
| 1796 | __u32 frame_sequence; | 1802 | __u32 frame_sequence; |
| 1797 | }; | 1803 | }; |
| 1798 | 1804 | ||
| 1805 | #define V4L2_EVENT_SRC_CH_RESOLUTION (1 << 0) | ||
| 1806 | |||
| 1807 | struct v4l2_event_src_change { | ||
| 1808 | __u32 changes; | ||
| 1809 | }; | ||
| 1810 | |||
| 1799 | struct v4l2_event { | 1811 | struct v4l2_event { |
| 1800 | __u32 type; | 1812 | __u32 type; |
| 1801 | union { | 1813 | union { |
| 1802 | struct v4l2_event_vsync vsync; | 1814 | struct v4l2_event_vsync vsync; |
| 1803 | struct v4l2_event_ctrl ctrl; | 1815 | struct v4l2_event_ctrl ctrl; |
| 1804 | struct v4l2_event_frame_sync frame_sync; | 1816 | struct v4l2_event_frame_sync frame_sync; |
| 1817 | struct v4l2_event_src_change src_change; | ||
| 1805 | __u8 data[64]; | 1818 | __u8 data[64]; |
| 1806 | } u; | 1819 | } u; |
| 1807 | __u32 pending; | 1820 | __u32 pending; |
