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 ...
Unified · Split
| @@ -125,7 +125,7 @@ location of the buffers in device memory can be determined with the · 124 unmodified lines | |||
| 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> · 567 unmodified lines | |||
| 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> · 155 unmodified lines | |||
| 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> |
| @@ -79,13 +79,13 @@ · 78 unmodified lines | |||
| 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 @@ · 61 unmodified lines | |||
| 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> |
| @@ -772,7 +772,7 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see · 771 unmodified lines | |||
| 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 · 33 unmodified lines | |||
| 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> |
| @@ -1898,6 +1898,134 @@ · 1897 unmodified lines | |||
| 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 @@ · 404 unmodified lines | |||
| 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 @@ · 172 unmodified lines | |||
| 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> |
| @@ -242,6 +242,22 @@ · 241 unmodified lines | |||
| 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 @@ · 22 unmodified lines | |||
| 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; |
| @@ -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 @@ · 21 unmodified lines | |||
| 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 @@ · 14 unmodified lines | |||
| 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> · 63 unmodified lines | |||
| 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> |
| @@ -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 @@ · 21 unmodified lines | |||
| 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> · 21 unmodified lines | |||
| 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> · 7 unmodified lines | |||
| 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> · 13 unmodified lines | |||
| 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> |
| @@ -154,6 +154,26 @@ · 153 unmodified lines | |||
| 154 | frame interval in between them.</para> | 154 | frame interval in between them.</para> |
| 155 | </entry> | 155 | </entry> |
| 156 | </row> | 156 | </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> | ||
| 157 | <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> |
| @@ -10,7 +10,8 @@ Required properties: · 9 unmodified lines | |||
| 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. |
| @@ -164,3 +164,4 @@ · 163 unmodified lines | |||
| 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 | ||
| @@ -92,3 +92,4 @@ · 91 unmodified lines | |||
| 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) | ||
| @@ -140,39 +140,9 @@ You can either grep through the kernel log to find relevant information, i.e. · 139 unmodified lines | |||
| 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). |
| @@ -77,7 +77,8 @@ struct skeleton { · 76 unmodified lines | |||
| 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 = { · 40 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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, · 13 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 57 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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, · 50 unmodified lines | |||
| 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 | ||
| @@ -7668,7 +7668,6 @@ L: linux-media@vger.kernel.org · 7667 unmodified lines | |||
| 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> · 296 unmodified lines | |||
| 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 |
| @@ -49,11 +49,6 @@ · 48 unmodified lines | |||
| 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) · 225 unmodified lines | |||
| 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) · 526 unmodified lines | |||
| 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 = { · 15 unmodified lines | |||
| 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) · 62 unmodified lines | |||
| 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 | ||
| @@ -356,11 +356,13 @@ · 355 unmodified lines | |||
| 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 @@ · 8 unmodified lines | |||
| 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 |
| @@ -446,6 +446,13 @@ config DVB_RTL2832 · 445 unmodified lines | |||
| 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 | ||
| @@ -78,6 +78,7 @@ obj-$(CONFIG_DVB_AF9013) += af9013.o · 77 unmodified lines | |||
| 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 |
| @@ -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); | ||
| @@ -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 | ||
| @@ -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 | ||
| @@ -571,35 +571,6 @@ static const struct v4l2_subdev_core_ops ad9389b_core_ops = { · 570 unmodified lines | |||
| 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, · 72 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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 = { · 2 unmodified lines | |||
| 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")); |
| @@ -461,6 +461,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd, · 460 unmodified lines | |||
| 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 = { · 5 unmodified lines | |||
| 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 | ||
| @@ -501,8 +501,6 @@ static const struct v4l2_ctrl_ops adv7183_ctrl_ops = { · 500 unmodified lines | |||
| 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 = { · 2 unmodified lines | |||
| 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, |
| @@ -597,34 +597,6 @@ static int adv7511_isr(struct v4l2_subdev *sd, u32 status, bool *handled) · 596 unmodified lines | |||
| 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, · 69 unmodified lines | |||
| 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 = { · 2 unmodified lines | |||
| 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 = { · 75 unmodified lines | |||
| 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 = { |
| @@ -1673,8 +1673,6 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) · 1672 unmodified lines | |||
| 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) · 80 unmodified lines | |||
| 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); |
| @@ -1399,6 +1399,9 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) · 1398 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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) · 588 unmodified lines | |||
| 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) · 23 unmodified lines | |||
| 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) · 28 unmodified lines | |||
| 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) · 537 unmodified lines | |||
| 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) · 74 unmodified lines | |||
| 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 = { · 170 unmodified lines | |||
| 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 = { · 3 unmodified lines | |||
| 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 = { · 3 unmodified lines | |||
| 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 = { |
| @@ -387,10 +387,10 @@ static const struct v4l2_subdev_core_ops bt819_core_ops = { · 386 unmodified lines | |||
| 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, |
| @@ -5041,8 +5041,6 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = { · 5040 unmodified lines | |||
| 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 = { · 18 unmodified lines | |||
| 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, |
| @@ -648,11 +648,8 @@ static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status) · 647 unmodified lines | |||
| 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 = { · 1 unmodified line | |||
| 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 | ||
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 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" |
| @@ -276,6 +276,7 @@ static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = { · 275 unmodified lines | |||
| 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 = { · 4 unmodified lines | |||
| 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, |
| @@ -649,10 +649,10 @@ static const struct v4l2_subdev_core_ops msp_core_ops = { · 648 unmodified lines | |||
| 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 | ||
| @@ -647,6 +647,28 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev, · 646 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 48 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) |
| @@ -643,10 +643,10 @@ static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = { · 642 unmodified lines | |||
| 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, |
| @@ -365,10 +365,10 @@ static const struct v4l2_subdev_core_ops saa7110_core_ops = { · 364 unmodified lines | |||
| 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, |
| @@ -1582,7 +1582,6 @@ static const struct v4l2_subdev_core_ops saa711x_core_ops = { · 1581 unmodified lines | |||
| 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 = { · 12 unmodified lines | |||
| 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, |
| @@ -1198,7 +1198,6 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = { · 1197 unmodified lines | |||
| 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 = { · 11 unmodified lines | |||
| 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, |
| @@ -573,10 +573,10 @@ static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status) · 572 unmodified lines | |||
| 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, |
| @@ -46,7 +46,7 @@ struct smiapp_pll { · 45 unmodified lines | |||
| 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; |
| @@ -606,7 +606,7 @@ static int smiapp_get_limits(struct smiapp_sensor *sensor, int const *limit, · 605 unmodified lines | |||
| 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) · 128 unmodified lines | |||
| 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) · 379 unmodified lines | |||
| 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) · 103 unmodified lines | |||
| 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) · 19 unmodified lines | |||
| 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, · 495 unmodified lines | |||
| 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) · 582 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 31 unmodified lines | |||
| 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) · 54 unmodified lines | |||
| 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) · 48 unmodified lines | |||
| 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) · 65 unmodified lines | |||
| 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) · 202 unmodified lines | |||
| 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); |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | |||
| 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, · 26 unmodified lines | |||
| 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) · 153 unmodified lines | |||
| 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) |
| @@ -35,19 +35,30 @@ struct smiapp_sensor; · 34 unmodified lines | |||
| 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 { · 2 unmodified lines | |||
| 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 | } |
| @@ -21,11 +21,11 @@ · 20 unmodified lines | |||
| 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) |
| @@ -114,14 +114,14 @@ static int ____smiapp_read(struct smiapp_sensor *sensor, u16 reg, · 113 unmodified lines | |||
| 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, · 37 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 6 unmodified lines | |||
| 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) · 26 unmodified lines | |||
| 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 | } | ||
| @@ -28,22 +28,23 @@ · 27 unmodified lines | |||
| 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 |
| @@ -814,8 +814,6 @@ done: · 813 unmodified lines | |||
| 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, · 50 unmodified lines | |||
| 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 = { · 3 unmodified lines | |||
| 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 = { |
| @@ -327,18 +327,18 @@ static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner · 326 unmodified lines | |||
| 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 | /* --------------------------------------------------------------------------*/ |
| @@ -410,6 +410,9 @@ static int ths8200_g_dv_timings(struct v4l2_subdev *sd, · 409 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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 = { · 3 unmodified lines | |||
| 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 = { · 2 unmodified lines | |||
| 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, |
| @@ -1862,7 +1862,6 @@ static const struct v4l2_subdev_core_ops tvaudio_core_ops = { · 1861 unmodified lines | |||
| 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 = { · 7 unmodified lines | |||
| 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 | /* ----------------------------------------------------------------------- */ |
| @@ -1010,10 +1010,10 @@ static const struct v4l2_subdev_core_ops tvp514x_core_ops = { · 1009 unmodified lines | |||
| 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, |
| @@ -913,7 +913,7 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) · 912 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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 = { · 133 unmodified lines | |||
| 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 = { · 6 unmodified lines | |||
| 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, |
| @@ -833,6 +833,9 @@ static int tvp7002_log_status(struct v4l2_subdev *sd) · 832 unmodified lines | |||
| 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 = { · 85 unmodified lines | |||
| 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 = { · 7 unmodified lines | |||
| 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 */ |
| @@ -342,12 +342,12 @@ static const struct v4l2_ctrl_ops tw2804_ctrl_ops = { · 341 unmodified lines | |||
| 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 = { |
| @@ -187,10 +187,10 @@ static const struct v4l2_ctrl_ops tw9903_ctrl_ops = { · 186 unmodified lines | |||
| 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 | ||
| @@ -157,10 +157,10 @@ static const struct v4l2_ctrl_ops tw9906_ctrl_ops = { · 156 unmodified lines | |||
| 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 | ||
| @@ -124,7 +124,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd) · 123 unmodified lines | |||
| 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 = { · 2 unmodified lines | |||
| 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 | /* ----------------------------------------------------------------------- */ |
| @@ -457,10 +457,10 @@ static const struct v4l2_subdev_core_ops vpx3220_core_ops = { · 456 unmodified lines | |||
| 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, |
| @@ -373,7 +373,8 @@ static void media_device_release(struct media_devnode *mdev) · 372 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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 |
| @@ -232,7 +232,8 @@ static const struct file_operations media_devnode_fops = { · 231 unmodified lines | |||
| 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) · 14 unmodified lines | |||
| 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) { |
| @@ -937,7 +937,7 @@ static struct qcam *qcam_init(struct parport *port) · 936 unmodified lines | |||
| 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"); |
| @@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); · 51 unmodified lines | |||
| 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[] = { · 2813 unmodified lines | |||
| 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) · 428 unmodified lines | |||
| 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) |
| @@ -4184,6 +4204,96 @@ init_RTV24 (struct bttv *btv) · 873 unmodified lines | |||
| 4184 | 4204 | ||
| 4185 | 4205 | ||
| 4186 | 4206 | ||
| 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 | |||
| 4187 | /* ----------------------------------------------------------------------- */ | 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 | /* |
| @@ -1182,7 +1182,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) · 1181 unmodified lines | |||
| 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 | } |
| @@ -189,6 +189,7 @@ · 188 unmodified lines | |||
| 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 |
| @@ -1544,7 +1544,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) · 1543 unmodified lines | |||
| 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) · 156 unmodified lines | |||
| 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 = { · 62 unmodified lines | |||
| 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 = { · 17 unmodified lines | |||
| 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 = { · 25 unmodified lines | |||
| 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 = { · 15 unmodified lines | |||
| 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, |
| @@ -1263,7 +1263,6 @@ static const struct v4l2_subdev_core_ops cx18_av_general_ops = { · 1262 unmodified lines | |||
| 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 = { · 13 unmodified lines | |||
| 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, |
| @@ -760,7 +760,7 @@ int cx18_v4l2_close(struct file *filp) · 759 unmodified lines | |||
| 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) { |
| @@ -180,7 +180,6 @@ static int gpiomux_s_audio_routing(struct v4l2_subdev *sd, · 179 unmodified lines | |||
| 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 = { · 4 unmodified lines | |||
| 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 | /* |
| @@ -602,7 +602,7 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) · 601 unmodified lines | |||
| 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 | ||
| @@ -326,7 +326,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) · 325 unmodified lines | |||
| 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, · 1256 unmodified lines | |||
| 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 |
| @@ -1012,7 +1012,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm) · 1011 unmodified lines | |||
| 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); |
| @@ -159,6 +159,12 @@ static int snd_ivtv_pcm_capture_open(struct snd_pcm_substream *substream) · 158 unmodified lines | |||
| 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); |
| @@ -894,7 +894,7 @@ int ivtv_v4l2_close(struct file *filp) · 893 unmodified lines | |||
| 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) { |
| @@ -1090,7 +1090,7 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id std) · 1089 unmodified lines | |||
| 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) |
| @@ -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 · 29 unmodified lines | |||
| 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 |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 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 · 241 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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, · 315 unmodified lines | |||
| 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, · 9 unmodified lines | |||
| 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, · 2 unmodified lines | |||
| 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) · 20 unmodified lines | |||
| 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 | } |
| @@ -69,6 +69,10 @@ module_param_named(no_overlay, saa7134_no_overlay, int, 0444); · 68 unmodified lines | |||
| 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) · 128 unmodified lines | |||
| 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, · 18 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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, · 7 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 13 unmodified lines | |||
| 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, · 647 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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, · 5 unmodified lines | |||
| 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, · 113 unmodified lines | |||
| 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); · 164 unmodified lines | |||
| 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 | */ | ||
| @@ -602,10 +602,10 @@ static int configure_tda827x_fe(struct saa7134_dev *dev, · 601 unmodified lines | |||
| 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) · 603 unmodified lines | |||
| 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) · 632 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 24 unmodified lines | |||
| 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) · 15 unmodified lines | |||
| 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 | */ | ||
| @@ -48,21 +48,16 @@ MODULE_PARM_DESC(debug,"enable debug messages"); · 47 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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, · 63 unmodified lines | |||
| 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 = { · 3 unmodified lines | |||
| 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 = { · 3 unmodified lines | |||
| 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) · 46 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 18 unmodified lines | |||
| 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 | */ | ||
| @@ -427,10 +427,3 @@ int saa7134_i2c_unregister(struct saa7134_dev *dev) · 426 unmodified lines | |||
| 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 | */ | ||
| @@ -167,17 +167,22 @@ · 166 unmodified lines | |||
| 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 @@ · 185 unmodified lines | |||
| 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 | |||
| @@ -39,26 +39,29 @@ MODULE_PARM_DESC(ts_debug,"enable debug messages [ts]"); · 38 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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) · 45 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 14 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 27 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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 | */ | ||
| @@ -1079,10 +1079,3 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) · 1078 unmodified lines | |||
| 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 | */ | ||
| @@ -67,10 +67,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf, · 66 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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) · 23 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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 | */ | ||
| @@ -381,42 +381,6 @@ static struct saa7134_format* format_by_fourcc(unsigned int fourcc) · 380 unmodified lines | |||
| 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) · 29 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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) · 12 unmodified lines | |||
| 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, · 301 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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, · 16 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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) · 71 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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, · 27 unmodified lines | |||
| 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, · 17 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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, · 74 unmodified lines | |||
| 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, · 14 unmodified lines | |||
| 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) · 45 unmodified lines | |||
| 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, · 3 unmodified lines | |||
| 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, · 12 unmodified lines | |||
| 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); · 24 unmodified lines | |||
| 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) · 32 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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 · 38 unmodified lines | |||
| 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, · 87 unmodified lines | |||
| 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) · 77 unmodified lines | |||
| 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 = · 51 unmodified lines | |||
| 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 = { · 10 unmodified lines | |||
| 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 = { · 17 unmodified lines | |||
| 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 = { · 71 unmodified lines | |||
| 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) · 45 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 86 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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 | */ | ||
| @@ -41,11 +41,11 @@ · 40 unmodified lines | |||
| 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 { · 401 unmodified lines | |||
| 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 { · 2 unmodified lines | |||
| 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 { · 19 unmodified lines | |||
| 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 { · 4 unmodified lines | |||
| 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 { · 62 unmodified lines | |||
| 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 { · 30 unmodified lines | |||
| 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 { · 47 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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, · 16 unmodified lines | |||
| 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; · 27 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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); · 10 unmodified lines | |||
| 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); · 10 unmodified lines | |||
| 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); |
| @@ -357,7 +357,7 @@ static int mxb_init_done(struct saa7146_dev* dev) · 356 unmodified lines | |||
| 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) · 15 unmodified lines | |||
| 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 · 384 unmodified lines | |||
| 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 · 3 unmodified lines | |||
| 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 | } |
| @@ -357,7 +357,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) · 356 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 64 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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 | /** |
| @@ -958,8 +958,10 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait) · 957 unmodified lines | |||
| 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; |
| @@ -1572,7 +1572,7 @@ zoran_init_hardware (struct zoran *zr) · 1571 unmodified lines | |||
| 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 | ||
| @@ -1469,7 +1469,7 @@ zoran_set_norm (struct zoran *zr, · 1468 unmodified lines | |||
| 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) |
| @@ -427,15 +427,12 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) · 426 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 176 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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) · 414 unmodified lines | |||
| 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"); |
| @@ -2269,7 +2269,7 @@ out: · 2268 unmodified lines | |||
| 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) · 19 unmodified lines | |||
| 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) · 932 unmodified lines | |||
| 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 | } |
| @@ -355,8 +355,17 @@ static int vpbe_start_streaming(struct vb2_queue *vq, unsigned int count) · 354 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 15 unmodified lines | |||
| 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, · 275 unmodified lines | |||
| 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) · 783 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 22 unmodified lines | |||
| 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) · 48 unmodified lines | |||
| 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 = { · 21 unmodified lines | |||
| 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, · 73 unmodified lines | |||
| 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, · 20 unmodified lines | |||
| 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 | ||
| @@ -498,6 +498,7 @@ unlock: · 497 unmodified lines | |||
| 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) · 13 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 202 unmodified lines | |||
| 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) · 469 unmodified lines | |||
| 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) · 686 unmodified lines | |||
| 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 | ||
| @@ -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 = { · 59 unmodified lines | |||
| 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); · 2 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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, · 13 unmodified lines | |||
| 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, · 3 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 4 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 15 unmodified lines | |||
| 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) · 70 unmodified lines | |||
| 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) · 195 unmodified lines | |||
| 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 | ||
| @@ -836,415 +758,6 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode) · 142 unmodified lines | |||
| 836 | common->set_addr = ch0_set_videobuf_addr; | 758 | common->set_addr = ch0_set_videobuf_addr; |
| 837 | } | 759 | } |
| 838 | 760 | ||
| 839 | /** | ||
| 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 | /** | 761 | /** |
| 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 |
| @@ -1348,8 +861,8 @@ static int vpif_set_input( · 97 unmodified lines | |||
| 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) · 19 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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, · 12 unmodified lines | |||
| 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, · 15 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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, · 22 unmodified lines | |||
| 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, · 9 unmodified lines | |||
| 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, · 14 unmodified lines | |||
| 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, · 19 unmodified lines | |||
| 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)); |
| @@ -1661,61 +1147,6 @@ static int vpif_querycap(struct file *file, void *priv, · 1 unmodified line | |||
| 1661 | return 0; | 1147 | return 0; |
| 1662 | } | 1148 | } |
| 1663 | 1149 | ||
| 1664 | /** | ||
| 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 | /** | 1150 | /** |
| 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 |
| @@ -1726,13 +1157,27 @@ static int · 4 unmodified lines | |||
| 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 · 7 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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, · 69 unmodified lines | |||
| 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) · 17 unmodified lines | |||
| 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, · 71 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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: · 6 unmodified lines | |||
| 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) · 30 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 17 unmodified lines | |||
| 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: · 66 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 8 unmodified lines | |||
| 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) · 14 unmodified lines | |||
| 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, |
| @@ -19,8 +19,6 @@ · 18 unmodified lines | |||
| 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 { · 36 unmodified lines | |||
| 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 { · 6 unmodified lines | |||
| 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 { · 14 unmodified lines | |||
| 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 { · 12 unmodified lines | |||
| 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 { · 13 unmodified lines | |||
| 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 */ |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 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); · 26 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 3 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 15 unmodified lines | |||
| 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) · 75 unmodified lines | |||
| 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) · 89 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 64 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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, · 8 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 2 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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, · 2 unmodified lines | |||
| 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, · 87 unmodified lines | |||
| 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 · 4 unmodified lines | |||
| 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, · 8 unmodified lines | |||
| 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, · 75 unmodified lines | |||
| 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) · 13 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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, · 22 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 20 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 19 unmodified lines | |||
| 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: · 59 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 12 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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, |
| @@ -13,8 +13,8 @@ · 12 unmodified lines | |||
| 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 { · 46 unmodified lines | |||
| 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 { · 6 unmodified lines | |||
| 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 { · 3 unmodified lines | |||
| 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 { · 3 unmodified lines | |||
| 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 { · 7 unmodified lines | |||
| 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 { · 3 unmodified lines | |||
| 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 */ | ||
| @@ -66,15 +66,13 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) · 65 unmodified lines | |||
| 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) |
| @@ -3,6 +3,7 @@ config VIDEO_SAMSUNG_EXYNOS4_IS · 2 unmodified lines | |||
| 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 · 8 unmodified lines | |||
| 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 |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | |||
| 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. */ |
| @@ -294,15 +294,15 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) · 293 unmodified lines | |||
| 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) |
| @@ -56,8 +56,8 @@ static struct fimc_fmt fimc_formats[] = { · 55 unmodified lines | |||
| 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) · 386 unmodified lines | |||
| 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; |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | |||
| 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) |
| @@ -367,6 +367,9 @@ static void fimc_is_free_cpu_memory(struct fimc_is *is) · 366 unmodified lines | |||
| 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 | } |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | |||
| 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, · 88 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 14 unmodified lines | |||
| 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) |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | |||
| 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 | ||
| @@ -12,7 +12,7 @@ · 11 unmodified lines | |||
| 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" |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | |||
| 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) · 313 unmodified lines | |||
| 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, |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | |||
| 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" |
| @@ -85,7 +85,7 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) · 84 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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, · 95 unmodified lines | |||
| 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, · 138 unmodified lines | |||
| 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) · 112 unmodified lines | |||
| 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, |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 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" |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | |||
| 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 @@ · 1 unmodified line | |||
| 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, · 174 unmodified lines | |||
| 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) · 19 unmodified lines | |||
| 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) · 71 unmodified lines | |||
| 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, · 13 unmodified lines | |||
| 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, · 40 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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) · 6 unmodified lines | |||
| 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: · 150 unmodified lines | |||
| 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, · 27 unmodified lines | |||
| 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) · 21 unmodified lines | |||
| 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) · 278 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 27 unmodified lines | |||
| 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) · 152 unmodified lines | |||
| 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: · 85 unmodified lines | |||
| 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) · 57 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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); |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | |||
| 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" |
| @@ -22,14 +22,13 @@ · 21 unmodified lines | |||
| 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) · 694 unmodified lines | |||
| 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, · 31 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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 | ||
| @@ -964,7 +964,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) · 963 unmodified lines | |||
| 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 | ||
| @@ -1156,7 +1156,7 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) · 1155 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 8 unmodified lines | |||
| 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 | ||
| @@ -787,7 +787,7 @@ static int m2mtest_start_streaming(struct vb2_queue *q, unsigned count) · 786 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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 = { |
| @@ -207,10 +207,8 @@ struct emmaprp_dev { · 206 unmodified lines | |||
| 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) · 684 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 20 unmodified lines | |||
| 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: · 27 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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 | } |
| @@ -435,10 +435,10 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) · 434 unmodified lines | |||
| 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, |
| @@ -192,8 +192,7 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { · 191 unmodified lines | |||
| 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) · 759 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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, · 83 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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, · 15 unmodified lines | |||
| 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) · 20 unmodified lines | |||
| 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, · 35 unmodified lines | |||
| 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 = { · 381 unmodified lines | |||
| 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) · 92 unmodified lines | |||
| 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) · 162 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 36 unmodified lines | |||
| 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 = { · 178 unmodified lines | |||
| 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[] = { · 12 unmodified lines | |||
| 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, |
| @@ -117,8 +117,10 @@ struct s5p_jpeg { · 116 unmodified lines | |||
| 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 | /** |
| @@ -141,6 +141,7 @@ · 140 unmodified lines | |||
| 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 @@ · 234 unmodified lines | |||
| 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) |
| @@ -18,8 +18,6 @@ · 17 unmodified lines | |||
| 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 @@ · 30 unmodified lines | |||
| 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*/ |
| @@ -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*/ | ||
| @@ -309,12 +309,15 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, · 308 unmodified lines | |||
| 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, · 18 unmodified lines | |||
| 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, · 11 unmodified lines | |||
| 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) · 269 unmodified lines | |||
| 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) · 114 unmodified lines | |||
| 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) · 103 unmodified lines | |||
| 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) · 307 unmodified lines | |||
| 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 = { · 139 unmodified lines | |||
| 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 = { · 20 unmodified lines | |||
| 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 = { · 20 unmodified lines | |||
| 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[] = { · 7 unmodified lines | |||
| 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[] = { · 9 unmodified lines | |||
| 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 | }; |
| @@ -23,8 +23,7 @@ · 22 unmodified lines | |||
| 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 { · 192 unmodified lines | |||
| 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 { · 101 unmodified lines | |||
| 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 { · 327 unmodified lines | |||
| 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); · 31 unmodified lines | |||
| 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_ */ |
| @@ -400,3 +400,65 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) · 399 unmodified lines | |||
| 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 | } | ||
| @@ -28,4 +28,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev); · 27 unmodified lines | |||
| 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 */ |
| @@ -25,15 +25,13 @@ · 24 unmodified lines | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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, · 124 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 69 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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: · 51 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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, · 69 unmodified lines | |||
| 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, · 163 unmodified lines | |||
| 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) · 170 unmodified lines | |||
| 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) · 37 unmodified lines | |||
| 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) · 113 unmodified lines | |||
| 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); |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 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[] = { · 9 unmodified lines | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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[] = { · 1 unmodified line | |||
| 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) · 676 unmodified lines | |||
| 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) · 98 unmodified lines | |||
| 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, · 46 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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) · 44 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 27 unmodified lines | |||
| 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) · 14 unmodified lines | |||
| 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) · 809 unmodified lines | |||
| 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) · 22 unmodified lines | |||
| 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) |
| @@ -31,6 +31,12 @@ void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev) · 30 unmodified lines | |||
| 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 | { |
| @@ -17,6 +17,259 @@ · 16 unmodified lines | |||
| 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 { · 57 unmodified lines | |||
| 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, |
| @@ -43,10 +43,10 @@ · 42 unmodified lines | |||
| 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) · 24 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 33 unmodified lines | |||
| 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) · 17 unmodified lines | |||
| 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) · 133 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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, · 5 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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, · 5 unmodified lines | |||
| 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, · 3 unmodified lines | |||
| 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, · 3 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 4 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 1 unmodified line | |||
| 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) · 1 unmodified line | |||
| 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) · 3 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 1 unmodified line | |||
| 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) · 1 unmodified line | |||
| 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) · 3 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 1 unmodified line | |||
| 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) · 4 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 15 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 4 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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, · 17 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 368 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 8 unmodified lines | |||
| 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 */ |
| @@ -40,11 +40,6 @@ · 39 unmodified lines | |||
| 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_ */ |
| @@ -674,6 +674,8 @@ static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd, · 673 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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 = { · 12 unmodified lines | |||
| 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, |
| @@ -225,6 +225,9 @@ static int hdmiphy_s_dv_timings(struct v4l2_subdev *sd, · 224 unmodified lines | |||
| 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 = { · 28 unmodified lines | |||
| 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, |
| @@ -509,9 +509,11 @@ static int mxr_enum_dv_timings(struct file *file, void *fh, · 508 unmodified lines | |||
| 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, · 49 unmodified lines | |||
| 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) · 409 unmodified lines | |||
| 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) · 39 unmodified lines | |||
| 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 = { |
| @@ -406,7 +406,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) · 405 unmodified lines | |||
| 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) · 20 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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 = { |
| @@ -741,7 +741,7 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) · 740 unmodified lines | |||
| 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) · 25 unmodified lines | |||
| 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 = { |
| @@ -406,7 +406,7 @@ static int mx3_videobuf_init(struct vb2_buffer *vb) · 405 unmodified lines | |||
| 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) · 17 unmodified lines | |||
| 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 = { |
| @@ -513,7 +513,7 @@ static int rcar_vin_videobuf_init(struct vb2_buffer *vb) · 512 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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 = { |
| @@ -471,7 +471,7 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb) · 470 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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 = { |
| @@ -314,7 +314,7 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a) · 313 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 948 unmodified lines | |||
| 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) · 714 unmodified lines | |||
| 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); |
| @@ -180,16 +180,16 @@ struct csc_data *csc_create(struct platform_device *pdev) · 179 unmodified lines | |||
| 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; |
| @@ -302,9 +302,9 @@ struct sc_data *sc_create(struct platform_device *pdev) · 301 unmodified lines | |||
| 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; |
| @@ -614,8 +614,17 @@ static void dump_dtd(struct vpdma_dtd *dtd) · 613 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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, · 1 unmodified line | |||
| 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, · 23 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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) · 67 unmodified lines | |||
| 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) · 23 unmodified lines | |||
| 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) · 21 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) { |
| @@ -35,8 +35,8 @@ struct vpdma_data { · 34 unmodified lines | |||
| 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, · 143 unmodified lines | |||
| 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, · 9 unmodified lines | |||
| 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 |
| @@ -410,8 +410,10 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx, · 409 unmodified lines | |||
| 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) · 568 unmodified lines | |||
| 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) · 22 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 20 unmodified lines | |||
| 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) · 522 unmodified lines | |||
| 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 = { · 81 unmodified lines | |||
| 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, · 106 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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) · 27 unmodified lines | |||
| 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) · 213 unmodified lines | |||
| 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) · 74 unmodified lines | |||
| 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: |
| @@ -347,7 +347,7 @@ static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id std) · 346 unmodified lines | |||
| 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) · 446 unmodified lines | |||
| 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) · 13 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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 | ||
| @@ -2586,7 +2586,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) · 2585 unmodified lines | |||
| 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) · 82 unmodified lines | |||
| 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, · 127 unmodified lines | |||
| 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 | ||
| @@ -906,12 +906,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) · 905 unmodified lines | |||
| 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) |
| @@ -720,7 +720,7 @@ static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) · 719 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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 = { |
| @@ -747,11 +747,19 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, · 746 unmodified lines | |||
| 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, · 511 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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); |
| @@ -230,6 +230,13 @@ config MEDIA_TUNER_TUA9001 · 229 unmodified lines | |||
| 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 |
| @@ -31,6 +31,7 @@ obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o · 30 unmodified lines | |||
| 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 |
| @@ -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"); | ||
| @@ -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 | ||
| @@ -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 | ||
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 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 { · 34 unmodified lines | |||
| 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 { · 61 unmodified lines | |||
| 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 { · 3 unmodified lines | |||
| 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) · 59 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 30 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 12 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 2 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 14 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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, · 11 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 17 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 35 unmodified lines | |||
| 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) · 23 unmodified lines | |||
| 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) · 40 unmodified lines | |||
| 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) · 69 unmodified lines | |||
| 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) · 18 unmodified lines | |||
| 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, · 59 unmodified lines | |||
| 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: · 11 unmodified lines | |||
| 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, · 20 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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, · 18 unmodified lines | |||
| 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) · 54 unmodified lines | |||
| 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: · 9 unmodified lines | |||
| 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: · 1 unmodified line | |||
| 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: · 22 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 12 unmodified lines | |||
| 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, · 65 unmodified lines | |||
| 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, · 24 unmodified lines | |||
| 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) { |
| @@ -114,16 +114,20 @@ static void urb_completion(struct urb *purb) · 113 unmodified lines | |||
| 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) · 122 unmodified lines | |||
| 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) · 36 unmodified lines | |||
| 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) · 36 unmodified lines | |||
| 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) · 38 unmodified lines | |||
| 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) · 83 unmodified lines | |||
| 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); |
| @@ -1109,7 +1109,7 @@ static void au0828_init_tuner(struct au0828_dev *dev) · 1108 unmodified lines | |||
| 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) · 252 unmodified lines | |||
| 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 | ||
| @@ -104,6 +104,8 @@ struct au0828_dvb { · 103 unmodified lines | |||
| 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 { |
| @@ -1516,7 +1516,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) · 1515 unmodified lines | |||
| 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 | ||
| @@ -1009,7 +1009,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) · 1008 unmodified lines | |||
| 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) · 92 unmodified lines | |||
| 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) · 984 unmodified lines | |||
| 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); |
| @@ -1537,6 +1537,12 @@ static const struct usb_device_id rtl28xxu_id_table[] = { · 1536 unmodified lines | |||
| 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, |
| @@ -1088,6 +1088,7 @@ static struct usb_device_id az6027_usb_table[] = { · 1087 unmodified lines | |||
| 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 = { · 42 unmodified lines | |||
| 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 = { · 19 unmodified lines | |||
| 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 | } |
| @@ -59,7 +59,7 @@ extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 · 58 unmodified lines | |||
| 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, |
| @@ -754,17 +754,20 @@ resubmit: · 753 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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, · 32 unmodified lines | |||
| 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 | } |
| @@ -514,7 +514,7 @@ static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d) · 513 unmodified lines | |||
| 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) { |
| @@ -214,10 +214,10 @@ static void technisat_usb2_frontend_reset(struct usb_device *udev) · 213 unmodified lines | |||
| 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 · 5 unmodified lines | |||
| 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 · 8 unmodified lines | |||
| 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) · 52 unmodified lines | |||
| 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) · 44 unmodified lines | |||
| 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) · 293 unmodified lines | |||
| 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 | } |
| @@ -57,6 +57,8 @@ config VIDEO_EM28XX_DVB · 56 unmodified lines | |||
| 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. |
| @@ -92,7 +92,7 @@ static void em28xx_audio_isocirq(struct urb *urb) · 91 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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) · 69 unmodified lines | |||
| 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) · 140 unmodified lines | |||
| 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, · 40 unmodified lines | |||
| 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) · 14 unmodified lines | |||
| 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, · 15 unmodified lines | |||
| 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) · 480 unmodified lines | |||
| 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) · 48 unmodified lines | |||
| 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) · 15 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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 | ||
| @@ -330,13 +330,14 @@ int em28xx_init_camera(struct em28xx *dev) · 329 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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) · 15 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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; |
| @@ -467,6 +467,18 @@ static struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = { · 466 unmodified lines | |||
| 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[] = { · 1747 unmodified lines | |||
| 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[] = { · 171 unmodified lines | |||
| 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) · 279 unmodified lines | |||
| 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) · 28 unmodified lines | |||
| 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, · 262 unmodified lines | |||
| 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, · 417 unmodified lines | |||
| 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 | } |
| @@ -55,6 +55,8 @@ · 54 unmodified lines | |||
| 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 { · 32 unmodified lines | |||
| 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) · 644 unmodified lines | |||
| 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) · 747 unmodified lines | |||
| 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) · 80 unmodified lines | |||
| 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) · 59 unmodified lines | |||
| 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; |
| @@ -939,7 +939,6 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, · 938 unmodified lines | |||
| 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) { |
| @@ -16,5 +16,5 @@ · 15 unmodified lines | |||
| 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; |
| @@ -47,12 +47,13 @@ static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, · 46 unmodified lines | |||
| 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, · 10 unmodified lines | |||
| 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", |
| @@ -141,6 +141,33 @@ static struct em28xx_fmt format[] = { · 140 unmodified lines | |||
| 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) · 19 unmodified lines | |||
| 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) · 18 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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, · 43 unmodified lines | |||
| 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) · 12 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 10 unmodified lines | |||
| 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, · 46 unmodified lines | |||
| 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, · 8 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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, · 1 unmodified line | |||
| 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, · 17 unmodified lines | |||
| 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, · 39 unmodified lines | |||
| 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, · 69 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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, · 13 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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, · 6 unmodified lines | |||
| 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, · 2 unmodified lines | |||
| 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, · 143 unmodified lines | |||
| 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 · 11 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 5 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 11 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 7 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 7 unmodified lines | |||
| 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) · 27 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 13 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 24 unmodified lines | |||
| 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, · 68 unmodified lines | |||
| 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, · 14 unmodified lines | |||
| 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, · 35 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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, · 4 unmodified lines | |||
| 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) · 7 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 1 unmodified line | |||
| 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, · 6 unmodified lines | |||
| 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, · 30 unmodified lines | |||
| 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, · 95 unmodified lines | |||
| 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, · 6 unmodified lines | |||
| 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, · 2 unmodified lines | |||
| 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, · 10 unmodified lines | |||
| 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, · 74 unmodified lines | |||
| 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, · 15 unmodified lines | |||
| 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, · 58 unmodified lines | |||
| 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, · 16 unmodified lines | |||
| 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,11 +1860,26 @@ static int radio_s_tuner(struct file *file, void *priv, · 6 unmodified lines | |||
| 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 | ||
| 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 | |||
| 1812 | /* | 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 |
| @@ -1817,6 +1888,7 @@ static int em28xx_v4l2_open(struct file *filp) · 2 unmodified lines | |||
| 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) · 12 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 32 unmodified lines | |||
| 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) · 9 unmodified lines | |||
| 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 = { · 50 unmodified lines | |||
| 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 = { · 22 unmodified lines | |||
| 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, · 27 unmodified lines | |||
| 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, · 7 unmodified lines | |||
| 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) · 4 unmodified lines | |||
| 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) · 8 unmodified lines | |||
| 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) · 1 unmodified line | |||
| 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) · 9 unmodified lines | |||
| 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) · 44 unmodified lines | |||
| 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) · 16 unmodified lines | |||
| 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) · 3 unmodified lines | |||
| 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) · 2 unmodified lines | |||
| 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) · 6 unmodified lines | |||
| 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 | } |
| @@ -140,6 +140,7 @@ · 139 unmodified lines | |||
| 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 { · 351 unmodified lines | |||
| 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 { · 10 unmodified lines | |||
| 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 { · 22 unmodified lines | |||
| 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 { · 7 unmodified lines | |||
| 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 { · 5 unmodified lines | |||
| 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 { · 6 unmodified lines | |||
| 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 { · 8 unmodified lines | |||
| 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 { · 37 unmodified lines | |||
| 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); · 81 unmodified lines | |||
| 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 |
| @@ -50,6 +50,16 @@ config USB_GSPCA_CPIA1 · 49 unmodified lines | |||
| 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 |
| @@ -2,6 +2,7 @@ obj-$(CONFIG_USB_GSPCA) += gspca_main.o · 1 unmodified line | |||
| 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 · 40 unmodified lines | |||
| 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 |
| @@ -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); | ||
366 more lines aren’t shown here.
This diff is large: its 499 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 1621 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 337 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 1048 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.