diff options
572 files changed, 37792 insertions, 21327 deletions
diff --git a/Documentation/ABI/testing/debugfs-cec-error-inj b/Documentation/ABI/testing/debugfs-cec-error-inj new file mode 100644 index 000000000000..122b65c5fe62 --- /dev/null +++ b/Documentation/ABI/testing/debugfs-cec-error-inj | |||
@@ -0,0 +1,40 @@ | |||
1 | What: /sys/kernel/debug/cec/*/error-inj | ||
2 | Date: March 2018 | ||
3 | Contact: Hans Verkuil <hans.verkuil@cisco.com> | ||
4 | Description: | ||
5 | |||
6 | The CEC Framework allows for CEC error injection commands through | ||
7 | debugfs. Drivers that support this will create an error-inj file | ||
8 | through which the error injection commands can be given. | ||
9 | |||
10 | The basic syntax is as follows: | ||
11 | |||
12 | Leading spaces/tabs are ignored. If the next character is a '#' or the | ||
13 | end of the line was reached, then the whole line is ignored. Otherwise | ||
14 | a command is expected. | ||
15 | |||
16 | It is up to the driver to decide what commands to implement. The only | ||
17 | exception is that the command 'clear' without any arguments must be | ||
18 | implemented and that it will remove all current error injection | ||
19 | commands. | ||
20 | |||
21 | This ensures that you can always do 'echo clear >error-inj' to clear any | ||
22 | error injections without having to know the details of the driver-specific | ||
23 | commands. | ||
24 | |||
25 | Note that the output of 'error-inj' shall be valid as input to 'error-inj'. | ||
26 | So this must work: | ||
27 | |||
28 | $ cat error-inj >einj.txt | ||
29 | $ cat einj.txt >error-inj | ||
30 | |||
31 | Other than these basic rules described above this ABI is not considered | ||
32 | stable and may change in the future. | ||
33 | |||
34 | Drivers that implement this functionality must document the commands as | ||
35 | part of the CEC documentation and must keep that documentation up to date | ||
36 | when changes are made. | ||
37 | |||
38 | The following CEC error injection implementations exist: | ||
39 | |||
40 | - Documentation/media/uapi/cec/cec-pin-error-inj.rst | ||
diff --git a/Documentation/devicetree/bindings/media/coda.txt b/Documentation/devicetree/bindings/media/coda.txt index 2865d04e4030..90eb74cc1993 100644 --- a/Documentation/devicetree/bindings/media/coda.txt +++ b/Documentation/devicetree/bindings/media/coda.txt | |||
@@ -7,8 +7,9 @@ called VPU (Video Processing Unit). | |||
7 | Required properties: | 7 | Required properties: |
8 | - compatible : should be "fsl,<chip>-src" for i.MX SoCs: | 8 | - compatible : should be "fsl,<chip>-src" for i.MX SoCs: |
9 | (a) "fsl,imx27-vpu" for CodaDx6 present in i.MX27 | 9 | (a) "fsl,imx27-vpu" for CodaDx6 present in i.MX27 |
10 | (b) "fsl,imx53-vpu" for CODA7541 present in i.MX53 | 10 | (b) "fsl,imx51-vpu" for CodaHx4 present in i.MX51 |
11 | (c) "fsl,imx6q-vpu" for CODA960 present in i.MX6q | 11 | (c) "fsl,imx53-vpu" for CODA7541 present in i.MX53 |
12 | (d) "fsl,imx6q-vpu" for CODA960 present in i.MX6q | ||
12 | - reg: should be register base and length as documented in the | 13 | - reg: should be register base and length as documented in the |
13 | SoC reference manual | 14 | SoC reference manual |
14 | - interrupts : Should contain the VPU interrupt. For CODA960, | 15 | - interrupts : Should contain the VPU interrupt. For CODA960, |
diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index 9cbd92eb5d05..dcf57e7c60eb 100644 --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt | |||
@@ -13,7 +13,11 @@ Required Properties: | |||
13 | - "adi,adv7611" for the ADV7611 | 13 | - "adi,adv7611" for the ADV7611 |
14 | - "adi,adv7612" for the ADV7612 | 14 | - "adi,adv7612" for the ADV7612 |
15 | 15 | ||
16 | - reg: I2C slave address | 16 | - reg: I2C slave addresses |
17 | The ADV76xx has up to thirteen 256-byte maps that can be accessed via the | ||
18 | main I2C ports. Each map has it own I2C address and acts as a standard | ||
19 | slave device on the I2C bus. The main address is mandatory, others are | ||
20 | optional and revert to defaults if not specified. | ||
17 | 21 | ||
18 | - hpd-gpios: References to the GPIOs that control the HDMI hot-plug | 22 | - hpd-gpios: References to the GPIOs that control the HDMI hot-plug |
19 | detection pins, one per HDMI input. The active flag indicates the GPIO | 23 | detection pins, one per HDMI input. The active flag indicates the GPIO |
@@ -35,6 +39,11 @@ Optional Properties: | |||
35 | 39 | ||
36 | - reset-gpios: Reference to the GPIO connected to the device's reset pin. | 40 | - reset-gpios: Reference to the GPIO connected to the device's reset pin. |
37 | - default-input: Select which input is selected after reset. | 41 | - default-input: Select which input is selected after reset. |
42 | - reg-names : Names of maps with programmable addresses. | ||
43 | It can contain any map needing a non-default address. | ||
44 | Possible maps names are : | ||
45 | "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe", | ||
46 | "rep", "edid", "hdmi", "test", "cp", "vdp" | ||
38 | 47 | ||
39 | Optional Endpoint Properties: | 48 | Optional Endpoint Properties: |
40 | 49 | ||
@@ -52,7 +61,12 @@ Example: | |||
52 | 61 | ||
53 | hdmi_receiver@4c { | 62 | hdmi_receiver@4c { |
54 | compatible = "adi,adv7611"; | 63 | compatible = "adi,adv7611"; |
55 | reg = <0x4c>; | 64 | /* |
65 | * The edid page will be accessible @ 0x66 on the I2C bus. All | ||
66 | * other maps will retain their default addresses. | ||
67 | */ | ||
68 | reg = <0x4c>, <0x66>; | ||
69 | reg-names "main", "edid"; | ||
56 | 70 | ||
57 | reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; | 71 | reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; |
58 | hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; | 72 | hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; |
diff --git a/Documentation/devicetree/bindings/media/i2c/ov2685.txt b/Documentation/devicetree/bindings/media/i2c/ov2685.txt new file mode 100644 index 000000000000..625c4a8c0d53 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov2685.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | * Omnivision OV2685 MIPI CSI-2 sensor | ||
2 | |||
3 | Required Properties: | ||
4 | - compatible: shall be "ovti,ov2685" | ||
5 | - clocks: reference to the xvclk input clock | ||
6 | - clock-names: shall be "xvclk" | ||
7 | - avdd-supply: Analog voltage supply, 2.8 volts | ||
8 | - dovdd-supply: Digital I/O voltage supply, 1.8 volts | ||
9 | - dvdd-supply: Digital core voltage supply, 1.8 volts | ||
10 | - reset-gpios: Low active reset gpio | ||
11 | |||
12 | The device node shall contain one 'port' child node with an | ||
13 | 'endpoint' subnode for its digital output video port, | ||
14 | in accordance with the video interface bindings defined in | ||
15 | Documentation/devicetree/bindings/media/video-interfaces.txt. | ||
16 | The endpoint optional property 'data-lanes' shall be "<1>". | ||
17 | |||
18 | Example: | ||
19 | &i2c7 { | ||
20 | ov2685: camera-sensor@3c { | ||
21 | compatible = "ovti,ov2685"; | ||
22 | reg = <0x3c>; | ||
23 | pinctrl-names = "default"; | ||
24 | pinctrl-0 = <&clk_24m_cam>; | ||
25 | |||
26 | clocks = <&cru SCLK_TESTCLKOUT1>; | ||
27 | clock-names = "xvclk"; | ||
28 | |||
29 | avdd-supply = <&pp2800_cam>; | ||
30 | dovdd-supply = <&pp1800>; | ||
31 | dvdd-supply = <&pp1800>; | ||
32 | reset-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; | ||
33 | |||
34 | port { | ||
35 | ucam_out: endpoint { | ||
36 | remote-endpoint = <&mipi_in_ucam>; | ||
37 | data-lanes = <1>; | ||
38 | }; | ||
39 | }; | ||
40 | }; | ||
41 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/i2c/ov5695.txt b/Documentation/devicetree/bindings/media/i2c/ov5695.txt new file mode 100644 index 000000000000..640a63717d96 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov5695.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | * Omnivision OV5695 MIPI CSI-2 sensor | ||
2 | |||
3 | Required Properties: | ||
4 | - compatible: shall be "ovti,ov5695" | ||
5 | - clocks: reference to the xvclk input clock | ||
6 | - clock-names: shall be "xvclk" | ||
7 | - avdd-supply: Analog voltage supply, 2.8 volts | ||
8 | - dovdd-supply: Digital I/O voltage supply, 1.8 volts | ||
9 | - dvdd-supply: Digital core voltage supply, 1.2 volts | ||
10 | - reset-gpios: Low active reset gpio | ||
11 | |||
12 | The device node shall contain one 'port' child node with an | ||
13 | 'endpoint' subnode for its digital output video port, | ||
14 | in accordance with the video interface bindings defined in | ||
15 | Documentation/devicetree/bindings/media/video-interfaces.txt. | ||
16 | The endpoint optional property 'data-lanes' shall be "<1 2>". | ||
17 | |||
18 | Example: | ||
19 | &i2c7 { | ||
20 | ov5695: camera-sensor@36 { | ||
21 | compatible = "ovti,ov5695"; | ||
22 | reg = <0x36>; | ||
23 | pinctrl-names = "default"; | ||
24 | pinctrl-0 = <&clk_24m_cam>; | ||
25 | |||
26 | clocks = <&cru SCLK_TESTCLKOUT1>; | ||
27 | clock-names = "xvclk"; | ||
28 | |||
29 | avdd-supply = <&pp2800_cam>; | ||
30 | dovdd-supply = <&pp1800>; | ||
31 | dvdd-supply = <&pp1250_cam>; | ||
32 | reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; | ||
33 | |||
34 | port { | ||
35 | wcam_out: endpoint { | ||
36 | remote-endpoint = <&mipi_in_wcam>; | ||
37 | data-lanes = <1 2>; | ||
38 | }; | ||
39 | }; | ||
40 | }; | ||
41 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/i2c/ov7670.txt b/Documentation/devicetree/bindings/media/i2c/ov7670.txt index 826b6563b009..2c972a56f3cb 100644 --- a/Documentation/devicetree/bindings/media/i2c/ov7670.txt +++ b/Documentation/devicetree/bindings/media/i2c/ov7670.txt | |||
@@ -9,14 +9,21 @@ Required Properties: | |||
9 | - clocks: reference to the xclk input clock. | 9 | - clocks: reference to the xclk input clock. |
10 | - clock-names: should be "xclk". | 10 | - clock-names: should be "xclk". |
11 | 11 | ||
12 | Required Endpoint Properties: | ||
13 | - hsync-active: active state of the HSYNC signal, 0/1 for LOW/HIGH respectively. | ||
14 | - vsync-active: active state of the VSYNC signal, 0/1 for LOW/HIGH respectively. | ||
15 | |||
12 | Optional Properties: | 16 | Optional Properties: |
13 | - reset-gpios: reference to the GPIO connected to the resetb pin, if any. | 17 | - reset-gpios: reference to the GPIO connected to the resetb pin, if any. |
14 | Active is low. | 18 | Active is low. |
15 | - powerdown-gpios: reference to the GPIO connected to the pwdn pin, if any. | 19 | - powerdown-gpios: reference to the GPIO connected to the pwdn pin, if any. |
16 | Active is high. | 20 | Active is high. |
21 | - ov7670,pclk-hb-disable: a boolean property to suppress pixel clock output | ||
22 | signal during horizontal blankings. | ||
17 | 23 | ||
18 | The device node must contain one 'port' child node for its digital output | 24 | The device node must contain one 'port' child node with one 'endpoint' child |
19 | video port, in accordance with the video interface bindings defined in | 25 | sub-node for its digital output video port, in accordance with the video |
26 | interface bindings defined in: | ||
20 | Documentation/devicetree/bindings/media/video-interfaces.txt. | 27 | Documentation/devicetree/bindings/media/video-interfaces.txt. |
21 | 28 | ||
22 | Example: | 29 | Example: |
@@ -34,8 +41,13 @@ Example: | |||
34 | assigned-clocks = <&pck0>; | 41 | assigned-clocks = <&pck0>; |
35 | assigned-clock-rates = <25000000>; | 42 | assigned-clock-rates = <25000000>; |
36 | 43 | ||
44 | ov7670,pclk-hb-disable; | ||
45 | |||
37 | port { | 46 | port { |
38 | ov7670_0: endpoint { | 47 | ov7670_0: endpoint { |
48 | hsync-active = <0>; | ||
49 | vsync-active = <0>; | ||
50 | |||
39 | remote-endpoint = <&isi_0>; | 51 | remote-endpoint = <&isi_0>; |
40 | }; | 52 | }; |
41 | }; | 53 | }; |
diff --git a/Documentation/devicetree/bindings/media/i2c/ov9650.txt b/Documentation/devicetree/bindings/media/i2c/ov9650.txt new file mode 100644 index 000000000000..506dfc52872a --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov9650.txt | |||
@@ -0,0 +1,36 @@ | |||
1 | * Omnivision OV9650/OV9652 CMOS sensor | ||
2 | |||
3 | Required Properties: | ||
4 | - compatible: shall be one of | ||
5 | "ovti,ov9650" | ||
6 | "ovti,ov9652" | ||
7 | - clocks: reference to the xvclk input clock. | ||
8 | |||
9 | Optional Properties: | ||
10 | - reset-gpios: reference to the GPIO connected to the resetb pin, if any. | ||
11 | Active is high. | ||
12 | - powerdown-gpios: reference to the GPIO connected to the pwdn pin, if any. | ||
13 | Active is high. | ||
14 | |||
15 | The device node shall contain one 'port' child node with one child 'endpoint' | ||
16 | subnode for its digital output video port, in accordance with the video | ||
17 | interface bindings defined in Documentation/devicetree/bindings/media/ | ||
18 | video-interfaces.txt. | ||
19 | |||
20 | Example: | ||
21 | |||
22 | &i2c0 { | ||
23 | ov9650: camera@30 { | ||
24 | compatible = "ovti,ov9650"; | ||
25 | reg = <0x30>; | ||
26 | reset-gpios = <&axi_gpio_0 0 GPIO_ACTIVE_HIGH>; | ||
27 | powerdown-gpios = <&axi_gpio_0 1 GPIO_ACTIVE_HIGH>; | ||
28 | clocks = <&xclk>; | ||
29 | |||
30 | port { | ||
31 | ov9650_0: endpoint { | ||
32 | remote-endpoint = <&vcap1_in0>; | ||
33 | }; | ||
34 | }; | ||
35 | }; | ||
36 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/i2c/tda1997x.txt b/Documentation/devicetree/bindings/media/i2c/tda1997x.txt new file mode 100644 index 000000000000..e76167999d76 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/tda1997x.txt | |||
@@ -0,0 +1,178 @@ | |||
1 | Device-Tree bindings for the NXP TDA1997x HDMI receiver | ||
2 | |||
3 | The TDA19971/73 are HDMI video receivers. | ||
4 | |||
5 | The TDA19971 Video port output pins can be used as follows: | ||
6 | - RGB 8bit per color (24 bits total): R[11:4] B[11:4] G[11:4] | ||
7 | - YUV444 8bit per color (24 bits total): Y[11:4] Cr[11:4] Cb[11:4] | ||
8 | - YUV422 semi-planar 8bit per component (16 bits total): Y[11:4] CbCr[11:4] | ||
9 | - YUV422 semi-planar 10bit per component (20 bits total): Y[11:2] CbCr[11:2] | ||
10 | - YUV422 semi-planar 12bit per component (24 bits total): - Y[11:0] CbCr[11:0] | ||
11 | - YUV422 BT656 8bit per component (8 bits total): YCbCr[11:4] (2-cycles) | ||
12 | - YUV422 BT656 10bit per component (10 bits total): YCbCr[11:2] (2-cycles) | ||
13 | - YUV422 BT656 12bit per component (12 bits total): YCbCr[11:0] (2-cycles) | ||
14 | |||
15 | The TDA19973 Video port output pins can be used as follows: | ||
16 | - RGB 12bit per color (36 bits total): R[11:0] B[11:0] G[11:0] | ||
17 | - YUV444 12bit per color (36 bits total): Y[11:0] Cb[11:0] Cr[11:0] | ||
18 | - YUV422 semi-planar 12bit per component (24 bits total): Y[11:0] CbCr[11:0] | ||
19 | - YUV422 BT656 12bit per component (12 bits total): YCbCr[11:0] (2-cycles) | ||
20 | |||
21 | The Video port output pins are mapped via 4-bit 'pin groups' allowing | ||
22 | for a variety of connection possibilities including swapping pin order within | ||
23 | pin groups. The video_portcfg device-tree property consists of register mapping | ||
24 | pairs which map a chip-specific VP output register to a 4-bit pin group. If | ||
25 | the pin group needs to be bit-swapped you can use the *_S pin-group defines. | ||
26 | |||
27 | Required Properties: | ||
28 | - compatible : | ||
29 | - "nxp,tda19971" for the TDA19971 | ||
30 | - "nxp,tda19973" for the TDA19973 | ||
31 | - reg : I2C slave address | ||
32 | - interrupts : The interrupt number | ||
33 | - DOVDD-supply : Digital I/O supply | ||
34 | - DVDD-supply : Digital Core supply | ||
35 | - AVDD-supply : Analog supply | ||
36 | - nxp,vidout-portcfg : array of pairs mapping VP output pins to pin groups. | ||
37 | |||
38 | Optional Properties: | ||
39 | - nxp,audout-format : DAI bus format: "i2s" or "spdif". | ||
40 | - nxp,audout-width : width of audio output data bus (1-4). | ||
41 | - nxp,audout-layout : data layout (0=AP0 used, 1=AP0/AP1/AP2/AP3 used). | ||
42 | - nxp,audout-mclk-fs : Multiplication factor between stream rate and codec | ||
43 | mclk. | ||
44 | |||
45 | The port node shall contain one endpoint child node for its digital | ||
46 | output video port, in accordance with the video interface bindings defined in | ||
47 | Documentation/devicetree/bindings/media/video-interfaces.txt. | ||
48 | |||
49 | Optional Endpoint Properties: | ||
50 | The following three properties are defined in video-interfaces.txt and | ||
51 | are valid for the output parallel bus endpoint: | ||
52 | - hsync-active: Horizontal synchronization polarity. Defaults to active high. | ||
53 | - vsync-active: Vertical synchronization polarity. Defaults to active high. | ||
54 | - data-active: Data polarity. Defaults to active high. | ||
55 | |||
56 | Examples: | ||
57 | - VP[15:0] connected to IMX6 CSI_DATA[19:4] for 16bit YUV422 | ||
58 | 16bit I2S layout0 with a 128*fs clock (A_WS, AP0, A_CLK pins) | ||
59 | hdmi-receiver@48 { | ||
60 | compatible = "nxp,tda19971"; | ||
61 | pinctrl-names = "default"; | ||
62 | pinctrl-0 = <&pinctrl_tda1997x>; | ||
63 | reg = <0x48>; | ||
64 | interrupt-parent = <&gpio1>; | ||
65 | interrupts = <7 IRQ_TYPE_LEVEL_LOW>; | ||
66 | DOVDD-supply = <®_3p3v>; | ||
67 | AVDD-supply = <®_1p8v>; | ||
68 | DVDD-supply = <®_1p8v>; | ||
69 | /* audio */ | ||
70 | #sound-dai-cells = <0>; | ||
71 | nxp,audout-format = "i2s"; | ||
72 | nxp,audout-layout = <0>; | ||
73 | nxp,audout-width = <16>; | ||
74 | nxp,audout-mclk-fs = <128>; | ||
75 | /* | ||
76 | * The 8bpp YUV422 semi-planar mode outputs CbCr[11:4] | ||
77 | * and Y[11:4] across 16bits in the same pixclk cycle. | ||
78 | */ | ||
79 | nxp,vidout-portcfg = | ||
80 | /* Y[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ | ||
81 | < TDA1997X_VP24_V15_12 TDA1997X_G_Y_11_8 >, | ||
82 | /* Y[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ | ||
83 | < TDA1997X_VP24_V11_08 TDA1997X_G_Y_7_4 >, | ||
84 | /* CbCc[11:8]<->VP[07:04]<->CSI_DATA[11:8] */ | ||
85 | < TDA1997X_VP24_V07_04 TDA1997X_R_CR_CBCR_11_8 >, | ||
86 | /* CbCr[7:4]<->VP[03:00]<->CSI_DATA[7:4] */ | ||
87 | < TDA1997X_VP24_V03_00 TDA1997X_R_CR_CBCR_7_4 >; | ||
88 | |||
89 | port { | ||
90 | tda1997x_to_ipu1_csi0_mux: endpoint { | ||
91 | remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; | ||
92 | bus-width = <16>; | ||
93 | hsync-active = <1>; | ||
94 | vsync-active = <1>; | ||
95 | data-active = <1>; | ||
96 | }; | ||
97 | }; | ||
98 | }; | ||
99 | - VP[15:8] connected to IMX6 CSI_DATA[19:12] for 8bit BT656 | ||
100 | 16bit I2S layout0 with a 128*fs clock (A_WS, AP0, A_CLK pins) | ||
101 | hdmi-receiver@48 { | ||
102 | compatible = "nxp,tda19971"; | ||
103 | pinctrl-names = "default"; | ||
104 | pinctrl-0 = <&pinctrl_tda1997x>; | ||
105 | reg = <0x48>; | ||
106 | interrupt-parent = <&gpio1>; | ||
107 | interrupts = <7 IRQ_TYPE_LEVEL_LOW>; | ||
108 | DOVDD-supply = <®_3p3v>; | ||
109 | AVDD-supply = <®_1p8v>; | ||
110 | DVDD-supply = <®_1p8v>; | ||
111 | /* audio */ | ||
112 | #sound-dai-cells = <0>; | ||
113 | nxp,audout-format = "i2s"; | ||
114 | nxp,audout-layout = <0>; | ||
115 | nxp,audout-width = <16>; | ||
116 | nxp,audout-mclk-fs = <128>; | ||
117 | /* | ||
118 | * The 8bpp YUV422 semi-planar mode outputs CbCr[11:4] | ||
119 | * and Y[11:4] across 16bits in the same pixclk cycle. | ||
120 | */ | ||
121 | nxp,vidout-portcfg = | ||
122 | /* Y[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ | ||
123 | < TDA1997X_VP24_V15_12 TDA1997X_G_Y_11_8 >, | ||
124 | /* Y[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ | ||
125 | < TDA1997X_VP24_V11_08 TDA1997X_G_Y_7_4 >, | ||
126 | /* CbCc[11:8]<->VP[07:04]<->CSI_DATA[11:8] */ | ||
127 | < TDA1997X_VP24_V07_04 TDA1997X_R_CR_CBCR_11_8 >, | ||
128 | /* CbCr[7:4]<->VP[03:00]<->CSI_DATA[7:4] */ | ||
129 | < TDA1997X_VP24_V03_00 TDA1997X_R_CR_CBCR_7_4 >; | ||
130 | |||
131 | port { | ||
132 | tda1997x_to_ipu1_csi0_mux: endpoint { | ||
133 | remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; | ||
134 | bus-width = <16>; | ||
135 | hsync-active = <1>; | ||
136 | vsync-active = <1>; | ||
137 | data-active = <1>; | ||
138 | }; | ||
139 | }; | ||
140 | }; | ||
141 | - VP[15:8] connected to IMX6 CSI_DATA[19:12] for 8bit BT656 | ||
142 | 16bit I2S layout0 with a 128*fs clock (A_WS, AP0, A_CLK pins) | ||
143 | hdmi-receiver@48 { | ||
144 | compatible = "nxp,tda19971"; | ||
145 | pinctrl-names = "default"; | ||
146 | pinctrl-0 = <&pinctrl_tda1997x>; | ||
147 | reg = <0x48>; | ||
148 | interrupt-parent = <&gpio1>; | ||
149 | interrupts = <7 IRQ_TYPE_LEVEL_LOW>; | ||
150 | DOVDD-supply = <®_3p3v>; | ||
151 | AVDD-supply = <®_1p8v>; | ||
152 | DVDD-supply = <®_1p8v>; | ||
153 | /* audio */ | ||
154 | #sound-dai-cells = <0>; | ||
155 | nxp,audout-format = "i2s"; | ||
156 | nxp,audout-layout = <0>; | ||
157 | nxp,audout-width = <16>; | ||
158 | nxp,audout-mclk-fs = <128>; | ||
159 | /* | ||
160 | * The 8bpp BT656 mode outputs YCbCr[11:4] across 8bits over | ||
161 | * 2 pixclk cycles. | ||
162 | */ | ||
163 | nxp,vidout-portcfg = | ||
164 | /* YCbCr[11:8]<->VP[15:12]<->CSI_DATA[19:16] */ | ||
165 | < TDA1997X_VP24_V15_12 TDA1997X_R_CR_CBCR_11_8 >, | ||
166 | /* YCbCr[7:4]<->VP[11:08]<->CSI_DATA[15:12] */ | ||
167 | < TDA1997X_VP24_V11_08 TDA1997X_R_CR_CBCR_7_4 >, | ||
168 | |||
169 | port { | ||
170 | tda1997x_to_ipu1_csi0_mux: endpoint { | ||
171 | remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; | ||
172 | bus-width = <16>; | ||
173 | hsync-active = <1>; | ||
174 | vsync-active = <1>; | ||
175 | data-active = <1>; | ||
176 | }; | ||
177 | }; | ||
178 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 19357d0bbe65..1ce7ff9449c5 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt | |||
@@ -56,7 +56,7 @@ Board setup example (vin1 composite video input) | |||
56 | ------------------------------------------------ | 56 | ------------------------------------------------ |
57 | 57 | ||
58 | &i2c2 { | 58 | &i2c2 { |
59 | status = "ok"; | 59 | status = "okay"; |
60 | pinctrl-0 = <&i2c2_pins>; | 60 | pinctrl-0 = <&i2c2_pins>; |
61 | pinctrl-names = "default"; | 61 | pinctrl-names = "default"; |
62 | 62 | ||
@@ -79,7 +79,7 @@ Board setup example (vin1 composite video input) | |||
79 | pinctrl-0 = <&vin1_pins>; | 79 | pinctrl-0 = <&vin1_pins>; |
80 | pinctrl-names = "default"; | 80 | pinctrl-names = "default"; |
81 | 81 | ||
82 | status = "ok"; | 82 | status = "okay"; |
83 | 83 | ||
84 | port { | 84 | port { |
85 | #address-cells = <1>; | 85 | #address-cells = <1>; |
diff --git a/Documentation/devicetree/bindings/media/renesas,ceu.txt b/Documentation/devicetree/bindings/media/renesas,ceu.txt new file mode 100644 index 000000000000..3fc66dfb192c --- /dev/null +++ b/Documentation/devicetree/bindings/media/renesas,ceu.txt | |||
@@ -0,0 +1,81 @@ | |||
1 | Renesas Capture Engine Unit (CEU) | ||
2 | ---------------------------------------------- | ||
3 | |||
4 | The Capture Engine Unit is the image capture interface found in the Renesas | ||
5 | SH Mobile and RZ SoCs. | ||
6 | |||
7 | The interface supports a single parallel input with data bus width of 8 or 16 | ||
8 | bits. | ||
9 | |||
10 | Required properties: | ||
11 | - compatible: Shall be "renesas,r7s72100-ceu" for CEU units found in RZ/A1H | ||
12 | and RZ/A1M SoCs. | ||
13 | - reg: Registers address base and size. | ||
14 | - interrupts: The interrupt specifier. | ||
15 | |||
16 | The CEU supports a single parallel input and should contain a single 'port' | ||
17 | subnode with a single 'endpoint'. Connection to input devices are modeled | ||
18 | according to the video interfaces OF bindings specified in: | ||
19 | Documentation/devicetree/bindings/media/video-interfaces.txt | ||
20 | |||
21 | Optional endpoint properties applicable to parallel input bus described in | ||
22 | the above mentioned "video-interfaces.txt" file are supported. | ||
23 | |||
24 | - hsync-active: Active state of the HSYNC signal, 0/1 for LOW/HIGH respectively. | ||
25 | If property is not present, default is active high. | ||
26 | - vsync-active: Active state of the VSYNC signal, 0/1 for LOW/HIGH respectively. | ||
27 | If property is not present, default is active high. | ||
28 | |||
29 | Example: | ||
30 | |||
31 | The example describes the connection between the Capture Engine Unit and an | ||
32 | OV7670 image sensor connected to i2c1 interface. | ||
33 | |||
34 | ceu: ceu@e8210000 { | ||
35 | reg = <0xe8210000 0x209c>; | ||
36 | compatible = "renesas,r7s72100-ceu"; | ||
37 | interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>; | ||
38 | |||
39 | pinctrl-names = "default"; | ||
40 | pinctrl-0 = <&vio_pins>; | ||
41 | |||
42 | status = "okay"; | ||
43 | |||
44 | port { | ||
45 | ceu_in: endpoint { | ||
46 | remote-endpoint = <&ov7670_out>; | ||
47 | |||
48 | hsync-active = <1>; | ||
49 | vsync-active = <0>; | ||
50 | }; | ||
51 | }; | ||
52 | }; | ||
53 | |||
54 | i2c1: i2c@fcfee400 { | ||
55 | pinctrl-names = "default"; | ||
56 | pinctrl-0 = <&i2c1_pins>; | ||
57 | |||
58 | status = "okay"; | ||
59 | |||
60 | clock-frequency = <100000>; | ||
61 | |||
62 | ov7670: camera@21 { | ||
63 | compatible = "ovti,ov7670"; | ||
64 | reg = <0x21>; | ||
65 | |||
66 | pinctrl-names = "default"; | ||
67 | pinctrl-0 = <&vio_pins>; | ||
68 | |||
69 | reset-gpios = <&port3 11 GPIO_ACTIVE_LOW>; | ||
70 | powerdown-gpios = <&port3 12 GPIO_ACTIVE_HIGH>; | ||
71 | |||
72 | port { | ||
73 | ov7670_out: endpoint { | ||
74 | remote-endpoint = <&ceu_in>; | ||
75 | |||
76 | hsync-active = <1>; | ||
77 | vsync-active = <0>; | ||
78 | }; | ||
79 | }; | ||
80 | }; | ||
81 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt index d3404b5d4d17..aa54c8159d9f 100644 --- a/Documentation/devicetree/bindings/media/s5p-mfc.txt +++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt | |||
@@ -13,6 +13,7 @@ Required properties: | |||
13 | (c) "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 | (d) "samsung,mfc-v8" for MFC v8 present in Exynos5800 SoC |
15 | (e) "samsung,exynos5433-mfc" for MFC v8 present in Exynos5433 SoC | 15 | (e) "samsung,exynos5433-mfc" for MFC v8 present in Exynos5433 SoC |
16 | (f) "samsung,mfc-v10" for MFC v10 present in Exynos7880 SoC | ||
16 | 17 | ||
17 | - reg : Physical base address of the IP registers and length of memory | 18 | - reg : Physical base address of the IP registers and length of memory |
18 | mapped region. | 19 | mapped region. |
diff --git a/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt b/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt new file mode 100644 index 000000000000..fc5aa263abe5 --- /dev/null +++ b/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | Sony CXD2880 DVB-T2/T tuner + demodulator driver SPI adapter | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "sony,cxd2880". | ||
5 | - reg: SPI chip select number for the device. | ||
6 | - spi-max-frequency: Maximum bus speed, should be set to <55000000> (55MHz). | ||
7 | |||
8 | Example: | ||
9 | |||
10 | cxd2880@0 { | ||
11 | compatible = "sony,cxd2880"; | ||
12 | reg = <0>; /* CE0 */ | ||
13 | spi-max-frequency = <55000000>; /* 55MHz */ | ||
14 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt b/Documentation/devicetree/bindings/media/sunxi-ir.txt index 91648c569b1e..278098987edb 100644 --- a/Documentation/devicetree/bindings/media/sunxi-ir.txt +++ b/Documentation/devicetree/bindings/media/sunxi-ir.txt | |||
@@ -11,6 +11,8 @@ Required properties: | |||
11 | Optional properties: | 11 | Optional properties: |
12 | - linux,rc-map-name: see rc.txt file in the same directory. | 12 | - linux,rc-map-name: see rc.txt file in the same directory. |
13 | - resets : phandle + reset specifier pair | 13 | - resets : phandle + reset specifier pair |
14 | - clock-frequency : IR Receiver clock frequency, in Hertz. Defaults to 8 MHz | ||
15 | if missing. | ||
14 | 16 | ||
15 | Example: | 17 | Example: |
16 | 18 | ||
@@ -18,6 +20,7 @@ ir0: ir@1c21800 { | |||
18 | compatible = "allwinner,sun4i-a10-ir"; | 20 | compatible = "allwinner,sun4i-a10-ir"; |
19 | clocks = <&apb0_gates 6>, <&ir0_clk>; | 21 | clocks = <&apb0_gates 6>, <&ir0_clk>; |
20 | clock-names = "apb", "ir"; | 22 | clock-names = "apb", "ir"; |
23 | clock-frequency = <3000000>; | ||
21 | resets = <&apb0_rst 1>; | 24 | resets = <&apb0_rst 1>; |
22 | interrupts = <0 5 1>; | 25 | interrupts = <0 5 1>; |
23 | reg = <0x01C21800 0x40>; | 26 | reg = <0x01C21800 0x40>; |
diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 62b9a1448177..a9f53f069a2d 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst | |||
@@ -110,11 +110,14 @@ your driver: | |||
110 | void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); | 110 | void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); |
111 | void (*adap_free)(struct cec_adapter *adap); | 111 | void (*adap_free)(struct cec_adapter *adap); |
112 | 112 | ||
113 | /* Error injection callbacks */ | ||
114 | ... | ||
115 | |||
113 | /* High-level callbacks */ | 116 | /* High-level callbacks */ |
114 | ... | 117 | ... |
115 | }; | 118 | }; |
116 | 119 | ||
117 | The five low-level ops deal with various aspects of controlling the CEC adapter | 120 | The seven low-level ops deal with various aspects of controlling the CEC adapter |
118 | hardware: | 121 | hardware: |
119 | 122 | ||
120 | 123 | ||
@@ -286,6 +289,70 @@ handling the receive interrupt. The framework expects to see the cec_transmit_do | |||
286 | call before the cec_received_msg call, otherwise it can get confused if the | 289 | call before the cec_received_msg call, otherwise it can get confused if the |
287 | received message was in reply to the transmitted message. | 290 | received message was in reply to the transmitted message. |
288 | 291 | ||
292 | Optional: Implementing Error Injection Support | ||
293 | ---------------------------------------------- | ||
294 | |||
295 | If the CEC adapter supports Error Injection functionality, then that can | ||
296 | be exposed through the Error Injection callbacks: | ||
297 | |||
298 | .. code-block:: none | ||
299 | |||
300 | struct cec_adap_ops { | ||
301 | /* Low-level callbacks */ | ||
302 | ... | ||
303 | |||
304 | /* Error injection callbacks */ | ||
305 | int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); | ||
306 | bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); | ||
307 | |||
308 | /* High-level CEC message callback */ | ||
309 | ... | ||
310 | }; | ||
311 | |||
312 | If both callbacks are set, then an ``error-inj`` file will appear in debugfs. | ||
313 | The basic syntax is as follows: | ||
314 | |||
315 | Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the | ||
316 | line was reached, then the whole line is ignored. Otherwise a command is expected. | ||
317 | |||
318 | This basic parsing is done in the CEC Framework. It is up to the driver to decide | ||
319 | what commands to implement. The only requirement is that the command ``clear`` without | ||
320 | any arguments must be implemented and that it will remove all current error injection | ||
321 | commands. | ||
322 | |||
323 | This ensures that you can always do ``echo clear >error-inj`` to clear any error | ||
324 | injections without having to know the details of the driver-specific commands. | ||
325 | |||
326 | Note that the output of ``error-inj`` shall be valid as input to ``error-inj``. | ||
327 | So this must work: | ||
328 | |||
329 | .. code-block:: none | ||
330 | |||
331 | $ cat error-inj >einj.txt | ||
332 | $ cat einj.txt >error-inj | ||
333 | |||
334 | The first callback is called when this file is read and it should show the | ||
335 | the current error injection state: | ||
336 | |||
337 | .. c:function:: | ||
338 | int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); | ||
339 | |||
340 | It is recommended that it starts with a comment block with basic usage | ||
341 | information. It returns 0 for success and an error otherwise. | ||
342 | |||
343 | The second callback will parse commands written to the ``error-inj`` file: | ||
344 | |||
345 | .. c:function:: | ||
346 | bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); | ||
347 | |||
348 | The ``line`` argument points to the start of the command. Any leading | ||
349 | spaces or tabs have already been skipped. It is a single line only (so there | ||
350 | are no embedded newlines) and it is 0-terminated. The callback is free to | ||
351 | modify the contents of the buffer. It is only called for lines containing a | ||
352 | command, so this callback is never called for empty lines or comment lines. | ||
353 | |||
354 | Return true if the command was valid or false if there were syntax errors. | ||
355 | |||
289 | Implementing the High-Level CEC Adapter | 356 | Implementing the High-Level CEC Adapter |
290 | --------------------------------------- | 357 | --------------------------------------- |
291 | 358 | ||
@@ -298,6 +365,9 @@ CEC protocol driven. The following high-level callbacks are available: | |||
298 | /* Low-level callbacks */ | 365 | /* Low-level callbacks */ |
299 | ... | 366 | ... |
300 | 367 | ||
368 | /* Error injection callbacks */ | ||
369 | ... | ||
370 | |||
301 | /* High-level CEC message callback */ | 371 | /* High-level CEC message callback */ |
302 | int (*received)(struct cec_adapter *adap, struct cec_msg *msg); | 372 | int (*received)(struct cec_adapter *adap, struct cec_msg *msg); |
303 | }; | 373 | }; |
diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions index c6e3a35d2c4e..984b61dc3f2e 100644 --- a/Documentation/media/lirc.h.rst.exceptions +++ b/Documentation/media/lirc.h.rst.exceptions | |||
@@ -57,6 +57,7 @@ ignore symbol RC_PROTO_RC6_MCE | |||
57 | ignore symbol RC_PROTO_SHARP | 57 | ignore symbol RC_PROTO_SHARP |
58 | ignore symbol RC_PROTO_XMP | 58 | ignore symbol RC_PROTO_XMP |
59 | ignore symbol RC_PROTO_CEC | 59 | ignore symbol RC_PROTO_CEC |
60 | ignore symbol RC_PROTO_IMON | ||
60 | 61 | ||
61 | # Undocumented macros | 62 | # Undocumented macros |
62 | 63 | ||
diff --git a/Documentation/media/uapi/cec/cec-api.rst b/Documentation/media/uapi/cec/cec-api.rst index b68ca9c1d2e0..1e2cf498ba30 100644 --- a/Documentation/media/uapi/cec/cec-api.rst +++ b/Documentation/media/uapi/cec/cec-api.rst | |||
@@ -23,6 +23,7 @@ This part describes the CEC: Consumer Electronics Control | |||
23 | 23 | ||
24 | cec-intro | 24 | cec-intro |
25 | cec-funcs | 25 | cec-funcs |
26 | cec-pin-error-inj | ||
26 | cec-header | 27 | cec-header |
27 | 28 | ||
28 | 29 | ||
diff --git a/Documentation/media/uapi/cec/cec-pin-error-inj.rst b/Documentation/media/uapi/cec/cec-pin-error-inj.rst new file mode 100644 index 000000000000..464b006dbe0a --- /dev/null +++ b/Documentation/media/uapi/cec/cec-pin-error-inj.rst | |||
@@ -0,0 +1,325 @@ | |||
1 | CEC Pin Framework Error Injection | ||
2 | ================================= | ||
3 | |||
4 | The CEC Pin Framework is a core CEC framework for CEC hardware that only | ||
5 | has low-level support for the CEC bus. Most hardware today will have | ||
6 | high-level CEC support where the hardware deals with driving the CEC bus, | ||
7 | but some older devices aren't that fancy. However, this framework also | ||
8 | allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and | ||
9 | you have now made a CEC adapter. | ||
10 | |||
11 | What makes doing this so interesting is that since we have full control | ||
12 | over the bus it is easy to support error injection. This is ideal to | ||
13 | test how well CEC adapters can handle error conditions. | ||
14 | |||
15 | Currently only the cec-gpio driver (when the CEC line is directly | ||
16 | connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver | ||
17 | support this framework. | ||
18 | |||
19 | If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available | ||
20 | through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is | ||
21 | now an ``error-inj`` file. | ||
22 | |||
23 | .. note:: | ||
24 | |||
25 | The error injection commands are not a stable ABI and may change in the | ||
26 | future. | ||
27 | |||
28 | With ``cat error-inj`` you can see both the possible commands and the current | ||
29 | error injection status:: | ||
30 | |||
31 | $ cat /sys/kernel/debug/cec/cec0/error-inj | ||
32 | # Clear error injections: | ||
33 | # clear clear all rx and tx error injections | ||
34 | # rx-clear clear all rx error injections | ||
35 | # tx-clear clear all tx error injections | ||
36 | # <op> clear clear all rx and tx error injections for <op> | ||
37 | # <op> rx-clear clear all rx error injections for <op> | ||
38 | # <op> tx-clear clear all tx error injections for <op> | ||
39 | # | ||
40 | # RX error injection: | ||
41 | # <op>[,<mode>] rx-nack NACK the message instead of sending an ACK | ||
42 | # <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position | ||
43 | # <op>[,<mode>] rx-add-byte add a spurious byte to the received CEC message | ||
44 | # <op>[,<mode>] rx-remove-byte remove the last byte from the received CEC message | ||
45 | # <op>[,<mode>] rx-arb-lost <poll> generate a POLL message to trigger an arbitration lost | ||
46 | # | ||
47 | # TX error injection settings: | ||
48 | # tx-ignore-nack-until-eom ignore early NACKs until EOM | ||
49 | # tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse | ||
50 | # tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse | ||
51 | # tx-custom-pulse transmit the custom pulse once the bus is idle | ||
52 | # | ||
53 | # TX error injection: | ||
54 | # <op>[,<mode>] tx-no-eom don't set the EOM bit | ||
55 | # <op>[,<mode>] tx-early-eom set the EOM bit one byte too soon | ||
56 | # <op>[,<mode>] tx-add-bytes <num> append <num> (1-255) spurious bytes to the message | ||
57 | # <op>[,<mode>] tx-remove-byte drop the last byte from the message | ||
58 | # <op>[,<mode>] tx-short-bit <bit> make this bit shorter than allowed | ||
59 | # <op>[,<mode>] tx-long-bit <bit> make this bit longer than allowed | ||
60 | # <op>[,<mode>] tx-custom-bit <bit> send the custom pulse instead of this bit | ||
61 | # <op>[,<mode>] tx-short-start send a start pulse that's too short | ||
62 | # <op>[,<mode>] tx-long-start send a start pulse that's too long | ||
63 | # <op>[,<mode>] tx-custom-start send the custom pulse instead of the start pulse | ||
64 | # <op>[,<mode>] tx-last-bit <bit> stop sending after this bit | ||
65 | # <op>[,<mode>] tx-low-drive <bit> force a low-drive condition at this bit position | ||
66 | # | ||
67 | # <op> CEC message opcode (0-255) or 'any' | ||
68 | # <mode> 'once' (default), 'always', 'toggle' or 'off' | ||
69 | # <bit> CEC message bit (0-159) | ||
70 | # 10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK | ||
71 | # <poll> CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f) | ||
72 | # <usecs> microseconds (0-10000000, default 1000) | ||
73 | |||
74 | clear | ||
75 | |||
76 | You can write error injection commands to ``error-inj`` using | ||
77 | ``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj`` | ||
78 | output contains the current error commands. You can save the output to a file | ||
79 | and use it as an input to ``error-inj`` later. | ||
80 | |||
81 | Basic Syntax | ||
82 | ------------ | ||
83 | |||
84 | Leading spaces/tabs are ignored. If the next character is a ``#`` or the end | ||
85 | of the line was reached, then the whole line is ignored. Otherwise a command | ||
86 | is expected. | ||
87 | |||
88 | The error injection commands fall in two main groups: those relating to | ||
89 | receiving CEC messages and those relating to transmitting CEC messages. In | ||
90 | addition, there are commands to clear existing error injection commands and | ||
91 | to create custom pulses on the CEC bus. | ||
92 | |||
93 | Most error injection commands can be executed for specific CEC opcodes or for | ||
94 | all opcodes (``any``). Each command also has a 'mode' which can be ``off`` | ||
95 | (can be used to turn off an existing error injection command), ``once`` | ||
96 | (the default) which will trigger the error injection only once for the next | ||
97 | received or transmitted message, ``always`` to always trigger the error | ||
98 | injection and ``toggle`` to toggle the error injection on or off for every | ||
99 | transmit or receive. | ||
100 | |||
101 | So '``any rx-nack``' will NACK the next received CEC message, | ||
102 | '``any,always rx-nack``' will NACK all received CEC messages and | ||
103 | '``0x82,toggle rx-nack``' will only NACK if an Active Source message was | ||
104 | received and do that only for every other received message. | ||
105 | |||
106 | After an error was injected with mode ``once`` the error injection command | ||
107 | is cleared automatically, so ``once`` is a one-time deal. | ||
108 | |||
109 | All combinations of ``<op>`` and error injection commands can co-exist. So | ||
110 | this is fine:: | ||
111 | |||
112 | 0x9e tx-add-bytes 1 | ||
113 | 0x9e tx-early-eom | ||
114 | 0x9f tx-add-bytes 2 | ||
115 | any rx-nack | ||
116 | |||
117 | All four error injection commands will be active simultaneously. | ||
118 | |||
119 | However, if the same ``<op>`` and command combination is specified, | ||
120 | but with different arguments:: | ||
121 | |||
122 | 0x9e tx-add-bytes 1 | ||
123 | 0x9e tx-add-bytes 2 | ||
124 | |||
125 | Then the second will overwrite the first. | ||
126 | |||
127 | Clear Error Injections | ||
128 | ---------------------- | ||
129 | |||
130 | ``clear`` | ||
131 | Clear all error injections. | ||
132 | |||
133 | ``rx-clear`` | ||
134 | Clear all receive error injections | ||
135 | |||
136 | ``tx-clear`` | ||
137 | Clear all transmit error injections | ||
138 | |||
139 | ``<op> clear`` | ||
140 | Clear all error injections for the given opcode. | ||
141 | |||
142 | ``<op> rx-clear`` | ||
143 | Clear all receive error injections for the given opcode. | ||
144 | |||
145 | ``<op> tx-clear`` | ||
146 | Clear all transmit error injections for the given opcode. | ||
147 | |||
148 | Receive Messages | ||
149 | ---------------- | ||
150 | |||
151 | ``<op>[,<mode>] rx-nack`` | ||
152 | NACK broadcast messages and messages directed to this CEC adapter. | ||
153 | Every byte of the message will be NACKed in case the transmitter | ||
154 | keeps transmitting after the first byte was NACKed. | ||
155 | |||
156 | ``<op>[,<mode>] rx-low-drive <bit>`` | ||
157 | Force a Low Drive condition at this bit position. If <op> specifies | ||
158 | a specific CEC opcode then the bit position must be at least 18, | ||
159 | otherwise the opcode hasn't been received yet. This tests if the | ||
160 | transmitter can handle the Low Drive condition correctly and reports | ||
161 | the error correctly. Note that a Low Drive in the first 4 bits can also | ||
162 | be interpreted as an Arbitration Lost condition by the transmitter. | ||
163 | This is implementation dependent. | ||
164 | |||
165 | ``<op>[,<mode>] rx-add-byte`` | ||
166 | Add a spurious 0x55 byte to the received CEC message, provided | ||
167 | the message was 15 bytes long or less. This is useful to test | ||
168 | the high-level protocol since spurious bytes should be ignored. | ||
169 | |||
170 | ``<op>[,<mode>] rx-remove-byte`` | ||
171 | Remove the last byte from the received CEC message, provided it | ||
172 | was at least 2 bytes long. This is useful to test the high-level | ||
173 | protocol since messages that are too short should be ignored. | ||
174 | |||
175 | ``<op>[,<mode>] rx-arb-lost <poll>`` | ||
176 | Generate a POLL message to trigger an Arbitration Lost condition. | ||
177 | This command is only allowed for ``<op>`` values of ``next`` or ``all``. | ||
178 | As soon as a start bit has been received the CEC adapter will switch | ||
179 | to transmit mode and it will transmit a POLL message. By default this is | ||
180 | 0x0f, but it can also be specified explicitly via the ``<poll>`` argument. | ||
181 | |||
182 | This command can be used to test the Arbitration Lost condition in | ||
183 | the remote CEC transmitter. Arbitration happens when two CEC adapters | ||
184 | start sending a message at the same time. In that case the initiator | ||
185 | with the most leading zeroes wins and the other transmitter has to | ||
186 | stop transmitting ('Arbitration Lost'). This is very hard to test, | ||
187 | except by using this error injection command. | ||
188 | |||
189 | This does not work if the remote CEC transmitter has logical address | ||
190 | 0 ('TV') since that will always win. | ||
191 | |||
192 | Transmit Messages | ||
193 | ----------------- | ||
194 | |||
195 | ``tx-ignore-nack-until-eom`` | ||
196 | This setting changes the behavior of transmitting CEC messages. Normally | ||
197 | as soon as the receiver NACKs a byte the transmit will stop, but the | ||
198 | specification also allows that the full message is transmitted and only | ||
199 | at the end will the transmitter look at the ACK bit. This is not | ||
200 | recommended behavior since there is no point in keeping the CEC bus busy | ||
201 | for longer than is strictly needed. Especially given how slow the bus is. | ||
202 | |||
203 | This setting can be used to test how well a receiver deals with | ||
204 | transmitters that ignore NACKs until the very end of the message. | ||
205 | |||
206 | ``<op>[,<mode>] tx-no-eom`` | ||
207 | Don't set the EOM bit. Normally the last byte of the message has the EOM | ||
208 | (End-Of-Message) bit set. With this command the transmit will just stop | ||
209 | without ever sending an EOM. This can be used to test how a receiver | ||
210 | handles this case. Normally receivers have a time-out after which | ||
211 | they will go back to the Idle state. | ||
212 | |||
213 | ``<op>[,<mode>] tx-early-eom`` | ||
214 | Set the EOM bit one byte too soon. This obviously only works for messages | ||
215 | of two bytes or more. The EOM bit will be set for the second-to-last byte | ||
216 | and not for the final byte. The receiver should ignore the last byte in | ||
217 | this case. Since the resulting message is likely to be too short for this | ||
218 | same reason the whole message is typically ignored. The receiver should be | ||
219 | in Idle state after the last byte was transmitted. | ||
220 | |||
221 | ``<op>[,<mode>] tx-add-bytes <num>`` | ||
222 | Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes | ||
223 | have the value of the byte position in the message. So if you transmit a | ||
224 | two byte message (e.g. a Get CEC Version message) and add 2 bytes, then | ||
225 | the full message received by the remote CEC adapter is | ||
226 | ``0x40 0x9f 0x02 0x03``. | ||
227 | |||
228 | This command can be used to test buffer overflows in the receiver. E.g. | ||
229 | what does it do when it receives more than the maximum message size of 16 | ||
230 | bytes. | ||
231 | |||
232 | ``<op>[,<mode>] tx-remove-byte`` | ||
233 | Drop the last byte from the message, provided the message is at least | ||
234 | two bytes long. The receiver should ignore messages that are too short. | ||
235 | |||
236 | ``<op>[,<mode>] tx-short-bit <bit>`` | ||
237 | Make this bit period shorter than allowed. The bit position cannot be | ||
238 | an Ack bit. If <op> specifies a specific CEC opcode then the bit position | ||
239 | must be at least 18, otherwise the opcode hasn't been received yet. | ||
240 | Normally the period of a data bit is between 2.05 and 2.75 milliseconds. | ||
241 | With this command the period of this bit is 1.8 milliseconds, this is | ||
242 | done by reducing the time the CEC bus is high. This bit period is less | ||
243 | than is allowed and the receiver should respond with a Low Drive | ||
244 | condition. | ||
245 | |||
246 | This command is ignored for 0 bits in bit positions 0 to 3. This is | ||
247 | because the receiver also looks for an Arbitration Lost condition in | ||
248 | those first four bits and it is undefined what will happen if it | ||
249 | sees a too-short 0 bit. | ||
250 | |||
251 | ``<op>[,<mode>] tx-long-bit <bit>`` | ||
252 | Make this bit period longer than is valid. The bit position cannot be | ||
253 | an Ack bit. If <op> specifies a specific CEC opcode then the bit position | ||
254 | must be at least 18, otherwise the opcode hasn't been received yet. | ||
255 | Normally the period of a data bit is between 2.05 and 2.75 milliseconds. | ||
256 | With this command the period of this bit is 2.9 milliseconds, this is | ||
257 | done by increasing the time the CEC bus is high. | ||
258 | |||
259 | Even though this bit period is longer than is valid it is undefined what | ||
260 | a receiver will do. It might just accept it, or it might time out and | ||
261 | return to Idle state. Unfortunately the CEC specification is silent about | ||
262 | this. | ||
263 | |||
264 | This command is ignored for 0 bits in bit positions 0 to 3. This is | ||
265 | because the receiver also looks for an Arbitration Lost condition in | ||
266 | those first four bits and it is undefined what will happen if it | ||
267 | sees a too-long 0 bit. | ||
268 | |||
269 | ``<op>[,<mode>] tx-short-start`` | ||
270 | Make this start bit period shorter than allowed. Normally the period of | ||
271 | a start bit is between 4.3 and 4.7 milliseconds. With this command the | ||
272 | period of the start bit is 4.1 milliseconds, this is done by reducing | ||
273 | the time the CEC bus is high. This start bit period is less than is | ||
274 | allowed and the receiver should return to Idle state when this is detected. | ||
275 | |||
276 | ``<op>[,<mode>] tx-long-start`` | ||
277 | Make this start bit period longer than is valid. Normally the period of | ||
278 | a start bit is between 4.3 and 4.7 milliseconds. With this command the | ||
279 | period of the start bit is 5 milliseconds, this is done by increasing | ||
280 | the time the CEC bus is high. This start bit period is more than is | ||
281 | valid and the receiver should return to Idle state when this is detected. | ||
282 | |||
283 | Even though this start bit period is longer than is valid it is undefined | ||
284 | what a receiver will do. It might just accept it, or it might time out and | ||
285 | return to Idle state. Unfortunately the CEC specification is silent about | ||
286 | this. | ||
287 | |||
288 | ``<op>[,<mode>] tx-last-bit <bit>`` | ||
289 | Just stop transmitting after this bit. If <op> specifies a specific CEC | ||
290 | opcode then the bit position must be at least 18, otherwise the opcode | ||
291 | hasn't been received yet. This command can be used to test how the receiver | ||
292 | reacts when a message just suddenly stops. It should time out and go back | ||
293 | to Idle state. | ||
294 | |||
295 | ``<op>[,<mode>] tx-low-drive <bit>`` | ||
296 | Force a Low Drive condition at this bit position. If <op> specifies a | ||
297 | specific CEC opcode then the bit position must be at least 18, otherwise | ||
298 | the opcode hasn't been received yet. This can be used to test how the | ||
299 | receiver handles Low Drive conditions. Note that if this happens at bit | ||
300 | positions 0-3 the receiver can interpret this as an Arbitration Lost | ||
301 | condition. This is implementation dependent. | ||
302 | |||
303 | Custom Pulses | ||
304 | ------------- | ||
305 | |||
306 | ``tx-custom-low-usecs <usecs>`` | ||
307 | This defines the duration in microseconds that the custom pulse pulls | ||
308 | the CEC line low. The default is 1000 microseconds. | ||
309 | |||
310 | ``tx-custom-high-usecs <usecs>`` | ||
311 | This defines the duration in microseconds that the custom pulse keeps the | ||
312 | CEC line high (unless another CEC adapter pulls it low in that time). | ||
313 | The default is 1000 microseconds. The total period of the custom pulse is | ||
314 | ``tx-custom-low-usecs + tx-custom-high-usecs``. | ||
315 | |||
316 | ``<op>[,<mode>] tx-custom-bit <bit>`` | ||
317 | Send the custom bit instead of a regular data bit. The bit position cannot | ||
318 | be an Ack bit. If <op> specifies a specific CEC opcode then the bit | ||
319 | position must be at least 18, otherwise the opcode hasn't been received yet. | ||
320 | |||
321 | ``<op>[,<mode>] tx-custom-start`` | ||
322 | Send the custom bit instead of a regular start bit. | ||
323 | |||
324 | ``tx-custom-pulse`` | ||
325 | Transmit a single custom pulse as soon as the CEC bus is idle. | ||
diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst index b59ce149efb5..45e76e5bc1ea 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst | |||
@@ -144,10 +144,21 @@ id's until they get an error. | |||
144 | 144 | ||
145 | - .. row 9 | 145 | - .. row 9 |
146 | 146 | ||
147 | - union | 147 | - __u32 |
148 | |||
149 | - ``reserved[4]`` | ||
150 | |||
151 | - | ||
152 | - | ||
153 | - Reserved for future extensions. Drivers and applications must set | ||
154 | the array to zero. | ||
148 | 155 | ||
149 | - .. row 10 | 156 | - .. row 10 |
150 | 157 | ||
158 | - union | ||
159 | |||
160 | - .. row 11 | ||
161 | |||
151 | - | 162 | - |
152 | - struct | 163 | - struct |
153 | 164 | ||
@@ -156,7 +167,7 @@ id's until they get an error. | |||
156 | - | 167 | - |
157 | - Valid for (sub-)devices that create a single device node. | 168 | - Valid for (sub-)devices that create a single device node. |
158 | 169 | ||
159 | - .. row 11 | 170 | - .. row 12 |
160 | 171 | ||
161 | - | 172 | - |
162 | - | 173 | - |
@@ -166,7 +177,7 @@ id's until they get an error. | |||
166 | 177 | ||
167 | - Device node major number. | 178 | - Device node major number. |
168 | 179 | ||
169 | - .. row 12 | 180 | - .. row 13 |
170 | 181 | ||
171 | - | 182 | - |
172 | - | 183 | - |
@@ -176,7 +187,7 @@ id's until they get an error. | |||
176 | 187 | ||
177 | - Device node minor number. | 188 | - Device node minor number. |
178 | 189 | ||
179 | - .. row 13 | 190 | - .. row 14 |
180 | 191 | ||
181 | - | 192 | - |
182 | - __u8 | 193 | - __u8 |
diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst index d05be16ffaf6..256168b3c3be 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-links.rst | |||
@@ -125,6 +125,15 @@ returned during the enumeration process. | |||
125 | 125 | ||
126 | - Pad flags, see :ref:`media-pad-flag` for more details. | 126 | - Pad flags, see :ref:`media-pad-flag` for more details. |
127 | 127 | ||
128 | - .. row 4 | ||
129 | |||
130 | - __u32 | ||
131 | |||
132 | - ``reserved[2]`` | ||
133 | |||
134 | - Reserved for future extensions. Drivers and applications must set | ||
135 | the array to zero. | ||
136 | |||
128 | 137 | ||
129 | 138 | ||
130 | .. c:type:: media_link_desc | 139 | .. c:type:: media_link_desc |
@@ -161,6 +170,15 @@ returned during the enumeration process. | |||
161 | 170 | ||
162 | - Link flags, see :ref:`media-link-flag` for more details. | 171 | - Link flags, see :ref:`media-link-flag` for more details. |
163 | 172 | ||
173 | - .. row 4 | ||
174 | |||
175 | - __u32 | ||
176 | |||
177 | - ``reserved[4]`` | ||
178 | |||
179 | - Reserved for future extensions. Drivers and applications must set | ||
180 | the array to zero. | ||
181 | |||
164 | 182 | ||
165 | Return Value | 183 | Return Value |
166 | ============ | 184 | ============ |
diff --git a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst index 997e6b17440d..c8f9ea37db2d 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst | |||
@@ -68,7 +68,7 @@ desired arrays with the media graph elements. | |||
68 | 68 | ||
69 | - .. row 2 | 69 | - .. row 2 |
70 | 70 | ||
71 | - __u64 | 71 | - __u32 |
72 | 72 | ||
73 | - ``num_entities`` | 73 | - ``num_entities`` |
74 | 74 | ||
@@ -76,6 +76,14 @@ desired arrays with the media graph elements. | |||
76 | 76 | ||
77 | - .. row 3 | 77 | - .. row 3 |
78 | 78 | ||
79 | - __u32 | ||
80 | |||
81 | - ``reserved1`` | ||
82 | |||
83 | - Applications and drivers shall set this to 0. | ||
84 | |||
85 | - .. row 4 | ||
86 | |||
79 | - __u64 | 87 | - __u64 |
80 | 88 | ||
81 | - ``ptr_entities`` | 89 | - ``ptr_entities`` |
@@ -85,15 +93,23 @@ desired arrays with the media graph elements. | |||
85 | the ioctl won't store the entities. It will just update | 93 | the ioctl won't store the entities. It will just update |
86 | ``num_entities`` | 94 | ``num_entities`` |
87 | 95 | ||
88 | - .. row 4 | 96 | - .. row 5 |
89 | 97 | ||
90 | - __u64 | 98 | - __u32 |
91 | 99 | ||
92 | - ``num_interfaces`` | 100 | - ``num_interfaces`` |
93 | 101 | ||
94 | - Number of interfaces in the graph | 102 | - Number of interfaces in the graph |
95 | 103 | ||
96 | - .. row 5 | 104 | - .. row 6 |
105 | |||
106 | - __u32 | ||
107 | |||
108 | - ``reserved2`` | ||
109 | |||
110 | - Applications and drivers shall set this to 0. | ||
111 | |||
112 | - .. row 7 | ||
97 | 113 | ||
98 | - __u64 | 114 | - __u64 |
99 | 115 | ||
@@ -104,15 +120,23 @@ desired arrays with the media graph elements. | |||
104 | the ioctl won't store the interfaces. It will just update | 120 | the ioctl won't store the interfaces. It will just update |
105 | ``num_interfaces`` | 121 | ``num_interfaces`` |
106 | 122 | ||
107 | - .. row 6 | 123 | - .. row 8 |
108 | 124 | ||
109 | - __u64 | 125 | - __u32 |
110 | 126 | ||
111 | - ``num_pads`` | 127 | - ``num_pads`` |
112 | 128 | ||
113 | - Total number of pads in the graph | 129 | - Total number of pads in the graph |
114 | 130 | ||
115 | - .. row 7 | 131 | - .. row 9 |
132 | |||
133 | - __u32 | ||
134 | |||
135 | - ``reserved3`` | ||
136 | |||
137 | - Applications and drivers shall set this to 0. | ||
138 | |||
139 | - .. row 10 | ||
116 | 140 | ||
117 | - __u64 | 141 | - __u64 |
118 | 142 | ||
@@ -122,15 +146,23 @@ desired arrays with the media graph elements. | |||
122 | converted to a 64-bits integer. It can be zero. if zero, the ioctl | 146 | converted to a 64-bits integer. It can be zero. if zero, the ioctl |
123 | won't store the pads. It will just update ``num_pads`` | 147 | won't store the pads. It will just update ``num_pads`` |
124 | 148 | ||
125 | - .. row 8 | 149 | - .. row 11 |
126 | 150 | ||
127 | - __u64 | 151 | - __u32 |
128 | 152 | ||
129 | - ``num_links`` | 153 | - ``num_links`` |
130 | 154 | ||
131 | - Total number of data and interface links in the graph | 155 | - Total number of data and interface links in the graph |
132 | 156 | ||
133 | - .. row 9 | 157 | - .. row 12 |
158 | |||
159 | - __u32 | ||
160 | |||
161 | - ``reserved4`` | ||
162 | |||
163 | - Applications and drivers shall set this to 0. | ||
164 | |||
165 | - .. row 13 | ||
134 | 166 | ||
135 | - __u64 | 167 | - __u64 |
136 | 168 | ||
@@ -334,7 +366,7 @@ desired arrays with the media graph elements. | |||
334 | 366 | ||
335 | - On pad to pad links: unique ID for the source pad. | 367 | - On pad to pad links: unique ID for the source pad. |
336 | 368 | ||
337 | On interface to entity links: unique ID for the entity. | 369 | On interface to entity links: unique ID for the interface. |
338 | 370 | ||
339 | - .. row 3 | 371 | - .. row 3 |
340 | 372 | ||
diff --git a/Documentation/media/uapi/mediactl/media-types.rst b/Documentation/media/uapi/mediactl/media-types.rst index 8d64b0c06ebc..f92f10b7ffbd 100644 --- a/Documentation/media/uapi/mediactl/media-types.rst +++ b/Documentation/media/uapi/mediactl/media-types.rst | |||
@@ -26,7 +26,7 @@ Types and flags used to represent the media graph elements | |||
26 | ``MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN`` | 26 | ``MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN`` |
27 | 27 | ||
28 | - Unknown entity. That generally indicates that a driver didn't | 28 | - Unknown entity. That generally indicates that a driver didn't |
29 | initialize properly the entity, with is a Kernel bug | 29 | initialize properly the entity, which is a Kernel bug |
30 | 30 | ||
31 | - .. row 2 | 31 | - .. row 2 |
32 | 32 | ||
@@ -293,7 +293,7 @@ Types and flags used to represent the media graph elements | |||
293 | 293 | ||
294 | - ``MEDIA_ENT_F_PROC_VIDEO_STATISTICS`` | 294 | - ``MEDIA_ENT_F_PROC_VIDEO_STATISTICS`` |
295 | 295 | ||
296 | - Video statistics computation (histogram, 3A, ...). An entity | 296 | - Video statistics computation (histogram, 3A, etc.). An entity |
297 | capable of statistics computation must have one sink pad and | 297 | capable of statistics computation must have one sink pad and |
298 | one source pad. It computes statistics over the frames | 298 | one source pad. It computes statistics over the frames |
299 | received on its sink pad and outputs the statistics data on | 299 | received on its sink pad and outputs the statistics data on |
@@ -318,8 +318,19 @@ Types and flags used to represent the media graph elements | |||
318 | - Video interface bridge. A video interface bridge entity must have at | 318 | - Video interface bridge. A video interface bridge entity must have at |
319 | least one sink pad and at least one source pad. It receives video | 319 | least one sink pad and at least one source pad. It receives video |
320 | frames on its sink pad from an input video bus of one type (HDMI, eDP, | 320 | frames on its sink pad from an input video bus of one type (HDMI, eDP, |
321 | MIPI CSI-2, ...), and outputs them on its source pad to an output | 321 | MIPI CSI-2, etc.), and outputs them on its source pad to an output |
322 | video bus of another type (eDP, MIPI CSI-2, parallel, ...). | 322 | video bus of another type (eDP, MIPI CSI-2, parallel, etc.). |
323 | |||
324 | - .. row 31 | ||
325 | |||
326 | .. _MEDIA-ENT-F-DTV-DECODER: | ||
327 | |||
328 | - ``MEDIA_ENT_F_DTV_DECODER`` | ||
329 | |||
330 | - Digital video decoder. The basic function of the video decoder is | ||
331 | to accept digital video from a wide variety of sources | ||
332 | and output it in some digital video standard, with appropriate | ||
333 | timing signals. | ||
323 | 334 | ||
324 | .. tabularcolumns:: |p{5.5cm}|p{12.0cm}| | 335 | .. tabularcolumns:: |p{5.5cm}|p{12.0cm}| |
325 | 336 | ||
@@ -337,7 +348,7 @@ Types and flags used to represent the media graph elements | |||
337 | - ``MEDIA_ENT_FL_DEFAULT`` | 348 | - ``MEDIA_ENT_FL_DEFAULT`` |
338 | 349 | ||
339 | - Default entity for its type. Used to discover the default audio, | 350 | - Default entity for its type. Used to discover the default audio, |
340 | VBI and video devices, the default camera sensor, ... | 351 | VBI and video devices, the default camera sensor, etc. |
341 | 352 | ||
342 | - .. row 2 | 353 | - .. row 2 |
343 | 354 | ||
@@ -345,7 +356,7 @@ Types and flags used to represent the media graph elements | |||
345 | 356 | ||
346 | - ``MEDIA_ENT_FL_CONNECTOR`` | 357 | - ``MEDIA_ENT_FL_CONNECTOR`` |
347 | 358 | ||
348 | - The entity represents a data conector | 359 | - The entity represents a connector. |
349 | 360 | ||
350 | 361 | ||
351 | .. tabularcolumns:: |p{6.5cm}|p{6.0cm}|p{5.0cm}| | 362 | .. tabularcolumns:: |p{6.5cm}|p{6.0cm}|p{5.0cm}| |
diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst b/Documentation/media/uapi/rc/lirc-dev-intro.rst index 3a74fec66d69..698e4f80270e 100644 --- a/Documentation/media/uapi/rc/lirc-dev-intro.rst +++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst | |||
@@ -18,7 +18,6 @@ Example dmesg output upon a driver registering w/LIRC: | |||
18 | .. code-block:: none | 18 | .. code-block:: none |
19 | 19 | ||
20 | $ dmesg |grep lirc_dev | 20 | $ dmesg |grep lirc_dev |
21 | lirc_dev: IR Remote Control driver registered, major 248 | ||
22 | rc rc0: lirc_dev: driver mceusb registered at minor = 0 | 21 | rc rc0: lirc_dev: driver mceusb registered at minor = 0 |
23 | 22 | ||
24 | What you should see for a chardev: | 23 | What you should see for a chardev: |
diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index ae6ee73f151c..e2c85ddc990b 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst | |||
@@ -13,7 +13,7 @@ Only pointers to buffers (planes) are exchanged, the data itself is not | |||
13 | copied. These pointers, together with meta-information like timestamps | 13 | copied. These pointers, together with meta-information like timestamps |
14 | or field parity, are stored in a struct :c:type:`v4l2_buffer`, | 14 | or field parity, are stored in a struct :c:type:`v4l2_buffer`, |
15 | argument to the :ref:`VIDIOC_QUERYBUF`, | 15 | argument to the :ref:`VIDIOC_QUERYBUF`, |
16 | :ref:`VIDIOC_QBUF` and | 16 | :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` and |
17 | :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. In the multi-planar API, | 17 | :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. In the multi-planar API, |
18 | some plane-specific members of struct :c:type:`v4l2_buffer`, | 18 | some plane-specific members of struct :c:type:`v4l2_buffer`, |
19 | such as pointers and sizes for each plane, are stored in struct | 19 | such as pointers and sizes for each plane, are stored in struct |
diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index dfe49ae57e78..d5f3eb6e674a 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst | |||
@@ -1960,6 +1960,416 @@ enum v4l2_vp8_golden_frame_sel - | |||
1960 | 1, 2 and 3 corresponding to encoder profiles 0, 1, 2 and 3. | 1960 | 1, 2 and 3 corresponding to encoder profiles 0, 1, 2 and 3. |
1961 | 1961 | ||
1962 | 1962 | ||
1963 | High Efficiency Video Coding (HEVC/H.265) Control Reference | ||
1964 | ----------------------------------------------------------- | ||
1965 | |||
1966 | The HEVC/H.265 controls include controls for encoding parameters of HEVC/H.265 | ||
1967 | video codec. | ||
1968 | |||
1969 | |||
1970 | .. _hevc-control-id: | ||
1971 | |||
1972 | HEVC/H.265 Control IDs | ||
1973 | ^^^^^^^^^^^^^^^^^^^^^^ | ||
1974 | |||
1975 | ``V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (integer)`` | ||
1976 | Minimum quantization parameter for HEVC. | ||
1977 | Valid range: from 0 to 51. | ||
1978 | |||
1979 | ``V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (integer)`` | ||
1980 | Maximum quantization parameter for HEVC. | ||
1981 | Valid range: from 0 to 51. | ||
1982 | |||
1983 | ``V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (integer)`` | ||
1984 | Quantization parameter for an I frame for HEVC. | ||
1985 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
1986 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
1987 | |||
1988 | ``V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP (integer)`` | ||
1989 | Quantization parameter for a P frame for HEVC. | ||
1990 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
1991 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
1992 | |||
1993 | ``V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP (integer)`` | ||
1994 | Quantization parameter for a B frame for HEVC. | ||
1995 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
1996 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
1997 | |||
1998 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP (boolean)`` | ||
1999 | HIERARCHICAL_QP allows the host to specify the quantization parameter | ||
2000 | values for each temporal layer through HIERARCHICAL_QP_LAYER. This is | ||
2001 | valid only if HIERARCHICAL_CODING_LAYER is greater than 1. Setting the | ||
2002 | control value to 1 enables setting of the QP values for the layers. | ||
2003 | |||
2004 | .. _v4l2-hevc-hier-coding-type: | ||
2005 | |||
2006 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE`` | ||
2007 | (enum) | ||
2008 | |||
2009 | enum v4l2_mpeg_video_hevc_hier_coding_type - | ||
2010 | Selects the hierarchical coding type for encoding. Possible values are: | ||
2011 | |||
2012 | .. raw:: latex | ||
2013 | |||
2014 | \footnotesize | ||
2015 | |||
2016 | .. tabularcolumns:: |p{9.0cm}|p{8.0cm}| | ||
2017 | |||
2018 | .. flat-table:: | ||
2019 | :header-rows: 0 | ||
2020 | :stub-columns: 0 | ||
2021 | |||
2022 | * - ``V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B`` | ||
2023 | - Use the B frame for hierarchical coding. | ||
2024 | * - ``V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P`` | ||
2025 | - Use the P frame for hierarchical coding. | ||
2026 | |||
2027 | .. raw:: latex | ||
2028 | |||
2029 | \normalsize | ||
2030 | |||
2031 | |||
2032 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER (integer)`` | ||
2033 | Selects the hierarchical coding layer. In normal encoding | ||
2034 | (non-hierarchial coding), it should be zero. Possible values are [0, 6]. | ||
2035 | 0 indicates HIERARCHICAL CODING LAYER 0, 1 indicates HIERARCHICAL CODING | ||
2036 | LAYER 1 and so on. | ||
2037 | |||
2038 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP (integer)`` | ||
2039 | Indicates quantization parameter for hierarchical coding layer 0. | ||
2040 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2041 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2042 | |||
2043 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP (integer)`` | ||
2044 | Indicates quantization parameter for hierarchical coding layer 1. | ||
2045 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2046 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2047 | |||
2048 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP (integer)`` | ||
2049 | Indicates quantization parameter for hierarchical coding layer 2. | ||
2050 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2051 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2052 | |||
2053 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP (integer)`` | ||
2054 | Indicates quantization parameter for hierarchical coding layer 3. | ||
2055 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2056 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2057 | |||
2058 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP (integer)`` | ||
2059 | Indicates quantization parameter for hierarchical coding layer 4. | ||
2060 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2061 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2062 | |||
2063 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP (integer)`` | ||
2064 | Indicates quantization parameter for hierarchical coding layer 5. | ||
2065 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2066 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2067 | |||
2068 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP (integer)`` | ||
2069 | Indicates quantization parameter for hierarchical coding layer 6. | ||
2070 | Valid range: [V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
2071 | V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP]. | ||
2072 | |||
2073 | .. _v4l2-hevc-profile: | ||
2074 | |||
2075 | ``V4L2_CID_MPEG_VIDEO_HEVC_PROFILE`` | ||
2076 | (enum) | ||
2077 | |||
2078 | enum v4l2_mpeg_video_hevc_profile - | ||
2079 | Select the desired profile for HEVC encoder. | ||
2080 | |||
2081 | .. raw:: latex | ||
2082 | |||
2083 | \footnotesize | ||
2084 | |||
2085 | .. tabularcolumns:: |p{9.0cm}|p{8.0cm}| | ||
2086 | |||
2087 | .. flat-table:: | ||
2088 | :header-rows: 0 | ||
2089 | :stub-columns: 0 | ||
2090 | |||
2091 | * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN`` | ||
2092 | - Main profile. | ||
2093 | * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE`` | ||
2094 | - Main still picture profile. | ||
2095 | * - ``V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10`` | ||
2096 | - Main 10 profile. | ||
2097 | |||
2098 | .. raw:: latex | ||
2099 | |||
2100 | \normalsize | ||
2101 | |||
2102 | |||
2103 | .. _v4l2-hevc-level: | ||
2104 | |||
2105 | ``V4L2_CID_MPEG_VIDEO_HEVC_LEVEL`` | ||
2106 | (enum) | ||
2107 | |||
2108 | enum v4l2_mpeg_video_hevc_level - | ||
2109 | Selects the desired level for HEVC encoder. | ||
2110 | |||
2111 | .. raw:: latex | ||
2112 | |||
2113 | \footnotesize | ||
2114 | |||
2115 | .. tabularcolumns:: |p{9.0cm}|p{8.0cm}| | ||
2116 | |||
2117 | .. flat-table:: | ||
2118 | :header-rows: 0 | ||
2119 | :stub-columns: 0 | ||
2120 | |||
2121 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_1`` | ||
2122 | - Level 1.0 | ||
2123 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_2`` | ||
2124 | - Level 2.0 | ||
2125 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1`` | ||
2126 | - Level 2.1 | ||
2127 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_3`` | ||
2128 | - Level 3.0 | ||
2129 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1`` | ||
2130 | - Level 3.1 | ||
2131 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_4`` | ||
2132 | - Level 4.0 | ||
2133 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1`` | ||
2134 | - Level 4.1 | ||
2135 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5`` | ||
2136 | - Level 5.0 | ||
2137 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1`` | ||
2138 | - Level 5.1 | ||
2139 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2`` | ||
2140 | - Level 5.2 | ||
2141 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6`` | ||
2142 | - Level 6.0 | ||
2143 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1`` | ||
2144 | - Level 6.1 | ||
2145 | * - ``V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2`` | ||
2146 | - Level 6.2 | ||
2147 | |||
2148 | .. raw:: latex | ||
2149 | |||
2150 | \normalsize | ||
2151 | |||
2152 | |||
2153 | ``V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION (integer)`` | ||
2154 | Indicates the number of evenly spaced subintervals, called ticks, within | ||
2155 | one second. This is a 16 bit unsigned integer and has a maximum value up to | ||
2156 | 0xffff and a minimum value of 1. | ||
2157 | |||
2158 | .. _v4l2-hevc-tier: | ||
2159 | |||
2160 | ``V4L2_CID_MPEG_VIDEO_HEVC_TIER`` | ||
2161 | (enum) | ||
2162 | |||
2163 | enum v4l2_mpeg_video_hevc_tier - | ||
2164 | TIER_FLAG specifies tiers information of the HEVC encoded picture. Tier | ||
2165 | were made to deal with applications that differ in terms of maximum bit | ||
2166 | rate. Setting the flag to 0 selects HEVC tier as Main tier and setting | ||
2167 | this flag to 1 indicates High tier. High tier is for applications requiring | ||
2168 | high bit rates. | ||
2169 | |||
2170 | .. raw:: latex | ||
2171 | |||
2172 | \footnotesize | ||
2173 | |||
2174 | .. tabularcolumns:: |p{9.0cm}|p{8.0cm}| | ||
2175 | |||
2176 | .. flat-table:: | ||
2177 | :header-rows: 0 | ||
2178 | :stub-columns: 0 | ||
2179 | |||
2180 | * - ``V4L2_MPEG_VIDEO_HEVC_TIER_MAIN`` | ||
2181 | - Main tier. | ||
2182 | * - ``V4L2_MPEG_VIDEO_HEVC_TIER_HIGH`` | ||
2183 | - High tier. | ||
2184 | |||
2185 | .. raw:: latex | ||
2186 | |||
2187 | \normalsize | ||
2188 | |||
2189 | |||
2190 | ``V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH (integer)`` | ||
2191 | Selects HEVC maximum coding unit depth. | ||
2192 | |||
2193 | .. _v4l2-hevc-loop-filter-mode: | ||
2194 | |||
2195 | ``V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE`` | ||
2196 | (enum) | ||
2197 | |||
2198 | enum v4l2_mpeg_video_hevc_loop_filter_mode - | ||
2199 | Loop filter mode for HEVC encoder. Possible values are: | ||
2200 | |||
2201 | .. raw:: latex | ||
2202 | |||
2203 | \footnotesize | ||
2204 | |||
2205 | .. tabularcolumns:: |p{10.7cm}|p{6.3cm}| | ||
2206 | |||
2207 | .. flat-table:: | ||
2208 | :header-rows: 0 | ||
2209 | :stub-columns: 0 | ||
2210 | |||
2211 | * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED`` | ||
2212 | - Loop filter is disabled. | ||
2213 | * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED`` | ||
2214 | - Loop filter is enabled. | ||
2215 | * - ``V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY`` | ||
2216 | - Loop filter is disabled at the slice boundary. | ||
2217 | |||
2218 | .. raw:: latex | ||
2219 | |||
2220 | \normalsize | ||
2221 | |||
2222 | |||
2223 | ``V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (integer)`` | ||
2224 | Selects HEVC loop filter beta offset. The valid range is [-6, +6]. | ||
2225 | |||
2226 | ``V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (integer)`` | ||
2227 | Selects HEVC loop filter tc offset. The valid range is [-6, +6]. | ||
2228 | |||
2229 | .. _v4l2-hevc-refresh-type: | ||
2230 | |||
2231 | ``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE`` | ||
2232 | (enum) | ||
2233 | |||
2234 | enum v4l2_mpeg_video_hevc_hier_refresh_type - | ||
2235 | Selects refresh type for HEVC encoder. | ||
2236 | Host has to specify the period into | ||
2237 | V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD. | ||
2238 | |||
2239 | .. raw:: latex | ||
2240 | |||
2241 | \footnotesize | ||
2242 | |||
2243 | .. tabularcolumns:: |p{8.0cm}|p{9.0cm}| | ||
2244 | |||
2245 | .. flat-table:: | ||
2246 | :header-rows: 0 | ||
2247 | :stub-columns: 0 | ||
2248 | |||
2249 | * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE`` | ||
2250 | - Use the B frame for hierarchical coding. | ||
2251 | * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA`` | ||
2252 | - Use CRA (Clean Random Access Unit) picture encoding. | ||
2253 | * - ``V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR`` | ||
2254 | - Use IDR (Instantaneous Decoding Refresh) picture encoding. | ||
2255 | |||
2256 | .. raw:: latex | ||
2257 | |||
2258 | \normalsize | ||
2259 | |||
2260 | |||
2261 | ``V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD (integer)`` | ||
2262 | Selects the refresh period for HEVC encoder. | ||
2263 | This specifies the number of I pictures between two CRA/IDR pictures. | ||
2264 | This is valid only if REFRESH_TYPE is not 0. | ||
2265 | |||
2266 | ``V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU (boolean)`` | ||
2267 | Indicates HEVC lossless encoding. Setting it to 0 disables lossless | ||
2268 | encoding. Setting it to 1 enables lossless encoding. | ||
2269 | |||
2270 | ``V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED (boolean)`` | ||
2271 | Indicates constant intra prediction for HEVC encoder. Specifies the | ||
2272 | constrained intra prediction in which intra largest coding unit (LCU) | ||
2273 | prediction is performed by using residual data and decoded samples of | ||
2274 | neighboring intra LCU only. Setting the value to 1 enables constant intra | ||
2275 | prediction and setting the value to 0 disables constant intra prediction. | ||
2276 | |||
2277 | ``V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT (boolean)`` | ||
2278 | Indicates wavefront parallel processing for HEVC encoder. Setting it to 0 | ||
2279 | disables the feature and setting it to 1 enables the wavefront parallel | ||
2280 | processing. | ||
2281 | |||
2282 | ``V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB (boolean)`` | ||
2283 | Setting the value to 1 enables combination of P and B frame for HEVC | ||
2284 | encoder. | ||
2285 | |||
2286 | ``V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID (boolean)`` | ||
2287 | Indicates temporal identifier for HEVC encoder which is enabled by | ||
2288 | setting the value to 1. | ||
2289 | |||
2290 | ``V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING (boolean)`` | ||
2291 | Indicates bi-linear interpolation is conditionally used in the intra | ||
2292 | prediction filtering process in the CVS when set to 1. Indicates bi-linear | ||
2293 | interpolation is not used in the CVS when set to 0. | ||
2294 | |||
2295 | ``V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1 (integer)`` | ||
2296 | Indicates maximum number of merge candidate motion vectors. | ||
2297 | Values are from 0 to 4. | ||
2298 | |||
2299 | ``V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION (boolean)`` | ||
2300 | Indicates temporal motion vector prediction for HEVC encoder. Setting it to | ||
2301 | 1 enables the prediction. Setting it to 0 disables the prediction. | ||
2302 | |||
2303 | ``V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE (boolean)`` | ||
2304 | Specifies if HEVC generates a stream with a size of the length field | ||
2305 | instead of start code pattern. The size of the length field is configurable | ||
2306 | through the V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD control. Setting | ||
2307 | the value to 0 disables encoding without startcode pattern. Setting the | ||
2308 | value to 1 will enables encoding without startcode pattern. | ||
2309 | |||
2310 | .. _v4l2-hevc-size-of-length-field: | ||
2311 | |||
2312 | ``V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD`` | ||
2313 | (enum) | ||
2314 | |||
2315 | enum v4l2_mpeg_video_hevc_size_of_length_field - | ||
2316 | Indicates the size of length field. | ||
2317 | This is valid when encoding WITHOUT_STARTCODE_ENABLE is enabled. | ||
2318 | |||
2319 | .. raw:: latex | ||
2320 | |||
2321 | \footnotesize | ||
2322 | |||
2323 | .. tabularcolumns:: |p{6.0cm}|p{11.0cm}| | ||
2324 | |||
2325 | .. flat-table:: | ||
2326 | :header-rows: 0 | ||
2327 | :stub-columns: 0 | ||
2328 | |||
2329 | * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_0`` | ||
2330 | - Generate start code pattern (Normal). | ||
2331 | * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_1`` | ||
2332 | - Generate size of length field instead of start code pattern and length is 1. | ||
2333 | * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_2`` | ||
2334 | - Generate size of length field instead of start code pattern and length is 2. | ||
2335 | * - ``V4L2_MPEG_VIDEO_HEVC_SIZE_4`` | ||
2336 | - Generate size of length field instead of start code pattern and length is 4. | ||
2337 | |||
2338 | .. raw:: latex | ||
2339 | |||
2340 | \normalsize | ||
2341 | |||
2342 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR (integer)`` | ||
2343 | Indicates bit rate for hierarchical coding layer 0 for HEVC encoder. | ||
2344 | |||
2345 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR (integer)`` | ||
2346 | Indicates bit rate for hierarchical coding layer 1 for HEVC encoder. | ||
2347 | |||
2348 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR (integer)`` | ||
2349 | Indicates bit rate for hierarchical coding layer 2 for HEVC encoder. | ||
2350 | |||
2351 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR (integer)`` | ||
2352 | Indicates bit rate for hierarchical coding layer 3 for HEVC encoder. | ||
2353 | |||
2354 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR (integer)`` | ||
2355 | Indicates bit rate for hierarchical coding layer 4 for HEVC encoder. | ||
2356 | |||
2357 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR (integer)`` | ||
2358 | Indicates bit rate for hierarchical coding layer 5 for HEVC encoder. | ||
2359 | |||
2360 | ``V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (integer)`` | ||
2361 | Indicates bit rate for hierarchical coding layer 6 for HEVC encoder. | ||
2362 | |||
2363 | ``V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (integer)`` | ||
2364 | Selects number of P reference pictures required for HEVC encoder. | ||
2365 | P-Frame can use 1 or 2 frames for reference. | ||
2366 | |||
2367 | ``V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (integer)`` | ||
2368 | Indicates whether to generate SPS and PPS at every IDR. Setting it to 0 | ||
2369 | disables generating SPS and PPS at every IDR. Setting it to one enables | ||
2370 | generating SPS and PPS at every IDR. | ||
2371 | |||
2372 | |||
1963 | .. _camera-controls: | 2373 | .. _camera-controls: |
1964 | 2374 | ||
1965 | Camera Control Reference | 2375 | Camera Control Reference |
diff --git a/Documentation/media/uapi/v4l/func-poll.rst b/Documentation/media/uapi/v4l/func-poll.rst index d0432dc09b05..360bc6523ae2 100644 --- a/Documentation/media/uapi/v4l/func-poll.rst +++ b/Documentation/media/uapi/v4l/func-poll.rst | |||
@@ -39,7 +39,7 @@ When streaming I/O has been negotiated this function waits until a | |||
39 | buffer has been filled by the capture device and can be dequeued with | 39 | buffer has been filled by the capture device and can be dequeued with |
40 | the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. For output devices this | 40 | the :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. For output devices this |
41 | function waits until the device is ready to accept a new buffer to be | 41 | function waits until the device is ready to accept a new buffer to be |
42 | queued up with the :ref:`VIDIOC_QBUF` ioctl for | 42 | queued up with the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl for |
43 | display. When buffers are already in the outgoing queue of the driver | 43 | display. When buffers are already in the outgoing queue of the driver |
44 | (capture) or the incoming queue isn't full (display) the function | 44 | (capture) or the incoming queue isn't full (display) the function |
45 | returns immediately. | 45 | returns immediately. |
@@ -52,11 +52,11 @@ flags in the ``revents`` field, output devices the ``POLLOUT`` and | |||
52 | ``POLLWRNORM`` flags. When the function timed out it returns a value of | 52 | ``POLLWRNORM`` flags. When the function timed out it returns a value of |
53 | zero, on failure it returns -1 and the ``errno`` variable is set | 53 | zero, on failure it returns -1 and the ``errno`` variable is set |
54 | appropriately. When the application did not call | 54 | appropriately. When the application did not call |
55 | :ref:`VIDIOC_STREAMON` the :ref:`poll() <func-poll>` | 55 | :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` the :ref:`poll() <func-poll>` |
56 | function succeeds, but sets the ``POLLERR`` flag in the ``revents`` | 56 | function succeeds, but sets the ``POLLERR`` flag in the ``revents`` |
57 | field. When the application has called | 57 | field. When the application has called |
58 | :ref:`VIDIOC_STREAMON` for a capture device but | 58 | :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` for a capture device but |
59 | hasn't yet called :ref:`VIDIOC_QBUF`, the | 59 | hasn't yet called :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, the |
60 | :ref:`poll() <func-poll>` function succeeds and sets the ``POLLERR`` flag in | 60 | :ref:`poll() <func-poll>` function succeeds and sets the ``POLLERR`` flag in |
61 | the ``revents`` field. For output devices this same situation will cause | 61 | the ``revents`` field. For output devices this same situation will cause |
62 | :ref:`poll() <func-poll>` to succeed as well, but it sets the ``POLLOUT`` and | 62 | :ref:`poll() <func-poll>` to succeed as well, but it sets the ``POLLOUT`` and |
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst index 728d7ede10fa..abec03937bb3 100644 --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst | |||
@@ -90,3 +90,8 @@ Compressed Formats | |||
90 | - ``V4L2_PIX_FMT_VP9`` | 90 | - ``V4L2_PIX_FMT_VP9`` |
91 | - 'VP90' | 91 | - 'VP90' |
92 | - VP9 video elementary stream. | 92 | - VP9 video elementary stream. |
93 | * .. _V4L2-PIX-FMT-HEVC: | ||
94 | |||
95 | - ``V4L2_PIX_FMT_HEVC`` | ||
96 | - 'HEVC' | ||
97 | - HEVC/H.265 video elementary stream. | ||
diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst index 2ee164c25637..6622938c1b41 100644 --- a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst +++ b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst | |||
@@ -40,7 +40,7 @@ Single-planar format structure | |||
40 | RGB formats in :ref:`rgb-formats`, YUV formats in | 40 | RGB formats in :ref:`rgb-formats`, YUV formats in |
41 | :ref:`yuv-formats`, and reserved codes in | 41 | :ref:`yuv-formats`, and reserved codes in |
42 | :ref:`reserved-formats` | 42 | :ref:`reserved-formats` |
43 | * - enum :c:type::`v4l2_field` | 43 | * - enum :c:type:`v4l2_field` |
44 | - ``field`` | 44 | - ``field`` |
45 | - Video images are typically interlaced. Applications can request to | 45 | - Video images are typically interlaced. Applications can request to |
46 | capture or output only the top or bottom field, or both fields | 46 | capture or output only the top or bottom field, or both fields |
diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index b1eea44550e1..9fcabe7f9367 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst | |||
@@ -16,10 +16,14 @@ Media Bus Formats | |||
16 | 16 | ||
17 | * - __u32 | 17 | * - __u32 |
18 | - ``width`` | 18 | - ``width`` |
19 | - Image width, in pixels. | 19 | - Image width in pixels. |
20 | * - __u32 | 20 | * - __u32 |
21 | - ``height`` | 21 | - ``height`` |
22 | - Image height, in pixels. | 22 | - Image height in pixels. If ``field`` is one of ``V4L2_FIELD_TOP``, |
23 | ``V4L2_FIELD_BOTTOM`` or ``V4L2_FIELD_ALTERNATE`` then height | ||
24 | refers to the number of lines in the field, otherwise it refers to | ||
25 | the number of lines in the frame (which is twice the field height | ||
26 | for interlaced formats). | ||
23 | * - __u32 | 27 | * - __u32 |
24 | - ``code`` | 28 | - ``code`` |
25 | - Format code, from enum | 29 | - Format code, from enum |
diff --git a/Documentation/media/uapi/v4l/vidioc-g-parm.rst b/Documentation/media/uapi/v4l/vidioc-g-parm.rst index 616a5ea3f8fa..e831fa5512f0 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-parm.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-parm.rst | |||
@@ -66,7 +66,7 @@ union holding separate parameters for input and output devices. | |||
66 | - | 66 | - |
67 | - The buffer (stream) type, same as struct | 67 | - The buffer (stream) type, same as struct |
68 | :c:type:`v4l2_format` ``type``, set by the | 68 | :c:type:`v4l2_format` ``type``, set by the |
69 | application. See :c:type:`v4l2_buf_type` | 69 | application. See :c:type:`v4l2_buf_type`. |
70 | * - union | 70 | * - union |
71 | - ``parm`` | 71 | - ``parm`` |
72 | - | 72 | - |
@@ -75,12 +75,13 @@ union holding separate parameters for input and output devices. | |||
75 | - struct :c:type:`v4l2_captureparm` | 75 | - struct :c:type:`v4l2_captureparm` |
76 | - ``capture`` | 76 | - ``capture`` |
77 | - Parameters for capture devices, used when ``type`` is | 77 | - Parameters for capture devices, used when ``type`` is |
78 | ``V4L2_BUF_TYPE_VIDEO_CAPTURE``. | 78 | ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or |
79 | ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``. | ||
79 | * - | 80 | * - |
80 | - struct :c:type:`v4l2_outputparm` | 81 | - struct :c:type:`v4l2_outputparm` |
81 | - ``output`` | 82 | - ``output`` |
82 | - Parameters for output devices, used when ``type`` is | 83 | - Parameters for output devices, used when ``type`` is |
83 | ``V4L2_BUF_TYPE_VIDEO_OUTPUT``. | 84 | ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``. |
84 | * - | 85 | * - |
85 | - __u8 | 86 | - __u8 |
86 | - ``raw_data``\ [200] | 87 | - ``raw_data``\ [200] |
diff --git a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst index 70687a86ae38..49f9f4c181de 100644 --- a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst +++ b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst | |||
@@ -34,7 +34,7 @@ Description | |||
34 | 34 | ||
35 | Applications can optionally call the :ref:`VIDIOC_PREPARE_BUF` ioctl to | 35 | Applications can optionally call the :ref:`VIDIOC_PREPARE_BUF` ioctl to |
36 | pass ownership of the buffer to the driver before actually enqueuing it, | 36 | pass ownership of the buffer to the driver before actually enqueuing it, |
37 | using the :ref:`VIDIOC_QBUF` ioctl, and to prepare it for future I/O. Such | 37 | using the :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl, and to prepare it for future I/O. Such |
38 | preparations may include cache invalidation or cleaning. Performing them | 38 | preparations may include cache invalidation or cleaning. Performing them |
39 | in advance saves time during the actual I/O. In case such cache | 39 | in advance saves time during the actual I/O. In case such cache |
40 | operations are not required, the application can use one of | 40 | operations are not required, the application can use one of |
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst index 3c4f58bda178..65d3d15eb159 100644 --- a/Documentation/media/v4l-drivers/imx.rst +++ b/Documentation/media/v4l-drivers/imx.rst | |||
@@ -109,7 +109,7 @@ imx6-mipi-csi2 | |||
109 | This is the MIPI CSI-2 receiver entity. It has one sink pad to receive | 109 | This is the MIPI CSI-2 receiver entity. It has one sink pad to receive |
110 | the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has | 110 | the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has |
111 | four source pads, corresponding to the four MIPI CSI-2 demuxed virtual | 111 | four source pads, corresponding to the four MIPI CSI-2 demuxed virtual |
112 | channel outputs. Multpiple source pads can be enabled to independently | 112 | channel outputs. Multiple source pads can be enabled to independently |
113 | stream from multiple virtual channels. | 113 | stream from multiple virtual channels. |
114 | 114 | ||
115 | This entity actually consists of two sub-blocks. One is the MIPI CSI-2 | 115 | This entity actually consists of two sub-blocks. One is the MIPI CSI-2 |
@@ -213,9 +213,11 @@ To give an example of crop and /2 downscale, this will crop a | |||
213 | 1280x960 input frame to 640x480, and then /2 downscale in both | 213 | 1280x960 input frame to 640x480, and then /2 downscale in both |
214 | dimensions to 320x240 (assumes ipu1_csi0 is linked to ipu1_csi0_mux): | 214 | dimensions to 320x240 (assumes ipu1_csi0 is linked to ipu1_csi0_mux): |
215 | 215 | ||
216 | media-ctl -V "'ipu1_csi0_mux':2[fmt:UYVY2X8/1280x960]" | 216 | .. code-block:: none |
217 | media-ctl -V "'ipu1_csi0':0[crop:(0,0)/640x480]" | 217 | |
218 | media-ctl -V "'ipu1_csi0':0[compose:(0,0)/320x240]" | 218 | media-ctl -V "'ipu1_csi0_mux':2[fmt:UYVY2X8/1280x960]" |
219 | media-ctl -V "'ipu1_csi0':0[crop:(0,0)/640x480]" | ||
220 | media-ctl -V "'ipu1_csi0':0[compose:(0,0)/320x240]" | ||
219 | 221 | ||
220 | Frame Skipping in ipuX_csiY | 222 | Frame Skipping in ipuX_csiY |
221 | --------------------------- | 223 | --------------------------- |
@@ -229,8 +231,10 @@ at the source pad. | |||
229 | The following example reduces an assumed incoming 60 Hz frame | 231 | The following example reduces an assumed incoming 60 Hz frame |
230 | rate by half at the IDMAC output source pad: | 232 | rate by half at the IDMAC output source pad: |
231 | 233 | ||
232 | media-ctl -V "'ipu1_csi0':0[fmt:UYVY2X8/640x480@1/60]" | 234 | .. code-block:: none |
233 | media-ctl -V "'ipu1_csi0':2[fmt:UYVY2X8/640x480@1/30]" | 235 | |
236 | media-ctl -V "'ipu1_csi0':0[fmt:UYVY2X8/640x480@1/60]" | ||
237 | media-ctl -V "'ipu1_csi0':2[fmt:UYVY2X8/640x480@1/30]" | ||
234 | 238 | ||
235 | Frame Interval Monitor in ipuX_csiY | 239 | Frame Interval Monitor in ipuX_csiY |
236 | ----------------------------------- | 240 | ----------------------------------- |
@@ -422,8 +426,7 @@ This pipeline uses the preprocess encode entity to route frames directly | |||
422 | from the CSI to the IC, to carry out scaling up to 1024x1024 resolution, | 426 | from the CSI to the IC, to carry out scaling up to 1024x1024 resolution, |
423 | CSC, flipping, and image rotation: | 427 | CSC, flipping, and image rotation: |
424 | 428 | ||
425 | -> ipuX_csiY:1 -> 0:ipuX_ic_prp:1 -> 0:ipuX_ic_prpenc:1 -> | 429 | -> ipuX_csiY:1 -> 0:ipuX_ic_prp:1 -> 0:ipuX_ic_prpenc:1 -> ipuX_ic_prpenc capture |
426 | ipuX_ic_prpenc capture | ||
427 | 430 | ||
428 | Motion Compensated De-interlace: | 431 | Motion Compensated De-interlace: |
429 | -------------------------------- | 432 | -------------------------------- |
@@ -432,8 +435,7 @@ This pipeline routes frames from the CSI direct pad to the VDIC entity to | |||
432 | support motion-compensated de-interlacing (high motion mode only), | 435 | support motion-compensated de-interlacing (high motion mode only), |
433 | scaling up to 1024x1024, CSC, flip, and rotation: | 436 | scaling up to 1024x1024, CSC, flip, and rotation: |
434 | 437 | ||
435 | -> ipuX_csiY:1 -> 0:ipuX_vdic:2 -> 0:ipuX_ic_prp:2 -> | 438 | -> ipuX_csiY:1 -> 0:ipuX_vdic:2 -> 0:ipuX_ic_prp:2 -> 0:ipuX_ic_prpvf:1 -> ipuX_ic_prpvf capture |
436 | 0:ipuX_ic_prpvf:1 -> ipuX_ic_prpvf capture | ||
437 | 439 | ||
438 | 440 | ||
439 | Usage Notes | 441 | Usage Notes |
@@ -458,8 +460,8 @@ This platform requires the OmniVision OV5642 module with a parallel | |||
458 | camera interface, and the OV5640 module with a MIPI CSI-2 | 460 | camera interface, and the OV5640 module with a MIPI CSI-2 |
459 | interface. Both modules are available from Boundary Devices: | 461 | interface. Both modules are available from Boundary Devices: |
460 | 462 | ||
461 | https://boundarydevices.com/product/nit6x_5mp | 463 | - https://boundarydevices.com/product/nit6x_5mp |
462 | https://boundarydevices.com/product/nit6x_5mp_mipi | 464 | - https://boundarydevices.com/product/nit6x_5mp_mipi |
463 | 465 | ||
464 | Note that if only one camera module is available, the other sensor | 466 | Note that if only one camera module is available, the other sensor |
465 | node can be disabled in the device tree. | 467 | node can be disabled in the device tree. |
diff --git a/MAINTAINERS b/MAINTAINERS index f830fc9abe00..2328eed6aea9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3275,6 +3275,7 @@ F: include/media/cec-notifier.h | |||
3275 | F: include/uapi/linux/cec.h | 3275 | F: include/uapi/linux/cec.h |
3276 | F: include/uapi/linux/cec-funcs.h | 3276 | F: include/uapi/linux/cec-funcs.h |
3277 | F: Documentation/devicetree/bindings/media/cec.txt | 3277 | F: Documentation/devicetree/bindings/media/cec.txt |
3278 | F: Documentation/ABI/testing/debugfs-cec-error-inj | ||
3278 | 3279 | ||
3279 | CEC GPIO DRIVER | 3280 | CEC GPIO DRIVER |
3280 | M: Hans Verkuil <hans.verkuil@cisco.com> | 3281 | M: Hans Verkuil <hans.verkuil@cisco.com> |
@@ -6865,6 +6866,13 @@ M: James Hogan <jhogan@kernel.org> | |||
6865 | S: Maintained | 6866 | S: Maintained |
6866 | F: drivers/media/rc/img-ir/ | 6867 | F: drivers/media/rc/img-ir/ |
6867 | 6868 | ||
6869 | IMON SOUNDGRAPH USB IR RECEIVER | ||
6870 | M: Sean Young <sean@mess.org> | ||
6871 | L: linux-media@vger.kernel.org | ||
6872 | S: Maintained | ||
6873 | F: drivers/media/rc/imon_raw.c | ||
6874 | F: drivers/media/rc/imon.c | ||
6875 | |||
6868 | IMS TWINTURBO FRAMEBUFFER DRIVER | 6876 | IMS TWINTURBO FRAMEBUFFER DRIVER |
6869 | L: linux-fbdev@vger.kernel.org | 6877 | L: linux-fbdev@vger.kernel.org |
6870 | S: Orphan | 6878 | S: Orphan |
@@ -8604,6 +8612,14 @@ T: git git://linuxtv.org/media_tree.git | |||
8604 | S: Supported | 8612 | S: Supported |
8605 | F: drivers/media/dvb-frontends/ascot2e* | 8613 | F: drivers/media/dvb-frontends/ascot2e* |
8606 | 8614 | ||
8615 | MEDIA DRIVERS FOR CXD2099AR CI CONTROLLERS | ||
8616 | M: Jasmin Jessich <jasmin@anw.at> | ||
8617 | L: linux-media@vger.kernel.org | ||
8618 | W: https://linuxtv.org | ||
8619 | T: git git://linuxtv.org/media_tree.git | ||
8620 | S: Maintained | ||
8621 | F: drivers/media/dvb-frontends/cxd2099* | ||
8622 | |||
8607 | MEDIA DRIVERS FOR CXD2841ER | 8623 | MEDIA DRIVERS FOR CXD2841ER |
8608 | M: Sergey Kozlov <serjk@netup.ru> | 8624 | M: Sergey Kozlov <serjk@netup.ru> |
8609 | M: Abylay Ospan <aospan@netup.ru> | 8625 | M: Abylay Ospan <aospan@netup.ru> |
@@ -8614,6 +8630,15 @@ T: git git://linuxtv.org/media_tree.git | |||
8614 | S: Supported | 8630 | S: Supported |
8615 | F: drivers/media/dvb-frontends/cxd2841er* | 8631 | F: drivers/media/dvb-frontends/cxd2841er* |
8616 | 8632 | ||
8633 | MEDIA DRIVERS FOR CXD2880 | ||
8634 | M: Yasunari Takiguchi <Yasunari.Takiguchi@sony.com> | ||
8635 | L: linux-media@vger.kernel.org | ||
8636 | W: http://linuxtv.org/ | ||
8637 | T: git git://linuxtv.org/media_tree.git | ||
8638 | S: Supported | ||
8639 | F: drivers/media/dvb-frontends/cxd2880/* | ||
8640 | F: drivers/media/spi/cxd2880* | ||
8641 | |||
8617 | MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES | 8642 | MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES |
8618 | M: Daniel Scheller <d.scheller.oss@gmail.com> | 8643 | M: Daniel Scheller <d.scheller.oss@gmail.com> |
8619 | L: linux-media@vger.kernel.org | 8644 | L: linux-media@vger.kernel.org |
@@ -8681,6 +8706,16 @@ T: git git://linuxtv.org/media_tree.git | |||
8681 | S: Supported | 8706 | S: Supported |
8682 | F: drivers/media/pci/netup_unidvb/* | 8707 | F: drivers/media/pci/netup_unidvb/* |
8683 | 8708 | ||
8709 | MEDIA DRIVERS FOR RENESAS - CEU | ||
8710 | M: Jacopo Mondi <jacopo@jmondi.org> | ||
8711 | L: linux-media@vger.kernel.org | ||
8712 | L: linux-renesas-soc@vger.kernel.org | ||
8713 | T: git git://linuxtv.org/media_tree.git | ||
8714 | S: Supported | ||
8715 | F: Documentation/devicetree/bindings/media/renesas,ceu.txt | ||
8716 | F: drivers/media/platform/renesas-ceu.c | ||
8717 | F: include/media/drv-intf/renesas-ceu.h | ||
8718 | |||
8684 | MEDIA DRIVERS FOR RENESAS - DRIF | 8719 | MEDIA DRIVERS FOR RENESAS - DRIF |
8685 | M: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> | 8720 | M: Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com> |
8686 | L: linux-media@vger.kernel.org | 8721 | L: linux-media@vger.kernel.org |
@@ -9365,6 +9400,14 @@ S: Maintained | |||
9365 | F: drivers/media/i2c/mt9t001.c | 9400 | F: drivers/media/i2c/mt9t001.c |
9366 | F: include/media/i2c/mt9t001.h | 9401 | F: include/media/i2c/mt9t001.h |
9367 | 9402 | ||
9403 | MT9T112 APTINA CAMERA SENSOR | ||
9404 | M: Jacopo Mondi <jacopo@jmondi.org> | ||
9405 | L: linux-media@vger.kernel.org | ||
9406 | T: git git://linuxtv.org/media_tree.git | ||
9407 | S: Odd Fixes | ||
9408 | F: drivers/media/i2c/mt9t112.c | ||
9409 | F: include/media/i2c/mt9t112.h | ||
9410 | |||
9368 | MT9V032 APTINA CAMERA SENSOR | 9411 | MT9V032 APTINA CAMERA SENSOR |
9369 | M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 9412 | M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
9370 | L: linux-media@vger.kernel.org | 9413 | L: linux-media@vger.kernel.org |
@@ -10170,6 +10213,13 @@ T: git git://linuxtv.org/media_tree.git | |||
10170 | S: Maintained | 10213 | S: Maintained |
10171 | F: drivers/media/i2c/ov13858.c | 10214 | F: drivers/media/i2c/ov13858.c |
10172 | 10215 | ||
10216 | OMNIVISION OV2685 SENSOR DRIVER | ||
10217 | M: Shunqian Zheng <zhengsq@rock-chips.com> | ||
10218 | L: linux-media@vger.kernel.org | ||
10219 | T: git git://linuxtv.org/media_tree.git | ||
10220 | S: Maintained | ||
10221 | F: drivers/media/i2c/ov2685.c | ||
10222 | |||
10173 | OMNIVISION OV5640 SENSOR DRIVER | 10223 | OMNIVISION OV5640 SENSOR DRIVER |
10174 | M: Steve Longerbeam <slongerbeam@gmail.com> | 10224 | M: Steve Longerbeam <slongerbeam@gmail.com> |
10175 | L: linux-media@vger.kernel.org | 10225 | L: linux-media@vger.kernel.org |
@@ -10184,6 +10234,13 @@ T: git git://linuxtv.org/media_tree.git | |||
10184 | S: Maintained | 10234 | S: Maintained |
10185 | F: drivers/media/i2c/ov5647.c | 10235 | F: drivers/media/i2c/ov5647.c |
10186 | 10236 | ||
10237 | OMNIVISION OV5695 SENSOR DRIVER | ||
10238 | M: Shunqian Zheng <zhengsq@rock-chips.com> | ||
10239 | L: linux-media@vger.kernel.org | ||
10240 | T: git git://linuxtv.org/media_tree.git | ||
10241 | S: Maintained | ||
10242 | F: drivers/media/i2c/ov5695.c | ||
10243 | |||
10187 | OMNIVISION OV7670 SENSOR DRIVER | 10244 | OMNIVISION OV7670 SENSOR DRIVER |
10188 | M: Jonathan Corbet <corbet@lwn.net> | 10245 | M: Jonathan Corbet <corbet@lwn.net> |
10189 | L: linux-media@vger.kernel.org | 10246 | L: linux-media@vger.kernel.org |
@@ -10192,6 +10249,14 @@ S: Maintained | |||
10192 | F: drivers/media/i2c/ov7670.c | 10249 | F: drivers/media/i2c/ov7670.c |
10193 | F: Documentation/devicetree/bindings/media/i2c/ov7670.txt | 10250 | F: Documentation/devicetree/bindings/media/i2c/ov7670.txt |
10194 | 10251 | ||
10252 | OMNIVISION OV772x SENSOR DRIVER | ||
10253 | M: Jacopo Mondi <jacopo@jmondi.org> | ||
10254 | L: linux-media@vger.kernel.org | ||
10255 | T: git git://linuxtv.org/media_tree.git | ||
10256 | S: Odd fixes | ||
10257 | F: drivers/media/i2c/ov772x.c | ||
10258 | F: include/media/i2c/ov772x.h | ||
10259 | |||
10195 | OMNIVISION OV7740 SENSOR DRIVER | 10260 | OMNIVISION OV7740 SENSOR DRIVER |
10196 | M: Wenyou Yang <wenyou.yang@microchip.com> | 10261 | M: Wenyou Yang <wenyou.yang@microchip.com> |
10197 | L: linux-media@vger.kernel.org | 10262 | L: linux-media@vger.kernel.org |
@@ -10200,6 +10265,16 @@ S: Maintained | |||
10200 | F: drivers/media/i2c/ov7740.c | 10265 | F: drivers/media/i2c/ov7740.c |
10201 | F: Documentation/devicetree/bindings/media/i2c/ov7740.txt | 10266 | F: Documentation/devicetree/bindings/media/i2c/ov7740.txt |
10202 | 10267 | ||
10268 | OMNIVISION OV9650 SENSOR DRIVER | ||
10269 | M: Sakari Ailus <sakari.ailus@linux.intel.com> | ||
10270 | R: Akinobu Mita <akinobu.mita@gmail.com> | ||
10271 | R: Sylwester Nawrocki <s.nawrocki@samsung.com> | ||
10272 | L: linux-media@vger.kernel.org | ||
10273 | T: git git://linuxtv.org/media_tree.git | ||
10274 | S: Maintained | ||
10275 | F: drivers/media/i2c/ov9650.c | ||
10276 | F: Documentation/devicetree/bindings/media/i2c/ov9650.txt | ||
10277 | |||
10203 | ONENAND FLASH DRIVER | 10278 | ONENAND FLASH DRIVER |
10204 | M: Kyungmin Park <kyungmin.park@samsung.com> | 10279 | M: Kyungmin Park <kyungmin.park@samsung.com> |
10205 | L: linux-mtd@lists.infradead.org | 10280 | L: linux-mtd@lists.infradead.org |
@@ -12780,10 +12855,9 @@ S: Maintained | |||
12780 | F: drivers/net/ethernet/smsc/smsc9420.* | 12855 | F: drivers/net/ethernet/smsc/smsc9420.* |
12781 | 12856 | ||
12782 | SOC-CAMERA V4L2 SUBSYSTEM | 12857 | SOC-CAMERA V4L2 SUBSYSTEM |
12783 | M: Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
12784 | L: linux-media@vger.kernel.org | 12858 | L: linux-media@vger.kernel.org |
12785 | T: git git://linuxtv.org/media_tree.git | 12859 | T: git git://linuxtv.org/media_tree.git |
12786 | S: Maintained | 12860 | S: Orphan |
12787 | F: include/media/soc* | 12861 | F: include/media/soc* |
12788 | F: drivers/media/i2c/soc_camera/ | 12862 | F: drivers/media/i2c/soc_camera/ |
12789 | F: drivers/media/platform/soc_camera/ | 12863 | F: drivers/media/platform/soc_camera/ |
@@ -13512,6 +13586,14 @@ T: git git://linuxtv.org/mkrufky/tuners.git | |||
13512 | S: Maintained | 13586 | S: Maintained |
13513 | F: drivers/media/tuners/tda18271* | 13587 | F: drivers/media/tuners/tda18271* |
13514 | 13588 | ||
13589 | TDA1997x MEDIA DRIVER | ||
13590 | M: Tim Harvey <tharvey@gateworks.com> | ||
13591 | L: linux-media@vger.kernel.org | ||
13592 | W: https://linuxtv.org | ||
13593 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ | ||
13594 | S: Maintained | ||
13595 | F: drivers/media/i2c/tda1997x.* | ||
13596 | |||
13515 | TDA827x MEDIA DRIVER | 13597 | TDA827x MEDIA DRIVER |
13516 | M: Michael Krufky <mkrufky@linuxtv.org> | 13598 | M: Michael Krufky <mkrufky@linuxtv.org> |
13517 | L: linux-media@vger.kernel.org | 13599 | L: linux-media@vger.kernel.org |
@@ -13593,6 +13675,12 @@ L: linux-media@vger.kernel.org | |||
13593 | S: Maintained | 13675 | S: Maintained |
13594 | F: drivers/media/rc/ttusbir.c | 13676 | F: drivers/media/rc/ttusbir.c |
13595 | 13677 | ||
13678 | TECHWELL TW9910 VIDEO DECODER | ||
13679 | L: linux-media@vger.kernel.org | ||
13680 | S: Orphan | ||
13681 | F: drivers/media/i2c/tw9910.c | ||
13682 | F: include/media/i2c/tw9910.h | ||
13683 | |||
13596 | TEE SUBSYSTEM | 13684 | TEE SUBSYSTEM |
13597 | M: Jens Wiklander <jens.wiklander@linaro.org> | 13685 | M: Jens Wiklander <jens.wiklander@linaro.org> |
13598 | S: Maintained | 13686 | S: Maintained |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 6f929abe0b50..adc61d14172c 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -7,44 +7,47 @@ | |||
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | */ | 9 | */ |
10 | 10 | #include <asm/clock.h> | |
11 | #include <linux/init.h> | 11 | #include <asm/heartbeat.h> |
12 | #include <asm/suspend.h> | ||
13 | #include <cpu/sh7724.h> | ||
14 | #include <linux/delay.h> | ||
12 | #include <linux/device.h> | 15 | #include <linux/device.h> |
13 | #include <linux/platform_device.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/io.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/input.h> | ||
20 | #include <linux/input/sh_keysc.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/memblock.h> | ||
23 | #include <linux/mfd/tmio.h> | ||
14 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
15 | #include <linux/mmc/sh_mmcif.h> | 25 | #include <linux/mmc/sh_mmcif.h> |
16 | #include <linux/mtd/physmap.h> | 26 | #include <linux/mtd/physmap.h> |
17 | #include <linux/mfd/tmio.h> | ||
18 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
19 | #include <linux/interrupt.h> | 28 | #include <linux/gpio/machine.h> |
20 | #include <linux/io.h> | 29 | #include <linux/platform_data/gpio_backlight.h> |
21 | #include <linux/delay.h> | 30 | #include <linux/platform_data/tsc2007.h> |
31 | #include <linux/platform_device.h> | ||
22 | #include <linux/regulator/fixed.h> | 32 | #include <linux/regulator/fixed.h> |
23 | #include <linux/regulator/machine.h> | 33 | #include <linux/regulator/machine.h> |
24 | #include <linux/usb/r8a66597.h> | ||
25 | #include <linux/usb/renesas_usbhs.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/platform_data/tsc2007.h> | ||
28 | #include <linux/spi/spi.h> | ||
29 | #include <linux/spi/sh_msiof.h> | ||
30 | #include <linux/spi/mmc_spi.h> | ||
31 | #include <linux/input.h> | ||
32 | #include <linux/input/sh_keysc.h> | ||
33 | #include <linux/platform_data/gpio_backlight.h> | ||
34 | #include <linux/sh_eth.h> | 34 | #include <linux/sh_eth.h> |
35 | #include <linux/sh_intc.h> | 35 | #include <linux/sh_intc.h> |
36 | #include <linux/spi/mmc_spi.h> | ||
37 | #include <linux/spi/sh_msiof.h> | ||
38 | #include <linux/spi/spi.h> | ||
39 | #include <linux/usb/r8a66597.h> | ||
40 | #include <linux/usb/renesas_usbhs.h> | ||
36 | #include <linux/videodev2.h> | 41 | #include <linux/videodev2.h> |
37 | #include <video/sh_mobile_lcdc.h> | 42 | |
43 | #include <media/drv-intf/renesas-ceu.h> | ||
44 | #include <media/i2c/mt9t112.h> | ||
45 | #include <media/i2c/tw9910.h> | ||
46 | |||
38 | #include <sound/sh_fsi.h> | 47 | #include <sound/sh_fsi.h> |
39 | #include <sound/simple_card.h> | 48 | #include <sound/simple_card.h> |
40 | #include <media/drv-intf/sh_mobile_ceu.h> | 49 | |
41 | #include <media/soc_camera.h> | 50 | #include <video/sh_mobile_lcdc.h> |
42 | #include <media/i2c/tw9910.h> | ||
43 | #include <media/i2c/mt9t112.h> | ||
44 | #include <asm/heartbeat.h> | ||
45 | #include <asm/clock.h> | ||
46 | #include <asm/suspend.h> | ||
47 | #include <cpu/sh7724.h> | ||
48 | 51 | ||
49 | /* | 52 | /* |
50 | * Address Interface BusWidth | 53 | * Address Interface BusWidth |
@@ -81,6 +84,10 @@ | |||
81 | * amixer set 'Out Mixer Right DAC Right' on | 84 | * amixer set 'Out Mixer Right DAC Right' on |
82 | */ | 85 | */ |
83 | 86 | ||
87 | #define CEU_BUFFER_MEMORY_SIZE (4 << 20) | ||
88 | static phys_addr_t ceu0_dma_membase; | ||
89 | static phys_addr_t ceu1_dma_membase; | ||
90 | |||
84 | /* Heartbeat */ | 91 | /* Heartbeat */ |
85 | static unsigned char led_pos[] = { 0, 1, 2, 3 }; | 92 | static unsigned char led_pos[] = { 0, 1, 2, 3 }; |
86 | 93 | ||
@@ -382,8 +389,24 @@ static struct platform_device gpio_backlight_device = { | |||
382 | }; | 389 | }; |
383 | 390 | ||
384 | /* CEU0 */ | 391 | /* CEU0 */ |
385 | static struct sh_mobile_ceu_info sh_mobile_ceu0_info = { | 392 | static struct ceu_platform_data ceu0_pdata = { |
386 | .flags = SH_CEU_FLAG_USE_8BIT_BUS, | 393 | .num_subdevs = 2, |
394 | .subdevs = { | ||
395 | { /* [0] = mt9t112 */ | ||
396 | .flags = 0, | ||
397 | .bus_width = 8, | ||
398 | .bus_shift = 0, | ||
399 | .i2c_adapter_id = 0, | ||
400 | .i2c_address = 0x3c, | ||
401 | }, | ||
402 | { /* [1] = tw9910 */ | ||
403 | .flags = 0, | ||
404 | .bus_width = 8, | ||
405 | .bus_shift = 0, | ||
406 | .i2c_adapter_id = 0, | ||
407 | .i2c_address = 0x45, | ||
408 | }, | ||
409 | }, | ||
387 | }; | 410 | }; |
388 | 411 | ||
389 | static struct resource ceu0_resources[] = { | 412 | static struct resource ceu0_resources[] = { |
@@ -397,24 +420,30 @@ static struct resource ceu0_resources[] = { | |||
397 | .start = evt2irq(0x880), | 420 | .start = evt2irq(0x880), |
398 | .flags = IORESOURCE_IRQ, | 421 | .flags = IORESOURCE_IRQ, |
399 | }, | 422 | }, |
400 | [2] = { | ||
401 | /* place holder for contiguous memory */ | ||
402 | }, | ||
403 | }; | 423 | }; |
404 | 424 | ||
405 | static struct platform_device ceu0_device = { | 425 | static struct platform_device ceu0_device = { |
406 | .name = "sh_mobile_ceu", | 426 | .name = "renesas-ceu", |
407 | .id = 0, /* "ceu0" clock */ | 427 | .id = 0, /* ceu.0 */ |
408 | .num_resources = ARRAY_SIZE(ceu0_resources), | 428 | .num_resources = ARRAY_SIZE(ceu0_resources), |
409 | .resource = ceu0_resources, | 429 | .resource = ceu0_resources, |
410 | .dev = { | 430 | .dev = { |
411 | .platform_data = &sh_mobile_ceu0_info, | 431 | .platform_data = &ceu0_pdata, |
412 | }, | 432 | }, |
413 | }; | 433 | }; |
414 | 434 | ||
415 | /* CEU1 */ | 435 | /* CEU1 */ |
416 | static struct sh_mobile_ceu_info sh_mobile_ceu1_info = { | 436 | static struct ceu_platform_data ceu1_pdata = { |
417 | .flags = SH_CEU_FLAG_USE_8BIT_BUS, | 437 | .num_subdevs = 1, |
438 | .subdevs = { | ||
439 | { /* [0] = mt9t112 */ | ||
440 | .flags = 0, | ||
441 | .bus_width = 8, | ||
442 | .bus_shift = 0, | ||
443 | .i2c_adapter_id = 1, | ||
444 | .i2c_address = 0x3c, | ||
445 | }, | ||
446 | }, | ||
418 | }; | 447 | }; |
419 | 448 | ||
420 | static struct resource ceu1_resources[] = { | 449 | static struct resource ceu1_resources[] = { |
@@ -428,26 +457,71 @@ static struct resource ceu1_resources[] = { | |||
428 | .start = evt2irq(0x9e0), | 457 | .start = evt2irq(0x9e0), |
429 | .flags = IORESOURCE_IRQ, | 458 | .flags = IORESOURCE_IRQ, |
430 | }, | 459 | }, |
431 | [2] = { | ||
432 | /* place holder for contiguous memory */ | ||
433 | }, | ||
434 | }; | 460 | }; |
435 | 461 | ||
436 | static struct platform_device ceu1_device = { | 462 | static struct platform_device ceu1_device = { |
437 | .name = "sh_mobile_ceu", | 463 | .name = "renesas-ceu", |
438 | .id = 1, /* "ceu1" clock */ | 464 | .id = 1, /* ceu.1 */ |
439 | .num_resources = ARRAY_SIZE(ceu1_resources), | 465 | .num_resources = ARRAY_SIZE(ceu1_resources), |
440 | .resource = ceu1_resources, | 466 | .resource = ceu1_resources, |
441 | .dev = { | 467 | .dev = { |
442 | .platform_data = &sh_mobile_ceu1_info, | 468 | .platform_data = &ceu1_pdata, |
469 | }, | ||
470 | }; | ||
471 | |||
472 | /* Power up/down GPIOs for camera devices and video decoder */ | ||
473 | static struct gpiod_lookup_table tw9910_gpios = { | ||
474 | .dev_id = "0-0045", | ||
475 | .table = { | ||
476 | GPIO_LOOKUP("sh7724_pfc", GPIO_PTU2, "pdn", GPIO_ACTIVE_HIGH), | ||
477 | }, | ||
478 | }; | ||
479 | |||
480 | static struct gpiod_lookup_table mt9t112_0_gpios = { | ||
481 | .dev_id = "0-003c", | ||
482 | .table = { | ||
483 | GPIO_LOOKUP("sh7724_pfc", GPIO_PTA3, "standby", | ||
484 | GPIO_ACTIVE_HIGH), | ||
485 | }, | ||
486 | }; | ||
487 | |||
488 | static struct gpiod_lookup_table mt9t112_1_gpios = { | ||
489 | .dev_id = "1-003c", | ||
490 | .table = { | ||
491 | GPIO_LOOKUP("sh7724_pfc", GPIO_PTA4, "standby", | ||
492 | GPIO_ACTIVE_HIGH), | ||
443 | }, | 493 | }, |
444 | }; | 494 | }; |
445 | 495 | ||
446 | /* I2C device */ | 496 | /* I2C device */ |
497 | static struct tw9910_video_info tw9910_info = { | ||
498 | .buswidth = 8, | ||
499 | .mpout = TW9910_MPO_FIELD, | ||
500 | }; | ||
501 | |||
502 | static struct mt9t112_platform_data mt9t112_0_pdata = { | ||
503 | .flags = MT9T112_FLAG_PCLK_RISING_EDGE, | ||
504 | .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ | ||
505 | }; | ||
506 | |||
507 | static struct mt9t112_platform_data mt9t112_1_pdata = { | ||
508 | .flags = MT9T112_FLAG_PCLK_RISING_EDGE, | ||
509 | .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ | ||
510 | }; | ||
511 | |||
447 | static struct i2c_board_info i2c0_devices[] = { | 512 | static struct i2c_board_info i2c0_devices[] = { |
448 | { | 513 | { |
449 | I2C_BOARD_INFO("da7210", 0x1a), | 514 | I2C_BOARD_INFO("da7210", 0x1a), |
450 | }, | 515 | }, |
516 | { | ||
517 | I2C_BOARD_INFO("tw9910", 0x45), | ||
518 | .platform_data = &tw9910_info, | ||
519 | }, | ||
520 | { | ||
521 | /* 1st camera */ | ||
522 | I2C_BOARD_INFO("mt9t112", 0x3c), | ||
523 | .platform_data = &mt9t112_0_pdata, | ||
524 | }, | ||
451 | }; | 525 | }; |
452 | 526 | ||
453 | static struct i2c_board_info i2c1_devices[] = { | 527 | static struct i2c_board_info i2c1_devices[] = { |
@@ -457,7 +531,12 @@ static struct i2c_board_info i2c1_devices[] = { | |||
457 | { | 531 | { |
458 | I2C_BOARD_INFO("lis3lv02d", 0x1c), | 532 | I2C_BOARD_INFO("lis3lv02d", 0x1c), |
459 | .irq = evt2irq(0x620), | 533 | .irq = evt2irq(0x620), |
460 | } | 534 | }, |
535 | { | ||
536 | /* 2nd camera */ | ||
537 | I2C_BOARD_INFO("mt9t112", 0x3c), | ||
538 | .platform_data = &mt9t112_1_pdata, | ||
539 | }, | ||
461 | }; | 540 | }; |
462 | 541 | ||
463 | /* KEYSC */ | 542 | /* KEYSC */ |
@@ -724,115 +803,6 @@ static struct platform_device msiof0_device = { | |||
724 | 803 | ||
725 | #endif | 804 | #endif |
726 | 805 | ||
727 | /* I2C Video/Camera */ | ||
728 | static struct i2c_board_info i2c_camera[] = { | ||
729 | { | ||
730 | I2C_BOARD_INFO("tw9910", 0x45), | ||
731 | }, | ||
732 | { | ||
733 | /* 1st camera */ | ||
734 | I2C_BOARD_INFO("mt9t112", 0x3c), | ||
735 | }, | ||
736 | { | ||
737 | /* 2nd camera */ | ||
738 | I2C_BOARD_INFO("mt9t112", 0x3c), | ||
739 | }, | ||
740 | }; | ||
741 | |||
742 | /* tw9910 */ | ||
743 | static int tw9910_power(struct device *dev, int mode) | ||
744 | { | ||
745 | int val = mode ? 0 : 1; | ||
746 | |||
747 | gpio_set_value(GPIO_PTU2, val); | ||
748 | if (mode) | ||
749 | mdelay(100); | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static struct tw9910_video_info tw9910_info = { | ||
755 | .buswidth = SOCAM_DATAWIDTH_8, | ||
756 | .mpout = TW9910_MPO_FIELD, | ||
757 | }; | ||
758 | |||
759 | static struct soc_camera_link tw9910_link = { | ||
760 | .i2c_adapter_id = 0, | ||
761 | .bus_id = 1, | ||
762 | .power = tw9910_power, | ||
763 | .board_info = &i2c_camera[0], | ||
764 | .priv = &tw9910_info, | ||
765 | }; | ||
766 | |||
767 | /* mt9t112 */ | ||
768 | static int mt9t112_power1(struct device *dev, int mode) | ||
769 | { | ||
770 | gpio_set_value(GPIO_PTA3, mode); | ||
771 | if (mode) | ||
772 | mdelay(100); | ||
773 | |||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static struct mt9t112_camera_info mt9t112_info1 = { | ||
778 | .flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8, | ||
779 | .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ | ||
780 | }; | ||
781 | |||
782 | static struct soc_camera_link mt9t112_link1 = { | ||
783 | .i2c_adapter_id = 0, | ||
784 | .power = mt9t112_power1, | ||
785 | .bus_id = 0, | ||
786 | .board_info = &i2c_camera[1], | ||
787 | .priv = &mt9t112_info1, | ||
788 | }; | ||
789 | |||
790 | static int mt9t112_power2(struct device *dev, int mode) | ||
791 | { | ||
792 | gpio_set_value(GPIO_PTA4, mode); | ||
793 | if (mode) | ||
794 | mdelay(100); | ||
795 | |||
796 | return 0; | ||
797 | } | ||
798 | |||
799 | static struct mt9t112_camera_info mt9t112_info2 = { | ||
800 | .flags = MT9T112_FLAG_PCLK_RISING_EDGE | MT9T112_FLAG_DATAWIDTH_8, | ||
801 | .divider = { 0x49, 0x6, 0, 6, 0, 9, 9, 6, 0 }, /* for 24MHz */ | ||
802 | }; | ||
803 | |||
804 | static struct soc_camera_link mt9t112_link2 = { | ||
805 | .i2c_adapter_id = 1, | ||
806 | .power = mt9t112_power2, | ||
807 | .bus_id = 1, | ||
808 | .board_info = &i2c_camera[2], | ||
809 | .priv = &mt9t112_info2, | ||
810 | }; | ||
811 | |||
812 | static struct platform_device camera_devices[] = { | ||
813 | { | ||
814 | .name = "soc-camera-pdrv", | ||
815 | .id = 0, | ||
816 | .dev = { | ||
817 | .platform_data = &tw9910_link, | ||
818 | }, | ||
819 | }, | ||
820 | { | ||
821 | .name = "soc-camera-pdrv", | ||
822 | .id = 1, | ||
823 | .dev = { | ||
824 | .platform_data = &mt9t112_link1, | ||
825 | }, | ||
826 | }, | ||
827 | { | ||
828 | .name = "soc-camera-pdrv", | ||
829 | .id = 2, | ||
830 | .dev = { | ||
831 | .platform_data = &mt9t112_link2, | ||
832 | }, | ||
833 | }, | ||
834 | }; | ||
835 | |||
836 | /* FSI */ | 806 | /* FSI */ |
837 | static struct resource fsi_resources[] = { | 807 | static struct resource fsi_resources[] = { |
838 | [0] = { | 808 | [0] = { |
@@ -979,6 +949,11 @@ static struct platform_device sh_mmcif_device = { | |||
979 | }; | 949 | }; |
980 | #endif | 950 | #endif |
981 | 951 | ||
952 | static struct platform_device *ecovec_ceu_devices[] __initdata = { | ||
953 | &ceu0_device, | ||
954 | &ceu1_device, | ||
955 | }; | ||
956 | |||
982 | static struct platform_device *ecovec_devices[] __initdata = { | 957 | static struct platform_device *ecovec_devices[] __initdata = { |
983 | &heartbeat_device, | 958 | &heartbeat_device, |
984 | &nor_flash_device, | 959 | &nor_flash_device, |
@@ -988,8 +963,6 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
988 | &usbhs_device, | 963 | &usbhs_device, |
989 | &lcdc_device, | 964 | &lcdc_device, |
990 | &gpio_backlight_device, | 965 | &gpio_backlight_device, |
991 | &ceu0_device, | ||
992 | &ceu1_device, | ||
993 | &keysc_device, | 966 | &keysc_device, |
994 | &cn12_power, | 967 | &cn12_power, |
995 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 968 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
@@ -1001,9 +974,6 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
1001 | #else | 974 | #else |
1002 | &msiof0_device, | 975 | &msiof0_device, |
1003 | #endif | 976 | #endif |
1004 | &camera_devices[0], | ||
1005 | &camera_devices[1], | ||
1006 | &camera_devices[2], | ||
1007 | &fsi_device, | 977 | &fsi_device, |
1008 | &fsi_da7210_device, | 978 | &fsi_da7210_device, |
1009 | &irda_device, | 979 | &irda_device, |
@@ -1240,7 +1210,6 @@ static int __init arch_setup(void) | |||
1240 | gpio_request(GPIO_FN_VIO0_CLK, NULL); | 1210 | gpio_request(GPIO_FN_VIO0_CLK, NULL); |
1241 | gpio_request(GPIO_FN_VIO0_FLD, NULL); | 1211 | gpio_request(GPIO_FN_VIO0_FLD, NULL); |
1242 | gpio_request(GPIO_FN_VIO0_HD, NULL); | 1212 | gpio_request(GPIO_FN_VIO0_HD, NULL); |
1243 | platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20); | ||
1244 | 1213 | ||
1245 | /* enable CEU1 */ | 1214 | /* enable CEU1 */ |
1246 | gpio_request(GPIO_FN_VIO1_D7, NULL); | 1215 | gpio_request(GPIO_FN_VIO1_D7, NULL); |
@@ -1255,7 +1224,6 @@ static int __init arch_setup(void) | |||
1255 | gpio_request(GPIO_FN_VIO1_HD, NULL); | 1224 | gpio_request(GPIO_FN_VIO1_HD, NULL); |
1256 | gpio_request(GPIO_FN_VIO1_VD, NULL); | 1225 | gpio_request(GPIO_FN_VIO1_VD, NULL); |
1257 | gpio_request(GPIO_FN_VIO1_CLK, NULL); | 1226 | gpio_request(GPIO_FN_VIO1_CLK, NULL); |
1258 | platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20); | ||
1259 | 1227 | ||
1260 | /* enable KEYSC */ | 1228 | /* enable KEYSC */ |
1261 | gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); | 1229 | gpio_request(GPIO_FN_KEYOUT5_IN5, NULL); |
@@ -1332,16 +1300,6 @@ static int __init arch_setup(void) | |||
1332 | __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000, | 1300 | __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000, |
1333 | IODRIVEA); | 1301 | IODRIVEA); |
1334 | 1302 | ||
1335 | /* enable Video */ | ||
1336 | gpio_request(GPIO_PTU2, NULL); | ||
1337 | gpio_direction_output(GPIO_PTU2, 1); | ||
1338 | |||
1339 | /* enable Camera */ | ||
1340 | gpio_request(GPIO_PTA3, NULL); | ||
1341 | gpio_request(GPIO_PTA4, NULL); | ||
1342 | gpio_direction_output(GPIO_PTA3, 0); | ||
1343 | gpio_direction_output(GPIO_PTA4, 0); | ||
1344 | |||
1345 | /* enable FSI */ | 1303 | /* enable FSI */ |
1346 | gpio_request(GPIO_FN_FSIMCKB, NULL); | 1304 | gpio_request(GPIO_FN_FSIMCKB, NULL); |
1347 | gpio_request(GPIO_FN_FSIIBSD, NULL); | 1305 | gpio_request(GPIO_FN_FSIIBSD, NULL); |
@@ -1390,6 +1348,11 @@ static int __init arch_setup(void) | |||
1390 | gpio_request(GPIO_PTU5, NULL); | 1348 | gpio_request(GPIO_PTU5, NULL); |
1391 | gpio_direction_output(GPIO_PTU5, 0); | 1349 | gpio_direction_output(GPIO_PTU5, 0); |
1392 | 1350 | ||
1351 | /* Register gpio lookup tables for cameras and video decoder */ | ||
1352 | gpiod_add_lookup_table(&tw9910_gpios); | ||
1353 | gpiod_add_lookup_table(&mt9t112_0_gpios); | ||
1354 | gpiod_add_lookup_table(&mt9t112_1_gpios); | ||
1355 | |||
1393 | /* enable I2C device */ | 1356 | /* enable I2C device */ |
1394 | i2c_register_board_info(0, i2c0_devices, | 1357 | i2c_register_board_info(0, i2c0_devices, |
1395 | ARRAY_SIZE(i2c0_devices)); | 1358 | ARRAY_SIZE(i2c0_devices)); |
@@ -1431,6 +1394,25 @@ static int __init arch_setup(void) | |||
1431 | gpio_set_value(GPIO_PTG4, 1); | 1394 | gpio_set_value(GPIO_PTG4, 1); |
1432 | #endif | 1395 | #endif |
1433 | 1396 | ||
1397 | /* Initialize CEU platform devices separately to map memory first */ | ||
1398 | device_initialize(&ecovec_ceu_devices[0]->dev); | ||
1399 | arch_setup_pdev_archdata(ecovec_ceu_devices[0]); | ||
1400 | dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev, | ||
1401 | ceu0_dma_membase, ceu0_dma_membase, | ||
1402 | ceu0_dma_membase + | ||
1403 | CEU_BUFFER_MEMORY_SIZE - 1, | ||
1404 | DMA_MEMORY_EXCLUSIVE); | ||
1405 | platform_device_add(ecovec_ceu_devices[0]); | ||
1406 | |||
1407 | device_initialize(&ecovec_ceu_devices[1]->dev); | ||
1408 | arch_setup_pdev_archdata(ecovec_ceu_devices[1]); | ||
1409 | dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev, | ||
1410 | ceu1_dma_membase, ceu1_dma_membase, | ||
1411 | ceu1_dma_membase + | ||
1412 | CEU_BUFFER_MEMORY_SIZE - 1, | ||
1413 | DMA_MEMORY_EXCLUSIVE); | ||
1414 | platform_device_add(ecovec_ceu_devices[1]); | ||
1415 | |||
1434 | return platform_add_devices(ecovec_devices, | 1416 | return platform_add_devices(ecovec_devices, |
1435 | ARRAY_SIZE(ecovec_devices)); | 1417 | ARRAY_SIZE(ecovec_devices)); |
1436 | } | 1418 | } |
@@ -1443,6 +1425,24 @@ static int __init devices_setup(void) | |||
1443 | } | 1425 | } |
1444 | device_initcall(devices_setup); | 1426 | device_initcall(devices_setup); |
1445 | 1427 | ||
1428 | /* Reserve a portion of memory for CEU 0 and CEU 1 buffers */ | ||
1429 | static void __init ecovec_mv_mem_reserve(void) | ||
1430 | { | ||
1431 | phys_addr_t phys; | ||
1432 | phys_addr_t size = CEU_BUFFER_MEMORY_SIZE; | ||
1433 | |||
1434 | phys = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_ALLOC_ANYWHERE); | ||
1435 | memblock_free(phys, size); | ||
1436 | memblock_remove(phys, size); | ||
1437 | ceu0_dma_membase = phys; | ||
1438 | |||
1439 | phys = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_ALLOC_ANYWHERE); | ||
1440 | memblock_free(phys, size); | ||
1441 | memblock_remove(phys, size); | ||
1442 | ceu1_dma_membase = phys; | ||
1443 | } | ||
1444 | |||
1446 | static struct sh_machine_vector mv_ecovec __initmv = { | 1445 | static struct sh_machine_vector mv_ecovec __initmv = { |
1447 | .mv_name = "R0P7724 (EcoVec)", | 1446 | .mv_name = "R0P7724 (EcoVec)", |
1447 | .mv_mem_reserve = ecovec_mv_mem_reserve, | ||
1448 | }; | 1448 | }; |
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 0bcbe58b11e9..271dfc260e82 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -1,17 +1,16 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Renesas System Solutions Asia Pte. Ltd - Migo-R | 3 | * Renesas System Solutions Asia Pte. Ltd - Migo-R |
3 | * | 4 | * |
4 | * Copyright (C) 2008 Magnus Damm | 5 | * Copyright (C) 2008 Magnus Damm |
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | 6 | */ |
7 | #include <linux/clkdev.h> | ||
10 | #include <linux/init.h> | 8 | #include <linux/init.h> |
11 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
12 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
13 | #include <linux/input.h> | 11 | #include <linux/input.h> |
14 | #include <linux/input/sh_keysc.h> | 12 | #include <linux/input/sh_keysc.h> |
13 | #include <linux/memblock.h> | ||
15 | #include <linux/mmc/host.h> | 14 | #include <linux/mmc/host.h> |
16 | #include <linux/mtd/physmap.h> | 15 | #include <linux/mtd/physmap.h> |
17 | #include <linux/mfd/tmio.h> | 16 | #include <linux/mfd/tmio.h> |
@@ -23,10 +22,11 @@ | |||
23 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
24 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
25 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/gpio/machine.h> | ||
26 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
27 | #include <linux/sh_intc.h> | 27 | #include <linux/sh_intc.h> |
28 | #include <video/sh_mobile_lcdc.h> | 28 | #include <video/sh_mobile_lcdc.h> |
29 | #include <media/drv-intf/sh_mobile_ceu.h> | 29 | #include <media/drv-intf/renesas-ceu.h> |
30 | #include <media/i2c/ov772x.h> | 30 | #include <media/i2c/ov772x.h> |
31 | #include <media/soc_camera.h> | 31 | #include <media/soc_camera.h> |
32 | #include <media/i2c/tw9910.h> | 32 | #include <media/i2c/tw9910.h> |
@@ -45,6 +45,9 @@ | |||
45 | * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A) | 45 | * 0x18000000 8GB 8 NAND Flash (K9K8G08U0A) |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #define CEU_BUFFER_MEMORY_SIZE (4 << 20) | ||
49 | static phys_addr_t ceu_dma_membase; | ||
50 | |||
48 | static struct smc91x_platdata smc91x_info = { | 51 | static struct smc91x_platdata smc91x_info = { |
49 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, | 52 | .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, |
50 | }; | 53 | }; |
@@ -301,65 +304,24 @@ static struct platform_device migor_lcdc_device = { | |||
301 | }, | 304 | }, |
302 | }; | 305 | }; |
303 | 306 | ||
304 | static struct clk *camera_clk; | 307 | static struct ceu_platform_data ceu_pdata = { |
305 | static DEFINE_MUTEX(camera_lock); | 308 | .num_subdevs = 2, |
306 | 309 | .subdevs = { | |
307 | static void camera_power_on(int is_tw) | 310 | { /* [0] = ov772x */ |
308 | { | 311 | .flags = 0, |
309 | mutex_lock(&camera_lock); | 312 | .bus_width = 8, |
310 | 313 | .bus_shift = 0, | |
311 | /* Use 10 MHz VIO_CKO instead of 24 MHz to work | 314 | .i2c_adapter_id = 0, |
312 | * around signal quality issues on Panel Board V2.1. | 315 | .i2c_address = 0x21, |
313 | */ | 316 | }, |
314 | camera_clk = clk_get(NULL, "video_clk"); | 317 | { /* [1] = tw9910 */ |
315 | clk_set_rate(camera_clk, 10000000); | 318 | .flags = 0, |
316 | clk_enable(camera_clk); /* start VIO_CKO */ | 319 | .bus_width = 8, |
317 | 320 | .bus_shift = 0, | |
318 | /* use VIO_RST to take camera out of reset */ | 321 | .i2c_adapter_id = 0, |
319 | mdelay(10); | 322 | .i2c_address = 0x45, |
320 | if (is_tw) { | 323 | }, |
321 | gpio_set_value(GPIO_PTT2, 0); | 324 | }, |
322 | gpio_set_value(GPIO_PTT0, 0); | ||
323 | } else { | ||
324 | gpio_set_value(GPIO_PTT0, 1); | ||
325 | } | ||
326 | gpio_set_value(GPIO_PTT3, 0); | ||
327 | mdelay(10); | ||
328 | gpio_set_value(GPIO_PTT3, 1); | ||
329 | mdelay(10); /* wait to let chip come out of reset */ | ||
330 | } | ||
331 | |||
332 | static void camera_power_off(void) | ||
333 | { | ||
334 | clk_disable(camera_clk); /* stop VIO_CKO */ | ||
335 | clk_put(camera_clk); | ||
336 | |||
337 | gpio_set_value(GPIO_PTT3, 0); | ||
338 | mutex_unlock(&camera_lock); | ||
339 | } | ||
340 | |||
341 | static int ov7725_power(struct device *dev, int mode) | ||
342 | { | ||
343 | if (mode) | ||
344 | camera_power_on(0); | ||
345 | else | ||
346 | camera_power_off(); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int tw9910_power(struct device *dev, int mode) | ||
352 | { | ||
353 | if (mode) | ||
354 | camera_power_on(1); | ||
355 | else | ||
356 | camera_power_off(); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static struct sh_mobile_ceu_info sh_mobile_ceu_info = { | ||
362 | .flags = SH_CEU_FLAG_USE_8BIT_BUS, | ||
363 | }; | 325 | }; |
364 | 326 | ||
365 | static struct resource migor_ceu_resources[] = { | 327 | static struct resource migor_ceu_resources[] = { |
@@ -373,18 +335,32 @@ static struct resource migor_ceu_resources[] = { | |||
373 | .start = evt2irq(0x880), | 335 | .start = evt2irq(0x880), |
374 | .flags = IORESOURCE_IRQ, | 336 | .flags = IORESOURCE_IRQ, |
375 | }, | 337 | }, |
376 | [2] = { | ||
377 | /* place holder for contiguous memory */ | ||
378 | }, | ||
379 | }; | 338 | }; |
380 | 339 | ||
381 | static struct platform_device migor_ceu_device = { | 340 | static struct platform_device migor_ceu_device = { |
382 | .name = "sh_mobile_ceu", | 341 | .name = "renesas-ceu", |
383 | .id = 0, /* "ceu0" clock */ | 342 | .id = 0, /* ceu.0 */ |
384 | .num_resources = ARRAY_SIZE(migor_ceu_resources), | 343 | .num_resources = ARRAY_SIZE(migor_ceu_resources), |
385 | .resource = migor_ceu_resources, | 344 | .resource = migor_ceu_resources, |
386 | .dev = { | 345 | .dev = { |
387 | .platform_data = &sh_mobile_ceu_info, | 346 | .platform_data = &ceu_pdata, |
347 | }, | ||
348 | }; | ||
349 | |||
350 | /* Powerdown/reset gpios for CEU image sensors */ | ||
351 | static struct gpiod_lookup_table ov7725_gpios = { | ||
352 | .dev_id = "0-0021", | ||
353 | .table = { | ||
354 | GPIO_LOOKUP("sh7722_pfc", GPIO_PTT0, "pwdn", GPIO_ACTIVE_HIGH), | ||
355 | GPIO_LOOKUP("sh7722_pfc", GPIO_PTT3, "rstb", GPIO_ACTIVE_LOW), | ||
356 | }, | ||
357 | }; | ||
358 | |||
359 | static struct gpiod_lookup_table tw9910_gpios = { | ||
360 | .dev_id = "0-0045", | ||
361 | .table = { | ||
362 | GPIO_LOOKUP("sh7722_pfc", GPIO_PTT2, "pdn", GPIO_ACTIVE_HIGH), | ||
363 | GPIO_LOOKUP("sh7722_pfc", GPIO_PTT3, "rstb", GPIO_ACTIVE_LOW), | ||
388 | }, | 364 | }, |
389 | }; | 365 | }; |
390 | 366 | ||
@@ -423,6 +399,15 @@ static struct platform_device sdhi_cn9_device = { | |||
423 | }, | 399 | }, |
424 | }; | 400 | }; |
425 | 401 | ||
402 | static struct ov772x_camera_info ov7725_info = { | ||
403 | .flags = 0, | ||
404 | }; | ||
405 | |||
406 | static struct tw9910_video_info tw9910_info = { | ||
407 | .buswidth = 8, | ||
408 | .mpout = TW9910_MPO_FIELD, | ||
409 | }; | ||
410 | |||
426 | static struct i2c_board_info migor_i2c_devices[] = { | 411 | static struct i2c_board_info migor_i2c_devices[] = { |
427 | { | 412 | { |
428 | I2C_BOARD_INFO("rs5c372b", 0x32), | 413 | I2C_BOARD_INFO("rs5c372b", 0x32), |
@@ -434,51 +419,13 @@ static struct i2c_board_info migor_i2c_devices[] = { | |||
434 | { | 419 | { |
435 | I2C_BOARD_INFO("wm8978", 0x1a), | 420 | I2C_BOARD_INFO("wm8978", 0x1a), |
436 | }, | 421 | }, |
437 | }; | ||
438 | |||
439 | static struct i2c_board_info migor_i2c_camera[] = { | ||
440 | { | 422 | { |
441 | I2C_BOARD_INFO("ov772x", 0x21), | 423 | I2C_BOARD_INFO("ov772x", 0x21), |
424 | .platform_data = &ov7725_info, | ||
442 | }, | 425 | }, |
443 | { | 426 | { |
444 | I2C_BOARD_INFO("tw9910", 0x45), | 427 | I2C_BOARD_INFO("tw9910", 0x45), |
445 | }, | 428 | .platform_data = &tw9910_info, |
446 | }; | ||
447 | |||
448 | static struct ov772x_camera_info ov7725_info; | ||
449 | |||
450 | static struct soc_camera_link ov7725_link = { | ||
451 | .power = ov7725_power, | ||
452 | .board_info = &migor_i2c_camera[0], | ||
453 | .i2c_adapter_id = 0, | ||
454 | .priv = &ov7725_info, | ||
455 | }; | ||
456 | |||
457 | static struct tw9910_video_info tw9910_info = { | ||
458 | .buswidth = SOCAM_DATAWIDTH_8, | ||
459 | .mpout = TW9910_MPO_FIELD, | ||
460 | }; | ||
461 | |||
462 | static struct soc_camera_link tw9910_link = { | ||
463 | .power = tw9910_power, | ||
464 | .board_info = &migor_i2c_camera[1], | ||
465 | .i2c_adapter_id = 0, | ||
466 | .priv = &tw9910_info, | ||
467 | }; | ||
468 | |||
469 | static struct platform_device migor_camera[] = { | ||
470 | { | ||
471 | .name = "soc-camera-pdrv", | ||
472 | .id = 0, | ||
473 | .dev = { | ||
474 | .platform_data = &ov7725_link, | ||
475 | }, | ||
476 | }, { | ||
477 | .name = "soc-camera-pdrv", | ||
478 | .id = 1, | ||
479 | .dev = { | ||
480 | .platform_data = &tw9910_link, | ||
481 | }, | ||
482 | }, | 429 | }, |
483 | }; | 430 | }; |
484 | 431 | ||
@@ -486,12 +433,9 @@ static struct platform_device *migor_devices[] __initdata = { | |||
486 | &smc91x_eth_device, | 433 | &smc91x_eth_device, |
487 | &sh_keysc_device, | 434 | &sh_keysc_device, |
488 | &migor_lcdc_device, | 435 | &migor_lcdc_device, |
489 | &migor_ceu_device, | ||
490 | &migor_nor_flash_device, | 436 | &migor_nor_flash_device, |
491 | &migor_nand_flash_device, | 437 | &migor_nand_flash_device, |
492 | &sdhi_cn9_device, | 438 | &sdhi_cn9_device, |
493 | &migor_camera[0], | ||
494 | &migor_camera[1], | ||
495 | }; | 439 | }; |
496 | 440 | ||
497 | extern char migor_sdram_enter_start; | 441 | extern char migor_sdram_enter_start; |
@@ -501,6 +445,8 @@ extern char migor_sdram_leave_end; | |||
501 | 445 | ||
502 | static int __init migor_devices_setup(void) | 446 | static int __init migor_devices_setup(void) |
503 | { | 447 | { |
448 | struct clk *video_clk; | ||
449 | |||
504 | /* register board specific self-refresh code */ | 450 | /* register board specific self-refresh code */ |
505 | sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, | 451 | sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, |
506 | &migor_sdram_enter_start, | 452 | &migor_sdram_enter_start, |
@@ -620,20 +566,8 @@ static int __init migor_devices_setup(void) | |||
620 | gpio_request(GPIO_FN_VIO_D9, NULL); | 566 | gpio_request(GPIO_FN_VIO_D9, NULL); |
621 | gpio_request(GPIO_FN_VIO_D8, NULL); | 567 | gpio_request(GPIO_FN_VIO_D8, NULL); |
622 | 568 | ||
623 | gpio_request(GPIO_PTT3, NULL); /* VIO_RST */ | ||
624 | gpio_direction_output(GPIO_PTT3, 0); | ||
625 | gpio_request(GPIO_PTT2, NULL); /* TV_IN_EN */ | ||
626 | gpio_direction_output(GPIO_PTT2, 1); | ||
627 | gpio_request(GPIO_PTT0, NULL); /* CAM_EN */ | ||
628 | #ifdef CONFIG_SH_MIGOR_RTA_WVGA | ||
629 | gpio_direction_output(GPIO_PTT0, 0); | ||
630 | #else | ||
631 | gpio_direction_output(GPIO_PTT0, 1); | ||
632 | #endif | ||
633 | __raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */ | 569 | __raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */ |
634 | 570 | ||
635 | platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20); | ||
636 | |||
637 | /* SIU: Port B */ | 571 | /* SIU: Port B */ |
638 | gpio_request(GPIO_FN_SIUBOLR, NULL); | 572 | gpio_request(GPIO_FN_SIUBOLR, NULL); |
639 | gpio_request(GPIO_FN_SIUBOBT, NULL); | 573 | gpio_request(GPIO_FN_SIUBOBT, NULL); |
@@ -647,9 +581,36 @@ static int __init migor_devices_setup(void) | |||
647 | */ | 581 | */ |
648 | __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA); | 582 | __raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA); |
649 | 583 | ||
584 | /* | ||
585 | * Use 10 MHz VIO_CKO instead of 24 MHz to work around signal quality | ||
586 | * issues on Panel Board V2.1. | ||
587 | */ | ||
588 | video_clk = clk_get(NULL, "video_clk"); | ||
589 | if (!IS_ERR(video_clk)) { | ||
590 | clk_set_rate(video_clk, clk_round_rate(video_clk, 10000000)); | ||
591 | clk_put(video_clk); | ||
592 | } | ||
593 | |||
594 | /* Add a clock alias for ov7725 xclk source. */ | ||
595 | clk_add_alias("xclk", "0-0021", "video_clk", NULL); | ||
596 | |||
597 | /* Register GPIOs for video sources. */ | ||
598 | gpiod_add_lookup_table(&ov7725_gpios); | ||
599 | gpiod_add_lookup_table(&tw9910_gpios); | ||
600 | |||
650 | i2c_register_board_info(0, migor_i2c_devices, | 601 | i2c_register_board_info(0, migor_i2c_devices, |
651 | ARRAY_SIZE(migor_i2c_devices)); | 602 | ARRAY_SIZE(migor_i2c_devices)); |
652 | 603 | ||
604 | /* Initialize CEU platform device separately to map memory first */ | ||
605 | device_initialize(&migor_ceu_device.dev); | ||
606 | arch_setup_pdev_archdata(&migor_ceu_device); | ||
607 | dma_declare_coherent_memory(&migor_ceu_device.dev, | ||
608 | ceu_dma_membase, ceu_dma_membase, | ||
609 | ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1, | ||
610 | DMA_MEMORY_EXCLUSIVE); | ||
611 | |||
612 | platform_device_add(&migor_ceu_device); | ||
613 | |||
653 | return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); | 614 | return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); |
654 | } | 615 | } |
655 | arch_initcall(migor_devices_setup); | 616 | arch_initcall(migor_devices_setup); |
@@ -665,10 +626,24 @@ static int migor_mode_pins(void) | |||
665 | return MODE_PIN0 | MODE_PIN1 | MODE_PIN5; | 626 | return MODE_PIN0 | MODE_PIN1 | MODE_PIN5; |
666 | } | 627 | } |
667 | 628 | ||
629 | /* Reserve a portion of memory for CEU buffers */ | ||
630 | static void __init migor_mv_mem_reserve(void) | ||
631 | { | ||
632 | phys_addr_t phys; | ||
633 | phys_addr_t size = CEU_BUFFER_MEMORY_SIZE; | ||
634 | |||
635 | phys = memblock_alloc_base(size, PAGE_SIZE, MEMBLOCK_ALLOC_ANYWHERE); | ||
636 | memblock_free(phys, size); | ||
637 | memblock_remove(phys, size); | ||
638 | |||
639 | ceu_dma_membase = phys; | ||
640 | } | ||
641 | |||
668 | /* | 642 | /* |
669 | * The Machine Vector | 643 | * The Machine Vector |
670 | */ | 644 | */ |
671 | static struct sh_machine_vector mv_migor __initmv = { | 645 | static struct sh_machine_vector mv_migor __initmv = { |
672 | .mv_name = "Migo-R", | 646 | .mv_name = "Migo-R", |
673 | .mv_mode_pins = migor_mode_pins, | 647 | .mv_mode_pins = migor_mode_pins, |
648 | .mv_mem_reserve = migor_mv_mem_reserve, | ||
674 | }; | 649 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 8f07a1a38692..d85091ec4b01 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c | |||
@@ -223,7 +223,7 @@ static struct clk_lookup lookups[] = { | |||
223 | CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]), | 223 | CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]), |
224 | CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), | 224 | CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), |
225 | CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]), | 225 | CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]), |
226 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]), | 226 | CLKDEV_DEV_ID("renesas-ceu.0", &mstp_clks[HWBLK_CEU]), |
227 | CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]), | 227 | CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]), |
228 | CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), | 228 | CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), |
229 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]), | 229 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]), |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index f27c618de527..3194336a3599 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c | |||
@@ -338,14 +338,14 @@ static struct clk_lookup lookups[] = { | |||
338 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), | 338 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), |
339 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), | 339 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), |
340 | CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU1]), | 340 | CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU1]), |
341 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[HWBLK_CEU1]), | 341 | CLKDEV_DEV_ID("renesas-ceu.1", &mstp_clks[HWBLK_CEU1]), |
342 | CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]), | 342 | CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]), |
343 | CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]), | 343 | CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]), |
344 | CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]), | 344 | CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]), |
345 | CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), | 345 | CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]), |
346 | CLKDEV_DEV_ID("sh-vou", &mstp_clks[HWBLK_VOU]), | 346 | CLKDEV_DEV_ID("sh-vou", &mstp_clks[HWBLK_VOU]), |
347 | CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]), | 347 | CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]), |
348 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU0]), | 348 | CLKDEV_DEV_ID("renesas-ceu.0", &mstp_clks[HWBLK_CEU0]), |
349 | CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]), | 349 | CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]), |
350 | CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), | 350 | CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]), |
351 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]), | 351 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]), |
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index f16f8358c70a..894843a7ec7b 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <media/v4l2-device.h> | 38 | #include <media/v4l2-device.h> |
39 | #include <media/v4l2-dev.h> | 39 | #include <media/v4l2-dev.h> |
40 | #include <media/v4l2-ioctl.h> | 40 | #include <media/v4l2-ioctl.h> |
41 | #include <media/v4l2-ctrls.h> | ||
41 | #include <media/videobuf2-v4l2.h> | 42 | #include <media/videobuf2-v4l2.h> |
42 | #include <media/videobuf2-dma-sg.h> | 43 | #include <media/videobuf2-dma-sg.h> |
43 | 44 | ||
@@ -81,7 +82,10 @@ struct sur40_blob { | |||
81 | 82 | ||
82 | __le32 area; /* size in pixels/pressure (?) */ | 83 | __le32 area; /* size in pixels/pressure (?) */ |
83 | 84 | ||
84 | u8 padding[32]; | 85 | u8 padding[24]; |
86 | |||
87 | __le32 tag_id; /* valid when type == 0x04 (SUR40_TAG) */ | ||
88 | __le32 unknown; | ||
85 | 89 | ||
86 | } __packed; | 90 | } __packed; |
87 | 91 | ||
@@ -146,6 +150,40 @@ struct sur40_image_header { | |||
146 | #define SUR40_TOUCH 0x02 | 150 | #define SUR40_TOUCH 0x02 |
147 | #define SUR40_TAG 0x04 | 151 | #define SUR40_TAG 0x04 |
148 | 152 | ||
153 | /* video controls */ | ||
154 | #define SUR40_BRIGHTNESS_MAX 0xff | ||
155 | #define SUR40_BRIGHTNESS_MIN 0x00 | ||
156 | #define SUR40_BRIGHTNESS_DEF 0xff | ||
157 | |||
158 | #define SUR40_CONTRAST_MAX 0x0f | ||
159 | #define SUR40_CONTRAST_MIN 0x00 | ||
160 | #define SUR40_CONTRAST_DEF 0x0a | ||
161 | |||
162 | #define SUR40_GAIN_MAX 0x09 | ||
163 | #define SUR40_GAIN_MIN 0x00 | ||
164 | #define SUR40_GAIN_DEF 0x08 | ||
165 | |||
166 | #define SUR40_BACKLIGHT_MAX 0x01 | ||
167 | #define SUR40_BACKLIGHT_MIN 0x00 | ||
168 | #define SUR40_BACKLIGHT_DEF 0x01 | ||
169 | |||
170 | #define sur40_str(s) #s | ||
171 | #define SUR40_PARAM_RANGE(lo, hi) " (range " sur40_str(lo) "-" sur40_str(hi) ")" | ||
172 | |||
173 | /* module parameters */ | ||
174 | static uint brightness = SUR40_BRIGHTNESS_DEF; | ||
175 | module_param(brightness, uint, 0644); | ||
176 | MODULE_PARM_DESC(brightness, "set initial brightness" | ||
177 | SUR40_PARAM_RANGE(SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX)); | ||
178 | static uint contrast = SUR40_CONTRAST_DEF; | ||
179 | module_param(contrast, uint, 0644); | ||
180 | MODULE_PARM_DESC(contrast, "set initial contrast" | ||
181 | SUR40_PARAM_RANGE(SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX)); | ||
182 | static uint gain = SUR40_GAIN_DEF; | ||
183 | module_param(gain, uint, 0644); | ||
184 | MODULE_PARM_DESC(gain, "set initial gain" | ||
185 | SUR40_PARAM_RANGE(SUR40_GAIN_MIN, SUR40_GAIN_MAX)); | ||
186 | |||
149 | static const struct v4l2_pix_format sur40_pix_format[] = { | 187 | static const struct v4l2_pix_format sur40_pix_format[] = { |
150 | { | 188 | { |
151 | .pixelformat = V4L2_TCH_FMT_TU08, | 189 | .pixelformat = V4L2_TCH_FMT_TU08, |
@@ -178,6 +216,7 @@ struct sur40_state { | |||
178 | struct video_device vdev; | 216 | struct video_device vdev; |
179 | struct mutex lock; | 217 | struct mutex lock; |
180 | struct v4l2_pix_format pix_fmt; | 218 | struct v4l2_pix_format pix_fmt; |
219 | struct v4l2_ctrl_handler hdl; | ||
181 | 220 | ||
182 | struct vb2_queue queue; | 221 | struct vb2_queue queue; |
183 | struct list_head buf_list; | 222 | struct list_head buf_list; |
@@ -187,6 +226,7 @@ struct sur40_state { | |||
187 | struct sur40_data *bulk_in_buffer; | 226 | struct sur40_data *bulk_in_buffer; |
188 | size_t bulk_in_size; | 227 | size_t bulk_in_size; |
189 | u8 bulk_in_epaddr; | 228 | u8 bulk_in_epaddr; |
229 | u8 vsvideo; | ||
190 | 230 | ||
191 | char phys[64]; | 231 | char phys[64]; |
192 | }; | 232 | }; |
@@ -200,6 +240,11 @@ struct sur40_buffer { | |||
200 | static const struct video_device sur40_video_device; | 240 | static const struct video_device sur40_video_device; |
201 | static const struct vb2_queue sur40_queue; | 241 | static const struct vb2_queue sur40_queue; |
202 | static void sur40_process_video(struct sur40_state *sur40); | 242 | static void sur40_process_video(struct sur40_state *sur40); |
243 | static int sur40_s_ctrl(struct v4l2_ctrl *ctrl); | ||
244 | |||
245 | static const struct v4l2_ctrl_ops sur40_ctrl_ops = { | ||
246 | .s_ctrl = sur40_s_ctrl, | ||
247 | }; | ||
203 | 248 | ||
204 | /* | 249 | /* |
205 | * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT | 250 | * Note: an earlier, non-public version of this driver used USB_RECIP_ENDPOINT |
@@ -220,6 +265,81 @@ static int sur40_command(struct sur40_state *dev, | |||
220 | 0x00, index, buffer, size, 1000); | 265 | 0x00, index, buffer, size, 1000); |
221 | } | 266 | } |
222 | 267 | ||
268 | /* poke a byte in the panel register space */ | ||
269 | static int sur40_poke(struct sur40_state *dev, u8 offset, u8 value) | ||
270 | { | ||
271 | int result; | ||
272 | u8 index = 0x96; // 0xae for permanent write | ||
273 | |||
274 | result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), | ||
275 | SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
276 | 0x32, index, NULL, 0, 1000); | ||
277 | if (result < 0) | ||
278 | goto error; | ||
279 | msleep(5); | ||
280 | |||
281 | result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), | ||
282 | SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
283 | 0x72, offset, NULL, 0, 1000); | ||
284 | if (result < 0) | ||
285 | goto error; | ||
286 | msleep(5); | ||
287 | |||
288 | result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), | ||
289 | SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
290 | 0xb2, value, NULL, 0, 1000); | ||
291 | if (result < 0) | ||
292 | goto error; | ||
293 | msleep(5); | ||
294 | |||
295 | error: | ||
296 | return result; | ||
297 | } | ||
298 | |||
299 | static int sur40_set_preprocessor(struct sur40_state *dev, u8 value) | ||
300 | { | ||
301 | u8 setting_07[2] = { 0x01, 0x00 }; | ||
302 | u8 setting_17[2] = { 0x85, 0x80 }; | ||
303 | int result; | ||
304 | |||
305 | if (value > 1) | ||
306 | return -ERANGE; | ||
307 | |||
308 | result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), | ||
309 | SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
310 | 0x07, setting_07[value], NULL, 0, 1000); | ||
311 | if (result < 0) | ||
312 | goto error; | ||
313 | msleep(5); | ||
314 | |||
315 | result = usb_control_msg(dev->usbdev, usb_sndctrlpipe(dev->usbdev, 0), | ||
316 | SUR40_POKE, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
317 | 0x17, setting_17[value], NULL, 0, 1000); | ||
318 | if (result < 0) | ||
319 | goto error; | ||
320 | msleep(5); | ||
321 | |||
322 | error: | ||
323 | return result; | ||
324 | } | ||
325 | |||
326 | static void sur40_set_vsvideo(struct sur40_state *handle, u8 value) | ||
327 | { | ||
328 | int i; | ||
329 | |||
330 | for (i = 0; i < 4; i++) | ||
331 | sur40_poke(handle, 0x1c+i, value); | ||
332 | handle->vsvideo = value; | ||
333 | } | ||
334 | |||
335 | static void sur40_set_irlevel(struct sur40_state *handle, u8 value) | ||
336 | { | ||
337 | int i; | ||
338 | |||
339 | for (i = 0; i < 8; i++) | ||
340 | sur40_poke(handle, 0x08+(2*i), value); | ||
341 | } | ||
342 | |||
223 | /* Initialization routine, called from sur40_open */ | 343 | /* Initialization routine, called from sur40_open */ |
224 | static int sur40_init(struct sur40_state *dev) | 344 | static int sur40_init(struct sur40_state *dev) |
225 | { | 345 | { |
@@ -631,6 +751,36 @@ static int sur40_probe(struct usb_interface *interface, | |||
631 | sur40->vdev.queue = &sur40->queue; | 751 | sur40->vdev.queue = &sur40->queue; |
632 | video_set_drvdata(&sur40->vdev, sur40); | 752 | video_set_drvdata(&sur40->vdev, sur40); |
633 | 753 | ||
754 | /* initialize the control handler for 4 controls */ | ||
755 | v4l2_ctrl_handler_init(&sur40->hdl, 4); | ||
756 | sur40->v4l2.ctrl_handler = &sur40->hdl; | ||
757 | sur40->vsvideo = (SUR40_CONTRAST_DEF << 4) | SUR40_GAIN_DEF; | ||
758 | |||
759 | v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, V4L2_CID_BRIGHTNESS, | ||
760 | SUR40_BRIGHTNESS_MIN, SUR40_BRIGHTNESS_MAX, 1, clamp(brightness, | ||
761 | (uint)SUR40_BRIGHTNESS_MIN, (uint)SUR40_BRIGHTNESS_MAX)); | ||
762 | |||
763 | v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, V4L2_CID_CONTRAST, | ||
764 | SUR40_CONTRAST_MIN, SUR40_CONTRAST_MAX, 1, clamp(contrast, | ||
765 | (uint)SUR40_CONTRAST_MIN, (uint)SUR40_CONTRAST_MAX)); | ||
766 | |||
767 | v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, V4L2_CID_GAIN, | ||
768 | SUR40_GAIN_MIN, SUR40_GAIN_MAX, 1, clamp(gain, | ||
769 | (uint)SUR40_GAIN_MIN, (uint)SUR40_GAIN_MAX)); | ||
770 | |||
771 | v4l2_ctrl_new_std(&sur40->hdl, &sur40_ctrl_ops, | ||
772 | V4L2_CID_BACKLIGHT_COMPENSATION, SUR40_BACKLIGHT_MIN, | ||
773 | SUR40_BACKLIGHT_MAX, 1, SUR40_BACKLIGHT_DEF); | ||
774 | |||
775 | v4l2_ctrl_handler_setup(&sur40->hdl); | ||
776 | |||
777 | if (sur40->hdl.error) { | ||
778 | dev_err(&interface->dev, | ||
779 | "Unable to register video controls."); | ||
780 | v4l2_ctrl_handler_free(&sur40->hdl); | ||
781 | goto err_unreg_v4l2; | ||
782 | } | ||
783 | |||
634 | error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1); | 784 | error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1); |
635 | if (error) { | 785 | if (error) { |
636 | dev_err(&interface->dev, | 786 | dev_err(&interface->dev, |
@@ -663,6 +813,7 @@ static void sur40_disconnect(struct usb_interface *interface) | |||
663 | { | 813 | { |
664 | struct sur40_state *sur40 = usb_get_intfdata(interface); | 814 | struct sur40_state *sur40 = usb_get_intfdata(interface); |
665 | 815 | ||
816 | v4l2_ctrl_handler_free(&sur40->hdl); | ||
666 | video_unregister_device(&sur40->vdev); | 817 | video_unregister_device(&sur40->vdev); |
667 | v4l2_device_unregister(&sur40->v4l2); | 818 | v4l2_device_unregister(&sur40->v4l2); |
668 | 819 | ||
@@ -856,6 +1007,31 @@ static int sur40_vidioc_g_fmt(struct file *file, void *priv, | |||
856 | return 0; | 1007 | return 0; |
857 | } | 1008 | } |
858 | 1009 | ||
1010 | static int sur40_s_ctrl(struct v4l2_ctrl *ctrl) | ||
1011 | { | ||
1012 | struct sur40_state *sur40 = container_of(ctrl->handler, | ||
1013 | struct sur40_state, hdl); | ||
1014 | u8 value = sur40->vsvideo; | ||
1015 | |||
1016 | switch (ctrl->id) { | ||
1017 | case V4L2_CID_BRIGHTNESS: | ||
1018 | sur40_set_irlevel(sur40, ctrl->val); | ||
1019 | break; | ||
1020 | case V4L2_CID_CONTRAST: | ||
1021 | value = (value & 0x0f) | (ctrl->val << 4); | ||
1022 | sur40_set_vsvideo(sur40, value); | ||
1023 | break; | ||
1024 | case V4L2_CID_GAIN: | ||
1025 | value = (value & 0xf0) | (ctrl->val); | ||
1026 | sur40_set_vsvideo(sur40, value); | ||
1027 | break; | ||
1028 | case V4L2_CID_BACKLIGHT_COMPENSATION: | ||
1029 | sur40_set_preprocessor(sur40, ctrl->val); | ||
1030 | break; | ||
1031 | } | ||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
859 | static int sur40_ioctl_parm(struct file *file, void *priv, | 1035 | static int sur40_ioctl_parm(struct file *file, void *priv, |
860 | struct v4l2_streamparm *p) | 1036 | struct v4l2_streamparm *p) |
861 | { | 1037 | { |
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 86c1a190d946..37124c3b8c2a 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -141,6 +141,7 @@ config DVB_CORE | |||
141 | tristate | 141 | tristate |
142 | depends on MEDIA_SUPPORT | 142 | depends on MEDIA_SUPPORT |
143 | depends on MEDIA_DIGITAL_TV_SUPPORT | 143 | depends on MEDIA_DIGITAL_TV_SUPPORT |
144 | depends on (I2C || I2C=n) | ||
144 | default y | 145 | default y |
145 | select CRC32 | 146 | select CRC32 |
146 | 147 | ||
diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig index 43428cec3a01..9c2b108c613a 100644 --- a/drivers/media/cec/Kconfig +++ b/drivers/media/cec/Kconfig | |||
@@ -4,3 +4,9 @@ config MEDIA_CEC_RC | |||
4 | depends on CEC_CORE=m || RC_CORE=y | 4 | depends on CEC_CORE=m || RC_CORE=y |
5 | ---help--- | 5 | ---help--- |
6 | Pass on CEC remote control messages to the RC framework. | 6 | Pass on CEC remote control messages to the RC framework. |
7 | |||
8 | config CEC_PIN_ERROR_INJ | ||
9 | bool "Enable CEC error injection support" | ||
10 | depends on CEC_PIN && DEBUG_FS | ||
11 | ---help--- | ||
12 | This option enables CEC error injection using debugfs. | ||
diff --git a/drivers/media/cec/Makefile b/drivers/media/cec/Makefile index 41ee3325e1ea..29a2ab9e77c5 100644 --- a/drivers/media/cec/Makefile +++ b/drivers/media/cec/Makefile | |||
@@ -9,4 +9,8 @@ ifeq ($(CONFIG_CEC_PIN),y) | |||
9 | cec-objs += cec-pin.o | 9 | cec-objs += cec-pin.o |
10 | endif | 10 | endif |
11 | 11 | ||
12 | ifeq ($(CONFIG_CEC_PIN_ERROR_INJ),y) | ||
13 | cec-objs += cec-pin-error-inj.o | ||
14 | endif | ||
15 | |||
12 | obj-$(CONFIG_CEC_CORE) += cec.o | 16 | obj-$(CONFIG_CEC_CORE) += cec.o |
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index 2b1e540587d6..002ed4c90371 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter | 3 | * cec-adap.c - HDMI Consumer Electronics Control framework - CEC adapter |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
@@ -85,8 +73,8 @@ static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr | |||
85 | void cec_queue_event_fh(struct cec_fh *fh, | 73 | void cec_queue_event_fh(struct cec_fh *fh, |
86 | const struct cec_event *new_ev, u64 ts) | 74 | const struct cec_event *new_ev, u64 ts) |
87 | { | 75 | { |
88 | static const u8 max_events[CEC_NUM_EVENTS] = { | 76 | static const u16 max_events[CEC_NUM_EVENTS] = { |
89 | 1, 1, 64, 64, 8, 8, | 77 | 1, 1, 800, 800, 8, 8, |
90 | }; | 78 | }; |
91 | struct cec_event_entry *entry; | 79 | struct cec_event_entry *entry; |
92 | unsigned int ev_idx = new_ev->event - 1; | 80 | unsigned int ev_idx = new_ev->event - 1; |
@@ -154,11 +142,13 @@ static void cec_queue_event(struct cec_adapter *adap, | |||
154 | } | 142 | } |
155 | 143 | ||
156 | /* Notify userspace that the CEC pin changed state at the given time. */ | 144 | /* Notify userspace that the CEC pin changed state at the given time. */ |
157 | void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts) | 145 | void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, |
146 | bool dropped_events, ktime_t ts) | ||
158 | { | 147 | { |
159 | struct cec_event ev = { | 148 | struct cec_event ev = { |
160 | .event = is_high ? CEC_EVENT_PIN_CEC_HIGH : | 149 | .event = is_high ? CEC_EVENT_PIN_CEC_HIGH : |
161 | CEC_EVENT_PIN_CEC_LOW, | 150 | CEC_EVENT_PIN_CEC_LOW, |
151 | .flags = dropped_events ? CEC_EVENT_FL_DROPPED_EVENTS : 0, | ||
162 | }; | 152 | }; |
163 | struct cec_fh *fh; | 153 | struct cec_fh *fh; |
164 | 154 | ||
@@ -711,16 +701,31 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, | |||
711 | else | 701 | else |
712 | msg->flags = 0; | 702 | msg->flags = 0; |
713 | 703 | ||
704 | if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { | ||
705 | msg->msg[2] = adap->phys_addr >> 8; | ||
706 | msg->msg[3] = adap->phys_addr & 0xff; | ||
707 | } | ||
708 | |||
714 | /* Sanity checks */ | 709 | /* Sanity checks */ |
715 | if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { | 710 | if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { |
716 | dprintk(1, "%s: invalid length %d\n", __func__, msg->len); | 711 | dprintk(1, "%s: invalid length %d\n", __func__, msg->len); |
717 | return -EINVAL; | 712 | return -EINVAL; |
718 | } | 713 | } |
714 | |||
715 | memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); | ||
716 | |||
717 | if (msg->timeout) | ||
718 | dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n", | ||
719 | __func__, msg->len, msg->msg, msg->reply, | ||
720 | !block ? ", nb" : ""); | ||
721 | else | ||
722 | dprintk(2, "%s: %*ph%s\n", | ||
723 | __func__, msg->len, msg->msg, !block ? " (nb)" : ""); | ||
724 | |||
719 | if (msg->timeout && msg->len == 1) { | 725 | if (msg->timeout && msg->len == 1) { |
720 | dprintk(1, "%s: can't reply for poll msg\n", __func__); | 726 | dprintk(1, "%s: can't reply to poll msg\n", __func__); |
721 | return -EINVAL; | 727 | return -EINVAL; |
722 | } | 728 | } |
723 | memset(msg->msg + msg->len, 0, sizeof(msg->msg) - msg->len); | ||
724 | if (msg->len == 1) { | 729 | if (msg->len == 1) { |
725 | if (cec_msg_destination(msg) == 0xf) { | 730 | if (cec_msg_destination(msg) == 0xf) { |
726 | dprintk(1, "%s: invalid poll message\n", __func__); | 731 | dprintk(1, "%s: invalid poll message\n", __func__); |
@@ -780,19 +785,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, | |||
780 | if (!msg->sequence) | 785 | if (!msg->sequence) |
781 | msg->sequence = ++adap->sequence; | 786 | msg->sequence = ++adap->sequence; |
782 | 787 | ||
783 | if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) { | ||
784 | msg->msg[2] = adap->phys_addr >> 8; | ||
785 | msg->msg[3] = adap->phys_addr & 0xff; | ||
786 | } | ||
787 | |||
788 | if (msg->timeout) | ||
789 | dprintk(2, "%s: %*ph (wait for 0x%02x%s)\n", | ||
790 | __func__, msg->len, msg->msg, msg->reply, | ||
791 | !block ? ", nb" : ""); | ||
792 | else | ||
793 | dprintk(2, "%s: %*ph%s\n", | ||
794 | __func__, msg->len, msg->msg, !block ? " (nb)" : ""); | ||
795 | |||
796 | data->msg = *msg; | 788 | data->msg = *msg; |
797 | data->fh = fh; | 789 | data->fh = fh; |
798 | data->adap = adap; | 790 | data->adap = adap; |
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index 492db12b8c4d..10b67fc40318 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cec-api.c - HDMI Consumer Electronics Control framework - API | 3 | * cec-api.c - HDMI Consumer Electronics Control framework - API |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index a9f9525db9ae..b0c87f9ea08f 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cec-core.c - HDMI Consumer Electronics Control framework - Core | 3 | * cec-core.c - HDMI Consumer Electronics Control framework - Core |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
@@ -207,6 +195,55 @@ void cec_register_cec_notifier(struct cec_adapter *adap, | |||
207 | EXPORT_SYMBOL_GPL(cec_register_cec_notifier); | 195 | EXPORT_SYMBOL_GPL(cec_register_cec_notifier); |
208 | #endif | 196 | #endif |
209 | 197 | ||
198 | #ifdef CONFIG_DEBUG_FS | ||
199 | static ssize_t cec_error_inj_write(struct file *file, | ||
200 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
201 | { | ||
202 | struct seq_file *sf = file->private_data; | ||
203 | struct cec_adapter *adap = sf->private; | ||
204 | char *buf; | ||
205 | char *line; | ||
206 | char *p; | ||
207 | |||
208 | buf = memdup_user_nul(ubuf, min_t(size_t, PAGE_SIZE, count)); | ||
209 | if (IS_ERR(buf)) | ||
210 | return PTR_ERR(buf); | ||
211 | p = buf; | ||
212 | while (p && *p) { | ||
213 | p = skip_spaces(p); | ||
214 | line = strsep(&p, "\n"); | ||
215 | if (!*line || *line == '#') | ||
216 | continue; | ||
217 | if (!adap->ops->error_inj_parse_line(adap, line)) { | ||
218 | kfree(buf); | ||
219 | return -EINVAL; | ||
220 | } | ||
221 | } | ||
222 | kfree(buf); | ||
223 | return count; | ||
224 | } | ||
225 | |||
226 | static int cec_error_inj_show(struct seq_file *sf, void *unused) | ||
227 | { | ||
228 | struct cec_adapter *adap = sf->private; | ||
229 | |||
230 | return adap->ops->error_inj_show(adap, sf); | ||
231 | } | ||
232 | |||
233 | static int cec_error_inj_open(struct inode *inode, struct file *file) | ||
234 | { | ||
235 | return single_open(file, cec_error_inj_show, inode->i_private); | ||
236 | } | ||
237 | |||
238 | static const struct file_operations cec_error_inj_fops = { | ||
239 | .open = cec_error_inj_open, | ||
240 | .write = cec_error_inj_write, | ||
241 | .read = seq_read, | ||
242 | .llseek = seq_lseek, | ||
243 | .release = single_release, | ||
244 | }; | ||
245 | #endif | ||
246 | |||
210 | struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, | 247 | struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, |
211 | void *priv, const char *name, u32 caps, | 248 | void *priv, const char *name, u32 caps, |
212 | u8 available_las) | 249 | u8 available_las) |
@@ -346,7 +383,16 @@ int cec_register_adapter(struct cec_adapter *adap, | |||
346 | pr_warn("cec-%s: Failed to create status file\n", adap->name); | 383 | pr_warn("cec-%s: Failed to create status file\n", adap->name); |
347 | debugfs_remove_recursive(adap->cec_dir); | 384 | debugfs_remove_recursive(adap->cec_dir); |
348 | adap->cec_dir = NULL; | 385 | adap->cec_dir = NULL; |
386 | return 0; | ||
349 | } | 387 | } |
388 | if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line) | ||
389 | return 0; | ||
390 | adap->error_inj_file = debugfs_create_file("error-inj", 0644, | ||
391 | adap->cec_dir, adap, | ||
392 | &cec_error_inj_fops); | ||
393 | if (IS_ERR_OR_NULL(adap->error_inj_file)) | ||
394 | pr_warn("cec-%s: Failed to create error-inj file\n", | ||
395 | adap->name); | ||
350 | #endif | 396 | #endif |
351 | return 0; | 397 | return 0; |
352 | } | 398 | } |
diff --git a/drivers/media/cec/cec-edid.c b/drivers/media/cec/cec-edid.c index 38e3fec6152b..ec72ac1c0b91 100644 --- a/drivers/media/cec/cec-edid.c +++ b/drivers/media/cec/cec-edid.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions | 3 | * cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c index 08b619d0ea1e..16dffa06c913 100644 --- a/drivers/media/cec/cec-notifier.c +++ b/drivers/media/cec/cec-notifier.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cec-notifier.c - notify CEC drivers of physical address changes | 3 | * cec-notifier.c - notify CEC drivers of physical address changes |
3 | * | 4 | * |
4 | * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk> | 5 | * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk> |
5 | * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 6 | * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <linux/export.h> | 9 | #include <linux/export.h> |
diff --git a/drivers/media/cec/cec-pin-error-inj.c b/drivers/media/cec/cec-pin-error-inj.c new file mode 100644 index 000000000000..aaa899a175ce --- /dev/null +++ b/drivers/media/cec/cec-pin-error-inj.c | |||
@@ -0,0 +1,342 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | ||
4 | */ | ||
5 | |||
6 | #include <linux/delay.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/sched/types.h> | ||
9 | |||
10 | #include <media/cec-pin.h> | ||
11 | #include "cec-pin-priv.h" | ||
12 | |||
13 | struct cec_error_inj_cmd { | ||
14 | unsigned int mode_offset; | ||
15 | int arg_idx; | ||
16 | const char *cmd; | ||
17 | }; | ||
18 | |||
19 | static const struct cec_error_inj_cmd cec_error_inj_cmds[] = { | ||
20 | { CEC_ERROR_INJ_RX_NACK_OFFSET, -1, "rx-nack" }, | ||
21 | { CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET, | ||
22 | CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, "rx-low-drive" }, | ||
23 | { CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, "rx-add-byte" }, | ||
24 | { CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, "rx-remove-byte" }, | ||
25 | { CEC_ERROR_INJ_RX_ARB_LOST_OFFSET, | ||
26 | CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, "rx-arb-lost" }, | ||
27 | |||
28 | { CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, "tx-no-eom" }, | ||
29 | { CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, "tx-early-eom" }, | ||
30 | { CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET, | ||
31 | CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, "tx-add-bytes" }, | ||
32 | { CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, "tx-remove-byte" }, | ||
33 | { CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET, | ||
34 | CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, "tx-short-bit" }, | ||
35 | { CEC_ERROR_INJ_TX_LONG_BIT_OFFSET, | ||
36 | CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, "tx-long-bit" }, | ||
37 | { CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET, | ||
38 | CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, "tx-custom-bit" }, | ||
39 | { CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, "tx-short-start" }, | ||
40 | { CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, "tx-long-start" }, | ||
41 | { CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, -1, "tx-custom-start" }, | ||
42 | { CEC_ERROR_INJ_TX_LAST_BIT_OFFSET, | ||
43 | CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, "tx-last-bit" }, | ||
44 | { CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET, | ||
45 | CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, "tx-low-drive" }, | ||
46 | { 0, -1, NULL } | ||
47 | }; | ||
48 | |||
49 | u16 cec_pin_rx_error_inj(struct cec_pin *pin) | ||
50 | { | ||
51 | u16 cmd = CEC_ERROR_INJ_OP_ANY; | ||
52 | |||
53 | /* Only when 18 bits have been received do we have a valid cmd */ | ||
54 | if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) && | ||
55 | pin->rx_bit >= 18) | ||
56 | cmd = pin->rx_msg.msg[1]; | ||
57 | return (pin->error_inj[cmd] & CEC_ERROR_INJ_RX_MASK) ? cmd : | ||
58 | CEC_ERROR_INJ_OP_ANY; | ||
59 | } | ||
60 | |||
61 | u16 cec_pin_tx_error_inj(struct cec_pin *pin) | ||
62 | { | ||
63 | u16 cmd = CEC_ERROR_INJ_OP_ANY; | ||
64 | |||
65 | if (!(pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) && | ||
66 | pin->tx_msg.len > 1) | ||
67 | cmd = pin->tx_msg.msg[1]; | ||
68 | return (pin->error_inj[cmd] & CEC_ERROR_INJ_TX_MASK) ? cmd : | ||
69 | CEC_ERROR_INJ_OP_ANY; | ||
70 | } | ||
71 | |||
72 | bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line) | ||
73 | { | ||
74 | static const char *delims = " \t\r"; | ||
75 | struct cec_pin *pin = adap->pin; | ||
76 | unsigned int i; | ||
77 | bool has_pos = false; | ||
78 | char *p = line; | ||
79 | char *token; | ||
80 | char *comma; | ||
81 | u64 *error; | ||
82 | u8 *args; | ||
83 | bool has_op; | ||
84 | u32 op; | ||
85 | u8 mode; | ||
86 | u8 pos; | ||
87 | u8 v; | ||
88 | |||
89 | p = skip_spaces(p); | ||
90 | token = strsep(&p, delims); | ||
91 | if (!strcmp(token, "clear")) { | ||
92 | memset(pin->error_inj, 0, sizeof(pin->error_inj)); | ||
93 | pin->rx_toggle = pin->tx_toggle = false; | ||
94 | pin->tx_ignore_nack_until_eom = false; | ||
95 | pin->tx_custom_pulse = false; | ||
96 | pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; | ||
97 | pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT; | ||
98 | return true; | ||
99 | } | ||
100 | if (!strcmp(token, "rx-clear")) { | ||
101 | for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++) | ||
102 | pin->error_inj[i] &= ~CEC_ERROR_INJ_RX_MASK; | ||
103 | pin->rx_toggle = false; | ||
104 | return true; | ||
105 | } | ||
106 | if (!strcmp(token, "tx-clear")) { | ||
107 | for (i = 0; i <= CEC_ERROR_INJ_OP_ANY; i++) | ||
108 | pin->error_inj[i] &= ~CEC_ERROR_INJ_TX_MASK; | ||
109 | pin->tx_toggle = false; | ||
110 | pin->tx_ignore_nack_until_eom = false; | ||
111 | pin->tx_custom_pulse = false; | ||
112 | pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; | ||
113 | pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT; | ||
114 | return true; | ||
115 | } | ||
116 | if (!strcmp(token, "tx-ignore-nack-until-eom")) { | ||
117 | pin->tx_ignore_nack_until_eom = true; | ||
118 | return true; | ||
119 | } | ||
120 | if (!strcmp(token, "tx-custom-pulse")) { | ||
121 | pin->tx_custom_pulse = true; | ||
122 | cec_pin_start_timer(pin); | ||
123 | return true; | ||
124 | } | ||
125 | if (!p) | ||
126 | return false; | ||
127 | |||
128 | p = skip_spaces(p); | ||
129 | if (!strcmp(token, "tx-custom-low-usecs")) { | ||
130 | u32 usecs; | ||
131 | |||
132 | if (kstrtou32(p, 0, &usecs) || usecs > 10000000) | ||
133 | return false; | ||
134 | pin->tx_custom_low_usecs = usecs; | ||
135 | return true; | ||
136 | } | ||
137 | if (!strcmp(token, "tx-custom-high-usecs")) { | ||
138 | u32 usecs; | ||
139 | |||
140 | if (kstrtou32(p, 0, &usecs) || usecs > 10000000) | ||
141 | return false; | ||
142 | pin->tx_custom_high_usecs = usecs; | ||
143 | return true; | ||
144 | } | ||
145 | |||
146 | comma = strchr(token, ','); | ||
147 | if (comma) | ||
148 | *comma++ = '\0'; | ||
149 | if (!strcmp(token, "any")) | ||
150 | op = CEC_ERROR_INJ_OP_ANY; | ||
151 | else if (!kstrtou8(token, 0, &v)) | ||
152 | op = v; | ||
153 | else | ||
154 | return false; | ||
155 | mode = CEC_ERROR_INJ_MODE_ONCE; | ||
156 | if (comma) { | ||
157 | if (!strcmp(comma, "off")) | ||
158 | mode = CEC_ERROR_INJ_MODE_OFF; | ||
159 | else if (!strcmp(comma, "once")) | ||
160 | mode = CEC_ERROR_INJ_MODE_ONCE; | ||
161 | else if (!strcmp(comma, "always")) | ||
162 | mode = CEC_ERROR_INJ_MODE_ALWAYS; | ||
163 | else if (!strcmp(comma, "toggle")) | ||
164 | mode = CEC_ERROR_INJ_MODE_TOGGLE; | ||
165 | else | ||
166 | return false; | ||
167 | } | ||
168 | |||
169 | error = pin->error_inj + op; | ||
170 | args = pin->error_inj_args[op]; | ||
171 | has_op = op <= 0xff; | ||
172 | |||
173 | token = strsep(&p, delims); | ||
174 | if (p) { | ||
175 | p = skip_spaces(p); | ||
176 | has_pos = !kstrtou8(p, 0, &pos); | ||
177 | } | ||
178 | |||
179 | if (!strcmp(token, "clear")) { | ||
180 | *error = 0; | ||
181 | return true; | ||
182 | } | ||
183 | if (!strcmp(token, "rx-clear")) { | ||
184 | *error &= ~CEC_ERROR_INJ_RX_MASK; | ||
185 | return true; | ||
186 | } | ||
187 | if (!strcmp(token, "tx-clear")) { | ||
188 | *error &= ~CEC_ERROR_INJ_TX_MASK; | ||
189 | return true; | ||
190 | } | ||
191 | |||
192 | for (i = 0; cec_error_inj_cmds[i].cmd; i++) { | ||
193 | const char *cmd = cec_error_inj_cmds[i].cmd; | ||
194 | unsigned int mode_offset; | ||
195 | u64 mode_mask; | ||
196 | int arg_idx; | ||
197 | bool is_bit_pos = true; | ||
198 | |||
199 | if (strcmp(token, cmd)) | ||
200 | continue; | ||
201 | |||
202 | mode_offset = cec_error_inj_cmds[i].mode_offset; | ||
203 | mode_mask = CEC_ERROR_INJ_MODE_MASK << mode_offset; | ||
204 | arg_idx = cec_error_inj_cmds[i].arg_idx; | ||
205 | |||
206 | if (mode_offset == CEC_ERROR_INJ_RX_ARB_LOST_OFFSET || | ||
207 | mode_offset == CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET) | ||
208 | is_bit_pos = false; | ||
209 | |||
210 | if (mode_offset == CEC_ERROR_INJ_RX_ARB_LOST_OFFSET) { | ||
211 | if (has_op) | ||
212 | return false; | ||
213 | if (!has_pos) | ||
214 | pos = 0x0f; | ||
215 | } | ||
216 | if (arg_idx >= 0 && is_bit_pos) { | ||
217 | if (!has_pos || pos >= 160) | ||
218 | return false; | ||
219 | if (has_op && pos < 10 + 8) | ||
220 | return false; | ||
221 | /* Invalid bit position may not be the Ack bit */ | ||
222 | if ((mode_offset == CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET || | ||
223 | mode_offset == CEC_ERROR_INJ_TX_LONG_BIT_OFFSET || | ||
224 | mode_offset == CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET) && | ||
225 | (pos % 10) == 9) | ||
226 | return false; | ||
227 | } | ||
228 | *error &= ~mode_mask; | ||
229 | *error |= (u64)mode << mode_offset; | ||
230 | if (arg_idx >= 0) | ||
231 | args[arg_idx] = pos; | ||
232 | return true; | ||
233 | } | ||
234 | return false; | ||
235 | } | ||
236 | |||
237 | static void cec_pin_show_cmd(struct seq_file *sf, u32 cmd, u8 mode) | ||
238 | { | ||
239 | if (cmd == CEC_ERROR_INJ_OP_ANY) | ||
240 | seq_puts(sf, "any,"); | ||
241 | else | ||
242 | seq_printf(sf, "0x%02x,", cmd); | ||
243 | switch (mode) { | ||
244 | case CEC_ERROR_INJ_MODE_ONCE: | ||
245 | seq_puts(sf, "once "); | ||
246 | break; | ||
247 | case CEC_ERROR_INJ_MODE_ALWAYS: | ||
248 | seq_puts(sf, "always "); | ||
249 | break; | ||
250 | case CEC_ERROR_INJ_MODE_TOGGLE: | ||
251 | seq_puts(sf, "toggle "); | ||
252 | break; | ||
253 | default: | ||
254 | seq_puts(sf, "off "); | ||
255 | break; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf) | ||
260 | { | ||
261 | struct cec_pin *pin = adap->pin; | ||
262 | unsigned int i, j; | ||
263 | |||
264 | seq_puts(sf, "# Clear error injections:\n"); | ||
265 | seq_puts(sf, "# clear clear all rx and tx error injections\n"); | ||
266 | seq_puts(sf, "# rx-clear clear all rx error injections\n"); | ||
267 | seq_puts(sf, "# tx-clear clear all tx error injections\n"); | ||
268 | seq_puts(sf, "# <op> clear clear all rx and tx error injections for <op>\n"); | ||
269 | seq_puts(sf, "# <op> rx-clear clear all rx error injections for <op>\n"); | ||
270 | seq_puts(sf, "# <op> tx-clear clear all tx error injections for <op>\n"); | ||
271 | seq_puts(sf, "#\n"); | ||
272 | seq_puts(sf, "# RX error injection:\n"); | ||
273 | seq_puts(sf, "# <op>[,<mode>] rx-nack NACK the message instead of sending an ACK\n"); | ||
274 | seq_puts(sf, "# <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position\n"); | ||
275 | seq_puts(sf, "# <op>[,<mode>] rx-add-byte add a spurious byte to the received CEC message\n"); | ||
276 | seq_puts(sf, "# <op>[,<mode>] rx-remove-byte remove the last byte from the received CEC message\n"); | ||
277 | seq_puts(sf, "# <op>[,<mode>] rx-arb-lost <poll> generate a POLL message to trigger an arbitration lost\n"); | ||
278 | seq_puts(sf, "#\n"); | ||
279 | seq_puts(sf, "# TX error injection settings:\n"); | ||
280 | seq_puts(sf, "# tx-ignore-nack-until-eom ignore early NACKs until EOM\n"); | ||
281 | seq_puts(sf, "# tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse\n"); | ||
282 | seq_puts(sf, "# tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse\n"); | ||
283 | seq_puts(sf, "# tx-custom-pulse transmit the custom pulse once the bus is idle\n"); | ||
284 | seq_puts(sf, "#\n"); | ||
285 | seq_puts(sf, "# TX error injection:\n"); | ||
286 | seq_puts(sf, "# <op>[,<mode>] tx-no-eom don't set the EOM bit\n"); | ||
287 | seq_puts(sf, "# <op>[,<mode>] tx-early-eom set the EOM bit one byte too soon\n"); | ||
288 | seq_puts(sf, "# <op>[,<mode>] tx-add-bytes <num> append <num> (1-255) spurious bytes to the message\n"); | ||
289 | seq_puts(sf, "# <op>[,<mode>] tx-remove-byte drop the last byte from the message\n"); | ||
290 | seq_puts(sf, "# <op>[,<mode>] tx-short-bit <bit> make this bit shorter than allowed\n"); | ||
291 | seq_puts(sf, "# <op>[,<mode>] tx-long-bit <bit> make this bit longer than allowed\n"); | ||
292 | seq_puts(sf, "# <op>[,<mode>] tx-custom-bit <bit> send the custom pulse instead of this bit\n"); | ||
293 | seq_puts(sf, "# <op>[,<mode>] tx-short-start send a start pulse that's too short\n"); | ||
294 | seq_puts(sf, "# <op>[,<mode>] tx-long-start send a start pulse that's too long\n"); | ||
295 | seq_puts(sf, "# <op>[,<mode>] tx-custom-start send the custom pulse instead of the start pulse\n"); | ||
296 | seq_puts(sf, "# <op>[,<mode>] tx-last-bit <bit> stop sending after this bit\n"); | ||
297 | seq_puts(sf, "# <op>[,<mode>] tx-low-drive <bit> force a low-drive condition at this bit position\n"); | ||
298 | seq_puts(sf, "#\n"); | ||
299 | seq_puts(sf, "# <op> CEC message opcode (0-255) or 'any'\n"); | ||
300 | seq_puts(sf, "# <mode> 'once' (default), 'always', 'toggle' or 'off'\n"); | ||
301 | seq_puts(sf, "# <bit> CEC message bit (0-159)\n"); | ||
302 | seq_puts(sf, "# 10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK\n"); | ||
303 | seq_puts(sf, "# <poll> CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)\n"); | ||
304 | seq_puts(sf, "# <usecs> microseconds (0-10000000, default 1000)\n"); | ||
305 | |||
306 | seq_puts(sf, "\nclear\n"); | ||
307 | |||
308 | for (i = 0; i < ARRAY_SIZE(pin->error_inj); i++) { | ||
309 | u64 e = pin->error_inj[i]; | ||
310 | |||
311 | for (j = 0; cec_error_inj_cmds[j].cmd; j++) { | ||
312 | const char *cmd = cec_error_inj_cmds[j].cmd; | ||
313 | unsigned int mode; | ||
314 | unsigned int mode_offset; | ||
315 | int arg_idx; | ||
316 | |||
317 | mode_offset = cec_error_inj_cmds[j].mode_offset; | ||
318 | arg_idx = cec_error_inj_cmds[j].arg_idx; | ||
319 | mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK; | ||
320 | if (!mode) | ||
321 | continue; | ||
322 | cec_pin_show_cmd(sf, i, mode); | ||
323 | seq_puts(sf, cmd); | ||
324 | if (arg_idx >= 0) | ||
325 | seq_printf(sf, " %u", | ||
326 | pin->error_inj_args[i][arg_idx]); | ||
327 | seq_puts(sf, "\n"); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | if (pin->tx_ignore_nack_until_eom) | ||
332 | seq_puts(sf, "tx-ignore-nack-until-eom\n"); | ||
333 | if (pin->tx_custom_pulse) | ||
334 | seq_puts(sf, "tx-custom-pulse\n"); | ||
335 | if (pin->tx_custom_low_usecs != CEC_TIM_CUSTOM_DEFAULT) | ||
336 | seq_printf(sf, "tx-custom-low-usecs %u\n", | ||
337 | pin->tx_custom_low_usecs); | ||
338 | if (pin->tx_custom_high_usecs != CEC_TIM_CUSTOM_DEFAULT) | ||
339 | seq_printf(sf, "tx-custom-high-usecs %u\n", | ||
340 | pin->tx_custom_high_usecs); | ||
341 | return 0; | ||
342 | } | ||
diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h index 7d0def199762..f423db8855d9 100644 --- a/drivers/media/cec/cec-pin-priv.h +++ b/drivers/media/cec/cec-pin-priv.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cec-pin-priv.h - internal cec-pin header | 3 | * cec-pin-priv.h - internal cec-pin header |
3 | * | 4 | * |
4 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef LINUX_CEC_PIN_PRIV_H | 8 | #ifndef LINUX_CEC_PIN_PRIV_H |
@@ -40,14 +28,30 @@ enum cec_pin_state { | |||
40 | CEC_ST_TX_START_BIT_LOW, | 28 | CEC_ST_TX_START_BIT_LOW, |
41 | /* Drive CEC high for the start bit */ | 29 | /* Drive CEC high for the start bit */ |
42 | CEC_ST_TX_START_BIT_HIGH, | 30 | CEC_ST_TX_START_BIT_HIGH, |
31 | /* Generate a start bit period that is too short */ | ||
32 | CEC_ST_TX_START_BIT_HIGH_SHORT, | ||
33 | /* Generate a start bit period that is too long */ | ||
34 | CEC_ST_TX_START_BIT_HIGH_LONG, | ||
35 | /* Drive CEC low for the start bit using the custom timing */ | ||
36 | CEC_ST_TX_START_BIT_LOW_CUSTOM, | ||
37 | /* Drive CEC high for the start bit using the custom timing */ | ||
38 | CEC_ST_TX_START_BIT_HIGH_CUSTOM, | ||
43 | /* Drive CEC low for the 0 bit */ | 39 | /* Drive CEC low for the 0 bit */ |
44 | CEC_ST_TX_DATA_BIT_0_LOW, | 40 | CEC_ST_TX_DATA_BIT_0_LOW, |
45 | /* Drive CEC high for the 0 bit */ | 41 | /* Drive CEC high for the 0 bit */ |
46 | CEC_ST_TX_DATA_BIT_0_HIGH, | 42 | CEC_ST_TX_DATA_BIT_0_HIGH, |
43 | /* Generate a bit period that is too short */ | ||
44 | CEC_ST_TX_DATA_BIT_0_HIGH_SHORT, | ||
45 | /* Generate a bit period that is too long */ | ||
46 | CEC_ST_TX_DATA_BIT_0_HIGH_LONG, | ||
47 | /* Drive CEC low for the 1 bit */ | 47 | /* Drive CEC low for the 1 bit */ |
48 | CEC_ST_TX_DATA_BIT_1_LOW, | 48 | CEC_ST_TX_DATA_BIT_1_LOW, |
49 | /* Drive CEC high for the 1 bit */ | 49 | /* Drive CEC high for the 1 bit */ |
50 | CEC_ST_TX_DATA_BIT_1_HIGH, | 50 | CEC_ST_TX_DATA_BIT_1_HIGH, |
51 | /* Generate a bit period that is too short */ | ||
52 | CEC_ST_TX_DATA_BIT_1_HIGH_SHORT, | ||
53 | /* Generate a bit period that is too long */ | ||
54 | CEC_ST_TX_DATA_BIT_1_HIGH_LONG, | ||
51 | /* | 55 | /* |
52 | * Wait for start of sample time to check for Ack bit or first | 56 | * Wait for start of sample time to check for Ack bit or first |
53 | * four initiator bits to check for Arbitration Lost. | 57 | * four initiator bits to check for Arbitration Lost. |
@@ -55,6 +59,20 @@ enum cec_pin_state { | |||
55 | CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE, | 59 | CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE, |
56 | /* Wait for end of bit period after sampling */ | 60 | /* Wait for end of bit period after sampling */ |
57 | CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE, | 61 | CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE, |
62 | /* Generate a bit period that is too short */ | ||
63 | CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT, | ||
64 | /* Generate a bit period that is too long */ | ||
65 | CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG, | ||
66 | /* Drive CEC low for a data bit using the custom timing */ | ||
67 | CEC_ST_TX_DATA_BIT_LOW_CUSTOM, | ||
68 | /* Drive CEC high for a data bit using the custom timing */ | ||
69 | CEC_ST_TX_DATA_BIT_HIGH_CUSTOM, | ||
70 | /* Drive CEC low for a standalone pulse using the custom timing */ | ||
71 | CEC_ST_TX_PULSE_LOW_CUSTOM, | ||
72 | /* Drive CEC high for a standalone pulse using the custom timing */ | ||
73 | CEC_ST_TX_PULSE_HIGH_CUSTOM, | ||
74 | /* Start low drive */ | ||
75 | CEC_ST_TX_LOW_DRIVE, | ||
58 | 76 | ||
59 | /* Rx states */ | 77 | /* Rx states */ |
60 | 78 | ||
@@ -66,8 +84,8 @@ enum cec_pin_state { | |||
66 | CEC_ST_RX_DATA_SAMPLE, | 84 | CEC_ST_RX_DATA_SAMPLE, |
67 | /* Wait for earliest end of bit period after sampling */ | 85 | /* Wait for earliest end of bit period after sampling */ |
68 | CEC_ST_RX_DATA_POST_SAMPLE, | 86 | CEC_ST_RX_DATA_POST_SAMPLE, |
69 | /* Wait for CEC to go high (i.e. end of bit period */ | 87 | /* Wait for CEC to go low (i.e. end of bit period) */ |
70 | CEC_ST_RX_DATA_HIGH, | 88 | CEC_ST_RX_DATA_WAIT_FOR_LOW, |
71 | /* Drive CEC low to send 0 Ack bit */ | 89 | /* Drive CEC low to send 0 Ack bit */ |
72 | CEC_ST_RX_ACK_LOW, | 90 | CEC_ST_RX_ACK_LOW, |
73 | /* End of 0 Ack time, wait for earliest end of bit period */ | 91 | /* End of 0 Ack time, wait for earliest end of bit period */ |
@@ -76,9 +94,9 @@ enum cec_pin_state { | |||
76 | CEC_ST_RX_ACK_HIGH_POST, | 94 | CEC_ST_RX_ACK_HIGH_POST, |
77 | /* Wait for earliest end of bit period and end of message */ | 95 | /* Wait for earliest end of bit period and end of message */ |
78 | CEC_ST_RX_ACK_FINISH, | 96 | CEC_ST_RX_ACK_FINISH, |
79 | |||
80 | /* Start low drive */ | 97 | /* Start low drive */ |
81 | CEC_ST_LOW_DRIVE, | 98 | CEC_ST_RX_LOW_DRIVE, |
99 | |||
82 | /* Monitor pin using interrupts */ | 100 | /* Monitor pin using interrupts */ |
83 | CEC_ST_RX_IRQ, | 101 | CEC_ST_RX_IRQ, |
84 | 102 | ||
@@ -86,7 +104,58 @@ enum cec_pin_state { | |||
86 | CEC_PIN_STATES | 104 | CEC_PIN_STATES |
87 | }; | 105 | }; |
88 | 106 | ||
89 | #define CEC_NUM_PIN_EVENTS 128 | 107 | /* Error Injection */ |
108 | |||
109 | /* Error injection modes */ | ||
110 | #define CEC_ERROR_INJ_MODE_OFF 0 | ||
111 | #define CEC_ERROR_INJ_MODE_ONCE 1 | ||
112 | #define CEC_ERROR_INJ_MODE_ALWAYS 2 | ||
113 | #define CEC_ERROR_INJ_MODE_TOGGLE 3 | ||
114 | #define CEC_ERROR_INJ_MODE_MASK 3ULL | ||
115 | |||
116 | /* Receive error injection options */ | ||
117 | #define CEC_ERROR_INJ_RX_NACK_OFFSET 0 | ||
118 | #define CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET 2 | ||
119 | #define CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET 4 | ||
120 | #define CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET 6 | ||
121 | #define CEC_ERROR_INJ_RX_ARB_LOST_OFFSET 8 | ||
122 | #define CEC_ERROR_INJ_RX_MASK 0xffffULL | ||
123 | |||
124 | /* Transmit error injection options */ | ||
125 | #define CEC_ERROR_INJ_TX_NO_EOM_OFFSET 16 | ||
126 | #define CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET 18 | ||
127 | #define CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET 20 | ||
128 | #define CEC_ERROR_INJ_TX_LONG_BIT_OFFSET 22 | ||
129 | #define CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET 24 | ||
130 | #define CEC_ERROR_INJ_TX_SHORT_START_OFFSET 26 | ||
131 | #define CEC_ERROR_INJ_TX_LONG_START_OFFSET 28 | ||
132 | #define CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET 30 | ||
133 | #define CEC_ERROR_INJ_TX_LAST_BIT_OFFSET 32 | ||
134 | #define CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET 34 | ||
135 | #define CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET 36 | ||
136 | #define CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET 38 | ||
137 | #define CEC_ERROR_INJ_TX_MASK 0xffffffffffff0000ULL | ||
138 | |||
139 | #define CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX 0 | ||
140 | #define CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX 1 | ||
141 | |||
142 | #define CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX 2 | ||
143 | #define CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX 3 | ||
144 | #define CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX 4 | ||
145 | #define CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX 5 | ||
146 | #define CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX 6 | ||
147 | #define CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX 7 | ||
148 | #define CEC_ERROR_INJ_NUM_ARGS 8 | ||
149 | |||
150 | /* Special CEC op values */ | ||
151 | #define CEC_ERROR_INJ_OP_ANY 0x00000100 | ||
152 | |||
153 | /* The default for the low/high time of the custom pulse */ | ||
154 | #define CEC_TIM_CUSTOM_DEFAULT 1000 | ||
155 | |||
156 | #define CEC_NUM_PIN_EVENTS 128 | ||
157 | #define CEC_PIN_EVENT_FL_IS_HIGH (1 << 0) | ||
158 | #define CEC_PIN_EVENT_FL_DROPPED (1 << 1) | ||
90 | 159 | ||
91 | #define CEC_PIN_IRQ_UNCHANGED 0 | 160 | #define CEC_PIN_IRQ_UNCHANGED 0 |
92 | #define CEC_PIN_IRQ_DISABLE 1 | 161 | #define CEC_PIN_IRQ_DISABLE 1 |
@@ -110,24 +179,63 @@ struct cec_pin { | |||
110 | u32 tx_bit; | 179 | u32 tx_bit; |
111 | bool tx_nacked; | 180 | bool tx_nacked; |
112 | u32 tx_signal_free_time; | 181 | u32 tx_signal_free_time; |
182 | bool tx_toggle; | ||
113 | struct cec_msg rx_msg; | 183 | struct cec_msg rx_msg; |
114 | u32 rx_bit; | 184 | u32 rx_bit; |
185 | bool rx_toggle; | ||
186 | u32 rx_start_bit_low_too_short_cnt; | ||
187 | u64 rx_start_bit_low_too_short_ts; | ||
188 | u32 rx_start_bit_low_too_short_delta; | ||
189 | u32 rx_start_bit_too_short_cnt; | ||
190 | u64 rx_start_bit_too_short_ts; | ||
191 | u32 rx_start_bit_too_short_delta; | ||
192 | u32 rx_start_bit_too_long_cnt; | ||
193 | u32 rx_data_bit_too_short_cnt; | ||
194 | u64 rx_data_bit_too_short_ts; | ||
195 | u32 rx_data_bit_too_short_delta; | ||
196 | u32 rx_data_bit_too_long_cnt; | ||
197 | u32 rx_low_drive_cnt; | ||
115 | 198 | ||
116 | struct cec_msg work_rx_msg; | 199 | struct cec_msg work_rx_msg; |
117 | u8 work_tx_status; | 200 | u8 work_tx_status; |
118 | ktime_t work_tx_ts; | 201 | ktime_t work_tx_ts; |
119 | atomic_t work_irq_change; | 202 | atomic_t work_irq_change; |
120 | atomic_t work_pin_events; | 203 | atomic_t work_pin_num_events; |
121 | unsigned int work_pin_events_wr; | 204 | unsigned int work_pin_events_wr; |
122 | unsigned int work_pin_events_rd; | 205 | unsigned int work_pin_events_rd; |
123 | ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS]; | 206 | ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS]; |
124 | bool work_pin_is_high[CEC_NUM_PIN_EVENTS]; | 207 | u8 work_pin_events[CEC_NUM_PIN_EVENTS]; |
208 | bool work_pin_events_dropped; | ||
209 | u32 work_pin_events_dropped_cnt; | ||
125 | ktime_t timer_ts; | 210 | ktime_t timer_ts; |
126 | u32 timer_cnt; | 211 | u32 timer_cnt; |
127 | u32 timer_100ms_overruns; | 212 | u32 timer_100ms_overruns; |
128 | u32 timer_300ms_overruns; | 213 | u32 timer_300ms_overruns; |
129 | u32 timer_max_overrun; | 214 | u32 timer_max_overrun; |
130 | u32 timer_sum_overrun; | 215 | u32 timer_sum_overrun; |
216 | |||
217 | u32 tx_custom_low_usecs; | ||
218 | u32 tx_custom_high_usecs; | ||
219 | bool tx_ignore_nack_until_eom; | ||
220 | bool tx_custom_pulse; | ||
221 | bool tx_generated_poll; | ||
222 | bool tx_post_eom; | ||
223 | u8 tx_extra_bytes; | ||
224 | u32 tx_low_drive_cnt; | ||
225 | #ifdef CONFIG_CEC_PIN_ERROR_INJ | ||
226 | u64 error_inj[CEC_ERROR_INJ_OP_ANY + 1]; | ||
227 | u8 error_inj_args[CEC_ERROR_INJ_OP_ANY + 1][CEC_ERROR_INJ_NUM_ARGS]; | ||
228 | #endif | ||
131 | }; | 229 | }; |
132 | 230 | ||
231 | void cec_pin_start_timer(struct cec_pin *pin); | ||
232 | |||
233 | #ifdef CONFIG_CEC_PIN_ERROR_INJ | ||
234 | bool cec_pin_error_inj_parse_line(struct cec_adapter *adap, char *line); | ||
235 | int cec_pin_error_inj_show(struct cec_adapter *adap, struct seq_file *sf); | ||
236 | |||
237 | u16 cec_pin_rx_error_inj(struct cec_pin *pin); | ||
238 | u16 cec_pin_tx_error_inj(struct cec_pin *pin); | ||
239 | #endif | ||
240 | |||
133 | #endif | 241 | #endif |
diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index b48dfe844118..fafe1ebc8aff 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c | |||
@@ -1,18 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 3 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
3 | * | ||
4 | * This program is free software; you may redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
9 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
10 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
11 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
12 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
15 | * SOFTWARE. | ||
16 | */ | 4 | */ |
17 | 5 | ||
18 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
@@ -51,11 +39,29 @@ | |||
51 | #define CEC_TIM_IDLE_SAMPLE 1000 | 39 | #define CEC_TIM_IDLE_SAMPLE 1000 |
52 | /* when processing the start bit, sample twice per millisecond */ | 40 | /* when processing the start bit, sample twice per millisecond */ |
53 | #define CEC_TIM_START_BIT_SAMPLE 500 | 41 | #define CEC_TIM_START_BIT_SAMPLE 500 |
54 | /* when polling for a state change, sample once every 50 micoseconds */ | 42 | /* when polling for a state change, sample once every 50 microseconds */ |
55 | #define CEC_TIM_SAMPLE 50 | 43 | #define CEC_TIM_SAMPLE 50 |
56 | 44 | ||
57 | #define CEC_TIM_LOW_DRIVE_ERROR (1.5 * CEC_TIM_DATA_BIT_TOTAL) | 45 | #define CEC_TIM_LOW_DRIVE_ERROR (1.5 * CEC_TIM_DATA_BIT_TOTAL) |
58 | 46 | ||
47 | /* | ||
48 | * Total data bit time that is too short/long for a valid bit, | ||
49 | * used for error injection. | ||
50 | */ | ||
51 | #define CEC_TIM_DATA_BIT_TOTAL_SHORT 1800 | ||
52 | #define CEC_TIM_DATA_BIT_TOTAL_LONG 2900 | ||
53 | |||
54 | /* | ||
55 | * Total start bit time that is too short/long for a valid bit, | ||
56 | * used for error injection. | ||
57 | */ | ||
58 | #define CEC_TIM_START_BIT_TOTAL_SHORT 4100 | ||
59 | #define CEC_TIM_START_BIT_TOTAL_LONG 5000 | ||
60 | |||
61 | /* Data bits are 0-7, EOM is bit 8 and ACK is bit 9 */ | ||
62 | #define EOM_BIT 8 | ||
63 | #define ACK_BIT 9 | ||
64 | |||
59 | struct cec_state { | 65 | struct cec_state { |
60 | const char * const name; | 66 | const char * const name; |
61 | unsigned int usecs; | 67 | unsigned int usecs; |
@@ -68,17 +74,32 @@ static const struct cec_state states[CEC_PIN_STATES] = { | |||
68 | { "Tx Wait for High", CEC_TIM_IDLE_SAMPLE }, | 74 | { "Tx Wait for High", CEC_TIM_IDLE_SAMPLE }, |
69 | { "Tx Start Bit Low", CEC_TIM_START_BIT_LOW }, | 75 | { "Tx Start Bit Low", CEC_TIM_START_BIT_LOW }, |
70 | { "Tx Start Bit High", CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW }, | 76 | { "Tx Start Bit High", CEC_TIM_START_BIT_TOTAL - CEC_TIM_START_BIT_LOW }, |
77 | { "Tx Start Bit High Short", CEC_TIM_START_BIT_TOTAL_SHORT - CEC_TIM_START_BIT_LOW }, | ||
78 | { "Tx Start Bit High Long", CEC_TIM_START_BIT_TOTAL_LONG - CEC_TIM_START_BIT_LOW }, | ||
79 | { "Tx Start Bit Low Custom", 0 }, | ||
80 | { "Tx Start Bit High Custom", 0 }, | ||
71 | { "Tx Data 0 Low", CEC_TIM_DATA_BIT_0_LOW }, | 81 | { "Tx Data 0 Low", CEC_TIM_DATA_BIT_0_LOW }, |
72 | { "Tx Data 0 High", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW }, | 82 | { "Tx Data 0 High", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_0_LOW }, |
83 | { "Tx Data 0 High Short", CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_0_LOW }, | ||
84 | { "Tx Data 0 High Long", CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_0_LOW }, | ||
73 | { "Tx Data 1 Low", CEC_TIM_DATA_BIT_1_LOW }, | 85 | { "Tx Data 1 Low", CEC_TIM_DATA_BIT_1_LOW }, |
74 | { "Tx Data 1 High", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW }, | 86 | { "Tx Data 1 High", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_1_LOW }, |
75 | { "Tx Data 1 Pre Sample", CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW }, | 87 | { "Tx Data 1 High Short", CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_1_LOW }, |
76 | { "Tx Data 1 Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE }, | 88 | { "Tx Data 1 High Long", CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_1_LOW }, |
89 | { "Tx Data 1 High Pre Sample", CEC_TIM_DATA_BIT_SAMPLE - CEC_TIM_DATA_BIT_1_LOW }, | ||
90 | { "Tx Data 1 High Post Sample", CEC_TIM_DATA_BIT_TOTAL - CEC_TIM_DATA_BIT_SAMPLE }, | ||
91 | { "Tx Data 1 High Post Sample Short", CEC_TIM_DATA_BIT_TOTAL_SHORT - CEC_TIM_DATA_BIT_SAMPLE }, | ||
92 | { "Tx Data 1 High Post Sample Long", CEC_TIM_DATA_BIT_TOTAL_LONG - CEC_TIM_DATA_BIT_SAMPLE }, | ||
93 | { "Tx Data Bit Low Custom", 0 }, | ||
94 | { "Tx Data Bit High Custom", 0 }, | ||
95 | { "Tx Pulse Low Custom", 0 }, | ||
96 | { "Tx Pulse High Custom", 0 }, | ||
97 | { "Tx Low Drive", CEC_TIM_LOW_DRIVE_ERROR }, | ||
77 | { "Rx Start Bit Low", CEC_TIM_SAMPLE }, | 98 | { "Rx Start Bit Low", CEC_TIM_SAMPLE }, |
78 | { "Rx Start Bit High", CEC_TIM_SAMPLE }, | 99 | { "Rx Start Bit High", CEC_TIM_SAMPLE }, |
79 | { "Rx Data Sample", CEC_TIM_DATA_BIT_SAMPLE }, | 100 | { "Rx Data Sample", CEC_TIM_DATA_BIT_SAMPLE }, |
80 | { "Rx Data Post Sample", CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE }, | 101 | { "Rx Data Post Sample", CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_SAMPLE }, |
81 | { "Rx Data High", CEC_TIM_SAMPLE }, | 102 | { "Rx Data Wait for Low", CEC_TIM_SAMPLE }, |
82 | { "Rx Ack Low", CEC_TIM_DATA_BIT_0_LOW }, | 103 | { "Rx Ack Low", CEC_TIM_DATA_BIT_0_LOW }, |
83 | { "Rx Ack Low Post", CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW }, | 104 | { "Rx Ack Low Post", CEC_TIM_DATA_BIT_HIGH - CEC_TIM_DATA_BIT_0_LOW }, |
84 | { "Rx Ack High Post", CEC_TIM_DATA_BIT_HIGH }, | 105 | { "Rx Ack High Post", CEC_TIM_DATA_BIT_HIGH }, |
@@ -93,12 +114,21 @@ static void cec_pin_update(struct cec_pin *pin, bool v, bool force) | |||
93 | return; | 114 | return; |
94 | 115 | ||
95 | pin->adap->cec_pin_is_high = v; | 116 | pin->adap->cec_pin_is_high = v; |
96 | if (atomic_read(&pin->work_pin_events) < CEC_NUM_PIN_EVENTS) { | 117 | if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) { |
97 | pin->work_pin_is_high[pin->work_pin_events_wr] = v; | 118 | u8 ev = v; |
119 | |||
120 | if (pin->work_pin_events_dropped) { | ||
121 | pin->work_pin_events_dropped = false; | ||
122 | v |= CEC_PIN_EVENT_FL_DROPPED; | ||
123 | } | ||
124 | pin->work_pin_events[pin->work_pin_events_wr] = ev; | ||
98 | pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get(); | 125 | pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get(); |
99 | pin->work_pin_events_wr = | 126 | pin->work_pin_events_wr = |
100 | (pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS; | 127 | (pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS; |
101 | atomic_inc(&pin->work_pin_events); | 128 | atomic_inc(&pin->work_pin_num_events); |
129 | } else { | ||
130 | pin->work_pin_events_dropped = true; | ||
131 | pin->work_pin_events_dropped_cnt++; | ||
102 | } | 132 | } |
103 | wake_up_interruptible(&pin->kthread_waitq); | 133 | wake_up_interruptible(&pin->kthread_waitq); |
104 | } | 134 | } |
@@ -123,6 +153,173 @@ static bool cec_pin_high(struct cec_pin *pin) | |||
123 | return cec_pin_read(pin); | 153 | return cec_pin_read(pin); |
124 | } | 154 | } |
125 | 155 | ||
156 | static bool rx_error_inj(struct cec_pin *pin, unsigned int mode_offset, | ||
157 | int arg_idx, u8 *arg) | ||
158 | { | ||
159 | #ifdef CONFIG_CEC_PIN_ERROR_INJ | ||
160 | u16 cmd = cec_pin_rx_error_inj(pin); | ||
161 | u64 e = pin->error_inj[cmd]; | ||
162 | unsigned int mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK; | ||
163 | |||
164 | if (arg_idx >= 0) { | ||
165 | u8 pos = pin->error_inj_args[cmd][arg_idx]; | ||
166 | |||
167 | if (arg) | ||
168 | *arg = pos; | ||
169 | else if (pos != pin->rx_bit) | ||
170 | return false; | ||
171 | } | ||
172 | |||
173 | switch (mode) { | ||
174 | case CEC_ERROR_INJ_MODE_ONCE: | ||
175 | pin->error_inj[cmd] &= | ||
176 | ~(CEC_ERROR_INJ_MODE_MASK << mode_offset); | ||
177 | return true; | ||
178 | case CEC_ERROR_INJ_MODE_ALWAYS: | ||
179 | return true; | ||
180 | case CEC_ERROR_INJ_MODE_TOGGLE: | ||
181 | return pin->rx_toggle; | ||
182 | default: | ||
183 | return false; | ||
184 | } | ||
185 | #else | ||
186 | return false; | ||
187 | #endif | ||
188 | } | ||
189 | |||
190 | static bool rx_nack(struct cec_pin *pin) | ||
191 | { | ||
192 | return rx_error_inj(pin, CEC_ERROR_INJ_RX_NACK_OFFSET, -1, NULL); | ||
193 | } | ||
194 | |||
195 | static bool rx_low_drive(struct cec_pin *pin) | ||
196 | { | ||
197 | return rx_error_inj(pin, CEC_ERROR_INJ_RX_LOW_DRIVE_OFFSET, | ||
198 | CEC_ERROR_INJ_RX_LOW_DRIVE_ARG_IDX, NULL); | ||
199 | } | ||
200 | |||
201 | static bool rx_add_byte(struct cec_pin *pin) | ||
202 | { | ||
203 | return rx_error_inj(pin, CEC_ERROR_INJ_RX_ADD_BYTE_OFFSET, -1, NULL); | ||
204 | } | ||
205 | |||
206 | static bool rx_remove_byte(struct cec_pin *pin) | ||
207 | { | ||
208 | return rx_error_inj(pin, CEC_ERROR_INJ_RX_REMOVE_BYTE_OFFSET, -1, NULL); | ||
209 | } | ||
210 | |||
211 | static bool rx_arb_lost(struct cec_pin *pin, u8 *poll) | ||
212 | { | ||
213 | return pin->tx_msg.len == 0 && | ||
214 | rx_error_inj(pin, CEC_ERROR_INJ_RX_ARB_LOST_OFFSET, | ||
215 | CEC_ERROR_INJ_RX_ARB_LOST_ARG_IDX, poll); | ||
216 | } | ||
217 | |||
218 | static bool tx_error_inj(struct cec_pin *pin, unsigned int mode_offset, | ||
219 | int arg_idx, u8 *arg) | ||
220 | { | ||
221 | #ifdef CONFIG_CEC_PIN_ERROR_INJ | ||
222 | u16 cmd = cec_pin_tx_error_inj(pin); | ||
223 | u64 e = pin->error_inj[cmd]; | ||
224 | unsigned int mode = (e >> mode_offset) & CEC_ERROR_INJ_MODE_MASK; | ||
225 | |||
226 | if (arg_idx >= 0) { | ||
227 | u8 pos = pin->error_inj_args[cmd][arg_idx]; | ||
228 | |||
229 | if (arg) | ||
230 | *arg = pos; | ||
231 | else if (pos != pin->tx_bit) | ||
232 | return false; | ||
233 | } | ||
234 | |||
235 | switch (mode) { | ||
236 | case CEC_ERROR_INJ_MODE_ONCE: | ||
237 | pin->error_inj[cmd] &= | ||
238 | ~(CEC_ERROR_INJ_MODE_MASK << mode_offset); | ||
239 | return true; | ||
240 | case CEC_ERROR_INJ_MODE_ALWAYS: | ||
241 | return true; | ||
242 | case CEC_ERROR_INJ_MODE_TOGGLE: | ||
243 | return pin->tx_toggle; | ||
244 | default: | ||
245 | return false; | ||
246 | } | ||
247 | #else | ||
248 | return false; | ||
249 | #endif | ||
250 | } | ||
251 | |||
252 | static bool tx_no_eom(struct cec_pin *pin) | ||
253 | { | ||
254 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_NO_EOM_OFFSET, -1, NULL); | ||
255 | } | ||
256 | |||
257 | static bool tx_early_eom(struct cec_pin *pin) | ||
258 | { | ||
259 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_EARLY_EOM_OFFSET, -1, NULL); | ||
260 | } | ||
261 | |||
262 | static bool tx_short_bit(struct cec_pin *pin) | ||
263 | { | ||
264 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_BIT_OFFSET, | ||
265 | CEC_ERROR_INJ_TX_SHORT_BIT_ARG_IDX, NULL); | ||
266 | } | ||
267 | |||
268 | static bool tx_long_bit(struct cec_pin *pin) | ||
269 | { | ||
270 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_BIT_OFFSET, | ||
271 | CEC_ERROR_INJ_TX_LONG_BIT_ARG_IDX, NULL); | ||
272 | } | ||
273 | |||
274 | static bool tx_custom_bit(struct cec_pin *pin) | ||
275 | { | ||
276 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_BIT_OFFSET, | ||
277 | CEC_ERROR_INJ_TX_CUSTOM_BIT_ARG_IDX, NULL); | ||
278 | } | ||
279 | |||
280 | static bool tx_short_start(struct cec_pin *pin) | ||
281 | { | ||
282 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_SHORT_START_OFFSET, -1, NULL); | ||
283 | } | ||
284 | |||
285 | static bool tx_long_start(struct cec_pin *pin) | ||
286 | { | ||
287 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_LONG_START_OFFSET, -1, NULL); | ||
288 | } | ||
289 | |||
290 | static bool tx_custom_start(struct cec_pin *pin) | ||
291 | { | ||
292 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_CUSTOM_START_OFFSET, | ||
293 | -1, NULL); | ||
294 | } | ||
295 | |||
296 | static bool tx_last_bit(struct cec_pin *pin) | ||
297 | { | ||
298 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_LAST_BIT_OFFSET, | ||
299 | CEC_ERROR_INJ_TX_LAST_BIT_ARG_IDX, NULL); | ||
300 | } | ||
301 | |||
302 | static u8 tx_add_bytes(struct cec_pin *pin) | ||
303 | { | ||
304 | u8 bytes; | ||
305 | |||
306 | if (tx_error_inj(pin, CEC_ERROR_INJ_TX_ADD_BYTES_OFFSET, | ||
307 | CEC_ERROR_INJ_TX_ADD_BYTES_ARG_IDX, &bytes)) | ||
308 | return bytes; | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static bool tx_remove_byte(struct cec_pin *pin) | ||
313 | { | ||
314 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_REMOVE_BYTE_OFFSET, -1, NULL); | ||
315 | } | ||
316 | |||
317 | static bool tx_low_drive(struct cec_pin *pin) | ||
318 | { | ||
319 | return tx_error_inj(pin, CEC_ERROR_INJ_TX_LOW_DRIVE_OFFSET, | ||
320 | CEC_ERROR_INJ_TX_LOW_DRIVE_ARG_IDX, NULL); | ||
321 | } | ||
322 | |||
126 | static void cec_pin_to_idle(struct cec_pin *pin) | 323 | static void cec_pin_to_idle(struct cec_pin *pin) |
127 | { | 324 | { |
128 | /* | 325 | /* |
@@ -132,8 +329,16 @@ static void cec_pin_to_idle(struct cec_pin *pin) | |||
132 | pin->rx_bit = pin->tx_bit = 0; | 329 | pin->rx_bit = pin->tx_bit = 0; |
133 | pin->rx_msg.len = 0; | 330 | pin->rx_msg.len = 0; |
134 | memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); | 331 | memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); |
135 | pin->state = CEC_ST_IDLE; | ||
136 | pin->ts = ns_to_ktime(0); | 332 | pin->ts = ns_to_ktime(0); |
333 | pin->tx_generated_poll = false; | ||
334 | pin->tx_post_eom = false; | ||
335 | if (pin->state >= CEC_ST_TX_WAIT && | ||
336 | pin->state <= CEC_ST_TX_LOW_DRIVE) | ||
337 | pin->tx_toggle ^= 1; | ||
338 | if (pin->state >= CEC_ST_RX_START_BIT_LOW && | ||
339 | pin->state <= CEC_ST_RX_LOW_DRIVE) | ||
340 | pin->rx_toggle ^= 1; | ||
341 | pin->state = CEC_ST_IDLE; | ||
137 | } | 342 | } |
138 | 343 | ||
139 | /* | 344 | /* |
@@ -174,42 +379,109 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) | |||
174 | break; | 379 | break; |
175 | 380 | ||
176 | case CEC_ST_TX_START_BIT_LOW: | 381 | case CEC_ST_TX_START_BIT_LOW: |
177 | pin->state = CEC_ST_TX_START_BIT_HIGH; | 382 | if (tx_short_start(pin)) { |
383 | /* | ||
384 | * Error Injection: send an invalid (too short) | ||
385 | * start pulse. | ||
386 | */ | ||
387 | pin->state = CEC_ST_TX_START_BIT_HIGH_SHORT; | ||
388 | } else if (tx_long_start(pin)) { | ||
389 | /* | ||
390 | * Error Injection: send an invalid (too long) | ||
391 | * start pulse. | ||
392 | */ | ||
393 | pin->state = CEC_ST_TX_START_BIT_HIGH_LONG; | ||
394 | } else { | ||
395 | pin->state = CEC_ST_TX_START_BIT_HIGH; | ||
396 | } | ||
397 | /* Generate start bit */ | ||
398 | cec_pin_high(pin); | ||
399 | break; | ||
400 | |||
401 | case CEC_ST_TX_START_BIT_LOW_CUSTOM: | ||
402 | pin->state = CEC_ST_TX_START_BIT_HIGH_CUSTOM; | ||
178 | /* Generate start bit */ | 403 | /* Generate start bit */ |
179 | cec_pin_high(pin); | 404 | cec_pin_high(pin); |
180 | break; | 405 | break; |
181 | 406 | ||
182 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE: | 407 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE: |
183 | /* If the read value is 1, then all is OK */ | 408 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT: |
184 | if (!cec_pin_read(pin)) { | 409 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG: |
410 | if (pin->tx_nacked) { | ||
411 | cec_pin_to_idle(pin); | ||
412 | pin->tx_msg.len = 0; | ||
413 | if (pin->tx_generated_poll) | ||
414 | break; | ||
415 | pin->work_tx_ts = ts; | ||
416 | pin->work_tx_status = CEC_TX_STATUS_NACK; | ||
417 | wake_up_interruptible(&pin->kthread_waitq); | ||
418 | break; | ||
419 | } | ||
420 | /* fall through */ | ||
421 | case CEC_ST_TX_DATA_BIT_0_HIGH: | ||
422 | case CEC_ST_TX_DATA_BIT_0_HIGH_SHORT: | ||
423 | case CEC_ST_TX_DATA_BIT_0_HIGH_LONG: | ||
424 | case CEC_ST_TX_DATA_BIT_1_HIGH: | ||
425 | case CEC_ST_TX_DATA_BIT_1_HIGH_SHORT: | ||
426 | case CEC_ST_TX_DATA_BIT_1_HIGH_LONG: | ||
427 | /* | ||
428 | * If the read value is 1, then all is OK, otherwise we have a | ||
429 | * low drive condition. | ||
430 | * | ||
431 | * Special case: when we generate a poll message due to an | ||
432 | * Arbitration Lost error injection, then ignore this since | ||
433 | * the pin can actually be low in that case. | ||
434 | */ | ||
435 | if (!cec_pin_read(pin) && !pin->tx_generated_poll) { | ||
185 | /* | 436 | /* |
186 | * It's 0, so someone detected an error and pulled the | 437 | * It's 0, so someone detected an error and pulled the |
187 | * line low for 1.5 times the nominal bit period. | 438 | * line low for 1.5 times the nominal bit period. |
188 | */ | 439 | */ |
189 | pin->tx_msg.len = 0; | 440 | pin->tx_msg.len = 0; |
441 | pin->state = CEC_ST_TX_WAIT_FOR_HIGH; | ||
190 | pin->work_tx_ts = ts; | 442 | pin->work_tx_ts = ts; |
191 | pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; | 443 | pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; |
192 | pin->state = CEC_ST_TX_WAIT_FOR_HIGH; | 444 | pin->tx_low_drive_cnt++; |
193 | wake_up_interruptible(&pin->kthread_waitq); | 445 | wake_up_interruptible(&pin->kthread_waitq); |
194 | break; | 446 | break; |
195 | } | 447 | } |
196 | if (pin->tx_nacked) { | 448 | /* fall through */ |
449 | case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM: | ||
450 | if (tx_last_bit(pin)) { | ||
451 | /* Error Injection: just stop sending after this bit */ | ||
197 | cec_pin_to_idle(pin); | 452 | cec_pin_to_idle(pin); |
198 | pin->tx_msg.len = 0; | 453 | pin->tx_msg.len = 0; |
454 | if (pin->tx_generated_poll) | ||
455 | break; | ||
199 | pin->work_tx_ts = ts; | 456 | pin->work_tx_ts = ts; |
200 | pin->work_tx_status = CEC_TX_STATUS_NACK; | 457 | pin->work_tx_status = CEC_TX_STATUS_OK; |
201 | wake_up_interruptible(&pin->kthread_waitq); | 458 | wake_up_interruptible(&pin->kthread_waitq); |
202 | break; | 459 | break; |
203 | } | 460 | } |
204 | /* fall through */ | ||
205 | case CEC_ST_TX_DATA_BIT_0_HIGH: | ||
206 | case CEC_ST_TX_DATA_BIT_1_HIGH: | ||
207 | pin->tx_bit++; | 461 | pin->tx_bit++; |
208 | /* fall through */ | 462 | /* fall through */ |
209 | case CEC_ST_TX_START_BIT_HIGH: | 463 | case CEC_ST_TX_START_BIT_HIGH: |
210 | if (pin->tx_bit / 10 >= pin->tx_msg.len) { | 464 | case CEC_ST_TX_START_BIT_HIGH_SHORT: |
465 | case CEC_ST_TX_START_BIT_HIGH_LONG: | ||
466 | case CEC_ST_TX_START_BIT_HIGH_CUSTOM: | ||
467 | if (tx_low_drive(pin)) { | ||
468 | /* Error injection: go to low drive */ | ||
469 | cec_pin_low(pin); | ||
470 | pin->state = CEC_ST_TX_LOW_DRIVE; | ||
471 | pin->tx_msg.len = 0; | ||
472 | if (pin->tx_generated_poll) | ||
473 | break; | ||
474 | pin->work_tx_ts = ts; | ||
475 | pin->work_tx_status = CEC_TX_STATUS_LOW_DRIVE; | ||
476 | pin->tx_low_drive_cnt++; | ||
477 | wake_up_interruptible(&pin->kthread_waitq); | ||
478 | break; | ||
479 | } | ||
480 | if (pin->tx_bit / 10 >= pin->tx_msg.len + pin->tx_extra_bytes) { | ||
211 | cec_pin_to_idle(pin); | 481 | cec_pin_to_idle(pin); |
212 | pin->tx_msg.len = 0; | 482 | pin->tx_msg.len = 0; |
483 | if (pin->tx_generated_poll) | ||
484 | break; | ||
213 | pin->work_tx_ts = ts; | 485 | pin->work_tx_ts = ts; |
214 | pin->work_tx_status = CEC_TX_STATUS_OK; | 486 | pin->work_tx_status = CEC_TX_STATUS_OK; |
215 | wake_up_interruptible(&pin->kthread_waitq); | 487 | wake_up_interruptible(&pin->kthread_waitq); |
@@ -217,39 +489,82 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) | |||
217 | } | 489 | } |
218 | 490 | ||
219 | switch (pin->tx_bit % 10) { | 491 | switch (pin->tx_bit % 10) { |
220 | default: | 492 | default: { |
221 | v = pin->tx_msg.msg[pin->tx_bit / 10] & | 493 | /* |
222 | (1 << (7 - (pin->tx_bit % 10))); | 494 | * In the CEC_ERROR_INJ_TX_ADD_BYTES case we transmit |
495 | * extra bytes, so pin->tx_bit / 10 can become >= 16. | ||
496 | * Generate bit values for those extra bytes instead | ||
497 | * of reading them from the transmit buffer. | ||
498 | */ | ||
499 | unsigned int idx = (pin->tx_bit / 10); | ||
500 | u8 val = idx; | ||
501 | |||
502 | if (idx < pin->tx_msg.len) | ||
503 | val = pin->tx_msg.msg[idx]; | ||
504 | v = val & (1 << (7 - (pin->tx_bit % 10))); | ||
505 | |||
223 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : | 506 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : |
224 | CEC_ST_TX_DATA_BIT_0_LOW; | 507 | CEC_ST_TX_DATA_BIT_0_LOW; |
225 | break; | 508 | break; |
226 | case 8: | 509 | } |
227 | v = pin->tx_bit / 10 == pin->tx_msg.len - 1; | 510 | case EOM_BIT: { |
511 | unsigned int tot_len = pin->tx_msg.len + | ||
512 | pin->tx_extra_bytes; | ||
513 | unsigned int tx_byte_idx = pin->tx_bit / 10; | ||
514 | |||
515 | v = !pin->tx_post_eom && tx_byte_idx == tot_len - 1; | ||
516 | if (tot_len > 1 && tx_byte_idx == tot_len - 2 && | ||
517 | tx_early_eom(pin)) { | ||
518 | /* Error injection: set EOM one byte early */ | ||
519 | v = true; | ||
520 | pin->tx_post_eom = true; | ||
521 | } else if (v && tx_no_eom(pin)) { | ||
522 | /* Error injection: no EOM */ | ||
523 | v = false; | ||
524 | } | ||
228 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : | 525 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_LOW : |
229 | CEC_ST_TX_DATA_BIT_0_LOW; | 526 | CEC_ST_TX_DATA_BIT_0_LOW; |
230 | break; | 527 | break; |
231 | case 9: | 528 | } |
529 | case ACK_BIT: | ||
232 | pin->state = CEC_ST_TX_DATA_BIT_1_LOW; | 530 | pin->state = CEC_ST_TX_DATA_BIT_1_LOW; |
233 | break; | 531 | break; |
234 | } | 532 | } |
533 | if (tx_custom_bit(pin)) | ||
534 | pin->state = CEC_ST_TX_DATA_BIT_LOW_CUSTOM; | ||
235 | cec_pin_low(pin); | 535 | cec_pin_low(pin); |
236 | break; | 536 | break; |
237 | 537 | ||
238 | case CEC_ST_TX_DATA_BIT_0_LOW: | 538 | case CEC_ST_TX_DATA_BIT_0_LOW: |
239 | case CEC_ST_TX_DATA_BIT_1_LOW: | 539 | case CEC_ST_TX_DATA_BIT_1_LOW: |
240 | v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW; | 540 | v = pin->state == CEC_ST_TX_DATA_BIT_1_LOW; |
241 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH : | 541 | is_ack_bit = pin->tx_bit % 10 == ACK_BIT; |
242 | CEC_ST_TX_DATA_BIT_0_HIGH; | 542 | if (v && (pin->tx_bit < 4 || is_ack_bit)) { |
243 | is_ack_bit = pin->tx_bit % 10 == 9; | ||
244 | if (v && (pin->tx_bit < 4 || is_ack_bit)) | ||
245 | pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE; | 543 | pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE; |
544 | } else if (!is_ack_bit && tx_short_bit(pin)) { | ||
545 | /* Error Injection: send an invalid (too short) bit */ | ||
546 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_SHORT : | ||
547 | CEC_ST_TX_DATA_BIT_0_HIGH_SHORT; | ||
548 | } else if (!is_ack_bit && tx_long_bit(pin)) { | ||
549 | /* Error Injection: send an invalid (too long) bit */ | ||
550 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH_LONG : | ||
551 | CEC_ST_TX_DATA_BIT_0_HIGH_LONG; | ||
552 | } else { | ||
553 | pin->state = v ? CEC_ST_TX_DATA_BIT_1_HIGH : | ||
554 | CEC_ST_TX_DATA_BIT_0_HIGH; | ||
555 | } | ||
556 | cec_pin_high(pin); | ||
557 | break; | ||
558 | |||
559 | case CEC_ST_TX_DATA_BIT_LOW_CUSTOM: | ||
560 | pin->state = CEC_ST_TX_DATA_BIT_HIGH_CUSTOM; | ||
246 | cec_pin_high(pin); | 561 | cec_pin_high(pin); |
247 | break; | 562 | break; |
248 | 563 | ||
249 | case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE: | 564 | case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE: |
250 | /* Read the CEC value at the sample time */ | 565 | /* Read the CEC value at the sample time */ |
251 | v = cec_pin_read(pin); | 566 | v = cec_pin_read(pin); |
252 | is_ack_bit = pin->tx_bit % 10 == 9; | 567 | is_ack_bit = pin->tx_bit % 10 == ACK_BIT; |
253 | /* | 568 | /* |
254 | * If v == 0 and we're within the first 4 bits | 569 | * If v == 0 and we're within the first 4 bits |
255 | * of the initiator, then someone else started | 570 | * of the initiator, then someone else started |
@@ -258,7 +573,7 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) | |||
258 | * transmitter has more leading 0 bits in the | 573 | * transmitter has more leading 0 bits in the |
259 | * initiator). | 574 | * initiator). |
260 | */ | 575 | */ |
261 | if (!v && !is_ack_bit) { | 576 | if (!v && !is_ack_bit && !pin->tx_generated_poll) { |
262 | pin->tx_msg.len = 0; | 577 | pin->tx_msg.len = 0; |
263 | pin->work_tx_ts = ts; | 578 | pin->work_tx_ts = ts; |
264 | pin->work_tx_status = CEC_TX_STATUS_ARB_LOST; | 579 | pin->work_tx_status = CEC_TX_STATUS_ARB_LOST; |
@@ -267,18 +582,27 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) | |||
267 | pin->tx_bit = 0; | 582 | pin->tx_bit = 0; |
268 | memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); | 583 | memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg)); |
269 | pin->rx_msg.msg[0] = pin->tx_msg.msg[0]; | 584 | pin->rx_msg.msg[0] = pin->tx_msg.msg[0]; |
270 | pin->rx_msg.msg[0] &= ~(1 << (7 - pin->rx_bit)); | 585 | pin->rx_msg.msg[0] &= (0xff << (8 - pin->rx_bit)); |
271 | pin->rx_msg.len = 0; | 586 | pin->rx_msg.len = 0; |
587 | pin->ts = ktime_sub_us(ts, CEC_TIM_DATA_BIT_SAMPLE); | ||
272 | pin->state = CEC_ST_RX_DATA_POST_SAMPLE; | 588 | pin->state = CEC_ST_RX_DATA_POST_SAMPLE; |
273 | pin->rx_bit++; | 589 | pin->rx_bit++; |
274 | break; | 590 | break; |
275 | } | 591 | } |
276 | pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE; | 592 | pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE; |
593 | if (!is_ack_bit && tx_short_bit(pin)) { | ||
594 | /* Error Injection: send an invalid (too short) bit */ | ||
595 | pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT; | ||
596 | } else if (!is_ack_bit && tx_long_bit(pin)) { | ||
597 | /* Error Injection: send an invalid (too long) bit */ | ||
598 | pin->state = CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG; | ||
599 | } | ||
277 | if (!is_ack_bit) | 600 | if (!is_ack_bit) |
278 | break; | 601 | break; |
279 | /* Was the message ACKed? */ | 602 | /* Was the message ACKed? */ |
280 | ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v; | 603 | ack = cec_msg_is_broadcast(&pin->tx_msg) ? v : !v; |
281 | if (!ack) { | 604 | if (!ack && !pin->tx_ignore_nack_until_eom && |
605 | pin->tx_bit / 10 < pin->tx_msg.len && !pin->tx_post_eom) { | ||
282 | /* | 606 | /* |
283 | * Note: the CEC spec is ambiguous regarding | 607 | * Note: the CEC spec is ambiguous regarding |
284 | * what action to take when a NACK appears | 608 | * what action to take when a NACK appears |
@@ -295,6 +619,15 @@ static void cec_pin_tx_states(struct cec_pin *pin, ktime_t ts) | |||
295 | } | 619 | } |
296 | break; | 620 | break; |
297 | 621 | ||
622 | case CEC_ST_TX_PULSE_LOW_CUSTOM: | ||
623 | cec_pin_high(pin); | ||
624 | pin->state = CEC_ST_TX_PULSE_HIGH_CUSTOM; | ||
625 | break; | ||
626 | |||
627 | case CEC_ST_TX_PULSE_HIGH_CUSTOM: | ||
628 | cec_pin_to_idle(pin); | ||
629 | break; | ||
630 | |||
298 | default: | 631 | default: |
299 | break; | 632 | break; |
300 | } | 633 | } |
@@ -322,6 +655,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) | |||
322 | bool ack; | 655 | bool ack; |
323 | bool bcast, for_us; | 656 | bool bcast, for_us; |
324 | u8 dest; | 657 | u8 dest; |
658 | u8 poll; | ||
325 | 659 | ||
326 | switch (pin->state) { | 660 | switch (pin->state) { |
327 | /* Receive states */ | 661 | /* Receive states */ |
@@ -331,24 +665,54 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) | |||
331 | break; | 665 | break; |
332 | pin->state = CEC_ST_RX_START_BIT_HIGH; | 666 | pin->state = CEC_ST_RX_START_BIT_HIGH; |
333 | delta = ktime_us_delta(ts, pin->ts); | 667 | delta = ktime_us_delta(ts, pin->ts); |
334 | pin->ts = ts; | ||
335 | /* Start bit low is too short, go back to idle */ | 668 | /* Start bit low is too short, go back to idle */ |
336 | if (delta < CEC_TIM_START_BIT_LOW_MIN - | 669 | if (delta < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_IDLE_SAMPLE) { |
337 | CEC_TIM_IDLE_SAMPLE) { | 670 | if (!pin->rx_start_bit_low_too_short_cnt++) { |
671 | pin->rx_start_bit_low_too_short_ts = pin->ts; | ||
672 | pin->rx_start_bit_low_too_short_delta = delta; | ||
673 | } | ||
338 | cec_pin_to_idle(pin); | 674 | cec_pin_to_idle(pin); |
675 | break; | ||
676 | } | ||
677 | if (rx_arb_lost(pin, &poll)) { | ||
678 | cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf); | ||
679 | pin->tx_generated_poll = true; | ||
680 | pin->tx_extra_bytes = 0; | ||
681 | pin->state = CEC_ST_TX_START_BIT_HIGH; | ||
682 | pin->ts = ts; | ||
339 | } | 683 | } |
340 | break; | 684 | break; |
341 | 685 | ||
342 | case CEC_ST_RX_START_BIT_HIGH: | 686 | case CEC_ST_RX_START_BIT_HIGH: |
343 | v = cec_pin_read(pin); | 687 | v = cec_pin_read(pin); |
344 | delta = ktime_us_delta(ts, pin->ts); | 688 | delta = ktime_us_delta(ts, pin->ts); |
345 | if (v && delta > CEC_TIM_START_BIT_TOTAL_MAX - | 689 | /* |
346 | CEC_TIM_START_BIT_LOW_MIN) { | 690 | * Unfortunately the spec does not specify when to give up |
691 | * and go to idle. We just pick TOTAL_LONG. | ||
692 | */ | ||
693 | if (v && delta > CEC_TIM_START_BIT_TOTAL_LONG) { | ||
694 | pin->rx_start_bit_too_long_cnt++; | ||
347 | cec_pin_to_idle(pin); | 695 | cec_pin_to_idle(pin); |
348 | break; | 696 | break; |
349 | } | 697 | } |
350 | if (v) | 698 | if (v) |
351 | break; | 699 | break; |
700 | /* Start bit is too short, go back to idle */ | ||
701 | if (delta < CEC_TIM_START_BIT_TOTAL_MIN - CEC_TIM_IDLE_SAMPLE) { | ||
702 | if (!pin->rx_start_bit_too_short_cnt++) { | ||
703 | pin->rx_start_bit_too_short_ts = pin->ts; | ||
704 | pin->rx_start_bit_too_short_delta = delta; | ||
705 | } | ||
706 | cec_pin_to_idle(pin); | ||
707 | break; | ||
708 | } | ||
709 | if (rx_low_drive(pin)) { | ||
710 | /* Error injection: go to low drive */ | ||
711 | cec_pin_low(pin); | ||
712 | pin->state = CEC_ST_RX_LOW_DRIVE; | ||
713 | pin->rx_low_drive_cnt++; | ||
714 | break; | ||
715 | } | ||
352 | pin->state = CEC_ST_RX_DATA_SAMPLE; | 716 | pin->state = CEC_ST_RX_DATA_SAMPLE; |
353 | pin->ts = ts; | 717 | pin->ts = ts; |
354 | pin->rx_eom = false; | 718 | pin->rx_eom = false; |
@@ -363,36 +727,55 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) | |||
363 | pin->rx_msg.msg[pin->rx_bit / 10] |= | 727 | pin->rx_msg.msg[pin->rx_bit / 10] |= |
364 | v << (7 - (pin->rx_bit % 10)); | 728 | v << (7 - (pin->rx_bit % 10)); |
365 | break; | 729 | break; |
366 | case 8: | 730 | case EOM_BIT: |
367 | pin->rx_eom = v; | 731 | pin->rx_eom = v; |
368 | pin->rx_msg.len = pin->rx_bit / 10 + 1; | 732 | pin->rx_msg.len = pin->rx_bit / 10 + 1; |
369 | break; | 733 | break; |
370 | case 9: | 734 | case ACK_BIT: |
371 | break; | 735 | break; |
372 | } | 736 | } |
373 | pin->rx_bit++; | 737 | pin->rx_bit++; |
374 | break; | 738 | break; |
375 | 739 | ||
376 | case CEC_ST_RX_DATA_POST_SAMPLE: | 740 | case CEC_ST_RX_DATA_POST_SAMPLE: |
377 | pin->state = CEC_ST_RX_DATA_HIGH; | 741 | pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW; |
378 | break; | 742 | break; |
379 | 743 | ||
380 | case CEC_ST_RX_DATA_HIGH: | 744 | case CEC_ST_RX_DATA_WAIT_FOR_LOW: |
381 | v = cec_pin_read(pin); | 745 | v = cec_pin_read(pin); |
382 | delta = ktime_us_delta(ts, pin->ts); | 746 | delta = ktime_us_delta(ts, pin->ts); |
383 | if (v && delta > CEC_TIM_DATA_BIT_TOTAL_MAX) { | 747 | /* |
748 | * Unfortunately the spec does not specify when to give up | ||
749 | * and go to idle. We just pick TOTAL_LONG. | ||
750 | */ | ||
751 | if (v && delta > CEC_TIM_DATA_BIT_TOTAL_LONG) { | ||
752 | pin->rx_data_bit_too_long_cnt++; | ||
384 | cec_pin_to_idle(pin); | 753 | cec_pin_to_idle(pin); |
385 | break; | 754 | break; |
386 | } | 755 | } |
387 | if (v) | 756 | if (v) |
388 | break; | 757 | break; |
758 | |||
759 | if (rx_low_drive(pin)) { | ||
760 | /* Error injection: go to low drive */ | ||
761 | cec_pin_low(pin); | ||
762 | pin->state = CEC_ST_RX_LOW_DRIVE; | ||
763 | pin->rx_low_drive_cnt++; | ||
764 | break; | ||
765 | } | ||
766 | |||
389 | /* | 767 | /* |
390 | * Go to low drive state when the total bit time is | 768 | * Go to low drive state when the total bit time is |
391 | * too short. | 769 | * too short. |
392 | */ | 770 | */ |
393 | if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) { | 771 | if (delta < CEC_TIM_DATA_BIT_TOTAL_MIN) { |
772 | if (!pin->rx_data_bit_too_short_cnt++) { | ||
773 | pin->rx_data_bit_too_short_ts = pin->ts; | ||
774 | pin->rx_data_bit_too_short_delta = delta; | ||
775 | } | ||
394 | cec_pin_low(pin); | 776 | cec_pin_low(pin); |
395 | pin->state = CEC_ST_LOW_DRIVE; | 777 | pin->state = CEC_ST_RX_LOW_DRIVE; |
778 | pin->rx_low_drive_cnt++; | ||
396 | break; | 779 | break; |
397 | } | 780 | } |
398 | pin->ts = ts; | 781 | pin->ts = ts; |
@@ -408,6 +791,11 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) | |||
408 | /* ACK bit value */ | 791 | /* ACK bit value */ |
409 | ack = bcast ? 1 : !for_us; | 792 | ack = bcast ? 1 : !for_us; |
410 | 793 | ||
794 | if (for_us && rx_nack(pin)) { | ||
795 | /* Error injection: toggle the ACK bit */ | ||
796 | ack = !ack; | ||
797 | } | ||
798 | |||
411 | if (ack) { | 799 | if (ack) { |
412 | /* No need to write to the bus, just wait */ | 800 | /* No need to write to the bus, just wait */ |
413 | pin->state = CEC_ST_RX_ACK_HIGH_POST; | 801 | pin->state = CEC_ST_RX_ACK_HIGH_POST; |
@@ -434,7 +822,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts) | |||
434 | break; | 822 | break; |
435 | } | 823 | } |
436 | pin->rx_bit++; | 824 | pin->rx_bit++; |
437 | pin->state = CEC_ST_RX_DATA_HIGH; | 825 | pin->state = CEC_ST_RX_DATA_WAIT_FOR_LOW; |
438 | break; | 826 | break; |
439 | 827 | ||
440 | case CEC_ST_RX_ACK_FINISH: | 828 | case CEC_ST_RX_ACK_FINISH: |
@@ -456,6 +844,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) | |||
456 | struct cec_adapter *adap = pin->adap; | 844 | struct cec_adapter *adap = pin->adap; |
457 | ktime_t ts; | 845 | ktime_t ts; |
458 | s32 delta; | 846 | s32 delta; |
847 | u32 usecs; | ||
459 | 848 | ||
460 | ts = ktime_get(); | 849 | ts = ktime_get(); |
461 | if (ktime_to_ns(pin->timer_ts)) { | 850 | if (ktime_to_ns(pin->timer_ts)) { |
@@ -503,13 +892,27 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) | |||
503 | /* Transmit states */ | 892 | /* Transmit states */ |
504 | case CEC_ST_TX_WAIT_FOR_HIGH: | 893 | case CEC_ST_TX_WAIT_FOR_HIGH: |
505 | case CEC_ST_TX_START_BIT_LOW: | 894 | case CEC_ST_TX_START_BIT_LOW: |
506 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE: | ||
507 | case CEC_ST_TX_DATA_BIT_0_HIGH: | ||
508 | case CEC_ST_TX_DATA_BIT_1_HIGH: | ||
509 | case CEC_ST_TX_START_BIT_HIGH: | 895 | case CEC_ST_TX_START_BIT_HIGH: |
896 | case CEC_ST_TX_START_BIT_HIGH_SHORT: | ||
897 | case CEC_ST_TX_START_BIT_HIGH_LONG: | ||
898 | case CEC_ST_TX_START_BIT_LOW_CUSTOM: | ||
899 | case CEC_ST_TX_START_BIT_HIGH_CUSTOM: | ||
510 | case CEC_ST_TX_DATA_BIT_0_LOW: | 900 | case CEC_ST_TX_DATA_BIT_0_LOW: |
901 | case CEC_ST_TX_DATA_BIT_0_HIGH: | ||
902 | case CEC_ST_TX_DATA_BIT_0_HIGH_SHORT: | ||
903 | case CEC_ST_TX_DATA_BIT_0_HIGH_LONG: | ||
511 | case CEC_ST_TX_DATA_BIT_1_LOW: | 904 | case CEC_ST_TX_DATA_BIT_1_LOW: |
905 | case CEC_ST_TX_DATA_BIT_1_HIGH: | ||
906 | case CEC_ST_TX_DATA_BIT_1_HIGH_SHORT: | ||
907 | case CEC_ST_TX_DATA_BIT_1_HIGH_LONG: | ||
512 | case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE: | 908 | case CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE: |
909 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE: | ||
910 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_SHORT: | ||
911 | case CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE_LONG: | ||
912 | case CEC_ST_TX_DATA_BIT_LOW_CUSTOM: | ||
913 | case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM: | ||
914 | case CEC_ST_TX_PULSE_LOW_CUSTOM: | ||
915 | case CEC_ST_TX_PULSE_HIGH_CUSTOM: | ||
513 | cec_pin_tx_states(pin, ts); | 916 | cec_pin_tx_states(pin, ts); |
514 | break; | 917 | break; |
515 | 918 | ||
@@ -518,7 +921,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) | |||
518 | case CEC_ST_RX_START_BIT_HIGH: | 921 | case CEC_ST_RX_START_BIT_HIGH: |
519 | case CEC_ST_RX_DATA_SAMPLE: | 922 | case CEC_ST_RX_DATA_SAMPLE: |
520 | case CEC_ST_RX_DATA_POST_SAMPLE: | 923 | case CEC_ST_RX_DATA_POST_SAMPLE: |
521 | case CEC_ST_RX_DATA_HIGH: | 924 | case CEC_ST_RX_DATA_WAIT_FOR_LOW: |
522 | case CEC_ST_RX_ACK_LOW: | 925 | case CEC_ST_RX_ACK_LOW: |
523 | case CEC_ST_RX_ACK_LOW_POST: | 926 | case CEC_ST_RX_ACK_LOW_POST: |
524 | case CEC_ST_RX_ACK_HIGH_POST: | 927 | case CEC_ST_RX_ACK_HIGH_POST: |
@@ -545,7 +948,10 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) | |||
545 | if (delta / CEC_TIM_DATA_BIT_TOTAL > | 948 | if (delta / CEC_TIM_DATA_BIT_TOTAL > |
546 | pin->tx_signal_free_time) { | 949 | pin->tx_signal_free_time) { |
547 | pin->tx_nacked = false; | 950 | pin->tx_nacked = false; |
548 | pin->state = CEC_ST_TX_START_BIT_LOW; | 951 | if (tx_custom_start(pin)) |
952 | pin->state = CEC_ST_TX_START_BIT_LOW_CUSTOM; | ||
953 | else | ||
954 | pin->state = CEC_ST_TX_START_BIT_LOW; | ||
549 | /* Generate start bit */ | 955 | /* Generate start bit */ |
550 | cec_pin_low(pin); | 956 | cec_pin_low(pin); |
551 | break; | 957 | break; |
@@ -555,6 +961,13 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) | |||
555 | pin->state = CEC_ST_TX_WAIT; | 961 | pin->state = CEC_ST_TX_WAIT; |
556 | break; | 962 | break; |
557 | } | 963 | } |
964 | if (pin->tx_custom_pulse && pin->state == CEC_ST_IDLE) { | ||
965 | pin->tx_custom_pulse = false; | ||
966 | /* Generate custom pulse */ | ||
967 | cec_pin_low(pin); | ||
968 | pin->state = CEC_ST_TX_PULSE_LOW_CUSTOM; | ||
969 | break; | ||
970 | } | ||
558 | if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL || | 971 | if (pin->state != CEC_ST_IDLE || pin->ops->enable_irq == NULL || |
559 | pin->enable_irq_failed || adap->is_configuring || | 972 | pin->enable_irq_failed || adap->is_configuring || |
560 | adap->is_configured || adap->monitor_all_cnt) | 973 | adap->is_configured || adap->monitor_all_cnt) |
@@ -565,21 +978,40 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer) | |||
565 | wake_up_interruptible(&pin->kthread_waitq); | 978 | wake_up_interruptible(&pin->kthread_waitq); |
566 | return HRTIMER_NORESTART; | 979 | return HRTIMER_NORESTART; |
567 | 980 | ||
568 | case CEC_ST_LOW_DRIVE: | 981 | case CEC_ST_TX_LOW_DRIVE: |
982 | case CEC_ST_RX_LOW_DRIVE: | ||
983 | cec_pin_high(pin); | ||
569 | cec_pin_to_idle(pin); | 984 | cec_pin_to_idle(pin); |
570 | break; | 985 | break; |
571 | 986 | ||
572 | default: | 987 | default: |
573 | break; | 988 | break; |
574 | } | 989 | } |
575 | if (!adap->monitor_pin_cnt || states[pin->state].usecs <= 150) { | 990 | |
991 | switch (pin->state) { | ||
992 | case CEC_ST_TX_START_BIT_LOW_CUSTOM: | ||
993 | case CEC_ST_TX_DATA_BIT_LOW_CUSTOM: | ||
994 | case CEC_ST_TX_PULSE_LOW_CUSTOM: | ||
995 | usecs = pin->tx_custom_low_usecs; | ||
996 | break; | ||
997 | case CEC_ST_TX_START_BIT_HIGH_CUSTOM: | ||
998 | case CEC_ST_TX_DATA_BIT_HIGH_CUSTOM: | ||
999 | case CEC_ST_TX_PULSE_HIGH_CUSTOM: | ||
1000 | usecs = pin->tx_custom_high_usecs; | ||
1001 | break; | ||
1002 | default: | ||
1003 | usecs = states[pin->state].usecs; | ||
1004 | break; | ||
1005 | } | ||
1006 | |||
1007 | if (!adap->monitor_pin_cnt || usecs <= 150) { | ||
576 | pin->wait_usecs = 0; | 1008 | pin->wait_usecs = 0; |
577 | pin->timer_ts = ktime_add_us(ts, states[pin->state].usecs); | 1009 | pin->timer_ts = ktime_add_us(ts, usecs); |
578 | hrtimer_forward_now(timer, | 1010 | hrtimer_forward_now(timer, |
579 | ns_to_ktime(states[pin->state].usecs * 1000)); | 1011 | ns_to_ktime(usecs * 1000)); |
580 | return HRTIMER_RESTART; | 1012 | return HRTIMER_RESTART; |
581 | } | 1013 | } |
582 | pin->wait_usecs = states[pin->state].usecs - 100; | 1014 | pin->wait_usecs = usecs - 100; |
583 | pin->timer_ts = ktime_add_us(ts, 100); | 1015 | pin->timer_ts = ktime_add_us(ts, 100); |
584 | hrtimer_forward_now(timer, ns_to_ktime(100000)); | 1016 | hrtimer_forward_now(timer, ns_to_ktime(100000)); |
585 | return HRTIMER_RESTART; | 1017 | return HRTIMER_RESTART; |
@@ -596,12 +1028,25 @@ static int cec_pin_thread_func(void *_adap) | |||
596 | pin->work_rx_msg.len || | 1028 | pin->work_rx_msg.len || |
597 | pin->work_tx_status || | 1029 | pin->work_tx_status || |
598 | atomic_read(&pin->work_irq_change) || | 1030 | atomic_read(&pin->work_irq_change) || |
599 | atomic_read(&pin->work_pin_events)); | 1031 | atomic_read(&pin->work_pin_num_events)); |
600 | 1032 | ||
601 | if (pin->work_rx_msg.len) { | 1033 | if (pin->work_rx_msg.len) { |
602 | cec_received_msg_ts(adap, &pin->work_rx_msg, | 1034 | struct cec_msg *msg = &pin->work_rx_msg; |
1035 | |||
1036 | if (msg->len > 1 && msg->len < CEC_MAX_MSG_SIZE && | ||
1037 | rx_add_byte(pin)) { | ||
1038 | /* Error injection: add byte to the message */ | ||
1039 | msg->msg[msg->len++] = 0x55; | ||
1040 | } | ||
1041 | if (msg->len > 2 && rx_remove_byte(pin)) { | ||
1042 | /* Error injection: remove byte from message */ | ||
1043 | msg->len--; | ||
1044 | } | ||
1045 | if (msg->len > CEC_MAX_MSG_SIZE) | ||
1046 | msg->len = CEC_MAX_MSG_SIZE; | ||
1047 | cec_received_msg_ts(adap, msg, | ||
603 | ns_to_ktime(pin->work_rx_msg.rx_ts)); | 1048 | ns_to_ktime(pin->work_rx_msg.rx_ts)); |
604 | pin->work_rx_msg.len = 0; | 1049 | msg->len = 0; |
605 | } | 1050 | } |
606 | if (pin->work_tx_status) { | 1051 | if (pin->work_tx_status) { |
607 | unsigned int tx_status = pin->work_tx_status; | 1052 | unsigned int tx_status = pin->work_tx_status; |
@@ -611,14 +1056,16 @@ static int cec_pin_thread_func(void *_adap) | |||
611 | pin->work_tx_ts); | 1056 | pin->work_tx_ts); |
612 | } | 1057 | } |
613 | 1058 | ||
614 | while (atomic_read(&pin->work_pin_events)) { | 1059 | while (atomic_read(&pin->work_pin_num_events)) { |
615 | unsigned int idx = pin->work_pin_events_rd; | 1060 | unsigned int idx = pin->work_pin_events_rd; |
1061 | u8 v = pin->work_pin_events[idx]; | ||
616 | 1062 | ||
617 | cec_queue_pin_cec_event(adap, | 1063 | cec_queue_pin_cec_event(adap, |
618 | pin->work_pin_is_high[idx], | 1064 | v & CEC_PIN_EVENT_FL_IS_HIGH, |
1065 | v & CEC_PIN_EVENT_FL_DROPPED, | ||
619 | pin->work_pin_ts[idx]); | 1066 | pin->work_pin_ts[idx]); |
620 | pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; | 1067 | pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS; |
621 | atomic_dec(&pin->work_pin_events); | 1068 | atomic_dec(&pin->work_pin_num_events); |
622 | } | 1069 | } |
623 | 1070 | ||
624 | switch (atomic_xchg(&pin->work_irq_change, | 1071 | switch (atomic_xchg(&pin->work_irq_change, |
@@ -654,8 +1101,9 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) | |||
654 | 1101 | ||
655 | pin->enabled = enable; | 1102 | pin->enabled = enable; |
656 | if (enable) { | 1103 | if (enable) { |
657 | atomic_set(&pin->work_pin_events, 0); | 1104 | atomic_set(&pin->work_pin_num_events, 0); |
658 | pin->work_pin_events_rd = pin->work_pin_events_wr = 0; | 1105 | pin->work_pin_events_rd = pin->work_pin_events_wr = 0; |
1106 | pin->work_pin_events_dropped = false; | ||
659 | cec_pin_read(pin); | 1107 | cec_pin_read(pin); |
660 | cec_pin_to_idle(pin); | 1108 | cec_pin_to_idle(pin); |
661 | pin->tx_msg.len = 0; | 1109 | pin->tx_msg.len = 0; |
@@ -692,23 +1140,37 @@ static int cec_pin_adap_log_addr(struct cec_adapter *adap, u8 log_addr) | |||
692 | return 0; | 1140 | return 0; |
693 | } | 1141 | } |
694 | 1142 | ||
1143 | void cec_pin_start_timer(struct cec_pin *pin) | ||
1144 | { | ||
1145 | if (pin->state != CEC_ST_RX_IRQ) | ||
1146 | return; | ||
1147 | |||
1148 | atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); | ||
1149 | pin->ops->disable_irq(pin->adap); | ||
1150 | cec_pin_high(pin); | ||
1151 | cec_pin_to_idle(pin); | ||
1152 | hrtimer_start(&pin->timer, ns_to_ktime(0), HRTIMER_MODE_REL); | ||
1153 | } | ||
1154 | |||
695 | static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, | 1155 | static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, |
696 | u32 signal_free_time, struct cec_msg *msg) | 1156 | u32 signal_free_time, struct cec_msg *msg) |
697 | { | 1157 | { |
698 | struct cec_pin *pin = adap->pin; | 1158 | struct cec_pin *pin = adap->pin; |
699 | 1159 | ||
700 | pin->tx_signal_free_time = signal_free_time; | 1160 | pin->tx_signal_free_time = signal_free_time; |
1161 | pin->tx_extra_bytes = 0; | ||
701 | pin->tx_msg = *msg; | 1162 | pin->tx_msg = *msg; |
1163 | if (msg->len > 1) { | ||
1164 | /* Error injection: add byte to the message */ | ||
1165 | pin->tx_extra_bytes = tx_add_bytes(pin); | ||
1166 | } | ||
1167 | if (msg->len > 2 && tx_remove_byte(pin)) { | ||
1168 | /* Error injection: remove byte from the message */ | ||
1169 | pin->tx_msg.len--; | ||
1170 | } | ||
702 | pin->work_tx_status = 0; | 1171 | pin->work_tx_status = 0; |
703 | pin->tx_bit = 0; | 1172 | pin->tx_bit = 0; |
704 | if (pin->state == CEC_ST_RX_IRQ) { | 1173 | cec_pin_start_timer(pin); |
705 | atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); | ||
706 | pin->ops->disable_irq(adap); | ||
707 | cec_pin_high(pin); | ||
708 | cec_pin_to_idle(pin); | ||
709 | hrtimer_start(&pin->timer, ns_to_ktime(0), | ||
710 | HRTIMER_MODE_REL); | ||
711 | } | ||
712 | return 0; | 1174 | return 0; |
713 | } | 1175 | } |
714 | 1176 | ||
@@ -717,10 +1179,12 @@ static void cec_pin_adap_status(struct cec_adapter *adap, | |||
717 | { | 1179 | { |
718 | struct cec_pin *pin = adap->pin; | 1180 | struct cec_pin *pin = adap->pin; |
719 | 1181 | ||
720 | seq_printf(file, "state: %s\n", states[pin->state].name); | 1182 | seq_printf(file, "state: %s\n", states[pin->state].name); |
721 | seq_printf(file, "tx_bit: %d\n", pin->tx_bit); | 1183 | seq_printf(file, "tx_bit: %d\n", pin->tx_bit); |
722 | seq_printf(file, "rx_bit: %d\n", pin->rx_bit); | 1184 | seq_printf(file, "rx_bit: %d\n", pin->rx_bit); |
723 | seq_printf(file, "cec pin: %d\n", pin->ops->read(adap)); | 1185 | seq_printf(file, "cec pin: %d\n", pin->ops->read(adap)); |
1186 | seq_printf(file, "cec pin events dropped: %u\n", | ||
1187 | pin->work_pin_events_dropped_cnt); | ||
724 | seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed); | 1188 | seq_printf(file, "irq failed: %d\n", pin->enable_irq_failed); |
725 | if (pin->timer_100ms_overruns) { | 1189 | if (pin->timer_100ms_overruns) { |
726 | seq_printf(file, "timer overruns > 100ms: %u of %u\n", | 1190 | seq_printf(file, "timer overruns > 100ms: %u of %u\n", |
@@ -732,11 +1196,45 @@ static void cec_pin_adap_status(struct cec_adapter *adap, | |||
732 | seq_printf(file, "avg timer overrun: %u usecs\n", | 1196 | seq_printf(file, "avg timer overrun: %u usecs\n", |
733 | pin->timer_sum_overrun / pin->timer_100ms_overruns); | 1197 | pin->timer_sum_overrun / pin->timer_100ms_overruns); |
734 | } | 1198 | } |
1199 | if (pin->rx_start_bit_low_too_short_cnt) | ||
1200 | seq_printf(file, | ||
1201 | "rx start bit low too short: %u (delta %u, ts %llu)\n", | ||
1202 | pin->rx_start_bit_low_too_short_cnt, | ||
1203 | pin->rx_start_bit_low_too_short_delta, | ||
1204 | pin->rx_start_bit_low_too_short_ts); | ||
1205 | if (pin->rx_start_bit_too_short_cnt) | ||
1206 | seq_printf(file, | ||
1207 | "rx start bit too short: %u (delta %u, ts %llu)\n", | ||
1208 | pin->rx_start_bit_too_short_cnt, | ||
1209 | pin->rx_start_bit_too_short_delta, | ||
1210 | pin->rx_start_bit_too_short_ts); | ||
1211 | if (pin->rx_start_bit_too_long_cnt) | ||
1212 | seq_printf(file, "rx start bit too long: %u\n", | ||
1213 | pin->rx_start_bit_too_long_cnt); | ||
1214 | if (pin->rx_data_bit_too_short_cnt) | ||
1215 | seq_printf(file, | ||
1216 | "rx data bit too short: %u (delta %u, ts %llu)\n", | ||
1217 | pin->rx_data_bit_too_short_cnt, | ||
1218 | pin->rx_data_bit_too_short_delta, | ||
1219 | pin->rx_data_bit_too_short_ts); | ||
1220 | if (pin->rx_data_bit_too_long_cnt) | ||
1221 | seq_printf(file, "rx data bit too long: %u\n", | ||
1222 | pin->rx_data_bit_too_long_cnt); | ||
1223 | seq_printf(file, "rx initiated low drive: %u\n", pin->rx_low_drive_cnt); | ||
1224 | seq_printf(file, "tx detected low drive: %u\n", pin->tx_low_drive_cnt); | ||
1225 | pin->work_pin_events_dropped_cnt = 0; | ||
735 | pin->timer_cnt = 0; | 1226 | pin->timer_cnt = 0; |
736 | pin->timer_100ms_overruns = 0; | 1227 | pin->timer_100ms_overruns = 0; |
737 | pin->timer_300ms_overruns = 0; | 1228 | pin->timer_300ms_overruns = 0; |
738 | pin->timer_max_overrun = 0; | 1229 | pin->timer_max_overrun = 0; |
739 | pin->timer_sum_overrun = 0; | 1230 | pin->timer_sum_overrun = 0; |
1231 | pin->rx_start_bit_low_too_short_cnt = 0; | ||
1232 | pin->rx_start_bit_too_short_cnt = 0; | ||
1233 | pin->rx_start_bit_too_long_cnt = 0; | ||
1234 | pin->rx_data_bit_too_short_cnt = 0; | ||
1235 | pin->rx_data_bit_too_long_cnt = 0; | ||
1236 | pin->rx_low_drive_cnt = 0; | ||
1237 | pin->tx_low_drive_cnt = 0; | ||
740 | if (pin->ops->status) | 1238 | if (pin->ops->status) |
741 | pin->ops->status(adap, file); | 1239 | pin->ops->status(adap, file); |
742 | } | 1240 | } |
@@ -778,6 +1276,10 @@ static const struct cec_adap_ops cec_pin_adap_ops = { | |||
778 | .adap_transmit = cec_pin_adap_transmit, | 1276 | .adap_transmit = cec_pin_adap_transmit, |
779 | .adap_status = cec_pin_adap_status, | 1277 | .adap_status = cec_pin_adap_status, |
780 | .adap_free = cec_pin_adap_free, | 1278 | .adap_free = cec_pin_adap_free, |
1279 | #ifdef CONFIG_CEC_PIN_ERROR_INJ | ||
1280 | .error_inj_parse_line = cec_pin_error_inj_parse_line, | ||
1281 | .error_inj_show = cec_pin_error_inj_show, | ||
1282 | #endif | ||
781 | }; | 1283 | }; |
782 | 1284 | ||
783 | struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, | 1285 | struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, |
@@ -792,6 +1294,8 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, | |||
792 | hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1294 | hrtimer_init(&pin->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
793 | pin->timer.function = cec_pin_timer; | 1295 | pin->timer.function = cec_pin_timer; |
794 | init_waitqueue_head(&pin->kthread_waitq); | 1296 | init_waitqueue_head(&pin->kthread_waitq); |
1297 | pin->tx_custom_low_usecs = CEC_TIM_CUSTOM_DEFAULT; | ||
1298 | pin->tx_custom_high_usecs = CEC_TIM_CUSTOM_DEFAULT; | ||
795 | 1299 | ||
796 | adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name, | 1300 | adap = cec_allocate_adapter(&cec_pin_adap_ops, priv, name, |
797 | caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN, | 1301 | caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN, |
diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h index daf597643af8..804e38f849c7 100644 --- a/drivers/media/cec/cec-priv.h +++ b/drivers/media/cec/cec-priv.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cec-priv.h - HDMI Consumer Electronics Control internal header | 3 | * cec-priv.h - HDMI Consumer Electronics Control internal header |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _CEC_PRIV_H | 8 | #ifndef _CEC_PRIV_H |
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index c5c827e11b64..b5dcc6d1fe90 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c | |||
@@ -631,7 +631,8 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, | |||
631 | 631 | ||
632 | cb->p = buffer; | 632 | cb->p = buffer; |
633 | cb->offset_in_common = buffer - (u8 *) common_buffer; | 633 | cb->offset_in_common = buffer - (u8 *) common_buffer; |
634 | cb->phys = common_buffer_phys + cb->offset_in_common; | 634 | if (common_buffer_phys) |
635 | cb->phys = common_buffer_phys + cb->offset_in_common; | ||
635 | 636 | ||
636 | return cb; | 637 | return cb; |
637 | } | 638 | } |
@@ -690,17 +691,21 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
690 | 691 | ||
691 | /* alloc common buffer */ | 692 | /* alloc common buffer */ |
692 | dev->common_buffer_size = params->buffer_size * params->num_buffers; | 693 | dev->common_buffer_size = params->buffer_size * params->num_buffers; |
693 | dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, | 694 | if (params->usb_device) |
694 | &dev->common_buffer_phys, | 695 | buffer = kzalloc(dev->common_buffer_size, GFP_KERNEL); |
695 | GFP_KERNEL | GFP_DMA); | 696 | else |
696 | if (!dev->common_buffer) { | 697 | buffer = dma_alloc_coherent(params->device, |
698 | dev->common_buffer_size, | ||
699 | &dev->common_buffer_phys, | ||
700 | GFP_KERNEL | GFP_DMA); | ||
701 | if (!buffer) { | ||
697 | smscore_unregister_device(dev); | 702 | smscore_unregister_device(dev); |
698 | return -ENOMEM; | 703 | return -ENOMEM; |
699 | } | 704 | } |
705 | dev->common_buffer = buffer; | ||
700 | 706 | ||
701 | /* prepare dma buffers */ | 707 | /* prepare dma buffers */ |
702 | for (buffer = dev->common_buffer; | 708 | for (; dev->num_buffers < params->num_buffers; |
703 | dev->num_buffers < params->num_buffers; | ||
704 | dev->num_buffers++, buffer += params->buffer_size) { | 709 | dev->num_buffers++, buffer += params->buffer_size) { |
705 | struct smscore_buffer_t *cb; | 710 | struct smscore_buffer_t *cb; |
706 | 711 | ||
@@ -720,6 +725,7 @@ int smscore_register_device(struct smsdevice_params_t *params, | |||
720 | dev->board_id = SMS_BOARD_UNKNOWN; | 725 | dev->board_id = SMS_BOARD_UNKNOWN; |
721 | dev->context = params->context; | 726 | dev->context = params->context; |
722 | dev->device = params->device; | 727 | dev->device = params->device; |
728 | dev->usb_device = params->usb_device; | ||
723 | dev->setmode_handler = params->setmode_handler; | 729 | dev->setmode_handler = params->setmode_handler; |
724 | dev->detectmode_handler = params->detectmode_handler; | 730 | dev->detectmode_handler = params->detectmode_handler; |
725 | dev->sendrequest_handler = params->sendrequest_handler; | 731 | dev->sendrequest_handler = params->sendrequest_handler; |
@@ -1231,10 +1237,15 @@ void smscore_unregister_device(struct smscore_device_t *coredev) | |||
1231 | 1237 | ||
1232 | pr_debug("freed %d buffers\n", num_buffers); | 1238 | pr_debug("freed %d buffers\n", num_buffers); |
1233 | 1239 | ||
1234 | if (coredev->common_buffer) | 1240 | if (coredev->common_buffer) { |
1235 | dma_free_coherent(NULL, coredev->common_buffer_size, | 1241 | if (coredev->usb_device) |
1236 | coredev->common_buffer, coredev->common_buffer_phys); | 1242 | kfree(coredev->common_buffer); |
1237 | 1243 | else | |
1244 | dma_free_coherent(coredev->device, | ||
1245 | coredev->common_buffer_size, | ||
1246 | coredev->common_buffer, | ||
1247 | coredev->common_buffer_phys); | ||
1248 | } | ||
1238 | kfree(coredev->fw_buf); | 1249 | kfree(coredev->fw_buf); |
1239 | 1250 | ||
1240 | list_del(&coredev->entry); | 1251 | list_del(&coredev->entry); |
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index 4cc39e4a8318..134c69f7ea7b 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h | |||
@@ -134,6 +134,7 @@ struct smscore_buffer_t { | |||
134 | 134 | ||
135 | struct smsdevice_params_t { | 135 | struct smsdevice_params_t { |
136 | struct device *device; | 136 | struct device *device; |
137 | struct usb_device *usb_device; | ||
137 | 138 | ||
138 | int buffer_size; | 139 | int buffer_size; |
139 | int num_buffers; | 140 | int num_buffers; |
@@ -176,6 +177,7 @@ struct smscore_device_t { | |||
176 | 177 | ||
177 | void *context; | 178 | void *context; |
178 | struct device *device; | 179 | struct device *device; |
180 | struct usb_device *usb_device; | ||
179 | 181 | ||
180 | char devpath[32]; | 182 | char devpath[32]; |
181 | unsigned long device_flags; | 183 | unsigned long device_flags; |
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c index 43180204fab2..3a3dc23c560c 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * v4l2-tpg-colors.c - A table that converts colors to various colorspaces | 3 | * v4l2-tpg-colors.c - A table that converts colors to various colorspaces |
3 | * | 4 | * |
@@ -20,19 +21,6 @@ | |||
20 | * in order to preserve precision. | 21 | * in order to preserve precision. |
21 | * | 22 | * |
22 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 23 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
23 | * | ||
24 | * This program is free software; you may redistribute it and/or modify | ||
25 | * it under the terms of the GNU General Public License as published by | ||
26 | * the Free Software Foundation; version 2 of the License. | ||
27 | * | ||
28 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
29 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
31 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
32 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
33 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
34 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
35 | * SOFTWARE. | ||
36 | */ | 24 | */ |
37 | 25 | ||
38 | #include <linux/videodev2.h> | 26 | #include <linux/videodev2.h> |
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 2b3d4ac4dfd4..37632bc524d4 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * v4l2-tpg-core.c - Test Pattern Generator | 3 | * v4l2-tpg-core.c - Test Pattern Generator |
3 | * | 4 | * |
@@ -5,19 +6,6 @@ | |||
5 | * vivi.c source for the copyright information of those functions. | 6 | * vivi.c source for the copyright information of those functions. |
6 | * | 7 | * |
7 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 8 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | 9 | */ |
22 | 10 | ||
23 | #include <linux/module.h> | 11 | #include <linux/module.h> |
@@ -1155,13 +1143,13 @@ static void gen_twopix(struct tpg_data *tpg, | |||
1155 | case V4L2_PIX_FMT_NV24: | 1143 | case V4L2_PIX_FMT_NV24: |
1156 | buf[0][offset] = r_y_h; | 1144 | buf[0][offset] = r_y_h; |
1157 | buf[1][2 * offset] = g_u_s; | 1145 | buf[1][2 * offset] = g_u_s; |
1158 | buf[1][2 * offset + 1] = b_v; | 1146 | buf[1][(2 * offset + 1) % 8] = b_v; |
1159 | break; | 1147 | break; |
1160 | 1148 | ||
1161 | case V4L2_PIX_FMT_NV42: | 1149 | case V4L2_PIX_FMT_NV42: |
1162 | buf[0][offset] = r_y_h; | 1150 | buf[0][offset] = r_y_h; |
1163 | buf[1][2 * offset] = b_v; | 1151 | buf[1][2 * offset] = b_v; |
1164 | buf[1][2 * offset + 1] = g_u_s; | 1152 | buf[1][(2 * offset + 1) %8] = g_u_s; |
1165 | break; | 1153 | break; |
1166 | 1154 | ||
1167 | case V4L2_PIX_FMT_YUYV: | 1155 | case V4L2_PIX_FMT_YUYV: |
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index debe35fc66b4..d3f7bb33a54d 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c | |||
@@ -1696,6 +1696,15 @@ static void __vb2_queue_cancel(struct vb2_queue *q) | |||
1696 | for (i = 0; i < q->num_buffers; ++i) { | 1696 | for (i = 0; i < q->num_buffers; ++i) { |
1697 | struct vb2_buffer *vb = q->bufs[i]; | 1697 | struct vb2_buffer *vb = q->bufs[i]; |
1698 | 1698 | ||
1699 | if (vb->state == VB2_BUF_STATE_PREPARED || | ||
1700 | vb->state == VB2_BUF_STATE_QUEUED) { | ||
1701 | unsigned int plane; | ||
1702 | |||
1703 | for (plane = 0; plane < vb->num_planes; ++plane) | ||
1704 | call_void_memop(vb, finish, | ||
1705 | vb->planes[plane].mem_priv); | ||
1706 | } | ||
1707 | |||
1699 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { | 1708 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { |
1700 | vb->state = VB2_BUF_STATE_PREPARED; | 1709 | vb->state = VB2_BUF_STATE_PREPARED; |
1701 | call_void_vb_qop(vb, buf_finish, vb); | 1710 | call_void_vb_qop(vb, buf_finish, vb); |
diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 3a7c80cd1a17..359fb9804d16 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c | |||
@@ -106,7 +106,7 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, | |||
106 | if (nums[i-1] + 1 != nums[i]) | 106 | if (nums[i-1] + 1 != nums[i]) |
107 | goto fail_map; | 107 | goto fail_map; |
108 | buf->vaddr = (__force void *) | 108 | buf->vaddr = (__force void *) |
109 | ioremap_nocache(nums[0] << PAGE_SHIFT, size); | 109 | ioremap_nocache(__pfn_to_phys(nums[0]), size + offset); |
110 | } else { | 110 | } else { |
111 | buf->vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1, | 111 | buf->vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1, |
112 | PAGE_KERNEL); | 112 | PAGE_KERNEL); |
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 204d0f6c678d..97365a863519 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c | |||
@@ -1254,8 +1254,8 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca, | |||
1254 | ca->pub->slot_ts_enable(ca->pub, slot); | 1254 | ca->pub->slot_ts_enable(ca->pub, slot); |
1255 | sl->slot_state = DVB_CA_SLOTSTATE_RUNNING; | 1255 | sl->slot_state = DVB_CA_SLOTSTATE_RUNNING; |
1256 | dvb_ca_en50221_thread_update_delay(ca); | 1256 | dvb_ca_en50221_thread_update_delay(ca); |
1257 | pr_err("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", | 1257 | pr_info("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", |
1258 | ca->dvbdev->adapter->num); | 1258 | ca->dvbdev->adapter->num); |
1259 | break; | 1259 | break; |
1260 | 1260 | ||
1261 | case DVB_CA_SLOTSTATE_RUNNING: | 1261 | case DVB_CA_SLOTSTATE_RUNNING: |
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index a7ed16e0841d..21a7d4b47e1a 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c | |||
@@ -2294,7 +2294,7 @@ static int dvb_frontend_handle_ioctl(struct file *file, | |||
2294 | if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) | 2294 | if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) |
2295 | return -EINVAL; | 2295 | return -EINVAL; |
2296 | 2296 | ||
2297 | tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); | 2297 | tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); |
2298 | if (IS_ERR(tvp)) | 2298 | if (IS_ERR(tvp)) |
2299 | return PTR_ERR(tvp); | 2299 | return PTR_ERR(tvp); |
2300 | 2300 | ||
@@ -2328,7 +2328,7 @@ static int dvb_frontend_handle_ioctl(struct file *file, | |||
2328 | if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) | 2328 | if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) |
2329 | return -EINVAL; | 2329 | return -EINVAL; |
2330 | 2330 | ||
2331 | tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); | 2331 | tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp)); |
2332 | if (IS_ERR(tvp)) | 2332 | if (IS_ERR(tvp)) |
2333 | return PTR_ERR(tvp); | 2333 | return PTR_ERR(tvp); |
2334 | 2334 | ||
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 60e9c2ba26be..787fe06df217 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/i2c.h> | ||
27 | #include <linux/init.h> | 28 | #include <linux/init.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <linux/device.h> | 30 | #include <linux/device.h> |
@@ -941,6 +942,55 @@ out: | |||
941 | return err; | 942 | return err; |
942 | } | 943 | } |
943 | 944 | ||
945 | #if IS_ENABLED(CONFIG_I2C) | ||
946 | struct i2c_client *dvb_module_probe(const char *module_name, | ||
947 | const char *name, | ||
948 | struct i2c_adapter *adap, | ||
949 | unsigned char addr, | ||
950 | void *platform_data) | ||
951 | { | ||
952 | struct i2c_client *client; | ||
953 | struct i2c_board_info *board_info; | ||
954 | |||
955 | board_info = kzalloc(sizeof(*board_info), GFP_KERNEL); | ||
956 | if (!board_info) | ||
957 | return NULL; | ||
958 | |||
959 | if (name) | ||
960 | strlcpy(board_info->type, name, I2C_NAME_SIZE); | ||
961 | else | ||
962 | strlcpy(board_info->type, module_name, I2C_NAME_SIZE); | ||
963 | |||
964 | board_info->addr = addr; | ||
965 | board_info->platform_data = platform_data; | ||
966 | request_module(module_name); | ||
967 | client = i2c_new_device(adap, board_info); | ||
968 | if (client == NULL || client->dev.driver == NULL) { | ||
969 | kfree(board_info); | ||
970 | return NULL; | ||
971 | } | ||
972 | |||
973 | if (!try_module_get(client->dev.driver->owner)) { | ||
974 | i2c_unregister_device(client); | ||
975 | client = NULL; | ||
976 | } | ||
977 | |||
978 | kfree(board_info); | ||
979 | return client; | ||
980 | } | ||
981 | EXPORT_SYMBOL_GPL(dvb_module_probe); | ||
982 | |||
983 | void dvb_module_release(struct i2c_client *client) | ||
984 | { | ||
985 | if (!client) | ||
986 | return; | ||
987 | |||
988 | module_put(client->dev.driver->owner); | ||
989 | i2c_unregister_device(client); | ||
990 | } | ||
991 | EXPORT_SYMBOL_GPL(dvb_module_release); | ||
992 | #endif | ||
993 | |||
944 | static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) | 994 | static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) |
945 | { | 995 | { |
946 | struct dvb_device *dvbdev = dev_get_drvdata(dev); | 996 | struct dvb_device *dvbdev = dev_get_drvdata(dev); |
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index d17722eb4456..0712069fd9fe 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig | |||
@@ -462,7 +462,7 @@ config DVB_TDA10048 | |||
462 | 462 | ||
463 | config DVB_AF9013 | 463 | config DVB_AF9013 |
464 | tristate "Afatech AF9013 demodulator" | 464 | tristate "Afatech AF9013 demodulator" |
465 | depends on DVB_CORE && I2C | 465 | depends on DVB_CORE && I2C && I2C_MUX |
466 | select REGMAP | 466 | select REGMAP |
467 | default m if !MEDIA_SUBDRV_AUTOSELECT | 467 | default m if !MEDIA_SUBDRV_AUTOSELECT |
468 | help | 468 | help |
@@ -546,6 +546,8 @@ config DVB_GP8PSK_FE | |||
546 | depends on DVB_CORE | 546 | depends on DVB_CORE |
547 | default DVB_USB_GP8PSK | 547 | default DVB_USB_GP8PSK |
548 | 548 | ||
549 | source "drivers/media/dvb-frontends/cxd2880/Kconfig" | ||
550 | |||
549 | comment "DVB-C (cable) frontends" | 551 | comment "DVB-C (cable) frontends" |
550 | depends on DVB_CORE | 552 | depends on DVB_CORE |
551 | 553 | ||
@@ -822,13 +824,6 @@ config DVB_A8293 | |||
822 | depends on DVB_CORE && I2C | 824 | depends on DVB_CORE && I2C |
823 | default m if !MEDIA_SUBDRV_AUTOSELECT | 825 | default m if !MEDIA_SUBDRV_AUTOSELECT |
824 | 826 | ||
825 | config DVB_SP2 | ||
826 | tristate "CIMaX SP2" | ||
827 | depends on DVB_CORE && I2C | ||
828 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
829 | help | ||
830 | CIMaX SP2/SP2HF Common Interface module. | ||
831 | |||
832 | config DVB_LGS8GL5 | 827 | config DVB_LGS8GL5 |
833 | tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" | 828 | tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" |
834 | depends on DVB_CORE && I2C | 829 | depends on DVB_CORE && I2C |
@@ -904,6 +899,27 @@ config DVB_HELENE | |||
904 | help | 899 | help |
905 | Say Y when you want to support this frontend. | 900 | Say Y when you want to support this frontend. |
906 | 901 | ||
902 | comment "Common Interface (EN50221) controller drivers" | ||
903 | depends on DVB_CORE | ||
904 | |||
905 | config DVB_CXD2099 | ||
906 | tristate "CXD2099AR Common Interface driver" | ||
907 | depends on DVB_CORE && I2C | ||
908 | select REGMAP_I2C | ||
909 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
910 | help | ||
911 | A driver for the CI controller currently found mostly on | ||
912 | Digital Devices DuoFlex CI (single) addon modules. | ||
913 | |||
914 | Say Y when you want to support these devices. | ||
915 | |||
916 | config DVB_SP2 | ||
917 | tristate "CIMaX SP2" | ||
918 | depends on DVB_CORE && I2C | ||
919 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
920 | help | ||
921 | CIMaX SP2/SP2HF Common Interface module. | ||
922 | |||
907 | comment "Tools to develop new frontends" | 923 | comment "Tools to develop new frontends" |
908 | 924 | ||
909 | config DVB_DUMMY_FE | 925 | config DVB_DUMMY_FE |
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile index 4be59fed4536..67a783fd5ed0 100644 --- a/drivers/media/dvb-frontends/Makefile +++ b/drivers/media/dvb-frontends/Makefile | |||
@@ -129,3 +129,5 @@ obj-$(CONFIG_DVB_HORUS3A) += horus3a.o | |||
129 | obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o | 129 | obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o |
130 | obj-$(CONFIG_DVB_HELENE) += helene.o | 130 | obj-$(CONFIG_DVB_HELENE) += helene.o |
131 | obj-$(CONFIG_DVB_ZD1301_DEMOD) += zd1301_demod.o | 131 | obj-$(CONFIG_DVB_ZD1301_DEMOD) += zd1301_demod.o |
132 | obj-$(CONFIG_DVB_CXD2099) += cxd2099.o | ||
133 | obj-$(CONFIG_DVB_CXD2880) += cxd2880/ | ||
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index b8f3ebfc3e27..482bce49819a 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c | |||
@@ -23,6 +23,7 @@ | |||
23 | struct af9013_state { | 23 | struct af9013_state { |
24 | struct i2c_client *client; | 24 | struct i2c_client *client; |
25 | struct regmap *regmap; | 25 | struct regmap *regmap; |
26 | struct i2c_mux_core *muxc; | ||
26 | struct dvb_frontend fe; | 27 | struct dvb_frontend fe; |
27 | u32 clk; | 28 | u32 clk; |
28 | u8 tuner; | 29 | u8 tuner; |
@@ -33,20 +34,20 @@ struct af9013_state { | |||
33 | u8 api_version[4]; | 34 | u8 api_version[4]; |
34 | u8 gpio[4]; | 35 | u8 gpio[4]; |
35 | 36 | ||
36 | /* tuner/demod RF and IF AGC limits used for signal strength calc */ | ||
37 | u8 signal_strength_en, rf_50, rf_80, if_50, if_80; | ||
38 | u16 signal_strength; | ||
39 | u32 ber; | ||
40 | u32 ucblocks; | ||
41 | u16 snr; | ||
42 | u32 bandwidth_hz; | 37 | u32 bandwidth_hz; |
43 | enum fe_status fe_status; | 38 | enum fe_status fe_status; |
39 | /* RF and IF AGC limits used for signal strength calc */ | ||
40 | u8 strength_en, rf_agc_50, rf_agc_80, if_agc_50, if_agc_80; | ||
44 | unsigned long set_frontend_jiffies; | 41 | unsigned long set_frontend_jiffies; |
45 | unsigned long read_status_jiffies; | 42 | unsigned long read_status_jiffies; |
43 | unsigned long strength_jiffies; | ||
44 | unsigned long cnr_jiffies; | ||
45 | unsigned long ber_ucb_jiffies; | ||
46 | u16 dvbv3_snr; | ||
47 | u16 dvbv3_strength; | ||
48 | u32 dvbv3_ber; | ||
49 | u32 dvbv3_ucblocks; | ||
46 | bool first_tune; | 50 | bool first_tune; |
47 | bool i2c_gate_state; | ||
48 | unsigned int statistics_step:3; | ||
49 | struct delayed_work statistics_work; | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) | 53 | static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) |
@@ -101,232 +102,6 @@ err: | |||
101 | return ret; | 102 | return ret; |
102 | } | 103 | } |
103 | 104 | ||
104 | static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe) | ||
105 | { | ||
106 | struct af9013_state *state = fe->demodulator_priv; | ||
107 | struct i2c_client *client = state->client; | ||
108 | int ret; | ||
109 | |||
110 | dev_dbg(&client->dev, "\n"); | ||
111 | |||
112 | /* reset and start BER counter */ | ||
113 | ret = regmap_update_bits(state->regmap, 0xd391, 0x10, 0x10); | ||
114 | if (ret) | ||
115 | goto err; | ||
116 | |||
117 | return 0; | ||
118 | err: | ||
119 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe) | ||
124 | { | ||
125 | struct af9013_state *state = fe->demodulator_priv; | ||
126 | struct i2c_client *client = state->client; | ||
127 | int ret; | ||
128 | unsigned int utmp; | ||
129 | u8 buf[5]; | ||
130 | |||
131 | dev_dbg(&client->dev, "\n"); | ||
132 | |||
133 | /* check if error bit count is ready */ | ||
134 | ret = regmap_read(state->regmap, 0xd391, &utmp); | ||
135 | if (ret) | ||
136 | goto err; | ||
137 | |||
138 | if (!((utmp >> 4) & 0x01)) { | ||
139 | dev_dbg(&client->dev, "not ready\n"); | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | ret = regmap_bulk_read(state->regmap, 0xd387, buf, 5); | ||
144 | if (ret) | ||
145 | goto err; | ||
146 | |||
147 | state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
148 | state->ucblocks += (buf[4] << 8) | buf[3]; | ||
149 | |||
150 | return 0; | ||
151 | err: | ||
152 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static int af9013_statistics_snr_start(struct dvb_frontend *fe) | ||
157 | { | ||
158 | struct af9013_state *state = fe->demodulator_priv; | ||
159 | struct i2c_client *client = state->client; | ||
160 | int ret; | ||
161 | |||
162 | dev_dbg(&client->dev, "\n"); | ||
163 | |||
164 | /* start SNR meas */ | ||
165 | ret = regmap_update_bits(state->regmap, 0xd2e1, 0x08, 0x08); | ||
166 | if (ret) | ||
167 | goto err; | ||
168 | |||
169 | return 0; | ||
170 | err: | ||
171 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
172 | return ret; | ||
173 | } | ||
174 | |||
175 | static int af9013_statistics_snr_result(struct dvb_frontend *fe) | ||
176 | { | ||
177 | struct af9013_state *state = fe->demodulator_priv; | ||
178 | struct i2c_client *client = state->client; | ||
179 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
180 | int ret, i, len; | ||
181 | unsigned int utmp; | ||
182 | u8 buf[3]; | ||
183 | u32 snr_val; | ||
184 | const struct af9013_snr *uninitialized_var(snr_lut); | ||
185 | |||
186 | dev_dbg(&client->dev, "\n"); | ||
187 | |||
188 | /* check if SNR ready */ | ||
189 | ret = regmap_read(state->regmap, 0xd2e1, &utmp); | ||
190 | if (ret) | ||
191 | goto err; | ||
192 | |||
193 | if (!((utmp >> 3) & 0x01)) { | ||
194 | dev_dbg(&client->dev, "not ready\n"); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /* read value */ | ||
199 | ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3); | ||
200 | if (ret) | ||
201 | goto err; | ||
202 | |||
203 | snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
204 | |||
205 | /* read current modulation */ | ||
206 | ret = regmap_read(state->regmap, 0xd3c1, &utmp); | ||
207 | if (ret) | ||
208 | goto err; | ||
209 | |||
210 | switch ((utmp >> 6) & 3) { | ||
211 | case 0: | ||
212 | len = ARRAY_SIZE(qpsk_snr_lut); | ||
213 | snr_lut = qpsk_snr_lut; | ||
214 | break; | ||
215 | case 1: | ||
216 | len = ARRAY_SIZE(qam16_snr_lut); | ||
217 | snr_lut = qam16_snr_lut; | ||
218 | break; | ||
219 | case 2: | ||
220 | len = ARRAY_SIZE(qam64_snr_lut); | ||
221 | snr_lut = qam64_snr_lut; | ||
222 | break; | ||
223 | default: | ||
224 | goto err; | ||
225 | } | ||
226 | |||
227 | for (i = 0; i < len; i++) { | ||
228 | utmp = snr_lut[i].snr; | ||
229 | |||
230 | if (snr_val < snr_lut[i].val) | ||
231 | break; | ||
232 | } | ||
233 | state->snr = utmp * 10; /* dB/10 */ | ||
234 | |||
235 | c->cnr.stat[0].svalue = 1000 * utmp; | ||
236 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
237 | |||
238 | return 0; | ||
239 | err: | ||
240 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | static int af9013_statistics_signal_strength(struct dvb_frontend *fe) | ||
245 | { | ||
246 | struct af9013_state *state = fe->demodulator_priv; | ||
247 | struct i2c_client *client = state->client; | ||
248 | int ret = 0; | ||
249 | u8 buf[2], rf_gain, if_gain; | ||
250 | int signal_strength; | ||
251 | |||
252 | dev_dbg(&client->dev, "\n"); | ||
253 | |||
254 | if (!state->signal_strength_en) | ||
255 | return 0; | ||
256 | |||
257 | ret = regmap_bulk_read(state->regmap, 0xd07c, buf, 2); | ||
258 | if (ret) | ||
259 | goto err; | ||
260 | |||
261 | rf_gain = buf[0]; | ||
262 | if_gain = buf[1]; | ||
263 | |||
264 | signal_strength = (0xffff / \ | ||
265 | (9 * (state->rf_50 + state->if_50) - \ | ||
266 | 11 * (state->rf_80 + state->if_80))) * \ | ||
267 | (10 * (rf_gain + if_gain) - \ | ||
268 | 11 * (state->rf_80 + state->if_80)); | ||
269 | if (signal_strength < 0) | ||
270 | signal_strength = 0; | ||
271 | else if (signal_strength > 0xffff) | ||
272 | signal_strength = 0xffff; | ||
273 | |||
274 | state->signal_strength = signal_strength; | ||
275 | |||
276 | return 0; | ||
277 | err: | ||
278 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | static void af9013_statistics_work(struct work_struct *work) | ||
283 | { | ||
284 | struct af9013_state *state = container_of(work, | ||
285 | struct af9013_state, statistics_work.work); | ||
286 | unsigned int next_msec; | ||
287 | |||
288 | /* update only signal strength when demod is not locked */ | ||
289 | if (!(state->fe_status & FE_HAS_LOCK)) { | ||
290 | state->statistics_step = 0; | ||
291 | state->ber = 0; | ||
292 | state->snr = 0; | ||
293 | } | ||
294 | |||
295 | switch (state->statistics_step) { | ||
296 | default: | ||
297 | state->statistics_step = 0; | ||
298 | /* fall-through */ | ||
299 | case 0: | ||
300 | af9013_statistics_signal_strength(&state->fe); | ||
301 | state->statistics_step++; | ||
302 | next_msec = 300; | ||
303 | break; | ||
304 | case 1: | ||
305 | af9013_statistics_snr_start(&state->fe); | ||
306 | state->statistics_step++; | ||
307 | next_msec = 200; | ||
308 | break; | ||
309 | case 2: | ||
310 | af9013_statistics_ber_unc_start(&state->fe); | ||
311 | state->statistics_step++; | ||
312 | next_msec = 1000; | ||
313 | break; | ||
314 | case 3: | ||
315 | af9013_statistics_snr_result(&state->fe); | ||
316 | state->statistics_step++; | ||
317 | next_msec = 400; | ||
318 | break; | ||
319 | case 4: | ||
320 | af9013_statistics_ber_unc_result(&state->fe); | ||
321 | state->statistics_step++; | ||
322 | next_msec = 100; | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | schedule_delayed_work(&state->statistics_work, | ||
327 | msecs_to_jiffies(next_msec)); | ||
328 | } | ||
329 | |||
330 | static int af9013_get_tune_settings(struct dvb_frontend *fe, | 105 | static int af9013_get_tune_settings(struct dvb_frontend *fe, |
331 | struct dvb_frontend_tune_settings *fesettings) | 106 | struct dvb_frontend_tune_settings *fesettings) |
332 | { | 107 | { |
@@ -751,46 +526,273 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) | |||
751 | { | 526 | { |
752 | struct af9013_state *state = fe->demodulator_priv; | 527 | struct af9013_state *state = fe->demodulator_priv; |
753 | struct i2c_client *client = state->client; | 528 | struct i2c_client *client = state->client; |
754 | int ret; | 529 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
755 | unsigned int utmp; | 530 | int ret, stmp1; |
531 | unsigned int utmp, utmp1, utmp2, utmp3, utmp4; | ||
532 | u8 buf[7]; | ||
533 | |||
534 | dev_dbg(&client->dev, "\n"); | ||
756 | 535 | ||
757 | /* | 536 | /* |
758 | * Return status from the cache if it is younger than 2000ms with the | 537 | * Return status from the cache if it is younger than 2000ms with the |
759 | * exception of last tune is done during 4000ms. | 538 | * exception of last tune is done during 4000ms. |
760 | */ | 539 | */ |
761 | if (time_is_after_jiffies( | 540 | if (time_is_after_jiffies(state->read_status_jiffies + msecs_to_jiffies(2000)) && |
762 | state->read_status_jiffies + msecs_to_jiffies(2000)) && | 541 | time_is_before_jiffies(state->set_frontend_jiffies + msecs_to_jiffies(4000))) { |
763 | time_is_before_jiffies( | 542 | *status = state->fe_status; |
764 | state->set_frontend_jiffies + msecs_to_jiffies(4000)) | ||
765 | ) { | ||
766 | *status = state->fe_status; | ||
767 | return 0; | ||
768 | } else { | 543 | } else { |
769 | *status = 0; | 544 | /* MPEG2 lock */ |
545 | ret = regmap_read(state->regmap, 0xd507, &utmp); | ||
546 | if (ret) | ||
547 | goto err; | ||
548 | |||
549 | if ((utmp >> 6) & 0x01) { | ||
550 | utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
551 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
552 | } else { | ||
553 | /* TPS lock */ | ||
554 | ret = regmap_read(state->regmap, 0xd330, &utmp); | ||
555 | if (ret) | ||
556 | goto err; | ||
557 | |||
558 | if ((utmp >> 3) & 0x01) | ||
559 | utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
560 | FE_HAS_VITERBI; | ||
561 | else | ||
562 | utmp1 = 0; | ||
563 | } | ||
564 | |||
565 | dev_dbg(&client->dev, "fe_status %02x\n", utmp1); | ||
566 | |||
567 | state->read_status_jiffies = jiffies; | ||
568 | |||
569 | state->fe_status = utmp1; | ||
570 | *status = utmp1; | ||
770 | } | 571 | } |
771 | 572 | ||
772 | /* MPEG2 lock */ | 573 | /* Signal strength */ |
773 | ret = regmap_read(state->regmap, 0xd507, &utmp); | 574 | switch (state->strength_en) { |
774 | if (ret) | 575 | case 0: |
775 | goto err; | 576 | /* Check if we support signal strength */ |
577 | ret = regmap_read(state->regmap, 0x9bee, &utmp); | ||
578 | if (ret) | ||
579 | goto err; | ||
776 | 580 | ||
777 | if ((utmp >> 6) & 0x01) | 581 | if ((utmp >> 0) & 0x01) { |
778 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | | 582 | /* Read agc values for signal strength estimation */ |
779 | FE_HAS_SYNC | FE_HAS_LOCK; | 583 | ret = regmap_read(state->regmap, 0x9bbd, &utmp1); |
584 | if (ret) | ||
585 | goto err; | ||
586 | ret = regmap_read(state->regmap, 0x9bd0, &utmp2); | ||
587 | if (ret) | ||
588 | goto err; | ||
589 | ret = regmap_read(state->regmap, 0x9be2, &utmp3); | ||
590 | if (ret) | ||
591 | goto err; | ||
592 | ret = regmap_read(state->regmap, 0x9be4, &utmp4); | ||
593 | if (ret) | ||
594 | goto err; | ||
780 | 595 | ||
781 | if (!*status) { | 596 | state->rf_agc_50 = utmp1; |
782 | /* TPS lock */ | 597 | state->rf_agc_80 = utmp2; |
783 | ret = regmap_read(state->regmap, 0xd330, &utmp); | 598 | state->if_agc_50 = utmp3; |
599 | state->if_agc_80 = utmp4; | ||
600 | dev_dbg(&client->dev, | ||
601 | "rf_agc_50 %u, rf_agc_80 %u, if_agc_50 %u, if_agc_80 %u\n", | ||
602 | utmp1, utmp2, utmp3, utmp4); | ||
603 | |||
604 | state->strength_en = 1; | ||
605 | } else { | ||
606 | /* Signal strength is not supported */ | ||
607 | state->strength_en = 2; | ||
608 | break; | ||
609 | } | ||
610 | /* Fall through */ | ||
611 | case 1: | ||
612 | if (time_is_after_jiffies(state->strength_jiffies + msecs_to_jiffies(2000))) | ||
613 | break; | ||
614 | |||
615 | /* Read value */ | ||
616 | ret = regmap_bulk_read(state->regmap, 0xd07c, buf, 2); | ||
784 | if (ret) | 617 | if (ret) |
785 | goto err; | 618 | goto err; |
786 | 619 | ||
787 | if ((utmp >> 3) & 0x01) | 620 | /* |
788 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | 621 | * Construct line equation from tuner dependent -80/-50 dBm agc |
789 | FE_HAS_VITERBI; | 622 | * limits and use it to map current agc value to dBm estimate |
623 | */ | ||
624 | #define agc_gain (buf[0] + buf[1]) | ||
625 | #define agc_gain_50dbm (state->rf_agc_50 + state->if_agc_50) | ||
626 | #define agc_gain_80dbm (state->rf_agc_80 + state->if_agc_80) | ||
627 | stmp1 = 30000 * (agc_gain - agc_gain_80dbm) / | ||
628 | (agc_gain_50dbm - agc_gain_80dbm) - 80000; | ||
629 | |||
630 | dev_dbg(&client->dev, | ||
631 | "strength %d, agc_gain %d, agc_gain_50dbm %d, agc_gain_80dbm %d\n", | ||
632 | stmp1, agc_gain, agc_gain_50dbm, agc_gain_80dbm); | ||
633 | |||
634 | state->strength_jiffies = jiffies; | ||
635 | /* Convert [-90, -30] dBm to [0x0000, 0xffff] for dvbv3 */ | ||
636 | utmp1 = clamp(stmp1 + 90000, 0, 60000); | ||
637 | state->dvbv3_strength = div_u64((u64)utmp1 * 0xffff, 60000); | ||
638 | |||
639 | c->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||
640 | c->strength.stat[0].svalue = stmp1; | ||
641 | break; | ||
642 | default: | ||
643 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
644 | break; | ||
790 | } | 645 | } |
791 | 646 | ||
792 | state->fe_status = *status; | 647 | /* CNR */ |
793 | state->read_status_jiffies = jiffies; | 648 | switch (state->fe_status & FE_HAS_VITERBI) { |
649 | case FE_HAS_VITERBI: | ||
650 | if (time_is_after_jiffies(state->cnr_jiffies + msecs_to_jiffies(2000))) | ||
651 | break; | ||
652 | |||
653 | /* Check if cnr ready */ | ||
654 | ret = regmap_read(state->regmap, 0xd2e1, &utmp); | ||
655 | if (ret) | ||
656 | goto err; | ||
657 | |||
658 | if (!((utmp >> 3) & 0x01)) { | ||
659 | dev_dbg(&client->dev, "cnr not ready\n"); | ||
660 | break; | ||
661 | } | ||
662 | |||
663 | /* Read value */ | ||
664 | ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3); | ||
665 | if (ret) | ||
666 | goto err; | ||
667 | |||
668 | utmp1 = buf[2] << 16 | buf[1] << 8 | buf[0] << 0; | ||
669 | |||
670 | /* Read current modulation */ | ||
671 | ret = regmap_read(state->regmap, 0xd3c1, &utmp); | ||
672 | if (ret) | ||
673 | goto err; | ||
674 | |||
675 | switch ((utmp >> 6) & 3) { | ||
676 | case 0: | ||
677 | /* | ||
678 | * QPSK | ||
679 | * CNR[dB] 13 * -log10((1690000 - value) / value) + 2.6 | ||
680 | * value [653799, 1689999], 2.6 / 13 = 3355443 | ||
681 | */ | ||
682 | utmp1 = clamp(utmp1, 653799U, 1689999U); | ||
683 | utmp1 = ((u64)(intlog10(utmp1) | ||
684 | - intlog10(1690000 - utmp1) | ||
685 | + 3355443) * 13 * 1000) >> 24; | ||
686 | break; | ||
687 | case 1: | ||
688 | /* | ||
689 | * QAM-16 | ||
690 | * CNR[dB] 6 * log10((value - 370000) / (828000 - value)) + 15.7 | ||
691 | * value [371105, 827999], 15.7 / 6 = 43900382 | ||
692 | */ | ||
693 | utmp1 = clamp(utmp1, 371105U, 827999U); | ||
694 | utmp1 = ((u64)(intlog10(utmp1 - 370000) | ||
695 | - intlog10(828000 - utmp1) | ||
696 | + 43900382) * 6 * 1000) >> 24; | ||
697 | break; | ||
698 | case 2: | ||
699 | /* | ||
700 | * QAM-64 | ||
701 | * CNR[dB] 8 * log10((value - 193000) / (425000 - value)) + 23.8 | ||
702 | * value [193246, 424999], 23.8 / 8 = 49912218 | ||
703 | */ | ||
704 | utmp1 = clamp(utmp1, 193246U, 424999U); | ||
705 | utmp1 = ((u64)(intlog10(utmp1 - 193000) | ||
706 | - intlog10(425000 - utmp1) | ||
707 | + 49912218) * 8 * 1000) >> 24; | ||
708 | break; | ||
709 | default: | ||
710 | dev_dbg(&client->dev, "invalid modulation %u\n", | ||
711 | (utmp >> 6) & 3); | ||
712 | utmp1 = 0; | ||
713 | break; | ||
714 | } | ||
715 | |||
716 | dev_dbg(&client->dev, "cnr %u\n", utmp1); | ||
717 | |||
718 | state->cnr_jiffies = jiffies; | ||
719 | state->dvbv3_snr = utmp1 / 100; | ||
720 | |||
721 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
722 | c->cnr.stat[0].svalue = utmp1; | ||
723 | break; | ||
724 | default: | ||
725 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
726 | break; | ||
727 | } | ||
728 | |||
729 | /* BER / PER */ | ||
730 | switch (state->fe_status & FE_HAS_SYNC) { | ||
731 | case FE_HAS_SYNC: | ||
732 | if (time_is_after_jiffies(state->ber_ucb_jiffies + msecs_to_jiffies(2000))) | ||
733 | break; | ||
734 | |||
735 | /* Check if ber / ucb is ready */ | ||
736 | ret = regmap_read(state->regmap, 0xd391, &utmp); | ||
737 | if (ret) | ||
738 | goto err; | ||
739 | |||
740 | if (!((utmp >> 4) & 0x01)) { | ||
741 | dev_dbg(&client->dev, "ber not ready\n"); | ||
742 | break; | ||
743 | } | ||
744 | |||
745 | /* Read value */ | ||
746 | ret = regmap_bulk_read(state->regmap, 0xd385, buf, 7); | ||
747 | if (ret) | ||
748 | goto err; | ||
749 | |||
750 | utmp1 = buf[4] << 16 | buf[3] << 8 | buf[2] << 0; | ||
751 | utmp2 = (buf[1] << 8 | buf[0] << 0) * 204 * 8; | ||
752 | utmp3 = buf[6] << 8 | buf[5] << 0; | ||
753 | utmp4 = buf[1] << 8 | buf[0] << 0; | ||
754 | |||
755 | /* Use 10000 TS packets for measure */ | ||
756 | if (utmp4 != 10000) { | ||
757 | buf[0] = (10000 >> 0) & 0xff; | ||
758 | buf[1] = (10000 >> 8) & 0xff; | ||
759 | ret = regmap_bulk_write(state->regmap, 0xd385, buf, 2); | ||
760 | if (ret) | ||
761 | goto err; | ||
762 | } | ||
763 | |||
764 | /* Reset ber / ucb counter */ | ||
765 | ret = regmap_update_bits(state->regmap, 0xd391, 0x20, 0x20); | ||
766 | if (ret) | ||
767 | goto err; | ||
768 | |||
769 | dev_dbg(&client->dev, "post_bit_error %u, post_bit_count %u\n", | ||
770 | utmp1, utmp2); | ||
771 | dev_dbg(&client->dev, "block_error %u, block_count %u\n", | ||
772 | utmp3, utmp4); | ||
773 | |||
774 | state->ber_ucb_jiffies = jiffies; | ||
775 | state->dvbv3_ber = utmp1; | ||
776 | state->dvbv3_ucblocks += utmp3; | ||
777 | |||
778 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||
779 | c->post_bit_error.stat[0].uvalue += utmp1; | ||
780 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; | ||
781 | c->post_bit_count.stat[0].uvalue += utmp2; | ||
782 | |||
783 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; | ||
784 | c->block_error.stat[0].uvalue += utmp3; | ||
785 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; | ||
786 | c->block_count.stat[0].uvalue += utmp4; | ||
787 | break; | ||
788 | default: | ||
789 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
790 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
791 | |||
792 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
793 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
794 | break; | ||
795 | } | ||
794 | 796 | ||
795 | return 0; | 797 | return 0; |
796 | err: | 798 | err: |
@@ -801,28 +803,36 @@ err: | |||
801 | static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) | 803 | static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) |
802 | { | 804 | { |
803 | struct af9013_state *state = fe->demodulator_priv; | 805 | struct af9013_state *state = fe->demodulator_priv; |
804 | *snr = state->snr; | 806 | |
807 | *snr = state->dvbv3_snr; | ||
808 | |||
805 | return 0; | 809 | return 0; |
806 | } | 810 | } |
807 | 811 | ||
808 | static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | 812 | static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
809 | { | 813 | { |
810 | struct af9013_state *state = fe->demodulator_priv; | 814 | struct af9013_state *state = fe->demodulator_priv; |
811 | *strength = state->signal_strength; | 815 | |
816 | *strength = state->dvbv3_strength; | ||
817 | |||
812 | return 0; | 818 | return 0; |
813 | } | 819 | } |
814 | 820 | ||
815 | static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) | 821 | static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) |
816 | { | 822 | { |
817 | struct af9013_state *state = fe->demodulator_priv; | 823 | struct af9013_state *state = fe->demodulator_priv; |
818 | *ber = state->ber; | 824 | |
825 | *ber = state->dvbv3_ber; | ||
826 | |||
819 | return 0; | 827 | return 0; |
820 | } | 828 | } |
821 | 829 | ||
822 | static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 830 | static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
823 | { | 831 | { |
824 | struct af9013_state *state = fe->demodulator_priv; | 832 | struct af9013_state *state = fe->demodulator_priv; |
825 | *ucblocks = state->ucblocks; | 833 | |
834 | *ucblocks = state->dvbv3_ucblocks; | ||
835 | |||
826 | return 0; | 836 | return 0; |
827 | } | 837 | } |
828 | 838 | ||
@@ -833,7 +843,7 @@ static int af9013_init(struct dvb_frontend *fe) | |||
833 | int ret, i, len; | 843 | int ret, i, len; |
834 | unsigned int utmp; | 844 | unsigned int utmp; |
835 | u8 buf[3]; | 845 | u8 buf[3]; |
836 | const struct af9013_reg_bit *init; | 846 | const struct af9013_reg_mask_val *tab; |
837 | 847 | ||
838 | dev_dbg(&client->dev, "\n"); | 848 | dev_dbg(&client->dev, "\n"); |
839 | 849 | ||
@@ -888,72 +898,66 @@ static int af9013_init(struct dvb_frontend *fe) | |||
888 | if (ret) | 898 | if (ret) |
889 | goto err; | 899 | goto err; |
890 | 900 | ||
891 | /* load OFSM settings */ | 901 | /* Demod core settings */ |
892 | dev_dbg(&client->dev, "load ofsm settings\n"); | 902 | dev_dbg(&client->dev, "load demod core settings\n"); |
893 | len = ARRAY_SIZE(ofsm_init); | 903 | len = ARRAY_SIZE(demod_init_tab); |
894 | init = ofsm_init; | 904 | tab = demod_init_tab; |
895 | for (i = 0; i < len; i++) { | 905 | for (i = 0; i < len; i++) { |
896 | u16 reg = init[i].addr; | 906 | ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask, |
897 | u8 mask = GENMASK(init[i].pos + init[i].len - 1, init[i].pos); | 907 | tab[i].val); |
898 | u8 val = init[i].val << init[i].pos; | ||
899 | |||
900 | ret = regmap_update_bits(state->regmap, reg, mask, val); | ||
901 | if (ret) | 908 | if (ret) |
902 | goto err; | 909 | goto err; |
903 | } | 910 | } |
904 | 911 | ||
905 | /* load tuner specific settings */ | 912 | /* Demod tuner specific settings */ |
906 | dev_dbg(&client->dev, "load tuner specific settings\n"); | 913 | dev_dbg(&client->dev, "load tuner specific settings\n"); |
907 | switch (state->tuner) { | 914 | switch (state->tuner) { |
908 | case AF9013_TUNER_MXL5003D: | 915 | case AF9013_TUNER_MXL5003D: |
909 | len = ARRAY_SIZE(tuner_init_mxl5003d); | 916 | len = ARRAY_SIZE(tuner_init_tab_mxl5003d); |
910 | init = tuner_init_mxl5003d; | 917 | tab = tuner_init_tab_mxl5003d; |
911 | break; | 918 | break; |
912 | case AF9013_TUNER_MXL5005D: | 919 | case AF9013_TUNER_MXL5005D: |
913 | case AF9013_TUNER_MXL5005R: | 920 | case AF9013_TUNER_MXL5005R: |
914 | case AF9013_TUNER_MXL5007T: | 921 | case AF9013_TUNER_MXL5007T: |
915 | len = ARRAY_SIZE(tuner_init_mxl5005); | 922 | len = ARRAY_SIZE(tuner_init_tab_mxl5005); |
916 | init = tuner_init_mxl5005; | 923 | tab = tuner_init_tab_mxl5005; |
917 | break; | 924 | break; |
918 | case AF9013_TUNER_ENV77H11D5: | 925 | case AF9013_TUNER_ENV77H11D5: |
919 | len = ARRAY_SIZE(tuner_init_env77h11d5); | 926 | len = ARRAY_SIZE(tuner_init_tab_env77h11d5); |
920 | init = tuner_init_env77h11d5; | 927 | tab = tuner_init_tab_env77h11d5; |
921 | break; | 928 | break; |
922 | case AF9013_TUNER_MT2060: | 929 | case AF9013_TUNER_MT2060: |
923 | len = ARRAY_SIZE(tuner_init_mt2060); | 930 | len = ARRAY_SIZE(tuner_init_tab_mt2060); |
924 | init = tuner_init_mt2060; | 931 | tab = tuner_init_tab_mt2060; |
925 | break; | 932 | break; |
926 | case AF9013_TUNER_MC44S803: | 933 | case AF9013_TUNER_MC44S803: |
927 | len = ARRAY_SIZE(tuner_init_mc44s803); | 934 | len = ARRAY_SIZE(tuner_init_tab_mc44s803); |
928 | init = tuner_init_mc44s803; | 935 | tab = tuner_init_tab_mc44s803; |
929 | break; | 936 | break; |
930 | case AF9013_TUNER_QT1010: | 937 | case AF9013_TUNER_QT1010: |
931 | case AF9013_TUNER_QT1010A: | 938 | case AF9013_TUNER_QT1010A: |
932 | len = ARRAY_SIZE(tuner_init_qt1010); | 939 | len = ARRAY_SIZE(tuner_init_tab_qt1010); |
933 | init = tuner_init_qt1010; | 940 | tab = tuner_init_tab_qt1010; |
934 | break; | 941 | break; |
935 | case AF9013_TUNER_MT2060_2: | 942 | case AF9013_TUNER_MT2060_2: |
936 | len = ARRAY_SIZE(tuner_init_mt2060_2); | 943 | len = ARRAY_SIZE(tuner_init_tab_mt2060_2); |
937 | init = tuner_init_mt2060_2; | 944 | tab = tuner_init_tab_mt2060_2; |
938 | break; | 945 | break; |
939 | case AF9013_TUNER_TDA18271: | 946 | case AF9013_TUNER_TDA18271: |
940 | case AF9013_TUNER_TDA18218: | 947 | case AF9013_TUNER_TDA18218: |
941 | len = ARRAY_SIZE(tuner_init_tda18271); | 948 | len = ARRAY_SIZE(tuner_init_tab_tda18271); |
942 | init = tuner_init_tda18271; | 949 | tab = tuner_init_tab_tda18271; |
943 | break; | 950 | break; |
944 | case AF9013_TUNER_UNKNOWN: | 951 | case AF9013_TUNER_UNKNOWN: |
945 | default: | 952 | default: |
946 | len = ARRAY_SIZE(tuner_init_unknown); | 953 | len = ARRAY_SIZE(tuner_init_tab_unknown); |
947 | init = tuner_init_unknown; | 954 | tab = tuner_init_tab_unknown; |
948 | break; | 955 | break; |
949 | } | 956 | } |
950 | 957 | ||
951 | for (i = 0; i < len; i++) { | 958 | for (i = 0; i < len; i++) { |
952 | u16 reg = init[i].addr; | 959 | ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask, |
953 | u8 mask = GENMASK(init[i].pos + init[i].len - 1, init[i].pos); | 960 | tab[i].val); |
954 | u8 val = init[i].val << init[i].pos; | ||
955 | |||
956 | ret = regmap_update_bits(state->regmap, reg, mask, val); | ||
957 | if (ret) | 961 | if (ret) |
958 | goto err; | 962 | goto err; |
959 | } | 963 | } |
@@ -972,50 +976,7 @@ static int af9013_init(struct dvb_frontend *fe) | |||
972 | if (ret) | 976 | if (ret) |
973 | goto err; | 977 | goto err; |
974 | 978 | ||
975 | /* check if we support signal strength */ | ||
976 | if (!state->signal_strength_en) { | ||
977 | ret = regmap_read(state->regmap, 0x9bee, &utmp); | ||
978 | if (ret) | ||
979 | goto err; | ||
980 | |||
981 | state->signal_strength_en = (utmp >> 0) & 0x01; | ||
982 | } | ||
983 | |||
984 | /* read values needed for signal strength calculation */ | ||
985 | if (state->signal_strength_en && !state->rf_50) { | ||
986 | ret = regmap_bulk_read(state->regmap, 0x9bbd, &state->rf_50, 1); | ||
987 | if (ret) | ||
988 | goto err; | ||
989 | ret = regmap_bulk_read(state->regmap, 0x9bd0, &state->rf_80, 1); | ||
990 | if (ret) | ||
991 | goto err; | ||
992 | ret = regmap_bulk_read(state->regmap, 0x9be2, &state->if_50, 1); | ||
993 | if (ret) | ||
994 | goto err; | ||
995 | ret = regmap_bulk_read(state->regmap, 0x9be4, &state->if_80, 1); | ||
996 | if (ret) | ||
997 | goto err; | ||
998 | } | ||
999 | |||
1000 | /* SNR */ | ||
1001 | ret = regmap_write(state->regmap, 0xd2e2, 0x01); | ||
1002 | if (ret) | ||
1003 | goto err; | ||
1004 | |||
1005 | /* BER / UCB */ | ||
1006 | buf[0] = (10000 >> 0) & 0xff; | ||
1007 | buf[1] = (10000 >> 8) & 0xff; | ||
1008 | ret = regmap_bulk_write(state->regmap, 0xd385, buf, 2); | ||
1009 | if (ret) | ||
1010 | goto err; | ||
1011 | |||
1012 | /* enable FEC monitor */ | ||
1013 | ret = regmap_update_bits(state->regmap, 0xd392, 0x02, 0x02); | ||
1014 | if (ret) | ||
1015 | goto err; | ||
1016 | |||
1017 | state->first_tune = true; | 979 | state->first_tune = true; |
1018 | schedule_delayed_work(&state->statistics_work, msecs_to_jiffies(400)); | ||
1019 | 980 | ||
1020 | return 0; | 981 | return 0; |
1021 | err: | 982 | err: |
@@ -1032,9 +993,6 @@ static int af9013_sleep(struct dvb_frontend *fe) | |||
1032 | 993 | ||
1033 | dev_dbg(&client->dev, "\n"); | 994 | dev_dbg(&client->dev, "\n"); |
1034 | 995 | ||
1035 | /* stop statistics polling */ | ||
1036 | cancel_delayed_work_sync(&state->statistics_work); | ||
1037 | |||
1038 | /* disable lock led */ | 996 | /* disable lock led */ |
1039 | ret = regmap_update_bits(state->regmap, 0xd730, 0x01, 0x00); | 997 | ret = regmap_update_bits(state->regmap, 0xd730, 0x01, 0x00); |
1040 | if (ret) | 998 | if (ret) |
@@ -1072,45 +1030,6 @@ err: | |||
1072 | return ret; | 1030 | return ret; |
1073 | } | 1031 | } |
1074 | 1032 | ||
1075 | static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
1076 | { | ||
1077 | int ret; | ||
1078 | struct af9013_state *state = fe->demodulator_priv; | ||
1079 | struct i2c_client *client = state->client; | ||
1080 | |||
1081 | dev_dbg(&client->dev, "enable %d\n", enable); | ||
1082 | |||
1083 | /* gate already open or close */ | ||
1084 | if (state->i2c_gate_state == enable) | ||
1085 | return 0; | ||
1086 | |||
1087 | if (state->ts_mode == AF9013_TS_MODE_USB) | ||
1088 | ret = regmap_update_bits(state->regmap, 0xd417, 0x08, | ||
1089 | enable << 3); | ||
1090 | else | ||
1091 | ret = regmap_update_bits(state->regmap, 0xd607, 0x04, | ||
1092 | enable << 2); | ||
1093 | if (ret) | ||
1094 | goto err; | ||
1095 | |||
1096 | state->i2c_gate_state = enable; | ||
1097 | |||
1098 | return 0; | ||
1099 | err: | ||
1100 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
1101 | return ret; | ||
1102 | } | ||
1103 | |||
1104 | static void af9013_release(struct dvb_frontend *fe) | ||
1105 | { | ||
1106 | struct af9013_state *state = fe->demodulator_priv; | ||
1107 | struct i2c_client *client = state->client; | ||
1108 | |||
1109 | dev_dbg(&client->dev, "\n"); | ||
1110 | |||
1111 | i2c_unregister_device(client); | ||
1112 | } | ||
1113 | |||
1114 | static const struct dvb_frontend_ops af9013_ops; | 1033 | static const struct dvb_frontend_ops af9013_ops; |
1115 | 1034 | ||
1116 | static int af9013_download_firmware(struct af9013_state *state) | 1035 | static int af9013_download_firmware(struct af9013_state *state) |
@@ -1213,40 +1132,6 @@ err: | |||
1213 | return ret; | 1132 | return ret; |
1214 | } | 1133 | } |
1215 | 1134 | ||
1216 | /* | ||
1217 | * XXX: That is wrapper to af9013_probe() via driver core in order to provide | ||
1218 | * proper I2C client for legacy media attach binding. | ||
1219 | * New users must use I2C client binding directly! | ||
1220 | */ | ||
1221 | struct dvb_frontend *af9013_attach(const struct af9013_config *config, | ||
1222 | struct i2c_adapter *i2c) | ||
1223 | { | ||
1224 | struct i2c_client *client; | ||
1225 | struct i2c_board_info board_info; | ||
1226 | struct af9013_platform_data pdata; | ||
1227 | |||
1228 | pdata.clk = config->clock; | ||
1229 | pdata.tuner = config->tuner; | ||
1230 | pdata.if_frequency = config->if_frequency; | ||
1231 | pdata.ts_mode = config->ts_mode; | ||
1232 | pdata.ts_output_pin = 7; | ||
1233 | pdata.spec_inv = config->spec_inv; | ||
1234 | memcpy(&pdata.api_version, config->api_version, sizeof(pdata.api_version)); | ||
1235 | memcpy(&pdata.gpio, config->gpio, sizeof(pdata.gpio)); | ||
1236 | pdata.attach_in_use = true; | ||
1237 | |||
1238 | memset(&board_info, 0, sizeof(board_info)); | ||
1239 | strlcpy(board_info.type, "af9013", sizeof(board_info.type)); | ||
1240 | board_info.addr = config->i2c_addr; | ||
1241 | board_info.platform_data = &pdata; | ||
1242 | client = i2c_new_device(i2c, &board_info); | ||
1243 | if (!client || !client->dev.driver) | ||
1244 | return NULL; | ||
1245 | |||
1246 | return pdata.get_dvb_frontend(client); | ||
1247 | } | ||
1248 | EXPORT_SYMBOL(af9013_attach); | ||
1249 | |||
1250 | static const struct dvb_frontend_ops af9013_ops = { | 1135 | static const struct dvb_frontend_ops af9013_ops = { |
1251 | .delsys = { SYS_DVBT }, | 1136 | .delsys = { SYS_DVBT }, |
1252 | .info = { | 1137 | .info = { |
@@ -1272,8 +1157,6 @@ static const struct dvb_frontend_ops af9013_ops = { | |||
1272 | FE_CAN_MUTE_TS | 1157 | FE_CAN_MUTE_TS |
1273 | }, | 1158 | }, |
1274 | 1159 | ||
1275 | .release = af9013_release, | ||
1276 | |||
1277 | .init = af9013_init, | 1160 | .init = af9013_init, |
1278 | .sleep = af9013_sleep, | 1161 | .sleep = af9013_sleep, |
1279 | 1162 | ||
@@ -1286,10 +1169,58 @@ static const struct dvb_frontend_ops af9013_ops = { | |||
1286 | .read_signal_strength = af9013_read_signal_strength, | 1169 | .read_signal_strength = af9013_read_signal_strength, |
1287 | .read_ber = af9013_read_ber, | 1170 | .read_ber = af9013_read_ber, |
1288 | .read_ucblocks = af9013_read_ucblocks, | 1171 | .read_ucblocks = af9013_read_ucblocks, |
1289 | |||
1290 | .i2c_gate_ctrl = af9013_i2c_gate_ctrl, | ||
1291 | }; | 1172 | }; |
1292 | 1173 | ||
1174 | static int af9013_pid_filter_ctrl(struct dvb_frontend *fe, int onoff) | ||
1175 | { | ||
1176 | struct af9013_state *state = fe->demodulator_priv; | ||
1177 | struct i2c_client *client = state->client; | ||
1178 | int ret; | ||
1179 | |||
1180 | dev_dbg(&client->dev, "onoff %d\n", onoff); | ||
1181 | |||
1182 | ret = regmap_update_bits(state->regmap, 0xd503, 0x01, onoff); | ||
1183 | if (ret) | ||
1184 | goto err; | ||
1185 | |||
1186 | return 0; | ||
1187 | err: | ||
1188 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
1189 | return ret; | ||
1190 | } | ||
1191 | |||
1192 | static int af9013_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, | ||
1193 | int onoff) | ||
1194 | { | ||
1195 | struct af9013_state *state = fe->demodulator_priv; | ||
1196 | struct i2c_client *client = state->client; | ||
1197 | int ret; | ||
1198 | u8 buf[2]; | ||
1199 | |||
1200 | dev_dbg(&client->dev, "index %d, pid %04x, onoff %d\n", | ||
1201 | index, pid, onoff); | ||
1202 | |||
1203 | if (pid > 0x1fff) { | ||
1204 | /* 0x2000 is kernel virtual pid for whole ts (all pids) */ | ||
1205 | ret = 0; | ||
1206 | goto err; | ||
1207 | } | ||
1208 | |||
1209 | buf[0] = (pid >> 0) & 0xff; | ||
1210 | buf[1] = (pid >> 8) & 0xff; | ||
1211 | ret = regmap_bulk_write(state->regmap, 0xd505, buf, 2); | ||
1212 | if (ret) | ||
1213 | goto err; | ||
1214 | ret = regmap_write(state->regmap, 0xd504, onoff << 5 | index << 0); | ||
1215 | if (ret) | ||
1216 | goto err; | ||
1217 | |||
1218 | return 0; | ||
1219 | err: | ||
1220 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
1221 | return ret; | ||
1222 | } | ||
1223 | |||
1293 | static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) | 1224 | static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) |
1294 | { | 1225 | { |
1295 | struct af9013_state *state = i2c_get_clientdata(client); | 1226 | struct af9013_state *state = i2c_get_clientdata(client); |
@@ -1299,9 +1230,65 @@ static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) | |||
1299 | return &state->fe; | 1230 | return &state->fe; |
1300 | } | 1231 | } |
1301 | 1232 | ||
1233 | static struct i2c_adapter *af9013_get_i2c_adapter(struct i2c_client *client) | ||
1234 | { | ||
1235 | struct af9013_state *state = i2c_get_clientdata(client); | ||
1236 | |||
1237 | dev_dbg(&client->dev, "\n"); | ||
1238 | |||
1239 | return state->muxc->adapter[0]; | ||
1240 | } | ||
1241 | |||
1242 | /* | ||
1243 | * XXX: Hackish solution. We use virtual register, reg bit 16, to carry info | ||
1244 | * about i2c adapter locking. Own locking is needed because i2c mux call has | ||
1245 | * already locked i2c adapter. | ||
1246 | */ | ||
1247 | static int af9013_select(struct i2c_mux_core *muxc, u32 chan) | ||
1248 | { | ||
1249 | struct af9013_state *state = i2c_mux_priv(muxc); | ||
1250 | struct i2c_client *client = state->client; | ||
1251 | int ret; | ||
1252 | |||
1253 | dev_dbg(&client->dev, "\n"); | ||
1254 | |||
1255 | if (state->ts_mode == AF9013_TS_MODE_USB) | ||
1256 | ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x08); | ||
1257 | else | ||
1258 | ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x04); | ||
1259 | if (ret) | ||
1260 | goto err; | ||
1261 | |||
1262 | return 0; | ||
1263 | err: | ||
1264 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
1265 | return ret; | ||
1266 | } | ||
1267 | |||
1268 | static int af9013_deselect(struct i2c_mux_core *muxc, u32 chan) | ||
1269 | { | ||
1270 | struct af9013_state *state = i2c_mux_priv(muxc); | ||
1271 | struct i2c_client *client = state->client; | ||
1272 | int ret; | ||
1273 | |||
1274 | dev_dbg(&client->dev, "\n"); | ||
1275 | |||
1276 | if (state->ts_mode == AF9013_TS_MODE_USB) | ||
1277 | ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x00); | ||
1278 | else | ||
1279 | ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x00); | ||
1280 | if (ret) | ||
1281 | goto err; | ||
1282 | |||
1283 | return 0; | ||
1284 | err: | ||
1285 | dev_dbg(&client->dev, "failed %d\n", ret); | ||
1286 | return ret; | ||
1287 | } | ||
1288 | |||
1302 | /* Own I2C access routines needed for regmap as chip uses extra command byte */ | 1289 | /* Own I2C access routines needed for regmap as chip uses extra command byte */ |
1303 | static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, | 1290 | static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, |
1304 | const u8 *val, int len) | 1291 | const u8 *val, int len, u8 lock) |
1305 | { | 1292 | { |
1306 | int ret; | 1293 | int ret; |
1307 | u8 buf[21]; | 1294 | u8 buf[21]; |
@@ -1323,7 +1310,12 @@ static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, | |||
1323 | buf[1] = (reg >> 0) & 0xff; | 1310 | buf[1] = (reg >> 0) & 0xff; |
1324 | buf[2] = cmd; | 1311 | buf[2] = cmd; |
1325 | memcpy(&buf[3], val, len); | 1312 | memcpy(&buf[3], val, len); |
1326 | ret = i2c_transfer(client->adapter, msg, 1); | 1313 | |
1314 | if (lock) | ||
1315 | i2c_lock_adapter(client->adapter); | ||
1316 | ret = __i2c_transfer(client->adapter, msg, 1); | ||
1317 | if (lock) | ||
1318 | i2c_unlock_adapter(client->adapter); | ||
1327 | if (ret < 0) { | 1319 | if (ret < 0) { |
1328 | goto err; | 1320 | goto err; |
1329 | } else if (ret != 1) { | 1321 | } else if (ret != 1) { |
@@ -1338,7 +1330,7 @@ err: | |||
1338 | } | 1330 | } |
1339 | 1331 | ||
1340 | static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg, | 1332 | static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg, |
1341 | u8 *val, int len) | 1333 | u8 *val, int len, u8 lock) |
1342 | { | 1334 | { |
1343 | int ret; | 1335 | int ret; |
1344 | u8 buf[3]; | 1336 | u8 buf[3]; |
@@ -1359,7 +1351,12 @@ static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg, | |||
1359 | buf[0] = (reg >> 8) & 0xff; | 1351 | buf[0] = (reg >> 8) & 0xff; |
1360 | buf[1] = (reg >> 0) & 0xff; | 1352 | buf[1] = (reg >> 0) & 0xff; |
1361 | buf[2] = cmd; | 1353 | buf[2] = cmd; |
1362 | ret = i2c_transfer(client->adapter, msg, 2); | 1354 | |
1355 | if (lock) | ||
1356 | i2c_lock_adapter(client->adapter); | ||
1357 | ret = __i2c_transfer(client->adapter, msg, 2); | ||
1358 | if (lock) | ||
1359 | i2c_unlock_adapter(client->adapter); | ||
1363 | if (ret < 0) { | 1360 | if (ret < 0) { |
1364 | goto err; | 1361 | goto err; |
1365 | } else if (ret != 2) { | 1362 | } else if (ret != 2) { |
@@ -1379,25 +1376,27 @@ static int af9013_regmap_write(void *context, const void *data, size_t count) | |||
1379 | struct af9013_state *state = i2c_get_clientdata(client); | 1376 | struct af9013_state *state = i2c_get_clientdata(client); |
1380 | int ret, i; | 1377 | int ret, i; |
1381 | u8 cmd; | 1378 | u8 cmd; |
1382 | u16 reg = ((u8 *)data)[0] << 8|((u8 *)data)[1] << 0; | 1379 | u8 lock = !((u8 *)data)[0]; |
1383 | u8 *val = &((u8 *)data)[2]; | 1380 | u16 reg = ((u8 *)data)[1] << 8 | ((u8 *)data)[2] << 0; |
1384 | const unsigned int len = count - 2; | 1381 | u8 *val = &((u8 *)data)[3]; |
1382 | const unsigned int len = count - 3; | ||
1385 | 1383 | ||
1386 | if (state->ts_mode == AF9013_TS_MODE_USB && (reg & 0xff00) != 0xae00) { | 1384 | if (state->ts_mode == AF9013_TS_MODE_USB && (reg & 0xff00) != 0xae00) { |
1387 | cmd = 0 << 7|0 << 6|(len - 1) << 2|1 << 1|1 << 0; | 1385 | cmd = 0 << 7|0 << 6|(len - 1) << 2|1 << 1|1 << 0; |
1388 | ret = af9013_wregs(client, cmd, reg, val, len); | 1386 | ret = af9013_wregs(client, cmd, reg, val, len, lock); |
1389 | if (ret) | 1387 | if (ret) |
1390 | goto err; | 1388 | goto err; |
1391 | } else if (reg >= 0x5100 && reg < 0x8fff) { | 1389 | } else if (reg >= 0x5100 && reg < 0x8fff) { |
1392 | /* Firmware download */ | 1390 | /* Firmware download */ |
1393 | cmd = 1 << 7|1 << 6|(len - 1) << 2|1 << 1|1 << 0; | 1391 | cmd = 1 << 7|1 << 6|(len - 1) << 2|1 << 1|1 << 0; |
1394 | ret = af9013_wregs(client, cmd, reg, val, len); | 1392 | ret = af9013_wregs(client, cmd, reg, val, len, lock); |
1395 | if (ret) | 1393 | if (ret) |
1396 | goto err; | 1394 | goto err; |
1397 | } else { | 1395 | } else { |
1398 | cmd = 0 << 7|0 << 6|(1 - 1) << 2|1 << 1|1 << 0; | 1396 | cmd = 0 << 7|0 << 6|(1 - 1) << 2|1 << 1|1 << 0; |
1399 | for (i = 0; i < len; i++) { | 1397 | for (i = 0; i < len; i++) { |
1400 | ret = af9013_wregs(client, cmd, reg + i, val + i, 1); | 1398 | ret = af9013_wregs(client, cmd, reg + i, val + i, 1, |
1399 | lock); | ||
1401 | if (ret) | 1400 | if (ret) |
1402 | goto err; | 1401 | goto err; |
1403 | } | 1402 | } |
@@ -1416,19 +1415,21 @@ static int af9013_regmap_read(void *context, const void *reg_buf, | |||
1416 | struct af9013_state *state = i2c_get_clientdata(client); | 1415 | struct af9013_state *state = i2c_get_clientdata(client); |
1417 | int ret, i; | 1416 | int ret, i; |
1418 | u8 cmd; | 1417 | u8 cmd; |
1419 | u16 reg = ((u8 *)reg_buf)[0] << 8|((u8 *)reg_buf)[1] << 0; | 1418 | u8 lock = !((u8 *)reg_buf)[0]; |
1419 | u16 reg = ((u8 *)reg_buf)[1] << 8 | ((u8 *)reg_buf)[2] << 0; | ||
1420 | u8 *val = &((u8 *)val_buf)[0]; | 1420 | u8 *val = &((u8 *)val_buf)[0]; |
1421 | const unsigned int len = val_size; | 1421 | const unsigned int len = val_size; |
1422 | 1422 | ||
1423 | if (state->ts_mode == AF9013_TS_MODE_USB && (reg & 0xff00) != 0xae00) { | 1423 | if (state->ts_mode == AF9013_TS_MODE_USB && (reg & 0xff00) != 0xae00) { |
1424 | cmd = 0 << 7|0 << 6|(len - 1) << 2|1 << 1|0 << 0; | 1424 | cmd = 0 << 7|0 << 6|(len - 1) << 2|1 << 1|0 << 0; |
1425 | ret = af9013_rregs(client, cmd, reg, val_buf, len); | 1425 | ret = af9013_rregs(client, cmd, reg, val_buf, len, lock); |
1426 | if (ret) | 1426 | if (ret) |
1427 | goto err; | 1427 | goto err; |
1428 | } else { | 1428 | } else { |
1429 | cmd = 0 << 7|0 << 6|(1 - 1) << 2|1 << 1|0 << 0; | 1429 | cmd = 0 << 7|0 << 6|(1 - 1) << 2|1 << 1|0 << 0; |
1430 | for (i = 0; i < len; i++) { | 1430 | for (i = 0; i < len; i++) { |
1431 | ret = af9013_rregs(client, cmd, reg + i, val + i, 1); | 1431 | ret = af9013_rregs(client, cmd, reg + i, val + i, 1, |
1432 | lock); | ||
1432 | if (ret) | 1433 | if (ret) |
1433 | goto err; | 1434 | goto err; |
1434 | } | 1435 | } |
@@ -1453,8 +1454,9 @@ static int af9013_probe(struct i2c_client *client, | |||
1453 | .write = af9013_regmap_write, | 1454 | .write = af9013_regmap_write, |
1454 | }; | 1455 | }; |
1455 | static const struct regmap_config regmap_config = { | 1456 | static const struct regmap_config regmap_config = { |
1456 | .reg_bits = 16, | 1457 | /* Actual reg is 16 bits, see i2c adapter lock */ |
1457 | .val_bits = 8, | 1458 | .reg_bits = 24, |
1459 | .val_bits = 8, | ||
1458 | }; | 1460 | }; |
1459 | 1461 | ||
1460 | state = kzalloc(sizeof(*state), GFP_KERNEL); | 1462 | state = kzalloc(sizeof(*state), GFP_KERNEL); |
@@ -1463,6 +1465,8 @@ static int af9013_probe(struct i2c_client *client, | |||
1463 | goto err; | 1465 | goto err; |
1464 | } | 1466 | } |
1465 | 1467 | ||
1468 | dev_dbg(&client->dev, "\n"); | ||
1469 | |||
1466 | /* Setup the state */ | 1470 | /* Setup the state */ |
1467 | state->client = client; | 1471 | state->client = client; |
1468 | i2c_set_clientdata(client, state); | 1472 | i2c_set_clientdata(client, state); |
@@ -1474,52 +1478,70 @@ static int af9013_probe(struct i2c_client *client, | |||
1474 | state->spec_inv = pdata->spec_inv; | 1478 | state->spec_inv = pdata->spec_inv; |
1475 | memcpy(&state->api_version, pdata->api_version, sizeof(state->api_version)); | 1479 | memcpy(&state->api_version, pdata->api_version, sizeof(state->api_version)); |
1476 | memcpy(&state->gpio, pdata->gpio, sizeof(state->gpio)); | 1480 | memcpy(&state->gpio, pdata->gpio, sizeof(state->gpio)); |
1477 | INIT_DELAYED_WORK(&state->statistics_work, af9013_statistics_work); | ||
1478 | state->regmap = regmap_init(&client->dev, ®map_bus, client, | 1481 | state->regmap = regmap_init(&client->dev, ®map_bus, client, |
1479 | ®map_config); | 1482 | ®map_config); |
1480 | if (IS_ERR(state->regmap)) { | 1483 | if (IS_ERR(state->regmap)) { |
1481 | ret = PTR_ERR(state->regmap); | 1484 | ret = PTR_ERR(state->regmap); |
1482 | goto err_kfree; | 1485 | goto err_kfree; |
1483 | } | 1486 | } |
1487 | /* Create mux i2c adapter */ | ||
1488 | state->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, 0, | ||
1489 | af9013_select, af9013_deselect); | ||
1490 | if (!state->muxc) { | ||
1491 | ret = -ENOMEM; | ||
1492 | goto err_regmap_exit; | ||
1493 | } | ||
1494 | state->muxc->priv = state; | ||
1495 | ret = i2c_mux_add_adapter(state->muxc, 0, 0, 0); | ||
1496 | if (ret) | ||
1497 | goto err_regmap_exit; | ||
1484 | 1498 | ||
1485 | /* Download firmware */ | 1499 | /* Download firmware */ |
1486 | if (state->ts_mode != AF9013_TS_MODE_USB) { | 1500 | if (state->ts_mode != AF9013_TS_MODE_USB) { |
1487 | ret = af9013_download_firmware(state); | 1501 | ret = af9013_download_firmware(state); |
1488 | if (ret) | 1502 | if (ret) |
1489 | goto err_regmap_exit; | 1503 | goto err_i2c_mux_del_adapters; |
1490 | } | 1504 | } |
1491 | 1505 | ||
1492 | /* Firmware version */ | 1506 | /* Firmware version */ |
1493 | ret = regmap_bulk_read(state->regmap, 0x5103, firmware_version, | 1507 | ret = regmap_bulk_read(state->regmap, 0x5103, firmware_version, |
1494 | sizeof(firmware_version)); | 1508 | sizeof(firmware_version)); |
1495 | if (ret) | 1509 | if (ret) |
1496 | goto err_regmap_exit; | 1510 | goto err_i2c_mux_del_adapters; |
1497 | 1511 | ||
1498 | /* Set GPIOs */ | 1512 | /* Set GPIOs */ |
1499 | for (i = 0; i < sizeof(state->gpio); i++) { | 1513 | for (i = 0; i < sizeof(state->gpio); i++) { |
1500 | ret = af9013_set_gpio(state, i, state->gpio[i]); | 1514 | ret = af9013_set_gpio(state, i, state->gpio[i]); |
1501 | if (ret) | 1515 | if (ret) |
1502 | goto err_regmap_exit; | 1516 | goto err_i2c_mux_del_adapters; |
1503 | } | 1517 | } |
1504 | 1518 | ||
1505 | /* Create dvb frontend */ | 1519 | /* Create dvb frontend */ |
1506 | memcpy(&state->fe.ops, &af9013_ops, sizeof(state->fe.ops)); | 1520 | memcpy(&state->fe.ops, &af9013_ops, sizeof(state->fe.ops)); |
1507 | if (!pdata->attach_in_use) | ||
1508 | state->fe.ops.release = NULL; | ||
1509 | state->fe.demodulator_priv = state; | 1521 | state->fe.demodulator_priv = state; |
1510 | 1522 | ||
1511 | /* Setup callbacks */ | 1523 | /* Setup callbacks */ |
1512 | pdata->get_dvb_frontend = af9013_get_dvb_frontend; | 1524 | pdata->get_dvb_frontend = af9013_get_dvb_frontend; |
1525 | pdata->get_i2c_adapter = af9013_get_i2c_adapter; | ||
1526 | pdata->pid_filter = af9013_pid_filter; | ||
1527 | pdata->pid_filter_ctrl = af9013_pid_filter_ctrl; | ||
1513 | 1528 | ||
1514 | /* Init stats to indicate which stats are supported */ | 1529 | /* Init stats to indicate which stats are supported */ |
1515 | c = &state->fe.dtv_property_cache; | 1530 | c = &state->fe.dtv_property_cache; |
1531 | c->strength.len = 1; | ||
1516 | c->cnr.len = 1; | 1532 | c->cnr.len = 1; |
1533 | c->post_bit_error.len = 1; | ||
1534 | c->post_bit_count.len = 1; | ||
1535 | c->block_error.len = 1; | ||
1536 | c->block_count.len = 1; | ||
1517 | 1537 | ||
1518 | dev_info(&client->dev, "Afatech AF9013 successfully attached\n"); | 1538 | dev_info(&client->dev, "Afatech AF9013 successfully attached\n"); |
1519 | dev_info(&client->dev, "firmware version: %d.%d.%d.%d\n", | 1539 | dev_info(&client->dev, "firmware version: %d.%d.%d.%d\n", |
1520 | firmware_version[0], firmware_version[1], | 1540 | firmware_version[0], firmware_version[1], |
1521 | firmware_version[2], firmware_version[3]); | 1541 | firmware_version[2], firmware_version[3]); |
1522 | return 0; | 1542 | return 0; |
1543 | err_i2c_mux_del_adapters: | ||
1544 | i2c_mux_del_adapters(state->muxc); | ||
1523 | err_regmap_exit: | 1545 | err_regmap_exit: |
1524 | regmap_exit(state->regmap); | 1546 | regmap_exit(state->regmap); |
1525 | err_kfree: | 1547 | err_kfree: |
@@ -1535,8 +1557,7 @@ static int af9013_remove(struct i2c_client *client) | |||
1535 | 1557 | ||
1536 | dev_dbg(&client->dev, "\n"); | 1558 | dev_dbg(&client->dev, "\n"); |
1537 | 1559 | ||
1538 | /* Stop statistics polling */ | 1560 | i2c_mux_del_adapters(state->muxc); |
1539 | cancel_delayed_work_sync(&state->statistics_work); | ||
1540 | 1561 | ||
1541 | regmap_exit(state->regmap); | 1562 | regmap_exit(state->regmap); |
1542 | 1563 | ||
diff --git a/drivers/media/dvb-frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h index a290722c04fd..165ae29ccac4 100644 --- a/drivers/media/dvb-frontends/af9013.h +++ b/drivers/media/dvb-frontends/af9013.h | |||
@@ -38,13 +38,9 @@ | |||
38 | * @api_version: Firmware API version. | 38 | * @api_version: Firmware API version. |
39 | * @gpio: GPIOs. | 39 | * @gpio: GPIOs. |
40 | * @get_dvb_frontend: Get DVB frontend callback. | 40 | * @get_dvb_frontend: Get DVB frontend callback. |
41 | * | 41 | * @get_i2c_adapter: Get I2C adapter. |
42 | * AF9013/5 GPIOs (mostly guessed): | 42 | * @pid_filter_ctrl: Control PID filter. |
43 | * * demod#1-gpio#0 - set demod#2 i2c-addr for dual devices | 43 | * @pid_filter: Set PID to PID filter. |
44 | * * demod#1-gpio#1 - xtal setting (?) | ||
45 | * * demod#1-gpio#3 - tuner#1 | ||
46 | * * demod#2-gpio#0 - tuner#2 | ||
47 | * * demod#2-gpio#1 - xtal setting (?) | ||
48 | */ | 44 | */ |
49 | struct af9013_platform_data { | 45 | struct af9013_platform_data { |
50 | /* | 46 | /* |
@@ -84,36 +80,18 @@ struct af9013_platform_data { | |||
84 | u8 gpio[4]; | 80 | u8 gpio[4]; |
85 | 81 | ||
86 | struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); | 82 | struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); |
87 | 83 | struct i2c_adapter* (*get_i2c_adapter)(struct i2c_client *); | |
88 | /* private: For legacy media attach wrapper. Do not set value. */ | 84 | int (*pid_filter_ctrl)(struct dvb_frontend *, int); |
89 | bool attach_in_use; | 85 | int (*pid_filter)(struct dvb_frontend *, u8, u16, int); |
90 | u8 i2c_addr; | ||
91 | u32 clock; | ||
92 | }; | 86 | }; |
93 | 87 | ||
94 | #define af9013_config af9013_platform_data | 88 | /* |
95 | #define AF9013_TS_USB AF9013_TS_MODE_USB | 89 | * AF9013/5 GPIOs (mostly guessed) |
96 | #define AF9013_TS_PARALLEL AF9013_TS_MODE_PARALLEL | 90 | * demod#1-gpio#0 - set demod#2 i2c-addr for dual devices |
97 | #define AF9013_TS_SERIAL AF9013_TS_MODE_SERIAL | 91 | * demod#1-gpio#1 - xtal setting (?) |
98 | 92 | * demod#1-gpio#3 - tuner#1 | |
99 | #if IS_REACHABLE(CONFIG_DVB_AF9013) | 93 | * demod#2-gpio#0 - tuner#2 |
100 | /** | 94 | * demod#2-gpio#1 - xtal setting (?) |
101 | * Attach an af9013 demod | ||
102 | * | ||
103 | * @config: pointer to &struct af9013_config with demod configuration. | ||
104 | * @i2c: i2c adapter to use. | ||
105 | * | ||
106 | * return: FE pointer on success, NULL on failure. | ||
107 | */ | 95 | */ |
108 | extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, | ||
109 | struct i2c_adapter *i2c); | ||
110 | #else | ||
111 | static inline struct dvb_frontend *af9013_attach( | ||
112 | const struct af9013_config *config, struct i2c_adapter *i2c) | ||
113 | { | ||
114 | pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||
115 | return NULL; | ||
116 | } | ||
117 | #endif /* CONFIG_DVB_AF9013 */ | ||
118 | 96 | ||
119 | #endif /* AF9013_H */ | 97 | #endif /* AF9013_H */ |
diff --git a/drivers/media/dvb-frontends/af9013_priv.h b/drivers/media/dvb-frontends/af9013_priv.h index 688fc3472cf6..3e95de7dba51 100644 --- a/drivers/media/dvb-frontends/af9013_priv.h +++ b/drivers/media/dvb-frontends/af9013_priv.h | |||
@@ -22,25 +22,21 @@ | |||
22 | #define AF9013_PRIV_H | 22 | #define AF9013_PRIV_H |
23 | 23 | ||
24 | #include <media/dvb_frontend.h> | 24 | #include <media/dvb_frontend.h> |
25 | #include <media/dvb_math.h> | ||
25 | #include "af9013.h" | 26 | #include "af9013.h" |
26 | #include <linux/firmware.h> | 27 | #include <linux/firmware.h> |
28 | #include <linux/i2c-mux.h> | ||
27 | #include <linux/math64.h> | 29 | #include <linux/math64.h> |
28 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
29 | 31 | ||
30 | #define AF9013_FIRMWARE "dvb-fe-af9013.fw" | 32 | #define AF9013_FIRMWARE "dvb-fe-af9013.fw" |
31 | 33 | ||
32 | struct af9013_reg_bit { | 34 | struct af9013_reg_mask_val { |
33 | u16 addr; | 35 | u16 reg; |
34 | u8 pos:4; | 36 | u8 mask; |
35 | u8 len:4; | ||
36 | u8 val; | 37 | u8 val; |
37 | }; | 38 | }; |
38 | 39 | ||
39 | struct af9013_snr { | ||
40 | u32 val; | ||
41 | u8 snr; | ||
42 | }; | ||
43 | |||
44 | struct af9013_coeff { | 40 | struct af9013_coeff { |
45 | u32 clock; | 41 | u32 clock; |
46 | u32 bandwidth_hz; | 42 | u32 bandwidth_hz; |
@@ -91,817 +87,775 @@ static const struct af9013_coeff coeff_lut[] = { | |||
91 | 0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } }, | 87 | 0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } }, |
92 | }; | 88 | }; |
93 | 89 | ||
94 | /* QPSK SNR lookup table */ | 90 | /* |
95 | static const struct af9013_snr qpsk_snr_lut[] = { | 91 | * Afatech AF9013 demod init |
96 | { 0x000000, 0 }, | 92 | */ |
97 | { 0x0b4771, 0 }, | 93 | static const struct af9013_reg_mask_val demod_init_tab[] = { |
98 | { 0x0c1aed, 1 }, | 94 | {0xd73a, 0xff, 0xa1}, |
99 | { 0x0d0d27, 2 }, | 95 | {0xd73b, 0xff, 0x1f}, |
100 | { 0x0e4d19, 3 }, | 96 | {0xd73c, 0xf0, 0xa0}, |
101 | { 0x0e5da8, 4 }, | 97 | {0xd732, 0x08, 0x00}, |
102 | { 0x107097, 5 }, | 98 | {0xd731, 0x30, 0x30}, |
103 | { 0x116975, 6 }, | 99 | {0xd73d, 0x80, 0x80}, |
104 | { 0x1252d9, 7 }, | 100 | {0xd740, 0x01, 0x00}, |
105 | { 0x131fa4, 8 }, | 101 | {0xd740, 0x02, 0x00}, |
106 | { 0x13d5e1, 9 }, | 102 | {0xd740, 0x04, 0x00}, |
107 | { 0x148e53, 10 }, | 103 | {0xd740, 0x08, 0x08}, |
108 | { 0x15358b, 11 }, | 104 | {0xd3c1, 0x10, 0x10}, |
109 | { 0x15dd29, 12 }, | 105 | {0x9124, 0xff, 0x58}, |
110 | { 0x168112, 13 }, | 106 | {0x9125, 0x03, 0x02}, |
111 | { 0x170b61, 14 }, | 107 | {0xd3a2, 0xff, 0x00}, |
112 | { 0xffffff, 15 }, | 108 | {0xd3a3, 0xff, 0x04}, |
113 | }; | 109 | {0xd305, 0xff, 0x32}, |
114 | 110 | {0xd306, 0xff, 0x10}, | |
115 | /* QAM16 SNR lookup table */ | 111 | {0xd304, 0xff, 0x04}, |
116 | static const struct af9013_snr qam16_snr_lut[] = { | 112 | {0x9112, 0x01, 0x01}, |
117 | { 0x000000, 0 }, | 113 | {0x911d, 0x01, 0x01}, |
118 | { 0x05eb62, 5 }, | 114 | {0x911a, 0x01, 0x01}, |
119 | { 0x05fecf, 6 }, | 115 | {0x911b, 0x01, 0x01}, |
120 | { 0x060b80, 7 }, | 116 | {0x9bce, 0x0f, 0x02}, |
121 | { 0x062501, 8 }, | 117 | {0x9116, 0x01, 0x01}, |
122 | { 0x064865, 9 }, | 118 | {0x9122, 0xff, 0xd0}, |
123 | { 0x069604, 10 }, | 119 | {0xd2e0, 0xff, 0xd0}, |
124 | { 0x06f356, 11 }, | 120 | {0xd2e9, 0x0f, 0x0d}, |
125 | { 0x07706a, 12 }, | 121 | {0xd38c, 0xff, 0xfc}, |
126 | { 0x0804d3, 13 }, | 122 | {0xd38d, 0xff, 0x00}, |
127 | { 0x089d1a, 14 }, | 123 | {0xd38e, 0xff, 0x7e}, |
128 | { 0x093e3d, 15 }, | 124 | {0xd38f, 0xff, 0x00}, |
129 | { 0x09e35d, 16 }, | 125 | {0xd390, 0xff, 0x2f}, |
130 | { 0x0a7c3c, 17 }, | 126 | {0xd145, 0x10, 0x10}, |
131 | { 0x0afaf8, 18 }, | 127 | {0xd1a9, 0x10, 0x10}, |
132 | { 0x0b719d, 19 }, | 128 | {0xd158, 0xe0, 0x20}, |
133 | { 0xffffff, 20 }, | 129 | {0xd159, 0x3f, 0x06}, |
134 | }; | 130 | {0xd167, 0xff, 0x00}, |
135 | 131 | {0xd168, 0x0f, 0x07}, | |
136 | /* QAM64 SNR lookup table */ | 132 | {0xd1c3, 0xe0, 0x00}, |
137 | static const struct af9013_snr qam64_snr_lut[] = { | 133 | {0xd1c4, 0x3f, 0x00}, |
138 | { 0x000000, 0 }, | 134 | {0xd1c5, 0x7f, 0x10}, |
139 | { 0x03109b, 12 }, | 135 | {0xd1c6, 0x07, 0x02}, |
140 | { 0x0310d4, 13 }, | 136 | {0xd080, 0x7c, 0x0c}, |
141 | { 0x031920, 14 }, | 137 | {0xd081, 0xf0, 0x90}, |
142 | { 0x0322d0, 15 }, | 138 | {0xd098, 0xf0, 0xf0}, |
143 | { 0x0339fc, 16 }, | 139 | {0xd098, 0x0f, 0x03}, |
144 | { 0x0364a1, 17 }, | 140 | {0xdbc0, 0x10, 0x10}, |
145 | { 0x038bcc, 18 }, | 141 | {0xdbc7, 0xff, 0x08}, |
146 | { 0x03c7d3, 19 }, | 142 | {0xdbc8, 0xf0, 0x00}, |
147 | { 0x0408cc, 20 }, | 143 | {0xdbc9, 0x1f, 0x01}, |
148 | { 0x043bed, 21 }, | 144 | {0xd280, 0xff, 0xe0}, |
149 | { 0x048061, 22 }, | 145 | {0xd281, 0xff, 0xff}, |
150 | { 0x04be95, 23 }, | 146 | {0xd282, 0xff, 0xff}, |
151 | { 0x04fa7d, 24 }, | 147 | {0xd283, 0xff, 0xc3}, |
152 | { 0x052405, 25 }, | 148 | {0xd284, 0xff, 0xff}, |
153 | { 0x05570d, 26 }, | 149 | {0xd285, 0x0f, 0x01}, |
154 | { 0xffffff, 27 }, | 150 | {0xd0f0, 0x7f, 0x1a}, |
155 | }; | 151 | {0xd0f1, 0x10, 0x10}, |
156 | 152 | {0xd0f2, 0xff, 0x0c}, | |
157 | static const struct af9013_reg_bit ofsm_init[] = { | 153 | {0xd101, 0xe0, 0xc0}, |
158 | { 0xd73a, 0, 8, 0xa1 }, | 154 | {0xd103, 0x0f, 0x08}, |
159 | { 0xd73b, 0, 8, 0x1f }, | 155 | {0xd0f8, 0x7f, 0x20}, |
160 | { 0xd73c, 4, 4, 0x0a }, | 156 | {0xd111, 0x20, 0x00}, |
161 | { 0xd732, 3, 1, 0x00 }, | 157 | {0xd111, 0x40, 0x00}, |
162 | { 0xd731, 4, 2, 0x03 }, | 158 | {0x910b, 0xff, 0x0a}, |
163 | { 0xd73d, 7, 1, 0x01 }, | 159 | {0x9115, 0xff, 0x02}, |
164 | { 0xd740, 0, 1, 0x00 }, | 160 | {0x910c, 0xff, 0x02}, |
165 | { 0xd740, 1, 1, 0x00 }, | 161 | {0x910d, 0xff, 0x08}, |
166 | { 0xd740, 2, 1, 0x00 }, | 162 | {0x910e, 0xff, 0x0a}, |
167 | { 0xd740, 3, 1, 0x01 }, | 163 | {0x9bf6, 0xff, 0x06}, |
168 | { 0xd3c1, 4, 1, 0x01 }, | 164 | {0x9bf8, 0xff, 0x02}, |
169 | { 0x9124, 0, 8, 0x58 }, | 165 | {0x9bf7, 0xff, 0x05}, |
170 | { 0x9125, 0, 2, 0x02 }, | 166 | {0x9bf9, 0xff, 0x0f}, |
171 | { 0xd3a2, 0, 8, 0x00 }, | 167 | {0x9bfc, 0xff, 0x13}, |
172 | { 0xd3a3, 0, 8, 0x04 }, | 168 | {0x9bd3, 0xff, 0xff}, |
173 | { 0xd305, 0, 8, 0x32 }, | 169 | {0x9bbe, 0x01, 0x01}, |
174 | { 0xd306, 0, 8, 0x10 }, | 170 | {0x9bcc, 0x01, 0x01}, |
175 | { 0xd304, 0, 8, 0x04 }, | ||
176 | { 0x9112, 0, 1, 0x01 }, | ||
177 | { 0x911d, 0, 1, 0x01 }, | ||
178 | { 0x911a, 0, 1, 0x01 }, | ||
179 | { 0x911b, 0, 1, 0x01 }, | ||
180 | { 0x9bce, 0, 4, 0x02 }, | ||
181 | { 0x9116, 0, 1, 0x01 }, | ||
182 | { 0x9122, 0, 8, 0xd0 }, | ||
183 | { 0xd2e0, 0, 8, 0xd0 }, | ||
184 | { 0xd2e9, 0, 4, 0x0d }, | ||
185 | { 0xd38c, 0, 8, 0xfc }, | ||
186 | { 0xd38d, 0, 8, 0x00 }, | ||
187 | { 0xd38e, 0, 8, 0x7e }, | ||
188 | { 0xd38f, 0, 8, 0x00 }, | ||
189 | { 0xd390, 0, 8, 0x2f }, | ||
190 | { 0xd145, 4, 1, 0x01 }, | ||
191 | { 0xd1a9, 4, 1, 0x01 }, | ||
192 | { 0xd158, 5, 3, 0x01 }, | ||
193 | { 0xd159, 0, 6, 0x06 }, | ||
194 | { 0xd167, 0, 8, 0x00 }, | ||
195 | { 0xd168, 0, 4, 0x07 }, | ||
196 | { 0xd1c3, 5, 3, 0x00 }, | ||
197 | { 0xd1c4, 0, 6, 0x00 }, | ||
198 | { 0xd1c5, 0, 7, 0x10 }, | ||
199 | { 0xd1c6, 0, 3, 0x02 }, | ||
200 | { 0xd080, 2, 5, 0x03 }, | ||
201 | { 0xd081, 4, 4, 0x09 }, | ||
202 | { 0xd098, 4, 4, 0x0f }, | ||
203 | { 0xd098, 0, 4, 0x03 }, | ||
204 | { 0xdbc0, 4, 1, 0x01 }, | ||
205 | { 0xdbc7, 0, 8, 0x08 }, | ||
206 | { 0xdbc8, 4, 4, 0x00 }, | ||
207 | { 0xdbc9, 0, 5, 0x01 }, | ||
208 | { 0xd280, 0, 8, 0xe0 }, | ||
209 | { 0xd281, 0, 8, 0xff }, | ||
210 | { 0xd282, 0, 8, 0xff }, | ||
211 | { 0xd283, 0, 8, 0xc3 }, | ||
212 | { 0xd284, 0, 8, 0xff }, | ||
213 | { 0xd285, 0, 4, 0x01 }, | ||
214 | { 0xd0f0, 0, 7, 0x1a }, | ||
215 | { 0xd0f1, 4, 1, 0x01 }, | ||
216 | { 0xd0f2, 0, 8, 0x0c }, | ||
217 | { 0xd101, 5, 3, 0x06 }, | ||
218 | { 0xd103, 0, 4, 0x08 }, | ||
219 | { 0xd0f8, 0, 7, 0x20 }, | ||
220 | { 0xd111, 5, 1, 0x00 }, | ||
221 | { 0xd111, 6, 1, 0x00 }, | ||
222 | { 0x910b, 0, 8, 0x0a }, | ||
223 | { 0x9115, 0, 8, 0x02 }, | ||
224 | { 0x910c, 0, 8, 0x02 }, | ||
225 | { 0x910d, 0, 8, 0x08 }, | ||
226 | { 0x910e, 0, 8, 0x0a }, | ||
227 | { 0x9bf6, 0, 8, 0x06 }, | ||
228 | { 0x9bf8, 0, 8, 0x02 }, | ||
229 | { 0x9bf7, 0, 8, 0x05 }, | ||
230 | { 0x9bf9, 0, 8, 0x0f }, | ||
231 | { 0x9bfc, 0, 8, 0x13 }, | ||
232 | { 0x9bd3, 0, 8, 0xff }, | ||
233 | { 0x9bbe, 0, 1, 0x01 }, | ||
234 | { 0x9bcc, 0, 1, 0x01 }, | ||
235 | }; | 171 | }; |
236 | 172 | ||
237 | /* Panasonic ENV77H11D5 tuner init | 173 | /* |
238 | AF9013_TUNER_ENV77H11D5 = 129 */ | 174 | * Panasonic ENV77H11D5 tuner init |
239 | static const struct af9013_reg_bit tuner_init_env77h11d5[] = { | 175 | * AF9013_TUNER_ENV77H11D5 0x81 |
240 | { 0x9bd5, 0, 8, 0x01 }, | 176 | */ |
241 | { 0x9bd6, 0, 8, 0x03 }, | 177 | static const struct af9013_reg_mask_val tuner_init_tab_env77h11d5[] = { |
242 | { 0x9bbe, 0, 8, 0x01 }, | 178 | {0x9bd5, 0xff, 0x01}, |
243 | { 0xd1a0, 1, 1, 0x01 }, | 179 | {0x9bd6, 0xff, 0x03}, |
244 | { 0xd000, 0, 1, 0x01 }, | 180 | {0x9bbe, 0xff, 0x01}, |
245 | { 0xd000, 1, 1, 0x00 }, | 181 | {0xd1a0, 0x02, 0x02}, |
246 | { 0xd001, 1, 1, 0x01 }, | 182 | {0xd000, 0x01, 0x01}, |
247 | { 0xd001, 0, 1, 0x00 }, | 183 | {0xd000, 0x02, 0x00}, |
248 | { 0xd001, 5, 1, 0x00 }, | 184 | {0xd001, 0x02, 0x02}, |
249 | { 0xd002, 0, 5, 0x19 }, | 185 | {0xd001, 0x01, 0x00}, |
250 | { 0xd003, 0, 5, 0x1a }, | 186 | {0xd001, 0x20, 0x00}, |
251 | { 0xd004, 0, 5, 0x19 }, | 187 | {0xd002, 0x1f, 0x19}, |
252 | { 0xd005, 0, 5, 0x1a }, | 188 | {0xd003, 0x1f, 0x1a}, |
253 | { 0xd00e, 0, 5, 0x10 }, | 189 | {0xd004, 0x1f, 0x19}, |
254 | { 0xd00f, 0, 3, 0x04 }, | 190 | {0xd005, 0x1f, 0x1a}, |
255 | { 0xd00f, 3, 3, 0x05 }, | 191 | {0xd00e, 0x1f, 0x10}, |
256 | { 0xd010, 0, 3, 0x04 }, | 192 | {0xd00f, 0x07, 0x04}, |
257 | { 0xd010, 3, 3, 0x05 }, | 193 | {0xd00f, 0x38, 0x28}, |
258 | { 0xd016, 4, 4, 0x03 }, | 194 | {0xd010, 0x07, 0x04}, |
259 | { 0xd01f, 0, 6, 0x0a }, | 195 | {0xd010, 0x38, 0x28}, |
260 | { 0xd020, 0, 6, 0x0a }, | 196 | {0xd016, 0xf0, 0x30}, |
261 | { 0x9bda, 0, 8, 0x00 }, | 197 | {0xd01f, 0x3f, 0x0a}, |
262 | { 0x9be3, 0, 8, 0x00 }, | 198 | {0xd020, 0x3f, 0x0a}, |
263 | { 0xd015, 0, 8, 0x50 }, | 199 | {0x9bda, 0xff, 0x00}, |
264 | { 0xd016, 0, 1, 0x00 }, | 200 | {0x9be3, 0xff, 0x00}, |
265 | { 0xd044, 0, 8, 0x46 }, | 201 | {0xd015, 0xff, 0x50}, |
266 | { 0xd045, 0, 1, 0x00 }, | 202 | {0xd016, 0x01, 0x00}, |
267 | { 0xd008, 0, 8, 0xdf }, | 203 | {0xd044, 0xff, 0x46}, |
268 | { 0xd009, 0, 2, 0x02 }, | 204 | {0xd045, 0x01, 0x00}, |
269 | { 0xd006, 0, 8, 0x44 }, | 205 | {0xd008, 0xff, 0xdf}, |
270 | { 0xd007, 0, 2, 0x01 }, | 206 | {0xd009, 0x03, 0x02}, |
271 | { 0xd00c, 0, 8, 0xeb }, | 207 | {0xd006, 0xff, 0x44}, |
272 | { 0xd00d, 0, 2, 0x02 }, | 208 | {0xd007, 0x03, 0x01}, |
273 | { 0xd00a, 0, 8, 0xf4 }, | 209 | {0xd00c, 0xff, 0xeb}, |
274 | { 0xd00b, 0, 2, 0x01 }, | 210 | {0xd00d, 0x03, 0x02}, |
275 | { 0x9bba, 0, 8, 0xf9 }, | 211 | {0xd00a, 0xff, 0xf4}, |
276 | { 0x9bc3, 0, 8, 0xdf }, | 212 | {0xd00b, 0x03, 0x01}, |
277 | { 0x9bc4, 0, 8, 0x02 }, | 213 | {0x9bba, 0xff, 0xf9}, |
278 | { 0x9bc5, 0, 8, 0xeb }, | 214 | {0x9bc3, 0xff, 0xdf}, |
279 | { 0x9bc6, 0, 8, 0x02 }, | 215 | {0x9bc4, 0xff, 0x02}, |
280 | { 0x9bc9, 0, 8, 0x52 }, | 216 | {0x9bc5, 0xff, 0xeb}, |
281 | { 0xd011, 0, 8, 0x3c }, | 217 | {0x9bc6, 0xff, 0x02}, |
282 | { 0xd012, 0, 2, 0x01 }, | 218 | {0x9bc9, 0xff, 0x52}, |
283 | { 0xd013, 0, 8, 0xf7 }, | 219 | {0xd011, 0xff, 0x3c}, |
284 | { 0xd014, 0, 2, 0x02 }, | 220 | {0xd012, 0x03, 0x01}, |
285 | { 0xd040, 0, 8, 0x0b }, | 221 | {0xd013, 0xff, 0xf7}, |
286 | { 0xd041, 0, 2, 0x02 }, | 222 | {0xd014, 0x03, 0x02}, |
287 | { 0xd042, 0, 8, 0x4d }, | 223 | {0xd040, 0xff, 0x0b}, |
288 | { 0xd043, 0, 2, 0x00 }, | 224 | {0xd041, 0x03, 0x02}, |
289 | { 0xd045, 1, 1, 0x00 }, | 225 | {0xd042, 0xff, 0x4d}, |
290 | { 0x9bcf, 0, 1, 0x01 }, | 226 | {0xd043, 0x03, 0x00}, |
291 | { 0xd045, 2, 1, 0x01 }, | 227 | {0xd045, 0x02, 0x00}, |
292 | { 0xd04f, 0, 8, 0x9a }, | 228 | {0x9bcf, 0x01, 0x01}, |
293 | { 0xd050, 0, 1, 0x01 }, | 229 | {0xd045, 0x04, 0x04}, |
294 | { 0xd051, 0, 8, 0x5a }, | 230 | {0xd04f, 0xff, 0x9a}, |
295 | { 0xd052, 0, 1, 0x01 }, | 231 | {0xd050, 0x01, 0x01}, |
296 | { 0xd053, 0, 8, 0x50 }, | 232 | {0xd051, 0xff, 0x5a}, |
297 | { 0xd054, 0, 8, 0x46 }, | 233 | {0xd052, 0x01, 0x01}, |
298 | { 0x9bd7, 0, 8, 0x0a }, | 234 | {0xd053, 0xff, 0x50}, |
299 | { 0x9bd8, 0, 8, 0x14 }, | 235 | {0xd054, 0xff, 0x46}, |
300 | { 0x9bd9, 0, 8, 0x08 }, | 236 | {0x9bd7, 0xff, 0x0a}, |
237 | {0x9bd8, 0xff, 0x14}, | ||
238 | {0x9bd9, 0xff, 0x08}, | ||
301 | }; | 239 | }; |
302 | 240 | ||
303 | /* Microtune MT2060 tuner init | 241 | /* |
304 | AF9013_TUNER_MT2060 = 130 */ | 242 | * Microtune MT2060 tuner init |
305 | static const struct af9013_reg_bit tuner_init_mt2060[] = { | 243 | * AF9013_TUNER_MT2060 0x82 |
306 | { 0x9bd5, 0, 8, 0x01 }, | 244 | */ |
307 | { 0x9bd6, 0, 8, 0x07 }, | 245 | static const struct af9013_reg_mask_val tuner_init_tab_mt2060[] = { |
308 | { 0xd1a0, 1, 1, 0x01 }, | 246 | {0x9bd5, 0xff, 0x01}, |
309 | { 0xd000, 0, 1, 0x01 }, | 247 | {0x9bd6, 0xff, 0x07}, |
310 | { 0xd000, 1, 1, 0x00 }, | 248 | {0xd1a0, 0x02, 0x02}, |
311 | { 0xd001, 1, 1, 0x01 }, | 249 | {0xd000, 0x01, 0x01}, |
312 | { 0xd001, 0, 1, 0x00 }, | 250 | {0xd000, 0x02, 0x00}, |
313 | { 0xd001, 5, 1, 0x00 }, | 251 | {0xd001, 0x02, 0x02}, |
314 | { 0xd002, 0, 5, 0x19 }, | 252 | {0xd001, 0x01, 0x00}, |
315 | { 0xd003, 0, 5, 0x1a }, | 253 | {0xd001, 0x20, 0x00}, |
316 | { 0xd004, 0, 5, 0x19 }, | 254 | {0xd002, 0x1f, 0x19}, |
317 | { 0xd005, 0, 5, 0x1a }, | 255 | {0xd003, 0x1f, 0x1a}, |
318 | { 0xd00e, 0, 5, 0x10 }, | 256 | {0xd004, 0x1f, 0x19}, |
319 | { 0xd00f, 0, 3, 0x04 }, | 257 | {0xd005, 0x1f, 0x1a}, |
320 | { 0xd00f, 3, 3, 0x05 }, | 258 | {0xd00e, 0x1f, 0x10}, |
321 | { 0xd010, 0, 3, 0x04 }, | 259 | {0xd00f, 0x07, 0x04}, |
322 | { 0xd010, 3, 3, 0x05 }, | 260 | {0xd00f, 0x38, 0x28}, |
323 | { 0xd016, 4, 4, 0x03 }, | 261 | {0xd010, 0x07, 0x04}, |
324 | { 0xd01f, 0, 6, 0x0a }, | 262 | {0xd010, 0x38, 0x28}, |
325 | { 0xd020, 0, 6, 0x0a }, | 263 | {0xd016, 0xf0, 0x30}, |
326 | { 0x9bda, 0, 8, 0x00 }, | 264 | {0xd01f, 0x3f, 0x0a}, |
327 | { 0x9be3, 0, 8, 0x00 }, | 265 | {0xd020, 0x3f, 0x0a}, |
328 | { 0x9bbe, 0, 1, 0x00 }, | 266 | {0x9bda, 0xff, 0x00}, |
329 | { 0x9bcc, 0, 1, 0x00 }, | 267 | {0x9be3, 0xff, 0x00}, |
330 | { 0x9bb9, 0, 8, 0x75 }, | 268 | {0x9bbe, 0x01, 0x00}, |
331 | { 0x9bcd, 0, 8, 0x24 }, | 269 | {0x9bcc, 0x01, 0x00}, |
332 | { 0x9bff, 0, 8, 0x30 }, | 270 | {0x9bb9, 0xff, 0x75}, |
333 | { 0xd015, 0, 8, 0x46 }, | 271 | {0x9bcd, 0xff, 0x24}, |
334 | { 0xd016, 0, 1, 0x00 }, | 272 | {0x9bff, 0xff, 0x30}, |
335 | { 0xd044, 0, 8, 0x46 }, | 273 | {0xd015, 0xff, 0x46}, |
336 | { 0xd045, 0, 1, 0x00 }, | 274 | {0xd016, 0x01, 0x00}, |
337 | { 0xd008, 0, 8, 0x0f }, | 275 | {0xd044, 0xff, 0x46}, |
338 | { 0xd009, 0, 2, 0x02 }, | 276 | {0xd045, 0x01, 0x00}, |
339 | { 0xd006, 0, 8, 0x32 }, | 277 | {0xd008, 0xff, 0x0f}, |
340 | { 0xd007, 0, 2, 0x01 }, | 278 | {0xd009, 0x03, 0x02}, |
341 | { 0xd00c, 0, 8, 0x36 }, | 279 | {0xd006, 0xff, 0x32}, |
342 | { 0xd00d, 0, 2, 0x03 }, | 280 | {0xd007, 0x03, 0x01}, |
343 | { 0xd00a, 0, 8, 0x35 }, | 281 | {0xd00c, 0xff, 0x36}, |
344 | { 0xd00b, 0, 2, 0x01 }, | 282 | {0xd00d, 0x03, 0x03}, |
345 | { 0x9bc7, 0, 8, 0x07 }, | 283 | {0xd00a, 0xff, 0x35}, |
346 | { 0x9bc8, 0, 8, 0x90 }, | 284 | {0xd00b, 0x03, 0x01}, |
347 | { 0x9bc3, 0, 8, 0x0f }, | 285 | {0x9bc7, 0xff, 0x07}, |
348 | { 0x9bc4, 0, 8, 0x02 }, | 286 | {0x9bc8, 0xff, 0x90}, |
349 | { 0x9bc5, 0, 8, 0x36 }, | 287 | {0x9bc3, 0xff, 0x0f}, |
350 | { 0x9bc6, 0, 8, 0x03 }, | 288 | {0x9bc4, 0xff, 0x02}, |
351 | { 0x9bba, 0, 8, 0xc9 }, | 289 | {0x9bc5, 0xff, 0x36}, |
352 | { 0x9bc9, 0, 8, 0x79 }, | 290 | {0x9bc6, 0xff, 0x03}, |
353 | { 0xd011, 0, 8, 0x10 }, | 291 | {0x9bba, 0xff, 0xc9}, |
354 | { 0xd012, 0, 2, 0x01 }, | 292 | {0x9bc9, 0xff, 0x79}, |
355 | { 0xd013, 0, 8, 0x45 }, | 293 | {0xd011, 0xff, 0x10}, |
356 | { 0xd014, 0, 2, 0x03 }, | 294 | {0xd012, 0x03, 0x01}, |
357 | { 0xd040, 0, 8, 0x98 }, | 295 | {0xd013, 0xff, 0x45}, |
358 | { 0xd041, 0, 2, 0x00 }, | 296 | {0xd014, 0x03, 0x03}, |
359 | { 0xd042, 0, 8, 0xcf }, | 297 | {0xd040, 0xff, 0x98}, |
360 | { 0xd043, 0, 2, 0x03 }, | 298 | {0xd041, 0x03, 0x00}, |
361 | { 0xd045, 1, 1, 0x00 }, | 299 | {0xd042, 0xff, 0xcf}, |
362 | { 0x9bcf, 0, 1, 0x01 }, | 300 | {0xd043, 0x03, 0x03}, |
363 | { 0xd045, 2, 1, 0x01 }, | 301 | {0xd045, 0x02, 0x00}, |
364 | { 0xd04f, 0, 8, 0x9a }, | 302 | {0x9bcf, 0x01, 0x01}, |
365 | { 0xd050, 0, 1, 0x01 }, | 303 | {0xd045, 0x04, 0x04}, |
366 | { 0xd051, 0, 8, 0x5a }, | 304 | {0xd04f, 0xff, 0x9a}, |
367 | { 0xd052, 0, 1, 0x01 }, | 305 | {0xd050, 0x01, 0x01}, |
368 | { 0xd053, 0, 8, 0x50 }, | 306 | {0xd051, 0xff, 0x5a}, |
369 | { 0xd054, 0, 8, 0x46 }, | 307 | {0xd052, 0x01, 0x01}, |
370 | { 0x9bd7, 0, 8, 0x0a }, | 308 | {0xd053, 0xff, 0x50}, |
371 | { 0x9bd8, 0, 8, 0x14 }, | 309 | {0xd054, 0xff, 0x46}, |
372 | { 0x9bd9, 0, 8, 0x08 }, | 310 | {0x9bd7, 0xff, 0x0a}, |
373 | { 0x9bd0, 0, 8, 0xcc }, | 311 | {0x9bd8, 0xff, 0x14}, |
374 | { 0x9be4, 0, 8, 0xa0 }, | 312 | {0x9bd9, 0xff, 0x08}, |
375 | { 0x9bbd, 0, 8, 0x8e }, | 313 | {0x9bd0, 0xff, 0xcc}, |
376 | { 0x9be2, 0, 8, 0x4d }, | 314 | {0x9be4, 0xff, 0xa0}, |
377 | { 0x9bee, 0, 1, 0x01 }, | 315 | {0x9bbd, 0xff, 0x8e}, |
316 | {0x9be2, 0xff, 0x4d}, | ||
317 | {0x9bee, 0x01, 0x01}, | ||
378 | }; | 318 | }; |
379 | 319 | ||
380 | /* Microtune MT2060 tuner init | 320 | /* |
381 | AF9013_TUNER_MT2060_2 = 147 */ | 321 | * Microtune MT2060 tuner init |
382 | static const struct af9013_reg_bit tuner_init_mt2060_2[] = { | 322 | * AF9013_TUNER_MT2060_2 0x93 |
383 | { 0x9bd5, 0, 8, 0x01 }, | 323 | */ |
384 | { 0x9bd6, 0, 8, 0x06 }, | 324 | static const struct af9013_reg_mask_val tuner_init_tab_mt2060_2[] = { |
385 | { 0x9bbe, 0, 8, 0x01 }, | 325 | {0x9bd5, 0xff, 0x01}, |
386 | { 0xd1a0, 1, 1, 0x01 }, | 326 | {0x9bd6, 0xff, 0x06}, |
387 | { 0xd000, 0, 1, 0x01 }, | 327 | {0x9bbe, 0xff, 0x01}, |
388 | { 0xd000, 1, 1, 0x00 }, | 328 | {0xd1a0, 0x02, 0x02}, |
389 | { 0xd001, 1, 1, 0x01 }, | 329 | {0xd000, 0x01, 0x01}, |
390 | { 0xd001, 0, 1, 0x00 }, | 330 | {0xd000, 0x02, 0x00}, |
391 | { 0xd001, 5, 1, 0x00 }, | 331 | {0xd001, 0x02, 0x02}, |
392 | { 0xd002, 0, 5, 0x19 }, | 332 | {0xd001, 0x01, 0x00}, |
393 | { 0xd003, 0, 5, 0x1a }, | 333 | {0xd001, 0x20, 0x00}, |
394 | { 0xd004, 0, 5, 0x19 }, | 334 | {0xd002, 0x1f, 0x19}, |
395 | { 0xd005, 0, 5, 0x1a }, | 335 | {0xd003, 0x1f, 0x1a}, |
396 | { 0xd00e, 0, 5, 0x10 }, | 336 | {0xd004, 0x1f, 0x19}, |
397 | { 0xd00f, 0, 3, 0x04 }, | 337 | {0xd005, 0x1f, 0x1a}, |
398 | { 0xd00f, 3, 3, 0x05 }, | 338 | {0xd00e, 0x1f, 0x10}, |
399 | { 0xd010, 0, 3, 0x04 }, | 339 | {0xd00f, 0x07, 0x04}, |
400 | { 0xd010, 3, 3, 0x05 }, | 340 | {0xd00f, 0x38, 0x28}, |
401 | { 0xd016, 4, 4, 0x03 }, | 341 | {0xd010, 0x07, 0x04}, |
402 | { 0xd01f, 0, 6, 0x0a }, | 342 | {0xd010, 0x38, 0x28}, |
403 | { 0xd020, 0, 6, 0x0a }, | 343 | {0xd016, 0xf0, 0x30}, |
404 | { 0xd015, 0, 8, 0x46 }, | 344 | {0xd01f, 0x3f, 0x0a}, |
405 | { 0xd016, 0, 1, 0x00 }, | 345 | {0xd020, 0x3f, 0x0a}, |
406 | { 0xd044, 0, 8, 0x46 }, | 346 | {0xd015, 0xff, 0x46}, |
407 | { 0xd045, 0, 1, 0x00 }, | 347 | {0xd016, 0x01, 0x00}, |
408 | { 0xd008, 0, 8, 0x0f }, | 348 | {0xd044, 0xff, 0x46}, |
409 | { 0xd009, 0, 2, 0x02 }, | 349 | {0xd045, 0x01, 0x00}, |
410 | { 0xd006, 0, 8, 0x32 }, | 350 | {0xd008, 0xff, 0x0f}, |
411 | { 0xd007, 0, 2, 0x01 }, | 351 | {0xd009, 0x03, 0x02}, |
412 | { 0xd00c, 0, 8, 0x36 }, | 352 | {0xd006, 0xff, 0x32}, |
413 | { 0xd00d, 0, 2, 0x03 }, | 353 | {0xd007, 0x03, 0x01}, |
414 | { 0xd00a, 0, 8, 0x35 }, | 354 | {0xd00c, 0xff, 0x36}, |
415 | { 0xd00b, 0, 2, 0x01 }, | 355 | {0xd00d, 0x03, 0x03}, |
416 | { 0x9bc7, 0, 8, 0x07 }, | 356 | {0xd00a, 0xff, 0x35}, |
417 | { 0x9bc8, 0, 8, 0x90 }, | 357 | {0xd00b, 0x03, 0x01}, |
418 | { 0x9bc3, 0, 8, 0x0f }, | 358 | {0x9bc7, 0xff, 0x07}, |
419 | { 0x9bc4, 0, 8, 0x02 }, | 359 | {0x9bc8, 0xff, 0x90}, |
420 | { 0x9bc5, 0, 8, 0x36 }, | 360 | {0x9bc3, 0xff, 0x0f}, |
421 | { 0x9bc6, 0, 8, 0x03 }, | 361 | {0x9bc4, 0xff, 0x02}, |
422 | { 0x9bba, 0, 8, 0xc9 }, | 362 | {0x9bc5, 0xff, 0x36}, |
423 | { 0x9bc9, 0, 8, 0x79 }, | 363 | {0x9bc6, 0xff, 0x03}, |
424 | { 0xd011, 0, 8, 0x10 }, | 364 | {0x9bba, 0xff, 0xc9}, |
425 | { 0xd012, 0, 2, 0x01 }, | 365 | {0x9bc9, 0xff, 0x79}, |
426 | { 0xd013, 0, 8, 0x45 }, | 366 | {0xd011, 0xff, 0x10}, |
427 | { 0xd014, 0, 2, 0x03 }, | 367 | {0xd012, 0x03, 0x01}, |
428 | { 0xd040, 0, 8, 0x98 }, | 368 | {0xd013, 0xff, 0x45}, |
429 | { 0xd041, 0, 2, 0x00 }, | 369 | {0xd014, 0x03, 0x03}, |
430 | { 0xd042, 0, 8, 0xcf }, | 370 | {0xd040, 0xff, 0x98}, |
431 | { 0xd043, 0, 2, 0x03 }, | 371 | {0xd041, 0x03, 0x00}, |
432 | { 0xd045, 1, 1, 0x00 }, | 372 | {0xd042, 0xff, 0xcf}, |
433 | { 0x9bcf, 0, 8, 0x01 }, | 373 | {0xd043, 0x03, 0x03}, |
434 | { 0xd045, 2, 1, 0x01 }, | 374 | {0xd045, 0x02, 0x00}, |
435 | { 0xd04f, 0, 8, 0x9a }, | 375 | {0x9bcf, 0xff, 0x01}, |
436 | { 0xd050, 0, 1, 0x01 }, | 376 | {0xd045, 0x04, 0x04}, |
437 | { 0xd051, 0, 8, 0x5a }, | 377 | {0xd04f, 0xff, 0x9a}, |
438 | { 0xd052, 0, 1, 0x01 }, | 378 | {0xd050, 0x01, 0x01}, |
439 | { 0xd053, 0, 8, 0x96 }, | 379 | {0xd051, 0xff, 0x5a}, |
440 | { 0xd054, 0, 8, 0x46 }, | 380 | {0xd052, 0x01, 0x01}, |
441 | { 0xd045, 7, 1, 0x00 }, | 381 | {0xd053, 0xff, 0x96}, |
442 | { 0x9bd7, 0, 8, 0x0a }, | 382 | {0xd054, 0xff, 0x46}, |
443 | { 0x9bd8, 0, 8, 0x14 }, | 383 | {0xd045, 0x80, 0x00}, |
444 | { 0x9bd9, 0, 8, 0x08 }, | 384 | {0x9bd7, 0xff, 0x0a}, |
385 | {0x9bd8, 0xff, 0x14}, | ||
386 | {0x9bd9, 0xff, 0x08}, | ||
445 | }; | 387 | }; |
446 | 388 | ||
447 | /* MaxLinear MXL5003 tuner init | 389 | /* |
448 | AF9013_TUNER_MXL5003D = 3 */ | 390 | * MaxLinear MXL5003 tuner init |
449 | static const struct af9013_reg_bit tuner_init_mxl5003d[] = { | 391 | * AF9013_TUNER_MXL5003D 0x03 |
450 | { 0x9bd5, 0, 8, 0x01 }, | 392 | */ |
451 | { 0x9bd6, 0, 8, 0x09 }, | 393 | static const struct af9013_reg_mask_val tuner_init_tab_mxl5003d[] = { |
452 | { 0xd1a0, 1, 1, 0x01 }, | 394 | {0x9bd5, 0xff, 0x01}, |
453 | { 0xd000, 0, 1, 0x01 }, | 395 | {0x9bd6, 0xff, 0x09}, |
454 | { 0xd000, 1, 1, 0x00 }, | 396 | {0xd1a0, 0x02, 0x02}, |
455 | { 0xd001, 1, 1, 0x01 }, | 397 | {0xd000, 0x01, 0x01}, |
456 | { 0xd001, 0, 1, 0x00 }, | 398 | {0xd000, 0x02, 0x00}, |
457 | { 0xd001, 5, 1, 0x00 }, | 399 | {0xd001, 0x02, 0x02}, |
458 | { 0xd002, 0, 5, 0x19 }, | 400 | {0xd001, 0x01, 0x00}, |
459 | { 0xd003, 0, 5, 0x1a }, | 401 | {0xd001, 0x20, 0x00}, |
460 | { 0xd004, 0, 5, 0x19 }, | 402 | {0xd002, 0x1f, 0x19}, |
461 | { 0xd005, 0, 5, 0x1a }, | 403 | {0xd003, 0x1f, 0x1a}, |
462 | { 0xd00e, 0, 5, 0x10 }, | 404 | {0xd004, 0x1f, 0x19}, |
463 | { 0xd00f, 0, 3, 0x04 }, | 405 | {0xd005, 0x1f, 0x1a}, |
464 | { 0xd00f, 3, 3, 0x05 }, | 406 | {0xd00e, 0x1f, 0x10}, |
465 | { 0xd010, 0, 3, 0x04 }, | 407 | {0xd00f, 0x07, 0x04}, |
466 | { 0xd010, 3, 3, 0x05 }, | 408 | {0xd00f, 0x38, 0x28}, |
467 | { 0xd016, 4, 4, 0x03 }, | 409 | {0xd010, 0x07, 0x04}, |
468 | { 0xd01f, 0, 6, 0x0a }, | 410 | {0xd010, 0x38, 0x28}, |
469 | { 0xd020, 0, 6, 0x0a }, | 411 | {0xd016, 0xf0, 0x30}, |
470 | { 0x9bda, 0, 8, 0x00 }, | 412 | {0xd01f, 0x3f, 0x0a}, |
471 | { 0x9be3, 0, 8, 0x00 }, | 413 | {0xd020, 0x3f, 0x0a}, |
472 | { 0x9bfc, 0, 8, 0x0f }, | 414 | {0x9bda, 0xff, 0x00}, |
473 | { 0x9bf6, 0, 8, 0x01 }, | 415 | {0x9be3, 0xff, 0x00}, |
474 | { 0x9bbe, 0, 1, 0x01 }, | 416 | {0x9bfc, 0xff, 0x0f}, |
475 | { 0xd015, 0, 8, 0x33 }, | 417 | {0x9bf6, 0xff, 0x01}, |
476 | { 0xd016, 0, 1, 0x00 }, | 418 | {0x9bbe, 0x01, 0x01}, |
477 | { 0xd044, 0, 8, 0x40 }, | 419 | {0xd015, 0xff, 0x33}, |
478 | { 0xd045, 0, 1, 0x00 }, | 420 | {0xd016, 0x01, 0x00}, |
479 | { 0xd008, 0, 8, 0x0f }, | 421 | {0xd044, 0xff, 0x40}, |
480 | { 0xd009, 0, 2, 0x02 }, | 422 | {0xd045, 0x01, 0x00}, |
481 | { 0xd006, 0, 8, 0x6c }, | 423 | {0xd008, 0xff, 0x0f}, |
482 | { 0xd007, 0, 2, 0x00 }, | 424 | {0xd009, 0x03, 0x02}, |
483 | { 0xd00c, 0, 8, 0x3d }, | 425 | {0xd006, 0xff, 0x6c}, |
484 | { 0xd00d, 0, 2, 0x00 }, | 426 | {0xd007, 0x03, 0x00}, |
485 | { 0xd00a, 0, 8, 0x45 }, | 427 | {0xd00c, 0xff, 0x3d}, |
486 | { 0xd00b, 0, 2, 0x01 }, | 428 | {0xd00d, 0x03, 0x00}, |
487 | { 0x9bc7, 0, 8, 0x07 }, | 429 | {0xd00a, 0xff, 0x45}, |
488 | { 0x9bc8, 0, 8, 0x52 }, | 430 | {0xd00b, 0x03, 0x01}, |
489 | { 0x9bc3, 0, 8, 0x0f }, | 431 | {0x9bc7, 0xff, 0x07}, |
490 | { 0x9bc4, 0, 8, 0x02 }, | 432 | {0x9bc8, 0xff, 0x52}, |
491 | { 0x9bc5, 0, 8, 0x3d }, | 433 | {0x9bc3, 0xff, 0x0f}, |
492 | { 0x9bc6, 0, 8, 0x00 }, | 434 | {0x9bc4, 0xff, 0x02}, |
493 | { 0x9bba, 0, 8, 0xa2 }, | 435 | {0x9bc5, 0xff, 0x3d}, |
494 | { 0x9bc9, 0, 8, 0xa0 }, | 436 | {0x9bc6, 0xff, 0x00}, |
495 | { 0xd011, 0, 8, 0x56 }, | 437 | {0x9bba, 0xff, 0xa2}, |
496 | { 0xd012, 0, 2, 0x00 }, | 438 | {0x9bc9, 0xff, 0xa0}, |
497 | { 0xd013, 0, 8, 0x50 }, | 439 | {0xd011, 0xff, 0x56}, |
498 | { 0xd014, 0, 2, 0x00 }, | 440 | {0xd012, 0x03, 0x00}, |
499 | { 0xd040, 0, 8, 0x56 }, | 441 | {0xd013, 0xff, 0x50}, |
500 | { 0xd041, 0, 2, 0x00 }, | 442 | {0xd014, 0x03, 0x00}, |
501 | { 0xd042, 0, 8, 0x50 }, | 443 | {0xd040, 0xff, 0x56}, |
502 | { 0xd043, 0, 2, 0x00 }, | 444 | {0xd041, 0x03, 0x00}, |
503 | { 0xd045, 1, 1, 0x00 }, | 445 | {0xd042, 0xff, 0x50}, |
504 | { 0x9bcf, 0, 8, 0x01 }, | 446 | {0xd043, 0x03, 0x00}, |
505 | { 0xd045, 2, 1, 0x01 }, | 447 | {0xd045, 0x02, 0x00}, |
506 | { 0xd04f, 0, 8, 0x9a }, | 448 | {0x9bcf, 0xff, 0x01}, |
507 | { 0xd050, 0, 1, 0x01 }, | 449 | {0xd045, 0x04, 0x04}, |
508 | { 0xd051, 0, 8, 0x5a }, | 450 | {0xd04f, 0xff, 0x9a}, |
509 | { 0xd052, 0, 1, 0x01 }, | 451 | {0xd050, 0x01, 0x01}, |
510 | { 0xd053, 0, 8, 0x50 }, | 452 | {0xd051, 0xff, 0x5a}, |
511 | { 0xd054, 0, 8, 0x46 }, | 453 | {0xd052, 0x01, 0x01}, |
512 | { 0x9bd7, 0, 8, 0x0a }, | 454 | {0xd053, 0xff, 0x50}, |
513 | { 0x9bd8, 0, 8, 0x14 }, | 455 | {0xd054, 0xff, 0x46}, |
514 | { 0x9bd9, 0, 8, 0x08 }, | 456 | {0x9bd7, 0xff, 0x0a}, |
457 | {0x9bd8, 0xff, 0x14}, | ||
458 | {0x9bd9, 0xff, 0x08}, | ||
515 | }; | 459 | }; |
516 | 460 | ||
517 | /* MaxLinear MXL5005S & MXL5007T tuner init | 461 | /* |
518 | AF9013_TUNER_MXL5005D = 13 | 462 | * MaxLinear MXL5005S & MXL5007T tuner init |
519 | AF9013_TUNER_MXL5005R = 30 | 463 | * AF9013_TUNER_MXL5005D 0x0d |
520 | AF9013_TUNER_MXL5007T = 177 */ | 464 | * AF9013_TUNER_MXL5005R 0x1e |
521 | static const struct af9013_reg_bit tuner_init_mxl5005[] = { | 465 | * AF9013_TUNER_MXL5007T 0xb1 |
522 | { 0x9bd5, 0, 8, 0x01 }, | 466 | */ |
523 | { 0x9bd6, 0, 8, 0x07 }, | 467 | static const struct af9013_reg_mask_val tuner_init_tab_mxl5005[] = { |
524 | { 0xd1a0, 1, 1, 0x01 }, | 468 | {0x9bd5, 0xff, 0x01}, |
525 | { 0xd000, 0, 1, 0x01 }, | 469 | {0x9bd6, 0xff, 0x07}, |
526 | { 0xd000, 1, 1, 0x00 }, | 470 | {0xd1a0, 0x02, 0x02}, |
527 | { 0xd001, 1, 1, 0x01 }, | 471 | {0xd000, 0x01, 0x01}, |
528 | { 0xd001, 0, 1, 0x00 }, | 472 | {0xd000, 0x02, 0x00}, |
529 | { 0xd001, 5, 1, 0x00 }, | 473 | {0xd001, 0x02, 0x02}, |
530 | { 0xd002, 0, 5, 0x19 }, | 474 | {0xd001, 0x01, 0x00}, |
531 | { 0xd003, 0, 5, 0x1a }, | 475 | {0xd001, 0x20, 0x00}, |
532 | { 0xd004, 0, 5, 0x19 }, | 476 | {0xd002, 0x1f, 0x19}, |
533 | { 0xd005, 0, 5, 0x1a }, | 477 | {0xd003, 0x1f, 0x1a}, |
534 | { 0xd00e, 0, 5, 0x10 }, | 478 | {0xd004, 0x1f, 0x19}, |
535 | { 0xd00f, 0, 3, 0x04 }, | 479 | {0xd005, 0x1f, 0x1a}, |
536 | { 0xd00f, 3, 3, 0x05 }, | 480 | {0xd00e, 0x1f, 0x10}, |
537 | { 0xd010, 0, 3, 0x04 }, | 481 | {0xd00f, 0x07, 0x04}, |
538 | { 0xd010, 3, 3, 0x05 }, | 482 | {0xd00f, 0x38, 0x28}, |
539 | { 0xd016, 4, 4, 0x03 }, | 483 | {0xd010, 0x07, 0x04}, |
540 | { 0xd01f, 0, 6, 0x0a }, | 484 | {0xd010, 0x38, 0x28}, |
541 | { 0xd020, 0, 6, 0x0a }, | 485 | {0xd016, 0xf0, 0x30}, |
542 | { 0x9bda, 0, 8, 0x01 }, | 486 | {0xd01f, 0x3f, 0x0a}, |
543 | { 0x9be3, 0, 8, 0x01 }, | 487 | {0xd020, 0x3f, 0x0a}, |
544 | { 0x9bbe, 0, 1, 0x01 }, | 488 | {0x9bda, 0xff, 0x01}, |
545 | { 0x9bcc, 0, 1, 0x01 }, | 489 | {0x9be3, 0xff, 0x01}, |
546 | { 0x9bb9, 0, 8, 0x00 }, | 490 | {0x9bbe, 0x01, 0x01}, |
547 | { 0x9bcd, 0, 8, 0x28 }, | 491 | {0x9bcc, 0x01, 0x01}, |
548 | { 0x9bff, 0, 8, 0x24 }, | 492 | {0x9bb9, 0xff, 0x00}, |
549 | { 0xd015, 0, 8, 0x40 }, | 493 | {0x9bcd, 0xff, 0x28}, |
550 | { 0xd016, 0, 1, 0x00 }, | 494 | {0x9bff, 0xff, 0x24}, |
551 | { 0xd044, 0, 8, 0x40 }, | 495 | {0xd015, 0xff, 0x40}, |
552 | { 0xd045, 0, 1, 0x00 }, | 496 | {0xd016, 0x01, 0x00}, |
553 | { 0xd008, 0, 8, 0x0f }, | 497 | {0xd044, 0xff, 0x40}, |
554 | { 0xd009, 0, 2, 0x02 }, | 498 | {0xd045, 0x01, 0x00}, |
555 | { 0xd006, 0, 8, 0x73 }, | 499 | {0xd008, 0xff, 0x0f}, |
556 | { 0xd007, 0, 2, 0x01 }, | 500 | {0xd009, 0x03, 0x02}, |
557 | { 0xd00c, 0, 8, 0xfa }, | 501 | {0xd006, 0xff, 0x73}, |
558 | { 0xd00d, 0, 2, 0x01 }, | 502 | {0xd007, 0x03, 0x01}, |
559 | { 0xd00a, 0, 8, 0xff }, | 503 | {0xd00c, 0xff, 0xfa}, |
560 | { 0xd00b, 0, 2, 0x01 }, | 504 | {0xd00d, 0x03, 0x01}, |
561 | { 0x9bc7, 0, 8, 0x23 }, | 505 | {0xd00a, 0xff, 0xff}, |
562 | { 0x9bc8, 0, 8, 0x55 }, | 506 | {0xd00b, 0x03, 0x01}, |
563 | { 0x9bc3, 0, 8, 0x01 }, | 507 | {0x9bc7, 0xff, 0x23}, |
564 | { 0x9bc4, 0, 8, 0x02 }, | 508 | {0x9bc8, 0xff, 0x55}, |
565 | { 0x9bc5, 0, 8, 0xfa }, | 509 | {0x9bc3, 0xff, 0x01}, |
566 | { 0x9bc6, 0, 8, 0x01 }, | 510 | {0x9bc4, 0xff, 0x02}, |
567 | { 0x9bba, 0, 8, 0xff }, | 511 | {0x9bc5, 0xff, 0xfa}, |
568 | { 0x9bc9, 0, 8, 0xff }, | 512 | {0x9bc6, 0xff, 0x01}, |
569 | { 0x9bd3, 0, 8, 0x95 }, | 513 | {0x9bba, 0xff, 0xff}, |
570 | { 0xd011, 0, 8, 0x70 }, | 514 | {0x9bc9, 0xff, 0xff}, |
571 | { 0xd012, 0, 2, 0x01 }, | 515 | {0x9bd3, 0xff, 0x95}, |
572 | { 0xd013, 0, 8, 0xfb }, | 516 | {0xd011, 0xff, 0x70}, |
573 | { 0xd014, 0, 2, 0x01 }, | 517 | {0xd012, 0x03, 0x01}, |
574 | { 0xd040, 0, 8, 0x70 }, | 518 | {0xd013, 0xff, 0xfb}, |
575 | { 0xd041, 0, 2, 0x01 }, | 519 | {0xd014, 0x03, 0x01}, |
576 | { 0xd042, 0, 8, 0xfb }, | 520 | {0xd040, 0xff, 0x70}, |
577 | { 0xd043, 0, 2, 0x01 }, | 521 | {0xd041, 0x03, 0x01}, |
578 | { 0xd045, 1, 1, 0x00 }, | 522 | {0xd042, 0xff, 0xfb}, |
579 | { 0x9bcf, 0, 1, 0x01 }, | 523 | {0xd043, 0x03, 0x01}, |
580 | { 0xd045, 2, 1, 0x01 }, | 524 | {0xd045, 0x02, 0x00}, |
581 | { 0xd04f, 0, 8, 0x9a }, | 525 | {0x9bcf, 0x01, 0x01}, |
582 | { 0xd050, 0, 1, 0x01 }, | 526 | {0xd045, 0x04, 0x04}, |
583 | { 0xd051, 0, 8, 0x5a }, | 527 | {0xd04f, 0xff, 0x9a}, |
584 | { 0xd052, 0, 1, 0x01 }, | 528 | {0xd050, 0x01, 0x01}, |
585 | { 0xd053, 0, 8, 0x50 }, | 529 | {0xd051, 0xff, 0x5a}, |
586 | { 0xd054, 0, 8, 0x46 }, | 530 | {0xd052, 0x01, 0x01}, |
587 | { 0x9bd7, 0, 8, 0x0a }, | 531 | {0xd053, 0xff, 0x50}, |
588 | { 0x9bd8, 0, 8, 0x14 }, | 532 | {0xd054, 0xff, 0x46}, |
589 | { 0x9bd9, 0, 8, 0x08 }, | 533 | {0x9bd7, 0xff, 0x0a}, |
590 | { 0x9bd0, 0, 8, 0x93 }, | 534 | {0x9bd8, 0xff, 0x14}, |
591 | { 0x9be4, 0, 8, 0xfe }, | 535 | {0x9bd9, 0xff, 0x08}, |
592 | { 0x9bbd, 0, 8, 0x63 }, | 536 | {0x9bd0, 0xff, 0x93}, |
593 | { 0x9be2, 0, 8, 0xfe }, | 537 | {0x9be4, 0xff, 0xfe}, |
594 | { 0x9bee, 0, 1, 0x01 }, | 538 | {0x9bbd, 0xff, 0x63}, |
539 | {0x9be2, 0xff, 0xfe}, | ||
540 | {0x9bee, 0x01, 0x01}, | ||
595 | }; | 541 | }; |
596 | 542 | ||
597 | /* Quantek QT1010 tuner init | 543 | /* |
598 | AF9013_TUNER_QT1010 = 134 | 544 | * Quantek QT1010 tuner init |
599 | AF9013_TUNER_QT1010A = 162 */ | 545 | * AF9013_TUNER_QT1010 0x86 |
600 | static const struct af9013_reg_bit tuner_init_qt1010[] = { | 546 | * AF9013_TUNER_QT1010A 0xa2 |
601 | { 0x9bd5, 0, 8, 0x01 }, | 547 | */ |
602 | { 0x9bd6, 0, 8, 0x09 }, | 548 | static const struct af9013_reg_mask_val tuner_init_tab_qt1010[] = { |
603 | { 0xd1a0, 1, 1, 0x01 }, | 549 | {0x9bd5, 0xff, 0x01}, |
604 | { 0xd000, 0, 1, 0x01 }, | 550 | {0x9bd6, 0xff, 0x09}, |
605 | { 0xd000, 1, 1, 0x00 }, | 551 | {0xd1a0, 0x02, 0x02}, |
606 | { 0xd001, 1, 1, 0x01 }, | 552 | {0xd000, 0x01, 0x01}, |
607 | { 0xd001, 0, 1, 0x00 }, | 553 | {0xd000, 0x02, 0x00}, |
608 | { 0xd001, 5, 1, 0x00 }, | 554 | {0xd001, 0x02, 0x02}, |
609 | { 0xd002, 0, 5, 0x19 }, | 555 | {0xd001, 0x01, 0x00}, |
610 | { 0xd003, 0, 5, 0x1a }, | 556 | {0xd001, 0x20, 0x00}, |
611 | { 0xd004, 0, 5, 0x19 }, | 557 | {0xd002, 0x1f, 0x19}, |
612 | { 0xd005, 0, 5, 0x1a }, | 558 | {0xd003, 0x1f, 0x1a}, |
613 | { 0xd00e, 0, 5, 0x10 }, | 559 | {0xd004, 0x1f, 0x19}, |
614 | { 0xd00f, 0, 3, 0x04 }, | 560 | {0xd005, 0x1f, 0x1a}, |
615 | { 0xd00f, 3, 3, 0x05 }, | 561 | {0xd00e, 0x1f, 0x10}, |
616 | { 0xd010, 0, 3, 0x04 }, | 562 | {0xd00f, 0x07, 0x04}, |
617 | { 0xd010, 3, 3, 0x05 }, | 563 | {0xd00f, 0x38, 0x28}, |
618 | { 0xd016, 4, 4, 0x03 }, | 564 | {0xd010, 0x07, 0x04}, |
619 | { 0xd01f, 0, 6, 0x0a }, | 565 | {0xd010, 0x38, 0x28}, |
620 | { 0xd020, 0, 6, 0x0a }, | 566 | {0xd016, 0xf0, 0x30}, |
621 | { 0x9bda, 0, 8, 0x01 }, | 567 | {0xd01f, 0x3f, 0x0a}, |
622 | { 0x9be3, 0, 8, 0x01 }, | 568 | {0xd020, 0x3f, 0x0a}, |
623 | { 0xd015, 0, 8, 0x46 }, | 569 | {0x9bda, 0xff, 0x01}, |
624 | { 0xd016, 0, 1, 0x00 }, | 570 | {0x9be3, 0xff, 0x01}, |
625 | { 0xd044, 0, 8, 0x46 }, | 571 | {0xd015, 0xff, 0x46}, |
626 | { 0xd045, 0, 1, 0x00 }, | 572 | {0xd016, 0x01, 0x00}, |
627 | { 0x9bbe, 0, 1, 0x01 }, | 573 | {0xd044, 0xff, 0x46}, |
628 | { 0x9bcc, 0, 1, 0x01 }, | 574 | {0xd045, 0x01, 0x00}, |
629 | { 0x9bb9, 0, 8, 0x00 }, | 575 | {0x9bbe, 0x01, 0x01}, |
630 | { 0x9bcd, 0, 8, 0x28 }, | 576 | {0x9bcc, 0x01, 0x01}, |
631 | { 0x9bff, 0, 8, 0x20 }, | 577 | {0x9bb9, 0xff, 0x00}, |
632 | { 0xd008, 0, 8, 0x0f }, | 578 | {0x9bcd, 0xff, 0x28}, |
633 | { 0xd009, 0, 2, 0x02 }, | 579 | {0x9bff, 0xff, 0x20}, |
634 | { 0xd006, 0, 8, 0x99 }, | 580 | {0xd008, 0xff, 0x0f}, |
635 | { 0xd007, 0, 2, 0x01 }, | 581 | {0xd009, 0x03, 0x02}, |
636 | { 0xd00c, 0, 8, 0x0f }, | 582 | {0xd006, 0xff, 0x99}, |
637 | { 0xd00d, 0, 2, 0x02 }, | 583 | {0xd007, 0x03, 0x01}, |
638 | { 0xd00a, 0, 8, 0x50 }, | 584 | {0xd00c, 0xff, 0x0f}, |
639 | { 0xd00b, 0, 2, 0x01 }, | 585 | {0xd00d, 0x03, 0x02}, |
640 | { 0x9bc7, 0, 8, 0x00 }, | 586 | {0xd00a, 0xff, 0x50}, |
641 | { 0x9bc8, 0, 8, 0x00 }, | 587 | {0xd00b, 0x03, 0x01}, |
642 | { 0x9bc3, 0, 8, 0x0f }, | 588 | {0x9bc7, 0xff, 0x00}, |
643 | { 0x9bc4, 0, 8, 0x02 }, | 589 | {0x9bc8, 0xff, 0x00}, |
644 | { 0x9bc5, 0, 8, 0x0f }, | 590 | {0x9bc3, 0xff, 0x0f}, |
645 | { 0x9bc6, 0, 8, 0x02 }, | 591 | {0x9bc4, 0xff, 0x02}, |
646 | { 0x9bba, 0, 8, 0xc5 }, | 592 | {0x9bc5, 0xff, 0x0f}, |
647 | { 0x9bc9, 0, 8, 0xff }, | 593 | {0x9bc6, 0xff, 0x02}, |
648 | { 0xd011, 0, 8, 0x58 }, | 594 | {0x9bba, 0xff, 0xc5}, |
649 | { 0xd012, 0, 2, 0x02 }, | 595 | {0x9bc9, 0xff, 0xff}, |
650 | { 0xd013, 0, 8, 0x89 }, | 596 | {0xd011, 0xff, 0x58}, |
651 | { 0xd014, 0, 2, 0x01 }, | 597 | {0xd012, 0x03, 0x02}, |
652 | { 0xd040, 0, 8, 0x58 }, | 598 | {0xd013, 0xff, 0x89}, |
653 | { 0xd041, 0, 2, 0x02 }, | 599 | {0xd014, 0x03, 0x01}, |
654 | { 0xd042, 0, 8, 0x89 }, | 600 | {0xd040, 0xff, 0x58}, |
655 | { 0xd043, 0, 2, 0x01 }, | 601 | {0xd041, 0x03, 0x02}, |
656 | { 0xd045, 1, 1, 0x00 }, | 602 | {0xd042, 0xff, 0x89}, |
657 | { 0x9bcf, 0, 1, 0x01 }, | 603 | {0xd043, 0x03, 0x01}, |
658 | { 0xd045, 2, 1, 0x01 }, | 604 | {0xd045, 0x02, 0x00}, |
659 | { 0xd04f, 0, 8, 0x9a }, | 605 | {0x9bcf, 0x01, 0x01}, |
660 | { 0xd050, 0, 1, 0x01 }, | 606 | {0xd045, 0x04, 0x04}, |
661 | { 0xd051, 0, 8, 0x5a }, | 607 | {0xd04f, 0xff, 0x9a}, |
662 | { 0xd052, 0, 1, 0x01 }, | 608 | {0xd050, 0x01, 0x01}, |
663 | { 0xd053, 0, 8, 0x50 }, | 609 | {0xd051, 0xff, 0x5a}, |
664 | { 0xd054, 0, 8, 0x46 }, | 610 | {0xd052, 0x01, 0x01}, |
665 | { 0x9bd7, 0, 8, 0x0a }, | 611 | {0xd053, 0xff, 0x50}, |
666 | { 0x9bd8, 0, 8, 0x14 }, | 612 | {0xd054, 0xff, 0x46}, |
667 | { 0x9bd9, 0, 8, 0x08 }, | 613 | {0x9bd7, 0xff, 0x0a}, |
668 | { 0x9bd0, 0, 8, 0xcd }, | 614 | {0x9bd8, 0xff, 0x14}, |
669 | { 0x9be4, 0, 8, 0xbb }, | 615 | {0x9bd9, 0xff, 0x08}, |
670 | { 0x9bbd, 0, 8, 0x93 }, | 616 | {0x9bd0, 0xff, 0xcd}, |
671 | { 0x9be2, 0, 8, 0x80 }, | 617 | {0x9be4, 0xff, 0xbb}, |
672 | { 0x9bee, 0, 1, 0x01 }, | 618 | {0x9bbd, 0xff, 0x93}, |
619 | {0x9be2, 0xff, 0x80}, | ||
620 | {0x9bee, 0x01, 0x01}, | ||
673 | }; | 621 | }; |
674 | 622 | ||
675 | /* Freescale MC44S803 tuner init | 623 | /* |
676 | AF9013_TUNER_MC44S803 = 133 */ | 624 | * Freescale MC44S803 tuner init |
677 | static const struct af9013_reg_bit tuner_init_mc44s803[] = { | 625 | * AF9013_TUNER_MC44S803 0x85 |
678 | { 0x9bd5, 0, 8, 0x01 }, | 626 | */ |
679 | { 0x9bd6, 0, 8, 0x06 }, | 627 | static const struct af9013_reg_mask_val tuner_init_tab_mc44s803[] = { |
680 | { 0xd1a0, 1, 1, 0x01 }, | 628 | {0x9bd5, 0xff, 0x01}, |
681 | { 0xd000, 0, 1, 0x01 }, | 629 | {0x9bd6, 0xff, 0x06}, |
682 | { 0xd000, 1, 1, 0x00 }, | 630 | {0xd1a0, 0x02, 0x02}, |
683 | { 0xd001, 1, 1, 0x01 }, | 631 | {0xd000, 0x01, 0x01}, |
684 | { 0xd001, 0, 1, 0x00 }, | 632 | {0xd000, 0x02, 0x00}, |
685 | { 0xd001, 5, 1, 0x00 }, | 633 | {0xd001, 0x02, 0x02}, |
686 | { 0xd002, 0, 5, 0x19 }, | 634 | {0xd001, 0x01, 0x00}, |
687 | { 0xd003, 0, 5, 0x1a }, | 635 | {0xd001, 0x20, 0x00}, |
688 | { 0xd004, 0, 5, 0x19 }, | 636 | {0xd002, 0x1f, 0x19}, |
689 | { 0xd005, 0, 5, 0x1a }, | 637 | {0xd003, 0x1f, 0x1a}, |
690 | { 0xd00e, 0, 5, 0x10 }, | 638 | {0xd004, 0x1f, 0x19}, |
691 | { 0xd00f, 0, 3, 0x04 }, | 639 | {0xd005, 0x1f, 0x1a}, |
692 | { 0xd00f, 3, 3, 0x05 }, | 640 | {0xd00e, 0x1f, 0x10}, |
693 | { 0xd010, 0, 3, 0x04 }, | 641 | {0xd00f, 0x07, 0x04}, |
694 | { 0xd010, 3, 3, 0x05 }, | 642 | {0xd00f, 0x38, 0x28}, |
695 | { 0xd016, 4, 4, 0x03 }, | 643 | {0xd010, 0x07, 0x04}, |
696 | { 0xd01f, 0, 6, 0x0a }, | 644 | {0xd010, 0x38, 0x28}, |
697 | { 0xd020, 0, 6, 0x0a }, | 645 | {0xd016, 0xf0, 0x30}, |
698 | { 0x9bda, 0, 8, 0x00 }, | 646 | {0xd01f, 0x3f, 0x0a}, |
699 | { 0x9be3, 0, 8, 0x00 }, | 647 | {0xd020, 0x3f, 0x0a}, |
700 | { 0x9bf6, 0, 8, 0x01 }, | 648 | {0x9bda, 0xff, 0x00}, |
701 | { 0x9bf8, 0, 8, 0x02 }, | 649 | {0x9be3, 0xff, 0x00}, |
702 | { 0x9bf9, 0, 8, 0x02 }, | 650 | {0x9bf6, 0xff, 0x01}, |
703 | { 0x9bfc, 0, 8, 0x1f }, | 651 | {0x9bf8, 0xff, 0x02}, |
704 | { 0x9bbe, 0, 1, 0x01 }, | 652 | {0x9bf9, 0xff, 0x02}, |
705 | { 0x9bcc, 0, 1, 0x01 }, | 653 | {0x9bfc, 0xff, 0x1f}, |
706 | { 0x9bb9, 0, 8, 0x00 }, | 654 | {0x9bbe, 0x01, 0x01}, |
707 | { 0x9bcd, 0, 8, 0x24 }, | 655 | {0x9bcc, 0x01, 0x01}, |
708 | { 0x9bff, 0, 8, 0x24 }, | 656 | {0x9bb9, 0xff, 0x00}, |
709 | { 0xd015, 0, 8, 0x46 }, | 657 | {0x9bcd, 0xff, 0x24}, |
710 | { 0xd016, 0, 1, 0x00 }, | 658 | {0x9bff, 0xff, 0x24}, |
711 | { 0xd044, 0, 8, 0x46 }, | 659 | {0xd015, 0xff, 0x46}, |
712 | { 0xd045, 0, 1, 0x00 }, | 660 | {0xd016, 0x01, 0x00}, |
713 | { 0xd008, 0, 8, 0x01 }, | 661 | {0xd044, 0xff, 0x46}, |
714 | { 0xd009, 0, 2, 0x02 }, | 662 | {0xd045, 0x01, 0x00}, |
715 | { 0xd006, 0, 8, 0x7b }, | 663 | {0xd008, 0xff, 0x01}, |
716 | { 0xd007, 0, 2, 0x00 }, | 664 | {0xd009, 0x03, 0x02}, |
717 | { 0xd00c, 0, 8, 0x7c }, | 665 | {0xd006, 0xff, 0x7b}, |
718 | { 0xd00d, 0, 2, 0x02 }, | 666 | {0xd007, 0x03, 0x00}, |
719 | { 0xd00a, 0, 8, 0xfe }, | 667 | {0xd00c, 0xff, 0x7c}, |
720 | { 0xd00b, 0, 2, 0x01 }, | 668 | {0xd00d, 0x03, 0x02}, |
721 | { 0x9bc7, 0, 8, 0x08 }, | 669 | {0xd00a, 0xff, 0xfe}, |
722 | { 0x9bc8, 0, 8, 0x9a }, | 670 | {0xd00b, 0x03, 0x01}, |
723 | { 0x9bc3, 0, 8, 0x01 }, | 671 | {0x9bc7, 0xff, 0x08}, |
724 | { 0x9bc4, 0, 8, 0x02 }, | 672 | {0x9bc8, 0xff, 0x9a}, |
725 | { 0x9bc5, 0, 8, 0x7c }, | 673 | {0x9bc3, 0xff, 0x01}, |
726 | { 0x9bc6, 0, 8, 0x02 }, | 674 | {0x9bc4, 0xff, 0x02}, |
727 | { 0x9bba, 0, 8, 0xfc }, | 675 | {0x9bc5, 0xff, 0x7c}, |
728 | { 0x9bc9, 0, 8, 0xaa }, | 676 | {0x9bc6, 0xff, 0x02}, |
729 | { 0xd011, 0, 8, 0x6b }, | 677 | {0x9bba, 0xff, 0xfc}, |
730 | { 0xd012, 0, 2, 0x00 }, | 678 | {0x9bc9, 0xff, 0xaa}, |
731 | { 0xd013, 0, 8, 0x88 }, | 679 | {0xd011, 0xff, 0x6b}, |
732 | { 0xd014, 0, 2, 0x02 }, | 680 | {0xd012, 0x03, 0x00}, |
733 | { 0xd040, 0, 8, 0x6b }, | 681 | {0xd013, 0xff, 0x88}, |
734 | { 0xd041, 0, 2, 0x00 }, | 682 | {0xd014, 0x03, 0x02}, |
735 | { 0xd042, 0, 8, 0x7c }, | 683 | {0xd040, 0xff, 0x6b}, |
736 | { 0xd043, 0, 2, 0x02 }, | 684 | {0xd041, 0x03, 0x00}, |
737 | { 0xd045, 1, 1, 0x00 }, | 685 | {0xd042, 0xff, 0x7c}, |
738 | { 0x9bcf, 0, 1, 0x01 }, | 686 | {0xd043, 0x03, 0x02}, |
739 | { 0xd045, 2, 1, 0x01 }, | 687 | {0xd045, 0x02, 0x00}, |
740 | { 0xd04f, 0, 8, 0x9a }, | 688 | {0x9bcf, 0x01, 0x01}, |
741 | { 0xd050, 0, 1, 0x01 }, | 689 | {0xd045, 0x04, 0x04}, |
742 | { 0xd051, 0, 8, 0x5a }, | 690 | {0xd04f, 0xff, 0x9a}, |
743 | { 0xd052, 0, 1, 0x01 }, | 691 | {0xd050, 0x01, 0x01}, |
744 | { 0xd053, 0, 8, 0x50 }, | 692 | {0xd051, 0xff, 0x5a}, |
745 | { 0xd054, 0, 8, 0x46 }, | 693 | {0xd052, 0x01, 0x01}, |
746 | { 0x9bd7, 0, 8, 0x0a }, | 694 | {0xd053, 0xff, 0x50}, |
747 | { 0x9bd8, 0, 8, 0x14 }, | 695 | {0xd054, 0xff, 0x46}, |
748 | { 0x9bd9, 0, 8, 0x08 }, | 696 | {0x9bd7, 0xff, 0x0a}, |
749 | { 0x9bd0, 0, 8, 0x9e }, | 697 | {0x9bd8, 0xff, 0x14}, |
750 | { 0x9be4, 0, 8, 0xff }, | 698 | {0x9bd9, 0xff, 0x08}, |
751 | { 0x9bbd, 0, 8, 0x9e }, | 699 | {0x9bd0, 0xff, 0x9e}, |
752 | { 0x9be2, 0, 8, 0x25 }, | 700 | {0x9be4, 0xff, 0xff}, |
753 | { 0x9bee, 0, 1, 0x01 }, | 701 | {0x9bbd, 0xff, 0x9e}, |
754 | { 0xd73b, 3, 1, 0x00 }, | 702 | {0x9be2, 0xff, 0x25}, |
703 | {0x9bee, 0x01, 0x01}, | ||
704 | {0xd73b, 0x08, 0x00}, | ||
755 | }; | 705 | }; |
756 | 706 | ||
757 | /* unknown, probably for tin can tuner, tuner init | 707 | /* |
758 | AF9013_TUNER_UNKNOWN = 140 */ | 708 | * Unknown, probably for tin can tuner, tuner init |
759 | static const struct af9013_reg_bit tuner_init_unknown[] = { | 709 | * AF9013_TUNER_UNKNOWN 0x8c |
760 | { 0x9bd5, 0, 8, 0x01 }, | 710 | */ |
761 | { 0x9bd6, 0, 8, 0x02 }, | 711 | static const struct af9013_reg_mask_val tuner_init_tab_unknown[] = { |
762 | { 0xd1a0, 1, 1, 0x01 }, | 712 | {0x9bd5, 0xff, 0x01}, |
763 | { 0xd000, 0, 1, 0x01 }, | 713 | {0x9bd6, 0xff, 0x02}, |
764 | { 0xd000, 1, 1, 0x00 }, | 714 | {0xd1a0, 0x02, 0x02}, |
765 | { 0xd001, 1, 1, 0x01 }, | 715 | {0xd000, 0x01, 0x01}, |
766 | { 0xd001, 0, 1, 0x00 }, | 716 | {0xd000, 0x02, 0x00}, |
767 | { 0xd001, 5, 1, 0x00 }, | 717 | {0xd001, 0x02, 0x02}, |
768 | { 0xd002, 0, 5, 0x19 }, | 718 | {0xd001, 0x01, 0x00}, |
769 | { 0xd003, 0, 5, 0x1a }, | 719 | {0xd001, 0x20, 0x00}, |
770 | { 0xd004, 0, 5, 0x19 }, | 720 | {0xd002, 0x1f, 0x19}, |
771 | { 0xd005, 0, 5, 0x1a }, | 721 | {0xd003, 0x1f, 0x1a}, |
772 | { 0xd00e, 0, 5, 0x10 }, | 722 | {0xd004, 0x1f, 0x19}, |
773 | { 0xd00f, 0, 3, 0x04 }, | 723 | {0xd005, 0x1f, 0x1a}, |
774 | { 0xd00f, 3, 3, 0x05 }, | 724 | {0xd00e, 0x1f, 0x10}, |
775 | { 0xd010, 0, 3, 0x04 }, | 725 | {0xd00f, 0x07, 0x04}, |
776 | { 0xd010, 3, 3, 0x05 }, | 726 | {0xd00f, 0x38, 0x28}, |
777 | { 0xd016, 4, 4, 0x03 }, | 727 | {0xd010, 0x07, 0x04}, |
778 | { 0xd01f, 0, 6, 0x0a }, | 728 | {0xd010, 0x38, 0x28}, |
779 | { 0xd020, 0, 6, 0x0a }, | 729 | {0xd016, 0xf0, 0x30}, |
780 | { 0x9bda, 0, 8, 0x01 }, | 730 | {0xd01f, 0x3f, 0x0a}, |
781 | { 0x9be3, 0, 8, 0x01 }, | 731 | {0xd020, 0x3f, 0x0a}, |
782 | { 0xd1a0, 1, 1, 0x00 }, | 732 | {0x9bda, 0xff, 0x01}, |
783 | { 0x9bbe, 0, 1, 0x01 }, | 733 | {0x9be3, 0xff, 0x01}, |
784 | { 0x9bcc, 0, 1, 0x01 }, | 734 | {0xd1a0, 0x02, 0x00}, |
785 | { 0x9bb9, 0, 8, 0x00 }, | 735 | {0x9bbe, 0x01, 0x01}, |
786 | { 0x9bcd, 0, 8, 0x18 }, | 736 | {0x9bcc, 0x01, 0x01}, |
787 | { 0x9bff, 0, 8, 0x2c }, | 737 | {0x9bb9, 0xff, 0x00}, |
788 | { 0xd015, 0, 8, 0x46 }, | 738 | {0x9bcd, 0xff, 0x18}, |
789 | { 0xd016, 0, 1, 0x00 }, | 739 | {0x9bff, 0xff, 0x2c}, |
790 | { 0xd044, 0, 8, 0x46 }, | 740 | {0xd015, 0xff, 0x46}, |
791 | { 0xd045, 0, 1, 0x00 }, | 741 | {0xd016, 0x01, 0x00}, |
792 | { 0xd008, 0, 8, 0xdf }, | 742 | {0xd044, 0xff, 0x46}, |
793 | { 0xd009, 0, 2, 0x02 }, | 743 | {0xd045, 0x01, 0x00}, |
794 | { 0xd006, 0, 8, 0x44 }, | 744 | {0xd008, 0xff, 0xdf}, |
795 | { 0xd007, 0, 2, 0x01 }, | 745 | {0xd009, 0x03, 0x02}, |
796 | { 0xd00c, 0, 8, 0x00 }, | 746 | {0xd006, 0xff, 0x44}, |
797 | { 0xd00d, 0, 2, 0x02 }, | 747 | {0xd007, 0x03, 0x01}, |
798 | { 0xd00a, 0, 8, 0xf6 }, | 748 | {0xd00c, 0xff, 0x00}, |
799 | { 0xd00b, 0, 2, 0x01 }, | 749 | {0xd00d, 0x03, 0x02}, |
800 | { 0x9bba, 0, 8, 0xf9 }, | 750 | {0xd00a, 0xff, 0xf6}, |
801 | { 0x9bc8, 0, 8, 0xaa }, | 751 | {0xd00b, 0x03, 0x01}, |
802 | { 0x9bc3, 0, 8, 0xdf }, | 752 | {0x9bba, 0xff, 0xf9}, |
803 | { 0x9bc4, 0, 8, 0x02 }, | 753 | {0x9bc8, 0xff, 0xaa}, |
804 | { 0x9bc5, 0, 8, 0x00 }, | 754 | {0x9bc3, 0xff, 0xdf}, |
805 | { 0x9bc6, 0, 8, 0x02 }, | 755 | {0x9bc4, 0xff, 0x02}, |
806 | { 0x9bc9, 0, 8, 0xf0 }, | 756 | {0x9bc5, 0xff, 0x00}, |
807 | { 0xd011, 0, 8, 0x3c }, | 757 | {0x9bc6, 0xff, 0x02}, |
808 | { 0xd012, 0, 2, 0x01 }, | 758 | {0x9bc9, 0xff, 0xf0}, |
809 | { 0xd013, 0, 8, 0xf7 }, | 759 | {0xd011, 0xff, 0x3c}, |
810 | { 0xd014, 0, 2, 0x02 }, | 760 | {0xd012, 0x03, 0x01}, |
811 | { 0xd040, 0, 8, 0x0b }, | 761 | {0xd013, 0xff, 0xf7}, |
812 | { 0xd041, 0, 2, 0x02 }, | 762 | {0xd014, 0x03, 0x02}, |
813 | { 0xd042, 0, 8, 0x4d }, | 763 | {0xd040, 0xff, 0x0b}, |
814 | { 0xd043, 0, 2, 0x00 }, | 764 | {0xd041, 0x03, 0x02}, |
815 | { 0xd045, 1, 1, 0x00 }, | 765 | {0xd042, 0xff, 0x4d}, |
816 | { 0x9bcf, 0, 1, 0x01 }, | 766 | {0xd043, 0x03, 0x00}, |
817 | { 0xd045, 2, 1, 0x01 }, | 767 | {0xd045, 0x02, 0x00}, |
818 | { 0xd04f, 0, 8, 0x9a }, | 768 | {0x9bcf, 0x01, 0x01}, |
819 | { 0xd050, 0, 1, 0x01 }, | 769 | {0xd045, 0x04, 0x04}, |
820 | { 0xd051, 0, 8, 0x5a }, | 770 | {0xd04f, 0xff, 0x9a}, |
821 | { 0xd052, 0, 1, 0x01 }, | 771 | {0xd050, 0x01, 0x01}, |
822 | { 0xd053, 0, 8, 0x50 }, | 772 | {0xd051, 0xff, 0x5a}, |
823 | { 0xd054, 0, 8, 0x46 }, | 773 | {0xd052, 0x01, 0x01}, |
824 | { 0x9bd7, 0, 8, 0x0a }, | 774 | {0xd053, 0xff, 0x50}, |
825 | { 0x9bd8, 0, 8, 0x14 }, | 775 | {0xd054, 0xff, 0x46}, |
826 | { 0x9bd9, 0, 8, 0x08 }, | 776 | {0x9bd7, 0xff, 0x0a}, |
777 | {0x9bd8, 0xff, 0x14}, | ||
778 | {0x9bd9, 0xff, 0x08}, | ||
827 | }; | 779 | }; |
828 | 780 | ||
829 | /* NXP TDA18271 & TDA18218 tuner init | 781 | /* |
830 | AF9013_TUNER_TDA18271 = 156 | 782 | * NXP TDA18271 & TDA18218 tuner init |
831 | AF9013_TUNER_TDA18218 = 179 */ | 783 | * AF9013_TUNER_TDA18271 0x9c |
832 | static const struct af9013_reg_bit tuner_init_tda18271[] = { | 784 | * AF9013_TUNER_TDA18218 0xb3 |
833 | { 0x9bd5, 0, 8, 0x01 }, | 785 | */ |
834 | { 0x9bd6, 0, 8, 0x04 }, | 786 | static const struct af9013_reg_mask_val tuner_init_tab_tda18271[] = { |
835 | { 0xd1a0, 1, 1, 0x01 }, | 787 | {0x9bd5, 0xff, 0x01}, |
836 | { 0xd000, 0, 1, 0x01 }, | 788 | {0x9bd6, 0xff, 0x04}, |
837 | { 0xd000, 1, 1, 0x00 }, | 789 | {0xd1a0, 0x02, 0x02}, |
838 | { 0xd001, 1, 1, 0x01 }, | 790 | {0xd000, 0x01, 0x01}, |
839 | { 0xd001, 0, 1, 0x00 }, | 791 | {0xd000, 0x02, 0x00}, |
840 | { 0xd001, 5, 1, 0x00 }, | 792 | {0xd001, 0x02, 0x02}, |
841 | { 0xd002, 0, 5, 0x19 }, | 793 | {0xd001, 0x01, 0x00}, |
842 | { 0xd003, 0, 5, 0x1a }, | 794 | {0xd001, 0x20, 0x00}, |
843 | { 0xd004, 0, 5, 0x19 }, | 795 | {0xd002, 0x1f, 0x19}, |
844 | { 0xd005, 0, 5, 0x1a }, | 796 | {0xd003, 0x1f, 0x1a}, |
845 | { 0xd00e, 0, 5, 0x10 }, | 797 | {0xd004, 0x1f, 0x19}, |
846 | { 0xd00f, 0, 3, 0x04 }, | 798 | {0xd005, 0x1f, 0x1a}, |
847 | { 0xd00f, 3, 3, 0x05 }, | 799 | {0xd00e, 0x1f, 0x10}, |
848 | { 0xd010, 0, 3, 0x04 }, | 800 | {0xd00f, 0x07, 0x04}, |
849 | { 0xd010, 3, 3, 0x05 }, | 801 | {0xd00f, 0x38, 0x28}, |
850 | { 0xd016, 4, 4, 0x03 }, | 802 | {0xd010, 0x07, 0x04}, |
851 | { 0xd01f, 0, 6, 0x0a }, | 803 | {0xd010, 0x38, 0x28}, |
852 | { 0xd020, 0, 6, 0x0a }, | 804 | {0xd016, 0xf0, 0x30}, |
853 | { 0x9bda, 0, 8, 0x01 }, | 805 | {0xd01f, 0x3f, 0x0a}, |
854 | { 0x9be3, 0, 8, 0x01 }, | 806 | {0xd020, 0x3f, 0x0a}, |
855 | { 0xd1a0, 1, 1, 0x00 }, | 807 | {0x9bda, 0xff, 0x01}, |
856 | { 0x9bbe, 0, 1, 0x01 }, | 808 | {0x9be3, 0xff, 0x01}, |
857 | { 0x9bcc, 0, 1, 0x01 }, | 809 | {0xd1a0, 0x02, 0x00}, |
858 | { 0x9bb9, 0, 8, 0x00 }, | 810 | {0x9bbe, 0x01, 0x01}, |
859 | { 0x9bcd, 0, 8, 0x18 }, | 811 | {0x9bcc, 0x01, 0x01}, |
860 | { 0x9bff, 0, 8, 0x2c }, | 812 | {0x9bb9, 0xff, 0x00}, |
861 | { 0xd015, 0, 8, 0x46 }, | 813 | {0x9bcd, 0xff, 0x18}, |
862 | { 0xd016, 0, 1, 0x00 }, | 814 | {0x9bff, 0xff, 0x2c}, |
863 | { 0xd044, 0, 8, 0x46 }, | 815 | {0xd015, 0xff, 0x46}, |
864 | { 0xd045, 0, 1, 0x00 }, | 816 | {0xd016, 0x01, 0x00}, |
865 | { 0xd008, 0, 8, 0xdf }, | 817 | {0xd044, 0xff, 0x46}, |
866 | { 0xd009, 0, 2, 0x02 }, | 818 | {0xd045, 0x01, 0x00}, |
867 | { 0xd006, 0, 8, 0x44 }, | 819 | {0xd008, 0xff, 0xdf}, |
868 | { 0xd007, 0, 2, 0x01 }, | 820 | {0xd009, 0x03, 0x02}, |
869 | { 0xd00c, 0, 8, 0x00 }, | 821 | {0xd006, 0xff, 0x44}, |
870 | { 0xd00d, 0, 2, 0x02 }, | 822 | {0xd007, 0x03, 0x01}, |
871 | { 0xd00a, 0, 8, 0xf6 }, | 823 | {0xd00c, 0xff, 0x00}, |
872 | { 0xd00b, 0, 2, 0x01 }, | 824 | {0xd00d, 0x03, 0x02}, |
873 | { 0x9bba, 0, 8, 0xf9 }, | 825 | {0xd00a, 0xff, 0xf6}, |
874 | { 0x9bc8, 0, 8, 0xaa }, | 826 | {0xd00b, 0x03, 0x01}, |
875 | { 0x9bc3, 0, 8, 0xdf }, | 827 | {0x9bba, 0xff, 0xf9}, |
876 | { 0x9bc4, 0, 8, 0x02 }, | 828 | {0x9bc8, 0xff, 0xaa}, |
877 | { 0x9bc5, 0, 8, 0x00 }, | 829 | {0x9bc3, 0xff, 0xdf}, |
878 | { 0x9bc6, 0, 8, 0x02 }, | 830 | {0x9bc4, 0xff, 0x02}, |
879 | { 0x9bc9, 0, 8, 0xf0 }, | 831 | {0x9bc5, 0xff, 0x00}, |
880 | { 0xd011, 0, 8, 0x3c }, | 832 | {0x9bc6, 0xff, 0x02}, |
881 | { 0xd012, 0, 2, 0x01 }, | 833 | {0x9bc9, 0xff, 0xf0}, |
882 | { 0xd013, 0, 8, 0xf7 }, | 834 | {0xd011, 0xff, 0x3c}, |
883 | { 0xd014, 0, 2, 0x02 }, | 835 | {0xd012, 0x03, 0x01}, |
884 | { 0xd040, 0, 8, 0x0b }, | 836 | {0xd013, 0xff, 0xf7}, |
885 | { 0xd041, 0, 2, 0x02 }, | 837 | {0xd014, 0x03, 0x02}, |
886 | { 0xd042, 0, 8, 0x4d }, | 838 | {0xd040, 0xff, 0x0b}, |
887 | { 0xd043, 0, 2, 0x00 }, | 839 | {0xd041, 0x03, 0x02}, |
888 | { 0xd045, 1, 1, 0x00 }, | 840 | {0xd042, 0xff, 0x4d}, |
889 | { 0x9bcf, 0, 1, 0x01 }, | 841 | {0xd043, 0x03, 0x00}, |
890 | { 0xd045, 2, 1, 0x01 }, | 842 | {0xd045, 0x02, 0x00}, |
891 | { 0xd04f, 0, 8, 0x9a }, | 843 | {0x9bcf, 0x01, 0x01}, |
892 | { 0xd050, 0, 1, 0x01 }, | 844 | {0xd045, 0x04, 0x04}, |
893 | { 0xd051, 0, 8, 0x5a }, | 845 | {0xd04f, 0xff, 0x9a}, |
894 | { 0xd052, 0, 1, 0x01 }, | 846 | {0xd050, 0x01, 0x01}, |
895 | { 0xd053, 0, 8, 0x50 }, | 847 | {0xd051, 0xff, 0x5a}, |
896 | { 0xd054, 0, 8, 0x46 }, | 848 | {0xd052, 0x01, 0x01}, |
897 | { 0x9bd7, 0, 8, 0x0a }, | 849 | {0xd053, 0xff, 0x50}, |
898 | { 0x9bd8, 0, 8, 0x14 }, | 850 | {0xd054, 0xff, 0x46}, |
899 | { 0x9bd9, 0, 8, 0x08 }, | 851 | {0x9bd7, 0xff, 0x0a}, |
900 | { 0x9bd0, 0, 8, 0xa8 }, | 852 | {0x9bd8, 0xff, 0x14}, |
901 | { 0x9be4, 0, 8, 0x7f }, | 853 | {0x9bd9, 0xff, 0x08}, |
902 | { 0x9bbd, 0, 8, 0xa8 }, | 854 | {0x9bd0, 0xff, 0xa8}, |
903 | { 0x9be2, 0, 8, 0x20 }, | 855 | {0x9be4, 0xff, 0x7f}, |
904 | { 0x9bee, 0, 1, 0x01 }, | 856 | {0x9bbd, 0xff, 0xa8}, |
857 | {0x9be2, 0xff, 0x20}, | ||
858 | {0x9bee, 0x01, 0x01}, | ||
905 | }; | 859 | }; |
906 | 860 | ||
907 | #endif /* AF9013_PRIV_H */ | 861 | #endif /* AF9013_PRIV_H */ |
diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/media/dvb-frontends/cxd2099.c index dc9cbd8f2104..c0a5849b76bb 100644 --- a/drivers/staging/media/cxd2099/cxd2099.c +++ b/drivers/media/dvb-frontends/cxd2099.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/wait.h> | 21 | #include <linux/wait.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
22 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
@@ -33,8 +34,9 @@ static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount); | |||
33 | struct cxd { | 34 | struct cxd { |
34 | struct dvb_ca_en50221 en; | 35 | struct dvb_ca_en50221 en; |
35 | 36 | ||
36 | struct i2c_adapter *i2c; | ||
37 | struct cxd2099_cfg cfg; | 37 | struct cxd2099_cfg cfg; |
38 | struct i2c_client *client; | ||
39 | struct regmap *regmap; | ||
38 | 40 | ||
39 | u8 regs[0x23]; | 41 | u8 regs[0x23]; |
40 | u8 lastaddress; | 42 | u8 lastaddress; |
@@ -56,69 +58,12 @@ struct cxd { | |||
56 | u8 wbuf[1028]; | 58 | u8 wbuf[1028]; |
57 | }; | 59 | }; |
58 | 60 | ||
59 | static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr, | ||
60 | u8 reg, u8 data) | ||
61 | { | ||
62 | u8 m[2] = {reg, data}; | ||
63 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2}; | ||
64 | |||
65 | if (i2c_transfer(adapter, &msg, 1) != 1) { | ||
66 | dev_err(&adapter->dev, | ||
67 | "Failed to write to I2C register %02x@%02x!\n", | ||
68 | reg, adr); | ||
69 | return -1; | ||
70 | } | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int i2c_write(struct i2c_adapter *adapter, u8 adr, | ||
75 | u8 *data, u16 len) | ||
76 | { | ||
77 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len}; | ||
78 | |||
79 | if (i2c_transfer(adapter, &msg, 1) != 1) { | ||
80 | dev_err(&adapter->dev, "Failed to write to I2C!\n"); | ||
81 | return -1; | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, | ||
87 | u8 reg, u8 *val) | ||
88 | { | ||
89 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
90 | .buf = ®, .len = 1}, | ||
91 | {.addr = adr, .flags = I2C_M_RD, | ||
92 | .buf = val, .len = 1} }; | ||
93 | |||
94 | if (i2c_transfer(adapter, msgs, 2) != 2) { | ||
95 | dev_err(&adapter->dev, "error in %s()\n", __func__); | ||
96 | return -1; | ||
97 | } | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int i2c_read(struct i2c_adapter *adapter, u8 adr, | ||
102 | u8 reg, u8 *data, u16 n) | ||
103 | { | ||
104 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
105 | .buf = ®, .len = 1}, | ||
106 | {.addr = adr, .flags = I2C_M_RD, | ||
107 | .buf = data, .len = n} }; | ||
108 | |||
109 | if (i2c_transfer(adapter, msgs, 2) != 2) { | ||
110 | dev_err(&adapter->dev, "error in %s()\n", __func__); | ||
111 | return -1; | ||
112 | } | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n) | 61 | static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n) |
117 | { | 62 | { |
118 | int status = 0; | 63 | int status = 0; |
119 | 64 | ||
120 | if (ci->lastaddress != adr) | 65 | if (ci->lastaddress != adr) |
121 | status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr); | 66 | status = regmap_write(ci->regmap, 0, adr); |
122 | if (!status) { | 67 | if (!status) { |
123 | ci->lastaddress = adr; | 68 | ci->lastaddress = adr; |
124 | 69 | ||
@@ -127,7 +72,7 @@ static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n) | |||
127 | 72 | ||
128 | if (ci->cfg.max_i2c && len > ci->cfg.max_i2c) | 73 | if (ci->cfg.max_i2c && len > ci->cfg.max_i2c) |
129 | len = ci->cfg.max_i2c; | 74 | len = ci->cfg.max_i2c; |
130 | status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, len); | 75 | status = regmap_raw_read(ci->regmap, 1, data, len); |
131 | if (status) | 76 | if (status) |
132 | return status; | 77 | return status; |
133 | data += len; | 78 | data += len; |
@@ -145,64 +90,66 @@ static int read_reg(struct cxd *ci, u8 reg, u8 *val) | |||
145 | static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n) | 90 | static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n) |
146 | { | 91 | { |
147 | int status; | 92 | int status; |
148 | u8 addr[3] = {2, address & 0xff, address >> 8}; | 93 | u8 addr[2] = {address & 0xff, address >> 8}; |
149 | 94 | ||
150 | status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | 95 | status = regmap_raw_write(ci->regmap, 2, addr, 2); |
151 | if (!status) | 96 | if (!status) |
152 | status = i2c_read(ci->i2c, ci->cfg.adr, 3, data, n); | 97 | status = regmap_raw_read(ci->regmap, 3, data, n); |
153 | return status; | 98 | return status; |
154 | } | 99 | } |
155 | 100 | ||
156 | static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n) | 101 | static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n) |
157 | { | 102 | { |
158 | int status; | 103 | int status; |
159 | u8 addr[3] = {2, address & 0xff, address >> 8}; | 104 | u8 addr[2] = {address & 0xff, address >> 8}; |
160 | 105 | ||
161 | status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | 106 | status = regmap_raw_write(ci->regmap, 2, addr, 2); |
162 | if (!status) { | 107 | if (!status) { |
163 | u8 buf[256] = {3}; | 108 | u8 buf[256]; |
164 | 109 | ||
165 | memcpy(buf + 1, data, n); | 110 | memcpy(buf, data, n); |
166 | status = i2c_write(ci->i2c, ci->cfg.adr, buf, n + 1); | 111 | status = regmap_raw_write(ci->regmap, 3, buf, n); |
167 | } | 112 | } |
168 | return status; | 113 | return status; |
169 | } | 114 | } |
170 | 115 | ||
171 | static int read_io(struct cxd *ci, u16 address, u8 *val) | 116 | static int read_io(struct cxd *ci, u16 address, unsigned int *val) |
172 | { | 117 | { |
173 | int status; | 118 | int status; |
174 | u8 addr[3] = {2, address & 0xff, address >> 8}; | 119 | u8 addr[2] = {address & 0xff, address >> 8}; |
175 | 120 | ||
176 | status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | 121 | status = regmap_raw_write(ci->regmap, 2, addr, 2); |
177 | if (!status) | 122 | if (!status) |
178 | status = i2c_read(ci->i2c, ci->cfg.adr, 3, val, 1); | 123 | status = regmap_read(ci->regmap, 3, val); |
179 | return status; | 124 | return status; |
180 | } | 125 | } |
181 | 126 | ||
182 | static int write_io(struct cxd *ci, u16 address, u8 val) | 127 | static int write_io(struct cxd *ci, u16 address, u8 val) |
183 | { | 128 | { |
184 | int status; | 129 | int status; |
185 | u8 addr[3] = {2, address & 0xff, address >> 8}; | 130 | u8 addr[2] = {address & 0xff, address >> 8}; |
186 | u8 buf[2] = {3, val}; | ||
187 | 131 | ||
188 | status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | 132 | status = regmap_raw_write(ci->regmap, 2, addr, 2); |
189 | if (!status) | 133 | if (!status) |
190 | status = i2c_write(ci->i2c, ci->cfg.adr, buf, 2); | 134 | status = regmap_write(ci->regmap, 3, val); |
191 | return status; | 135 | return status; |
192 | } | 136 | } |
193 | 137 | ||
194 | static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask) | 138 | static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask) |
195 | { | 139 | { |
196 | int status = 0; | 140 | int status = 0; |
141 | unsigned int regval; | ||
197 | 142 | ||
198 | if (ci->lastaddress != reg) | 143 | if (ci->lastaddress != reg) |
199 | status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, reg); | 144 | status = regmap_write(ci->regmap, 0, reg); |
200 | if (!status && reg >= 6 && reg <= 8 && mask != 0xff) | 145 | if (!status && reg >= 6 && reg <= 8 && mask != 0xff) { |
201 | status = i2c_read_reg(ci->i2c, ci->cfg.adr, 1, &ci->regs[reg]); | 146 | status = regmap_read(ci->regmap, 1, ®val); |
147 | ci->regs[reg] = regval; | ||
148 | } | ||
202 | ci->lastaddress = reg; | 149 | ci->lastaddress = reg; |
203 | ci->regs[reg] = (ci->regs[reg] & (~mask)) | val; | 150 | ci->regs[reg] = (ci->regs[reg] & (~mask)) | val; |
204 | if (!status) | 151 | if (!status) |
205 | status = i2c_write_reg(ci->i2c, ci->cfg.adr, 1, ci->regs[reg]); | 152 | status = regmap_write(ci->regmap, 1, ci->regs[reg]); |
206 | if (reg == 0x20) | 153 | if (reg == 0x20) |
207 | ci->regs[reg] &= 0x7f; | 154 | ci->regs[reg] &= 0x7f; |
208 | return status; | 155 | return status; |
@@ -219,19 +166,18 @@ static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n) | |||
219 | u8 *buf = ci->wbuf; | 166 | u8 *buf = ci->wbuf; |
220 | 167 | ||
221 | if (ci->lastaddress != adr) | 168 | if (ci->lastaddress != adr) |
222 | status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr); | 169 | status = regmap_write(ci->regmap, 0, adr); |
223 | if (status) | 170 | if (status) |
224 | return status; | 171 | return status; |
225 | 172 | ||
226 | ci->lastaddress = adr; | 173 | ci->lastaddress = adr; |
227 | buf[0] = 1; | ||
228 | while (n) { | 174 | while (n) { |
229 | int len = n; | 175 | int len = n; |
230 | 176 | ||
231 | if (ci->cfg.max_i2c && (len + 1 > ci->cfg.max_i2c)) | 177 | if (ci->cfg.max_i2c && (len + 1 > ci->cfg.max_i2c)) |
232 | len = ci->cfg.max_i2c - 1; | 178 | len = ci->cfg.max_i2c - 1; |
233 | memcpy(buf + 1, data, len); | 179 | memcpy(buf, data, len); |
234 | status = i2c_write(ci->i2c, ci->cfg.adr, buf, len + 1); | 180 | status = regmap_raw_write(ci->regmap, 1, buf, len); |
235 | if (status) | 181 | if (status) |
236 | return status; | 182 | return status; |
237 | n -= len; | 183 | n -= len; |
@@ -273,7 +219,7 @@ static void cam_mode(struct cxd *ci, int mode) | |||
273 | if (!ci->en.read_data) | 219 | if (!ci->en.read_data) |
274 | return; | 220 | return; |
275 | ci->write_busy = 0; | 221 | ci->write_busy = 0; |
276 | dev_info(&ci->i2c->dev, "enable cam buffer mode\n"); | 222 | dev_info(&ci->client->dev, "enable cam buffer mode\n"); |
277 | write_reg(ci, 0x0d, 0x00); | 223 | write_reg(ci, 0x0d, 0x00); |
278 | write_reg(ci, 0x0e, 0x01); | 224 | write_reg(ci, 0x0e, 0x01); |
279 | write_regm(ci, 0x08, 0x40, 0x40); | 225 | write_regm(ci, 0x08, 0x40, 0x40); |
@@ -464,7 +410,7 @@ static int read_cam_control(struct dvb_ca_en50221 *ca, | |||
464 | int slot, u8 address) | 410 | int slot, u8 address) |
465 | { | 411 | { |
466 | struct cxd *ci = ca->data; | 412 | struct cxd *ci = ca->data; |
467 | u8 val; | 413 | unsigned int val; |
468 | 414 | ||
469 | mutex_lock(&ci->lock); | 415 | mutex_lock(&ci->lock); |
470 | set_mode(ci, 0); | 416 | set_mode(ci, 0); |
@@ -518,7 +464,7 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | |||
518 | { | 464 | { |
519 | struct cxd *ci = ca->data; | 465 | struct cxd *ci = ca->data; |
520 | 466 | ||
521 | dev_dbg(&ci->i2c->dev, "%s\n", __func__); | 467 | dev_dbg(&ci->client->dev, "%s\n", __func__); |
522 | if (ci->cammode) | 468 | if (ci->cammode) |
523 | read_data(ca, slot, ci->rbuf, 0); | 469 | read_data(ca, slot, ci->rbuf, 0); |
524 | mutex_lock(&ci->lock); | 470 | mutex_lock(&ci->lock); |
@@ -577,7 +523,7 @@ static int campoll(struct cxd *ci) | |||
577 | if (ci->slot_stat) { | 523 | if (ci->slot_stat) { |
578 | ci->slot_stat = 0; | 524 | ci->slot_stat = 0; |
579 | write_regm(ci, 0x03, 0x00, 0x08); | 525 | write_regm(ci, 0x03, 0x00, 0x08); |
580 | dev_info(&ci->i2c->dev, "NO CAM\n"); | 526 | dev_info(&ci->client->dev, "NO CAM\n"); |
581 | ci->ready = 0; | 527 | ci->ready = 0; |
582 | } | 528 | } |
583 | } | 529 | } |
@@ -660,26 +606,41 @@ static struct dvb_ca_en50221 en_templ = { | |||
660 | .write_data = write_data, | 606 | .write_data = write_data, |
661 | }; | 607 | }; |
662 | 608 | ||
663 | struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, | 609 | static int cxd2099_probe(struct i2c_client *client, |
664 | void *priv, | 610 | const struct i2c_device_id *id) |
665 | struct i2c_adapter *i2c) | ||
666 | { | 611 | { |
667 | struct cxd *ci; | 612 | struct cxd *ci; |
668 | u8 val; | 613 | struct cxd2099_cfg *cfg = client->dev.platform_data; |
614 | static const struct regmap_config rm_cfg = { | ||
615 | .reg_bits = 8, | ||
616 | .val_bits = 8, | ||
617 | }; | ||
618 | unsigned int val; | ||
619 | int ret; | ||
669 | 620 | ||
670 | if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) { | 621 | ci = kzalloc(sizeof(*ci), GFP_KERNEL); |
671 | dev_info(&i2c->dev, "No CXD2099AR detected at 0x%02x\n", | 622 | if (!ci) { |
672 | cfg->adr); | 623 | ret = -ENOMEM; |
673 | return NULL; | 624 | goto err; |
674 | } | 625 | } |
675 | 626 | ||
676 | ci = kzalloc(sizeof(*ci), GFP_KERNEL); | 627 | ci->client = client; |
677 | if (!ci) | 628 | memcpy(&ci->cfg, cfg, sizeof(ci->cfg)); |
678 | return NULL; | 629 | |
630 | ci->regmap = regmap_init_i2c(client, &rm_cfg); | ||
631 | if (IS_ERR(ci->regmap)) { | ||
632 | ret = PTR_ERR(ci->regmap); | ||
633 | goto err_kfree; | ||
634 | } | ||
635 | |||
636 | ret = regmap_read(ci->regmap, 0x00, &val); | ||
637 | if (ret < 0) { | ||
638 | dev_info(&client->dev, "No CXD2099AR detected at 0x%02x\n", | ||
639 | client->addr); | ||
640 | goto err_rmexit; | ||
641 | } | ||
679 | 642 | ||
680 | mutex_init(&ci->lock); | 643 | mutex_init(&ci->lock); |
681 | ci->cfg = *cfg; | ||
682 | ci->i2c = i2c; | ||
683 | ci->lastaddress = 0xff; | 644 | ci->lastaddress = 0xff; |
684 | ci->clk_reg_b = 0x4a; | 645 | ci->clk_reg_b = 0x4a; |
685 | ci->clk_reg_f = 0x1b; | 646 | ci->clk_reg_f = 0x1b; |
@@ -687,18 +648,56 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, | |||
687 | ci->en = en_templ; | 648 | ci->en = en_templ; |
688 | ci->en.data = ci; | 649 | ci->en.data = ci; |
689 | init(ci); | 650 | init(ci); |
690 | dev_info(&i2c->dev, "Attached CXD2099AR at 0x%02x\n", ci->cfg.adr); | 651 | dev_info(&client->dev, "Attached CXD2099AR at 0x%02x\n", client->addr); |
652 | |||
653 | *cfg->en = &ci->en; | ||
691 | 654 | ||
692 | if (!buffermode) { | 655 | if (!buffermode) { |
693 | ci->en.read_data = NULL; | 656 | ci->en.read_data = NULL; |
694 | ci->en.write_data = NULL; | 657 | ci->en.write_data = NULL; |
695 | } else { | 658 | } else { |
696 | dev_info(&i2c->dev, "Using CXD2099AR buffer mode"); | 659 | dev_info(&client->dev, "Using CXD2099AR buffer mode"); |
697 | } | 660 | } |
698 | 661 | ||
699 | return &ci->en; | 662 | i2c_set_clientdata(client, ci); |
663 | |||
664 | return 0; | ||
665 | |||
666 | err_rmexit: | ||
667 | regmap_exit(ci->regmap); | ||
668 | err_kfree: | ||
669 | kfree(ci); | ||
670 | err: | ||
671 | |||
672 | return ret; | ||
700 | } | 673 | } |
701 | EXPORT_SYMBOL(cxd2099_attach); | 674 | |
675 | static int cxd2099_remove(struct i2c_client *client) | ||
676 | { | ||
677 | struct cxd *ci = i2c_get_clientdata(client); | ||
678 | |||
679 | regmap_exit(ci->regmap); | ||
680 | kfree(ci); | ||
681 | |||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static const struct i2c_device_id cxd2099_id[] = { | ||
686 | {"cxd2099", 0}, | ||
687 | {} | ||
688 | }; | ||
689 | MODULE_DEVICE_TABLE(i2c, cxd2099_id); | ||
690 | |||
691 | static struct i2c_driver cxd2099_driver = { | ||
692 | .driver = { | ||
693 | .name = "cxd2099", | ||
694 | }, | ||
695 | .probe = cxd2099_probe, | ||
696 | .remove = cxd2099_remove, | ||
697 | .id_table = cxd2099_id, | ||
698 | }; | ||
699 | |||
700 | module_i2c_driver(cxd2099_driver); | ||
702 | 701 | ||
703 | MODULE_DESCRIPTION("CXD2099AR Common Interface controller driver"); | 702 | MODULE_DESCRIPTION("CXD2099AR Common Interface controller driver"); |
704 | MODULE_AUTHOR("Ralph Metzler"); | 703 | MODULE_AUTHOR("Ralph Metzler"); |
diff --git a/drivers/staging/media/cxd2099/cxd2099.h b/drivers/media/dvb-frontends/cxd2099.h index 253e3155a6df..8fa45a4c615a 100644 --- a/drivers/staging/media/cxd2099/cxd2099.h +++ b/drivers/media/dvb-frontends/cxd2099.h | |||
@@ -20,26 +20,13 @@ | |||
20 | 20 | ||
21 | struct cxd2099_cfg { | 21 | struct cxd2099_cfg { |
22 | u32 bitrate; | 22 | u32 bitrate; |
23 | u8 adr; | ||
24 | u8 polarity; | 23 | u8 polarity; |
25 | u8 clock_mode; | 24 | u8 clock_mode; |
26 | 25 | ||
27 | u32 max_i2c; | 26 | u32 max_i2c; |
28 | }; | ||
29 | |||
30 | #if defined(CONFIG_DVB_CXD2099) || \ | ||
31 | (defined(CONFIG_DVB_CXD2099_MODULE) && defined(MODULE)) | ||
32 | struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, | ||
33 | void *priv, struct i2c_adapter *i2c); | ||
34 | #else | ||
35 | 27 | ||
36 | static inline struct | 28 | /* ptr to DVB CA struct */ |
37 | dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, void *priv, | 29 | struct dvb_ca_en50221 **en; |
38 | struct i2c_adapter *i2c) | 30 | }; |
39 | { | ||
40 | dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__); | ||
41 | return NULL; | ||
42 | } | ||
43 | #endif | ||
44 | 31 | ||
45 | #endif | 32 | #endif |
diff --git a/drivers/media/dvb-frontends/cxd2880/Kconfig b/drivers/media/dvb-frontends/cxd2880/Kconfig new file mode 100644 index 000000000000..9d989676e800 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/Kconfig | |||
@@ -0,0 +1,8 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | config DVB_CXD2880 | ||
4 | tristate "Sony CXD2880 DVB-T2/T tuner + demodulator" | ||
5 | depends on DVB_CORE && SPI | ||
6 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
7 | help | ||
8 | Say Y when you want to support this frontend. \ No newline at end of file | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/Makefile b/drivers/media/dvb-frontends/cxd2880/Makefile new file mode 100644 index 000000000000..c6baa4caba19 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | cxd2880-objs := cxd2880_common.o \ | ||
4 | cxd2880_devio_spi.o \ | ||
5 | cxd2880_integ.o \ | ||
6 | cxd2880_io.o \ | ||
7 | cxd2880_spi_device.o \ | ||
8 | cxd2880_tnrdmd.o \ | ||
9 | cxd2880_tnrdmd_dvbt2.o \ | ||
10 | cxd2880_tnrdmd_dvbt2_mon.o \ | ||
11 | cxd2880_tnrdmd_dvbt.o \ | ||
12 | cxd2880_tnrdmd_dvbt_mon.o\ | ||
13 | cxd2880_tnrdmd_mon.o\ | ||
14 | cxd2880_top.o | ||
15 | |||
16 | obj-$(CONFIG_DVB_CXD2880) += cxd2880.o | ||
17 | |||
18 | ccflags-y += -Idrivers/media/dvb-frontends | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880.h b/drivers/media/dvb-frontends/cxd2880/cxd2880.h new file mode 100644 index 000000000000..4ea3510aab66 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver public definitions | ||
5 | * | ||
6 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
7 | */ | ||
8 | |||
9 | #ifndef CXD2880_H | ||
10 | #define CXD2880_H | ||
11 | |||
12 | struct cxd2880_config { | ||
13 | struct spi_device *spi; | ||
14 | struct mutex *spi_mutex; /* For SPI access exclusive control */ | ||
15 | }; | ||
16 | |||
17 | #if IS_REACHABLE(CONFIG_DVB_CXD2880) | ||
18 | extern struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe, | ||
19 | struct cxd2880_config *cfg); | ||
20 | #else | ||
21 | static inline struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe, | ||
22 | struct cxd2880_config *cfg) | ||
23 | { | ||
24 | pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||
25 | return NULL; | ||
26 | } | ||
27 | #endif /* CONFIG_DVB_CXD2880 */ | ||
28 | |||
29 | #endif /* CXD2880_H */ | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c new file mode 100644 index 000000000000..d6f5af6609c1 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c | |||
@@ -0,0 +1,21 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_common.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * common functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include "cxd2880_common.h" | ||
11 | |||
12 | int cxd2880_convert2s_complement(u32 value, u32 bitlen) | ||
13 | { | ||
14 | if (!bitlen || bitlen >= 32) | ||
15 | return (int)value; | ||
16 | |||
17 | if (value & (u32)(1 << (bitlen - 1))) | ||
18 | return (int)(GENMASK(31, bitlen) | value); | ||
19 | else | ||
20 | return (int)(GENMASK(bitlen - 1, 0) & value); | ||
21 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_common.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.h new file mode 100644 index 000000000000..b05bce71ab35 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_common.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver common definitions | ||
5 | * | ||
6 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
7 | */ | ||
8 | |||
9 | #ifndef CXD2880_COMMON_H | ||
10 | #define CXD2880_COMMON_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/string.h> | ||
16 | |||
17 | int cxd2880_convert2s_complement(u32 value, u32 bitlen); | ||
18 | |||
19 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c new file mode 100644 index 000000000000..aba59400859e --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c | |||
@@ -0,0 +1,129 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_devio_spi.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * I/O interface via SPI | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include "cxd2880_devio_spi.h" | ||
11 | |||
12 | #define BURST_WRITE_MAX 128 | ||
13 | |||
14 | static int cxd2880_io_spi_read_reg(struct cxd2880_io *io, | ||
15 | enum cxd2880_io_tgt tgt, | ||
16 | u8 sub_address, u8 *data, | ||
17 | u32 size) | ||
18 | { | ||
19 | int ret = 0; | ||
20 | struct cxd2880_spi *spi = NULL; | ||
21 | u8 send_data[6]; | ||
22 | u8 *read_data_top = data; | ||
23 | |||
24 | if (!io || !io->if_object || !data) | ||
25 | return -EINVAL; | ||
26 | |||
27 | if (sub_address + size > 0x100) | ||
28 | return -EINVAL; | ||
29 | |||
30 | spi = io->if_object; | ||
31 | |||
32 | if (tgt == CXD2880_IO_TGT_SYS) | ||
33 | send_data[0] = 0x0b; | ||
34 | else | ||
35 | send_data[0] = 0x0a; | ||
36 | |||
37 | send_data[3] = 0; | ||
38 | send_data[4] = 0; | ||
39 | send_data[5] = 0; | ||
40 | |||
41 | while (size > 0) { | ||
42 | send_data[1] = sub_address; | ||
43 | if (size > 255) | ||
44 | send_data[2] = 255; | ||
45 | else | ||
46 | send_data[2] = size; | ||
47 | |||
48 | ret = | ||
49 | spi->write_read(spi, send_data, sizeof(send_data), | ||
50 | read_data_top, send_data[2]); | ||
51 | if (ret) | ||
52 | return ret; | ||
53 | |||
54 | sub_address += send_data[2]; | ||
55 | read_data_top += send_data[2]; | ||
56 | size -= send_data[2]; | ||
57 | } | ||
58 | |||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | static int cxd2880_io_spi_write_reg(struct cxd2880_io *io, | ||
63 | enum cxd2880_io_tgt tgt, | ||
64 | u8 sub_address, | ||
65 | const u8 *data, u32 size) | ||
66 | { | ||
67 | int ret = 0; | ||
68 | struct cxd2880_spi *spi = NULL; | ||
69 | u8 send_data[BURST_WRITE_MAX + 4]; | ||
70 | const u8 *write_data_top = data; | ||
71 | |||
72 | if (!io || !io->if_object || !data) | ||
73 | return -EINVAL; | ||
74 | |||
75 | if (size > BURST_WRITE_MAX) | ||
76 | return -EINVAL; | ||
77 | |||
78 | if (sub_address + size > 0x100) | ||
79 | return -EINVAL; | ||
80 | |||
81 | spi = io->if_object; | ||
82 | |||
83 | if (tgt == CXD2880_IO_TGT_SYS) | ||
84 | send_data[0] = 0x0f; | ||
85 | else | ||
86 | send_data[0] = 0x0e; | ||
87 | |||
88 | while (size > 0) { | ||
89 | send_data[1] = sub_address; | ||
90 | if (size > 255) | ||
91 | send_data[2] = 255; | ||
92 | else | ||
93 | send_data[2] = size; | ||
94 | |||
95 | memcpy(&send_data[3], write_data_top, send_data[2]); | ||
96 | |||
97 | if (tgt == CXD2880_IO_TGT_SYS) { | ||
98 | send_data[3 + send_data[2]] = 0x00; | ||
99 | ret = spi->write(spi, send_data, send_data[2] + 4); | ||
100 | } else { | ||
101 | ret = spi->write(spi, send_data, send_data[2] + 3); | ||
102 | } | ||
103 | if (ret) | ||
104 | return ret; | ||
105 | |||
106 | sub_address += send_data[2]; | ||
107 | write_data_top += send_data[2]; | ||
108 | size -= send_data[2]; | ||
109 | } | ||
110 | |||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | int cxd2880_io_spi_create(struct cxd2880_io *io, | ||
115 | struct cxd2880_spi *spi, u8 slave_select) | ||
116 | { | ||
117 | if (!io || !spi) | ||
118 | return -EINVAL; | ||
119 | |||
120 | io->read_regs = cxd2880_io_spi_read_reg; | ||
121 | io->write_regs = cxd2880_io_spi_write_reg; | ||
122 | io->write_reg = cxd2880_io_common_write_one_reg; | ||
123 | io->if_object = spi; | ||
124 | io->i2c_address_sys = 0; | ||
125 | io->i2c_address_demod = 0; | ||
126 | io->slave_select = slave_select; | ||
127 | |||
128 | return 0; | ||
129 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h new file mode 100644 index 000000000000..27f7cb12fad4 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_devio_spi.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * I/O interface via SPI | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_DEVIO_SPI_H | ||
11 | #define CXD2880_DEVIO_SPI_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | #include "cxd2880_io.h" | ||
15 | #include "cxd2880_spi.h" | ||
16 | |||
17 | #include "cxd2880_tnrdmd.h" | ||
18 | |||
19 | int cxd2880_io_spi_create(struct cxd2880_io *io, | ||
20 | struct cxd2880_spi *spi, | ||
21 | u8 slave_select); | ||
22 | |||
23 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h new file mode 100644 index 000000000000..820f4757a520 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_dtv.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DTV related definitions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_DTV_H | ||
11 | #define CXD2880_DTV_H | ||
12 | |||
13 | enum cxd2880_dtv_sys { | ||
14 | CXD2880_DTV_SYS_UNKNOWN, | ||
15 | CXD2880_DTV_SYS_DVBT, | ||
16 | CXD2880_DTV_SYS_DVBT2, | ||
17 | CXD2880_DTV_SYS_ANY | ||
18 | }; | ||
19 | |||
20 | enum cxd2880_dtv_bandwidth { | ||
21 | CXD2880_DTV_BW_UNKNOWN = 0, | ||
22 | CXD2880_DTV_BW_1_7_MHZ = 1, | ||
23 | CXD2880_DTV_BW_5_MHZ = 5, | ||
24 | CXD2880_DTV_BW_6_MHZ = 6, | ||
25 | CXD2880_DTV_BW_7_MHZ = 7, | ||
26 | CXD2880_DTV_BW_8_MHZ = 8 | ||
27 | }; | ||
28 | |||
29 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h new file mode 100644 index 000000000000..76a1acc346ef --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_dvbt.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DVB-T related definitions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_DVBT_H | ||
11 | #define CXD2880_DVBT_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | |||
15 | enum cxd2880_dvbt_constellation { | ||
16 | CXD2880_DVBT_CONSTELLATION_QPSK, | ||
17 | CXD2880_DVBT_CONSTELLATION_16QAM, | ||
18 | CXD2880_DVBT_CONSTELLATION_64QAM, | ||
19 | CXD2880_DVBT_CONSTELLATION_RESERVED_3 | ||
20 | }; | ||
21 | |||
22 | enum cxd2880_dvbt_hierarchy { | ||
23 | CXD2880_DVBT_HIERARCHY_NON, | ||
24 | CXD2880_DVBT_HIERARCHY_1, | ||
25 | CXD2880_DVBT_HIERARCHY_2, | ||
26 | CXD2880_DVBT_HIERARCHY_4 | ||
27 | }; | ||
28 | |||
29 | enum cxd2880_dvbt_coderate { | ||
30 | CXD2880_DVBT_CODERATE_1_2, | ||
31 | CXD2880_DVBT_CODERATE_2_3, | ||
32 | CXD2880_DVBT_CODERATE_3_4, | ||
33 | CXD2880_DVBT_CODERATE_5_6, | ||
34 | CXD2880_DVBT_CODERATE_7_8, | ||
35 | CXD2880_DVBT_CODERATE_RESERVED_5, | ||
36 | CXD2880_DVBT_CODERATE_RESERVED_6, | ||
37 | CXD2880_DVBT_CODERATE_RESERVED_7 | ||
38 | }; | ||
39 | |||
40 | enum cxd2880_dvbt_guard { | ||
41 | CXD2880_DVBT_GUARD_1_32, | ||
42 | CXD2880_DVBT_GUARD_1_16, | ||
43 | CXD2880_DVBT_GUARD_1_8, | ||
44 | CXD2880_DVBT_GUARD_1_4 | ||
45 | }; | ||
46 | |||
47 | enum cxd2880_dvbt_mode { | ||
48 | CXD2880_DVBT_MODE_2K, | ||
49 | CXD2880_DVBT_MODE_8K, | ||
50 | CXD2880_DVBT_MODE_RESERVED_2, | ||
51 | CXD2880_DVBT_MODE_RESERVED_3 | ||
52 | }; | ||
53 | |||
54 | enum cxd2880_dvbt_profile { | ||
55 | CXD2880_DVBT_PROFILE_HP = 0, | ||
56 | CXD2880_DVBT_PROFILE_LP | ||
57 | }; | ||
58 | |||
59 | struct cxd2880_dvbt_tpsinfo { | ||
60 | enum cxd2880_dvbt_constellation constellation; | ||
61 | enum cxd2880_dvbt_hierarchy hierarchy; | ||
62 | enum cxd2880_dvbt_coderate rate_hp; | ||
63 | enum cxd2880_dvbt_coderate rate_lp; | ||
64 | enum cxd2880_dvbt_guard guard; | ||
65 | enum cxd2880_dvbt_mode mode; | ||
66 | u8 fnum; | ||
67 | u8 length_indicator; | ||
68 | u16 cell_id; | ||
69 | u8 cell_id_ok; | ||
70 | u8 reserved_even; | ||
71 | u8 reserved_odd; | ||
72 | }; | ||
73 | |||
74 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h new file mode 100644 index 000000000000..191047b158fe --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h | |||
@@ -0,0 +1,385 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_dvbt2.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DVB-T2 related definitions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_DVBT2_H | ||
11 | #define CXD2880_DVBT2_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | |||
15 | enum cxd2880_dvbt2_profile { | ||
16 | CXD2880_DVBT2_PROFILE_BASE, | ||
17 | CXD2880_DVBT2_PROFILE_LITE, | ||
18 | CXD2880_DVBT2_PROFILE_ANY | ||
19 | }; | ||
20 | |||
21 | enum cxd2880_dvbt2_version { | ||
22 | CXD2880_DVBT2_V111, | ||
23 | CXD2880_DVBT2_V121, | ||
24 | CXD2880_DVBT2_V131 | ||
25 | }; | ||
26 | |||
27 | enum cxd2880_dvbt2_s1 { | ||
28 | CXD2880_DVBT2_S1_BASE_SISO = 0x00, | ||
29 | CXD2880_DVBT2_S1_BASE_MISO = 0x01, | ||
30 | CXD2880_DVBT2_S1_NON_DVBT2 = 0x02, | ||
31 | CXD2880_DVBT2_S1_LITE_SISO = 0x03, | ||
32 | CXD2880_DVBT2_S1_LITE_MISO = 0x04, | ||
33 | CXD2880_DVBT2_S1_RSVD3 = 0x05, | ||
34 | CXD2880_DVBT2_S1_RSVD4 = 0x06, | ||
35 | CXD2880_DVBT2_S1_RSVD5 = 0x07, | ||
36 | CXD2880_DVBT2_S1_UNKNOWN = 0xff | ||
37 | }; | ||
38 | |||
39 | enum cxd2880_dvbt2_base_s2 { | ||
40 | CXD2880_DVBT2_BASE_S2_M2K_G_ANY = 0x00, | ||
41 | CXD2880_DVBT2_BASE_S2_M8K_G_DVBT = 0x01, | ||
42 | CXD2880_DVBT2_BASE_S2_M4K_G_ANY = 0x02, | ||
43 | CXD2880_DVBT2_BASE_S2_M1K_G_ANY = 0x03, | ||
44 | CXD2880_DVBT2_BASE_S2_M16K_G_ANY = 0x04, | ||
45 | CXD2880_DVBT2_BASE_S2_M32K_G_DVBT = 0x05, | ||
46 | CXD2880_DVBT2_BASE_S2_M8K_G_DVBT2 = 0x06, | ||
47 | CXD2880_DVBT2_BASE_S2_M32K_G_DVBT2 = 0x07, | ||
48 | CXD2880_DVBT2_BASE_S2_UNKNOWN = 0xff | ||
49 | }; | ||
50 | |||
51 | enum cxd2880_dvbt2_lite_s2 { | ||
52 | CXD2880_DVBT2_LITE_S2_M2K_G_ANY = 0x00, | ||
53 | CXD2880_DVBT2_LITE_S2_M8K_G_DVBT = 0x01, | ||
54 | CXD2880_DVBT2_LITE_S2_M4K_G_ANY = 0x02, | ||
55 | CXD2880_DVBT2_LITE_S2_M16K_G_DVBT2 = 0x03, | ||
56 | CXD2880_DVBT2_LITE_S2_M16K_G_DVBT = 0x04, | ||
57 | CXD2880_DVBT2_LITE_S2_RSVD1 = 0x05, | ||
58 | CXD2880_DVBT2_LITE_S2_M8K_G_DVBT2 = 0x06, | ||
59 | CXD2880_DVBT2_LITE_S2_RSVD2 = 0x07, | ||
60 | CXD2880_DVBT2_LITE_S2_UNKNOWN = 0xff | ||
61 | }; | ||
62 | |||
63 | enum cxd2880_dvbt2_guard { | ||
64 | CXD2880_DVBT2_G1_32 = 0x00, | ||
65 | CXD2880_DVBT2_G1_16 = 0x01, | ||
66 | CXD2880_DVBT2_G1_8 = 0x02, | ||
67 | CXD2880_DVBT2_G1_4 = 0x03, | ||
68 | CXD2880_DVBT2_G1_128 = 0x04, | ||
69 | CXD2880_DVBT2_G19_128 = 0x05, | ||
70 | CXD2880_DVBT2_G19_256 = 0x06, | ||
71 | CXD2880_DVBT2_G_RSVD1 = 0x07, | ||
72 | CXD2880_DVBT2_G_UNKNOWN = 0xff | ||
73 | }; | ||
74 | |||
75 | enum cxd2880_dvbt2_mode { | ||
76 | CXD2880_DVBT2_M2K = 0x00, | ||
77 | CXD2880_DVBT2_M8K = 0x01, | ||
78 | CXD2880_DVBT2_M4K = 0x02, | ||
79 | CXD2880_DVBT2_M1K = 0x03, | ||
80 | CXD2880_DVBT2_M16K = 0x04, | ||
81 | CXD2880_DVBT2_M32K = 0x05, | ||
82 | CXD2880_DVBT2_M_RSVD1 = 0x06, | ||
83 | CXD2880_DVBT2_M_RSVD2 = 0x07 | ||
84 | }; | ||
85 | |||
86 | enum cxd2880_dvbt2_bw { | ||
87 | CXD2880_DVBT2_BW_8 = 0x00, | ||
88 | CXD2880_DVBT2_BW_7 = 0x01, | ||
89 | CXD2880_DVBT2_BW_6 = 0x02, | ||
90 | CXD2880_DVBT2_BW_5 = 0x03, | ||
91 | CXD2880_DVBT2_BW_10 = 0x04, | ||
92 | CXD2880_DVBT2_BW_1_7 = 0x05, | ||
93 | CXD2880_DVBT2_BW_RSVD1 = 0x06, | ||
94 | CXD2880_DVBT2_BW_RSVD2 = 0x07, | ||
95 | CXD2880_DVBT2_BW_RSVD3 = 0x08, | ||
96 | CXD2880_DVBT2_BW_RSVD4 = 0x09, | ||
97 | CXD2880_DVBT2_BW_RSVD5 = 0x0a, | ||
98 | CXD2880_DVBT2_BW_RSVD6 = 0x0b, | ||
99 | CXD2880_DVBT2_BW_RSVD7 = 0x0c, | ||
100 | CXD2880_DVBT2_BW_RSVD8 = 0x0d, | ||
101 | CXD2880_DVBT2_BW_RSVD9 = 0x0e, | ||
102 | CXD2880_DVBT2_BW_RSVD10 = 0x0f, | ||
103 | CXD2880_DVBT2_BW_UNKNOWN = 0xff | ||
104 | }; | ||
105 | |||
106 | enum cxd2880_dvbt2_l1pre_type { | ||
107 | CXD2880_DVBT2_L1PRE_TYPE_TS = 0x00, | ||
108 | CXD2880_DVBT2_L1PRE_TYPE_GS = 0x01, | ||
109 | CXD2880_DVBT2_L1PRE_TYPE_TS_GS = 0x02, | ||
110 | CXD2880_DVBT2_L1PRE_TYPE_RESERVED = 0x03, | ||
111 | CXD2880_DVBT2_L1PRE_TYPE_UNKNOWN = 0xff | ||
112 | }; | ||
113 | |||
114 | enum cxd2880_dvbt2_papr { | ||
115 | CXD2880_DVBT2_PAPR_0 = 0x00, | ||
116 | CXD2880_DVBT2_PAPR_1 = 0x01, | ||
117 | CXD2880_DVBT2_PAPR_2 = 0x02, | ||
118 | CXD2880_DVBT2_PAPR_3 = 0x03, | ||
119 | CXD2880_DVBT2_PAPR_RSVD1 = 0x04, | ||
120 | CXD2880_DVBT2_PAPR_RSVD2 = 0x05, | ||
121 | CXD2880_DVBT2_PAPR_RSVD3 = 0x06, | ||
122 | CXD2880_DVBT2_PAPR_RSVD4 = 0x07, | ||
123 | CXD2880_DVBT2_PAPR_RSVD5 = 0x08, | ||
124 | CXD2880_DVBT2_PAPR_RSVD6 = 0x09, | ||
125 | CXD2880_DVBT2_PAPR_RSVD7 = 0x0a, | ||
126 | CXD2880_DVBT2_PAPR_RSVD8 = 0x0b, | ||
127 | CXD2880_DVBT2_PAPR_RSVD9 = 0x0c, | ||
128 | CXD2880_DVBT2_PAPR_RSVD10 = 0x0d, | ||
129 | CXD2880_DVBT2_PAPR_RSVD11 = 0x0e, | ||
130 | CXD2880_DVBT2_PAPR_RSVD12 = 0x0f, | ||
131 | CXD2880_DVBT2_PAPR_UNKNOWN = 0xff | ||
132 | }; | ||
133 | |||
134 | enum cxd2880_dvbt2_l1post_constell { | ||
135 | CXD2880_DVBT2_L1POST_BPSK = 0x00, | ||
136 | CXD2880_DVBT2_L1POST_QPSK = 0x01, | ||
137 | CXD2880_DVBT2_L1POST_QAM16 = 0x02, | ||
138 | CXD2880_DVBT2_L1POST_QAM64 = 0x03, | ||
139 | CXD2880_DVBT2_L1POST_C_RSVD1 = 0x04, | ||
140 | CXD2880_DVBT2_L1POST_C_RSVD2 = 0x05, | ||
141 | CXD2880_DVBT2_L1POST_C_RSVD3 = 0x06, | ||
142 | CXD2880_DVBT2_L1POST_C_RSVD4 = 0x07, | ||
143 | CXD2880_DVBT2_L1POST_C_RSVD5 = 0x08, | ||
144 | CXD2880_DVBT2_L1POST_C_RSVD6 = 0x09, | ||
145 | CXD2880_DVBT2_L1POST_C_RSVD7 = 0x0a, | ||
146 | CXD2880_DVBT2_L1POST_C_RSVD8 = 0x0b, | ||
147 | CXD2880_DVBT2_L1POST_C_RSVD9 = 0x0c, | ||
148 | CXD2880_DVBT2_L1POST_C_RSVD10 = 0x0d, | ||
149 | CXD2880_DVBT2_L1POST_C_RSVD11 = 0x0e, | ||
150 | CXD2880_DVBT2_L1POST_C_RSVD12 = 0x0f, | ||
151 | CXD2880_DVBT2_L1POST_CONSTELL_UNKNOWN = 0xff | ||
152 | }; | ||
153 | |||
154 | enum cxd2880_dvbt2_l1post_cr { | ||
155 | CXD2880_DVBT2_L1POST_R1_2 = 0x00, | ||
156 | CXD2880_DVBT2_L1POST_R_RSVD1 = 0x01, | ||
157 | CXD2880_DVBT2_L1POST_R_RSVD2 = 0x02, | ||
158 | CXD2880_DVBT2_L1POST_R_RSVD3 = 0x03, | ||
159 | CXD2880_DVBT2_L1POST_R_UNKNOWN = 0xff | ||
160 | }; | ||
161 | |||
162 | enum cxd2880_dvbt2_l1post_fec_type { | ||
163 | CXD2880_DVBT2_L1POST_FEC_LDPC16K = 0x00, | ||
164 | CXD2880_DVBT2_L1POST_FEC_RSVD1 = 0x01, | ||
165 | CXD2880_DVBT2_L1POST_FEC_RSVD2 = 0x02, | ||
166 | CXD2880_DVBT2_L1POST_FEC_RSVD3 = 0x03, | ||
167 | CXD2880_DVBT2_L1POST_FEC_UNKNOWN = 0xff | ||
168 | }; | ||
169 | |||
170 | enum cxd2880_dvbt2_pp { | ||
171 | CXD2880_DVBT2_PP1 = 0x00, | ||
172 | CXD2880_DVBT2_PP2 = 0x01, | ||
173 | CXD2880_DVBT2_PP3 = 0x02, | ||
174 | CXD2880_DVBT2_PP4 = 0x03, | ||
175 | CXD2880_DVBT2_PP5 = 0x04, | ||
176 | CXD2880_DVBT2_PP6 = 0x05, | ||
177 | CXD2880_DVBT2_PP7 = 0x06, | ||
178 | CXD2880_DVBT2_PP8 = 0x07, | ||
179 | CXD2880_DVBT2_PP_RSVD1 = 0x08, | ||
180 | CXD2880_DVBT2_PP_RSVD2 = 0x09, | ||
181 | CXD2880_DVBT2_PP_RSVD3 = 0x0a, | ||
182 | CXD2880_DVBT2_PP_RSVD4 = 0x0b, | ||
183 | CXD2880_DVBT2_PP_RSVD5 = 0x0c, | ||
184 | CXD2880_DVBT2_PP_RSVD6 = 0x0d, | ||
185 | CXD2880_DVBT2_PP_RSVD7 = 0x0e, | ||
186 | CXD2880_DVBT2_PP_RSVD8 = 0x0f, | ||
187 | CXD2880_DVBT2_PP_UNKNOWN = 0xff | ||
188 | }; | ||
189 | |||
190 | enum cxd2880_dvbt2_plp_code_rate { | ||
191 | CXD2880_DVBT2_R1_2 = 0x00, | ||
192 | CXD2880_DVBT2_R3_5 = 0x01, | ||
193 | CXD2880_DVBT2_R2_3 = 0x02, | ||
194 | CXD2880_DVBT2_R3_4 = 0x03, | ||
195 | CXD2880_DVBT2_R4_5 = 0x04, | ||
196 | CXD2880_DVBT2_R5_6 = 0x05, | ||
197 | CXD2880_DVBT2_R1_3 = 0x06, | ||
198 | CXD2880_DVBT2_R2_5 = 0x07, | ||
199 | CXD2880_DVBT2_PLP_CR_UNKNOWN = 0xff | ||
200 | }; | ||
201 | |||
202 | enum cxd2880_dvbt2_plp_constell { | ||
203 | CXD2880_DVBT2_QPSK = 0x00, | ||
204 | CXD2880_DVBT2_QAM16 = 0x01, | ||
205 | CXD2880_DVBT2_QAM64 = 0x02, | ||
206 | CXD2880_DVBT2_QAM256 = 0x03, | ||
207 | CXD2880_DVBT2_CON_RSVD1 = 0x04, | ||
208 | CXD2880_DVBT2_CON_RSVD2 = 0x05, | ||
209 | CXD2880_DVBT2_CON_RSVD3 = 0x06, | ||
210 | CXD2880_DVBT2_CON_RSVD4 = 0x07, | ||
211 | CXD2880_DVBT2_CONSTELL_UNKNOWN = 0xff | ||
212 | }; | ||
213 | |||
214 | enum cxd2880_dvbt2_plp_type { | ||
215 | CXD2880_DVBT2_PLP_TYPE_COMMON = 0x00, | ||
216 | CXD2880_DVBT2_PLP_TYPE_DATA1 = 0x01, | ||
217 | CXD2880_DVBT2_PLP_TYPE_DATA2 = 0x02, | ||
218 | CXD2880_DVBT2_PLP_TYPE_RSVD1 = 0x03, | ||
219 | CXD2880_DVBT2_PLP_TYPE_RSVD2 = 0x04, | ||
220 | CXD2880_DVBT2_PLP_TYPE_RSVD3 = 0x05, | ||
221 | CXD2880_DVBT2_PLP_TYPE_RSVD4 = 0x06, | ||
222 | CXD2880_DVBT2_PLP_TYPE_RSVD5 = 0x07, | ||
223 | CXD2880_DVBT2_PLP_TYPE_UNKNOWN = 0xff | ||
224 | }; | ||
225 | |||
226 | enum cxd2880_dvbt2_plp_payload { | ||
227 | CXD2880_DVBT2_PLP_PAYLOAD_GFPS = 0x00, | ||
228 | CXD2880_DVBT2_PLP_PAYLOAD_GCS = 0x01, | ||
229 | CXD2880_DVBT2_PLP_PAYLOAD_GSE = 0x02, | ||
230 | CXD2880_DVBT2_PLP_PAYLOAD_TS = 0x03, | ||
231 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD1 = 0x04, | ||
232 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD2 = 0x05, | ||
233 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD3 = 0x06, | ||
234 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD4 = 0x07, | ||
235 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD5 = 0x08, | ||
236 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD6 = 0x09, | ||
237 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD7 = 0x0a, | ||
238 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD8 = 0x0b, | ||
239 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD9 = 0x0c, | ||
240 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD10 = 0x0d, | ||
241 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD11 = 0x0e, | ||
242 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD12 = 0x0f, | ||
243 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD13 = 0x10, | ||
244 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD14 = 0x11, | ||
245 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD15 = 0x12, | ||
246 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD16 = 0x13, | ||
247 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD17 = 0x14, | ||
248 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD18 = 0x15, | ||
249 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD19 = 0x16, | ||
250 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD20 = 0x17, | ||
251 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD21 = 0x18, | ||
252 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD22 = 0x19, | ||
253 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD23 = 0x1a, | ||
254 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD24 = 0x1b, | ||
255 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD25 = 0x1c, | ||
256 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD26 = 0x1d, | ||
257 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD27 = 0x1e, | ||
258 | CXD2880_DVBT2_PLP_PAYLOAD_RSVD28 = 0x1f, | ||
259 | CXD2880_DVBT2_PLP_PAYLOAD_UNKNOWN = 0xff | ||
260 | }; | ||
261 | |||
262 | enum cxd2880_dvbt2_plp_fec { | ||
263 | CXD2880_DVBT2_FEC_LDPC_16K = 0x00, | ||
264 | CXD2880_DVBT2_FEC_LDPC_64K = 0x01, | ||
265 | CXD2880_DVBT2_FEC_RSVD1 = 0x02, | ||
266 | CXD2880_DVBT2_FEC_RSVD2 = 0x03, | ||
267 | CXD2880_DVBT2_FEC_UNKNOWN = 0xff | ||
268 | }; | ||
269 | |||
270 | enum cxd2880_dvbt2_plp_mode { | ||
271 | CXD2880_DVBT2_PLP_MODE_NOTSPECIFIED = 0x00, | ||
272 | CXD2880_DVBT2_PLP_MODE_NM = 0x01, | ||
273 | CXD2880_DVBT2_PLP_MODE_HEM = 0x02, | ||
274 | CXD2880_DVBT2_PLP_MODE_RESERVED = 0x03, | ||
275 | CXD2880_DVBT2_PLP_MODE_UNKNOWN = 0xff | ||
276 | }; | ||
277 | |||
278 | enum cxd2880_dvbt2_plp_btype { | ||
279 | CXD2880_DVBT2_PLP_COMMON, | ||
280 | CXD2880_DVBT2_PLP_DATA | ||
281 | }; | ||
282 | |||
283 | enum cxd2880_dvbt2_stream { | ||
284 | CXD2880_DVBT2_STREAM_GENERIC_PACKETIZED = 0x00, | ||
285 | CXD2880_DVBT2_STREAM_GENERIC_CONTINUOUS = 0x01, | ||
286 | CXD2880_DVBT2_STREAM_GENERIC_ENCAPSULATED = 0x02, | ||
287 | CXD2880_DVBT2_STREAM_TRANSPORT = 0x03, | ||
288 | CXD2880_DVBT2_STREAM_UNKNOWN = 0xff | ||
289 | }; | ||
290 | |||
291 | struct cxd2880_dvbt2_l1pre { | ||
292 | enum cxd2880_dvbt2_l1pre_type type; | ||
293 | u8 bw_ext; | ||
294 | enum cxd2880_dvbt2_s1 s1; | ||
295 | u8 s2; | ||
296 | u8 mixed; | ||
297 | enum cxd2880_dvbt2_mode fft_mode; | ||
298 | u8 l1_rep; | ||
299 | enum cxd2880_dvbt2_guard gi; | ||
300 | enum cxd2880_dvbt2_papr papr; | ||
301 | enum cxd2880_dvbt2_l1post_constell mod; | ||
302 | enum cxd2880_dvbt2_l1post_cr cr; | ||
303 | enum cxd2880_dvbt2_l1post_fec_type fec; | ||
304 | u32 l1_post_size; | ||
305 | u32 l1_post_info_size; | ||
306 | enum cxd2880_dvbt2_pp pp; | ||
307 | u8 tx_id_availability; | ||
308 | u16 cell_id; | ||
309 | u16 network_id; | ||
310 | u16 sys_id; | ||
311 | u8 num_frames; | ||
312 | u16 num_symbols; | ||
313 | u8 regen; | ||
314 | u8 post_ext; | ||
315 | u8 num_rf_freqs; | ||
316 | u8 rf_idx; | ||
317 | enum cxd2880_dvbt2_version t2_version; | ||
318 | u8 l1_post_scrambled; | ||
319 | u8 t2_base_lite; | ||
320 | u32 crc32; | ||
321 | }; | ||
322 | |||
323 | struct cxd2880_dvbt2_plp { | ||
324 | u8 id; | ||
325 | enum cxd2880_dvbt2_plp_type type; | ||
326 | enum cxd2880_dvbt2_plp_payload payload; | ||
327 | u8 ff; | ||
328 | u8 first_rf_idx; | ||
329 | u8 first_frm_idx; | ||
330 | u8 group_id; | ||
331 | enum cxd2880_dvbt2_plp_constell constell; | ||
332 | enum cxd2880_dvbt2_plp_code_rate plp_cr; | ||
333 | u8 rot; | ||
334 | enum cxd2880_dvbt2_plp_fec fec; | ||
335 | u16 num_blocks_max; | ||
336 | u8 frm_int; | ||
337 | u8 til_len; | ||
338 | u8 til_type; | ||
339 | u8 in_band_a_flag; | ||
340 | u8 in_band_b_flag; | ||
341 | u16 rsvd; | ||
342 | enum cxd2880_dvbt2_plp_mode plp_mode; | ||
343 | u8 static_flag; | ||
344 | u8 static_padding_flag; | ||
345 | }; | ||
346 | |||
347 | struct cxd2880_dvbt2_l1post { | ||
348 | u16 sub_slices_per_frame; | ||
349 | u8 num_plps; | ||
350 | u8 num_aux; | ||
351 | u8 aux_cfg_rfu; | ||
352 | u8 rf_idx; | ||
353 | u32 freq; | ||
354 | u8 fef_type; | ||
355 | u32 fef_length; | ||
356 | u8 fef_intvl; | ||
357 | }; | ||
358 | |||
359 | struct cxd2880_dvbt2_ofdm { | ||
360 | u8 mixed; | ||
361 | u8 is_miso; | ||
362 | enum cxd2880_dvbt2_mode mode; | ||
363 | enum cxd2880_dvbt2_guard gi; | ||
364 | enum cxd2880_dvbt2_pp pp; | ||
365 | u8 bw_ext; | ||
366 | enum cxd2880_dvbt2_papr papr; | ||
367 | u16 num_symbols; | ||
368 | }; | ||
369 | |||
370 | struct cxd2880_dvbt2_bbheader { | ||
371 | enum cxd2880_dvbt2_stream stream_input; | ||
372 | u8 is_single_input_stream; | ||
373 | u8 is_constant_coding_modulation; | ||
374 | u8 issy_indicator; | ||
375 | u8 null_packet_deletion; | ||
376 | u8 ext; | ||
377 | u8 input_stream_identifier; | ||
378 | u16 user_packet_length; | ||
379 | u16 data_field_length; | ||
380 | u8 sync_byte; | ||
381 | u32 issy; | ||
382 | enum cxd2880_dvbt2_plp_mode plp_mode; | ||
383 | }; | ||
384 | |||
385 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c new file mode 100644 index 000000000000..5302ab0964c1 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c | |||
@@ -0,0 +1,72 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_integ.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * integration layer common functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include <linux/ktime.h> | ||
11 | #include <linux/errno.h> | ||
12 | |||
13 | #include "cxd2880_tnrdmd.h" | ||
14 | #include "cxd2880_tnrdmd_mon.h" | ||
15 | #include "cxd2880_integ.h" | ||
16 | |||
17 | int cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd) | ||
18 | { | ||
19 | int ret; | ||
20 | ktime_t start; | ||
21 | u8 cpu_task_completed = 0; | ||
22 | |||
23 | if (!tnr_dmd) | ||
24 | return -EINVAL; | ||
25 | |||
26 | ret = cxd2880_tnrdmd_init1(tnr_dmd); | ||
27 | if (ret) | ||
28 | return ret; | ||
29 | |||
30 | start = ktime_get(); | ||
31 | |||
32 | while (1) { | ||
33 | ret = | ||
34 | cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd, | ||
35 | &cpu_task_completed); | ||
36 | if (ret) | ||
37 | return ret; | ||
38 | |||
39 | if (cpu_task_completed) | ||
40 | break; | ||
41 | |||
42 | if (ktime_to_ms(ktime_sub(ktime_get(), start)) > | ||
43 | CXD2880_TNRDMD_WAIT_INIT_TIMEOUT) | ||
44 | return -ETIMEDOUT; | ||
45 | |||
46 | usleep_range(CXD2880_TNRDMD_WAIT_INIT_INTVL, | ||
47 | CXD2880_TNRDMD_WAIT_INIT_INTVL + 1000); | ||
48 | } | ||
49 | |||
50 | return cxd2880_tnrdmd_init2(tnr_dmd); | ||
51 | } | ||
52 | |||
53 | int cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd) | ||
54 | { | ||
55 | if (!tnr_dmd) | ||
56 | return -EINVAL; | ||
57 | |||
58 | atomic_set(&tnr_dmd->cancel, 1); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | int cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd *tnr_dmd) | ||
64 | { | ||
65 | if (!tnr_dmd) | ||
66 | return -EINVAL; | ||
67 | |||
68 | if (atomic_read(&tnr_dmd->cancel) != 0) | ||
69 | return -ECANCELED; | ||
70 | |||
71 | return 0; | ||
72 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h new file mode 100644 index 000000000000..7160225db8b9 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_integ.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * integration layer common interface | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_INTEG_H | ||
11 | #define CXD2880_INTEG_H | ||
12 | |||
13 | #include "cxd2880_tnrdmd.h" | ||
14 | |||
15 | #define CXD2880_TNRDMD_WAIT_INIT_TIMEOUT 500 | ||
16 | #define CXD2880_TNRDMD_WAIT_INIT_INTVL 10 | ||
17 | |||
18 | #define CXD2880_TNRDMD_WAIT_AGC_STABLE 100 | ||
19 | |||
20 | int cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd); | ||
21 | |||
22 | int cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd); | ||
23 | |||
24 | int cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd | ||
25 | *tnr_dmd); | ||
26 | |||
27 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_io.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.c new file mode 100644 index 000000000000..9d932bccfa6c --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.c | |||
@@ -0,0 +1,66 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_io.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * register I/O interface functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include "cxd2880_io.h" | ||
11 | |||
12 | int cxd2880_io_common_write_one_reg(struct cxd2880_io *io, | ||
13 | enum cxd2880_io_tgt tgt, | ||
14 | u8 sub_address, u8 data) | ||
15 | { | ||
16 | if (!io) | ||
17 | return -EINVAL; | ||
18 | |||
19 | return io->write_regs(io, tgt, sub_address, &data, 1); | ||
20 | } | ||
21 | |||
22 | int cxd2880_io_set_reg_bits(struct cxd2880_io *io, | ||
23 | enum cxd2880_io_tgt tgt, | ||
24 | u8 sub_address, u8 data, u8 mask) | ||
25 | { | ||
26 | int ret; | ||
27 | |||
28 | if (!io) | ||
29 | return -EINVAL; | ||
30 | |||
31 | if (mask == 0x00) | ||
32 | return 0; | ||
33 | |||
34 | if (mask != 0xff) { | ||
35 | u8 rdata = 0x00; | ||
36 | |||
37 | ret = io->read_regs(io, tgt, sub_address, &rdata, 1); | ||
38 | if (ret) | ||
39 | return ret; | ||
40 | |||
41 | data = (data & mask) | (rdata & (mask ^ 0xff)); | ||
42 | } | ||
43 | |||
44 | return io->write_reg(io, tgt, sub_address, data); | ||
45 | } | ||
46 | |||
47 | int cxd2880_io_write_multi_regs(struct cxd2880_io *io, | ||
48 | enum cxd2880_io_tgt tgt, | ||
49 | const struct cxd2880_reg_value reg_value[], | ||
50 | u8 size) | ||
51 | { | ||
52 | int ret; | ||
53 | int i; | ||
54 | |||
55 | if (!io) | ||
56 | return -EINVAL; | ||
57 | |||
58 | for (i = 0; i < size ; i++) { | ||
59 | ret = io->write_reg(io, tgt, reg_value[i].addr, | ||
60 | reg_value[i].value); | ||
61 | if (ret) | ||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_io.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.h new file mode 100644 index 000000000000..ba550278881d --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_io.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_io.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * register I/O interface definitions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_IO_H | ||
11 | #define CXD2880_IO_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | |||
15 | enum cxd2880_io_tgt { | ||
16 | CXD2880_IO_TGT_SYS, | ||
17 | CXD2880_IO_TGT_DMD | ||
18 | }; | ||
19 | |||
20 | struct cxd2880_reg_value { | ||
21 | u8 addr; | ||
22 | u8 value; | ||
23 | }; | ||
24 | |||
25 | struct cxd2880_io { | ||
26 | int (*read_regs)(struct cxd2880_io *io, | ||
27 | enum cxd2880_io_tgt tgt, u8 sub_address, | ||
28 | u8 *data, u32 size); | ||
29 | int (*write_regs)(struct cxd2880_io *io, | ||
30 | enum cxd2880_io_tgt tgt, u8 sub_address, | ||
31 | const u8 *data, u32 size); | ||
32 | int (*write_reg)(struct cxd2880_io *io, | ||
33 | enum cxd2880_io_tgt tgt, u8 sub_address, | ||
34 | u8 data); | ||
35 | void *if_object; | ||
36 | u8 i2c_address_sys; | ||
37 | u8 i2c_address_demod; | ||
38 | u8 slave_select; | ||
39 | void *user; | ||
40 | }; | ||
41 | |||
42 | int cxd2880_io_common_write_one_reg(struct cxd2880_io *io, | ||
43 | enum cxd2880_io_tgt tgt, | ||
44 | u8 sub_address, u8 data); | ||
45 | |||
46 | int cxd2880_io_set_reg_bits(struct cxd2880_io *io, | ||
47 | enum cxd2880_io_tgt tgt, | ||
48 | u8 sub_address, u8 data, u8 mask); | ||
49 | |||
50 | int cxd2880_io_write_multi_regs(struct cxd2880_io *io, | ||
51 | enum cxd2880_io_tgt tgt, | ||
52 | const struct cxd2880_reg_value reg_value[], | ||
53 | u8 size); | ||
54 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h new file mode 100644 index 000000000000..2be207461847 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_spi.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * SPI access definitions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_SPI_H | ||
11 | #define CXD2880_SPI_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | |||
15 | enum cxd2880_spi_mode { | ||
16 | CXD2880_SPI_MODE_0, | ||
17 | CXD2880_SPI_MODE_1, | ||
18 | CXD2880_SPI_MODE_2, | ||
19 | CXD2880_SPI_MODE_3 | ||
20 | }; | ||
21 | |||
22 | struct cxd2880_spi { | ||
23 | int (*read)(struct cxd2880_spi *spi, u8 *data, | ||
24 | u32 size); | ||
25 | int (*write)(struct cxd2880_spi *spi, const u8 *data, | ||
26 | u32 size); | ||
27 | int (*write_read)(struct cxd2880_spi *spi, | ||
28 | const u8 *tx_data, u32 tx_size, | ||
29 | u8 *rx_data, u32 rx_size); | ||
30 | u32 flags; | ||
31 | void *user; | ||
32 | }; | ||
33 | |||
34 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c new file mode 100644 index 000000000000..b8cbaa8d7aff --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c | |||
@@ -0,0 +1,113 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_spi_device.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * SPI access functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include <linux/spi/spi.h> | ||
11 | |||
12 | #include "cxd2880_spi_device.h" | ||
13 | |||
14 | static int cxd2880_spi_device_write(struct cxd2880_spi *spi, | ||
15 | const u8 *data, u32 size) | ||
16 | { | ||
17 | struct cxd2880_spi_device *spi_device = NULL; | ||
18 | struct spi_message msg; | ||
19 | struct spi_transfer tx; | ||
20 | int result = 0; | ||
21 | |||
22 | if (!spi || !spi->user || !data || size == 0) | ||
23 | return -EINVAL; | ||
24 | |||
25 | spi_device = spi->user; | ||
26 | |||
27 | memset(&tx, 0, sizeof(tx)); | ||
28 | tx.tx_buf = data; | ||
29 | tx.len = size; | ||
30 | |||
31 | spi_message_init(&msg); | ||
32 | spi_message_add_tail(&tx, &msg); | ||
33 | result = spi_sync(spi_device->spi, &msg); | ||
34 | |||
35 | if (result < 0) | ||
36 | return -EIO; | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi, | ||
42 | const u8 *tx_data, | ||
43 | u32 tx_size, | ||
44 | u8 *rx_data, | ||
45 | u32 rx_size) | ||
46 | { | ||
47 | struct cxd2880_spi_device *spi_device = NULL; | ||
48 | int result = 0; | ||
49 | |||
50 | if (!spi || !spi->user || !tx_data || | ||
51 | !tx_size || !rx_data || !rx_size) | ||
52 | return -EINVAL; | ||
53 | |||
54 | spi_device = spi->user; | ||
55 | |||
56 | result = spi_write_then_read(spi_device->spi, tx_data, | ||
57 | tx_size, rx_data, rx_size); | ||
58 | if (result < 0) | ||
59 | return -EIO; | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | int | ||
65 | cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, | ||
66 | enum cxd2880_spi_mode mode, | ||
67 | u32 speed_hz) | ||
68 | { | ||
69 | int result = 0; | ||
70 | struct spi_device *spi = spi_device->spi; | ||
71 | |||
72 | switch (mode) { | ||
73 | case CXD2880_SPI_MODE_0: | ||
74 | spi->mode = SPI_MODE_0; | ||
75 | break; | ||
76 | case CXD2880_SPI_MODE_1: | ||
77 | spi->mode = SPI_MODE_1; | ||
78 | break; | ||
79 | case CXD2880_SPI_MODE_2: | ||
80 | spi->mode = SPI_MODE_2; | ||
81 | break; | ||
82 | case CXD2880_SPI_MODE_3: | ||
83 | spi->mode = SPI_MODE_3; | ||
84 | break; | ||
85 | default: | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | spi->max_speed_hz = speed_hz; | ||
90 | spi->bits_per_word = 8; | ||
91 | result = spi_setup(spi); | ||
92 | if (result != 0) { | ||
93 | pr_err("spi_setup failed %d\n", result); | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, | ||
101 | struct cxd2880_spi_device *spi_device) | ||
102 | { | ||
103 | if (!spi || !spi_device) | ||
104 | return -EINVAL; | ||
105 | |||
106 | spi->read = NULL; | ||
107 | spi->write = cxd2880_spi_device_write; | ||
108 | spi->write_read = cxd2880_spi_device_write_read; | ||
109 | spi->flags = 0; | ||
110 | spi->user = spi_device; | ||
111 | |||
112 | return 0; | ||
113 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h new file mode 100644 index 000000000000..05e3a03de3a3 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_spi_device.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * SPI access interface | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_SPI_DEVICE_H | ||
11 | #define CXD2880_SPI_DEVICE_H | ||
12 | |||
13 | #include "cxd2880_spi.h" | ||
14 | |||
15 | struct cxd2880_spi_device { | ||
16 | struct spi_device *spi; | ||
17 | }; | ||
18 | |||
19 | int cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, | ||
20 | enum cxd2880_spi_mode mode, | ||
21 | u32 speedHz); | ||
22 | |||
23 | int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, | ||
24 | struct cxd2880_spi_device *spi_device); | ||
25 | |||
26 | #endif /* CXD2880_SPI_DEVICE_H */ | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c new file mode 100644 index 000000000000..4cf2d7cfd3f5 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c | |||
@@ -0,0 +1,3519 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_tnrdmd.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * common control functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include <media/dvb_frontend.h> | ||
11 | #include "cxd2880_common.h" | ||
12 | #include "cxd2880_tnrdmd.h" | ||
13 | #include "cxd2880_tnrdmd_mon.h" | ||
14 | #include "cxd2880_tnrdmd_dvbt.h" | ||
15 | #include "cxd2880_tnrdmd_dvbt2.h" | ||
16 | |||
17 | static const struct cxd2880_reg_value p_init1_seq[] = { | ||
18 | {0x11, 0x16}, {0x00, 0x10}, | ||
19 | }; | ||
20 | |||
21 | static const struct cxd2880_reg_value rf_init1_seq1[] = { | ||
22 | {0x4f, 0x18}, {0x61, 0x00}, {0x71, 0x00}, {0x9d, 0x01}, | ||
23 | {0x7d, 0x02}, {0x8f, 0x01}, {0x8b, 0xc6}, {0x9a, 0x03}, | ||
24 | {0x1c, 0x00}, | ||
25 | }; | ||
26 | |||
27 | static const struct cxd2880_reg_value rf_init1_seq2[] = { | ||
28 | {0xb9, 0x07}, {0x33, 0x01}, {0xc1, 0x01}, {0xc4, 0x1e}, | ||
29 | }; | ||
30 | |||
31 | static const struct cxd2880_reg_value rf_init1_seq3[] = { | ||
32 | {0x00, 0x10}, {0x51, 0x01}, {0xc5, 0x07}, {0x00, 0x11}, | ||
33 | {0x70, 0xe9}, {0x76, 0x0a}, {0x78, 0x32}, {0x7a, 0x46}, | ||
34 | {0x7c, 0x86}, {0x7e, 0xa4}, {0x00, 0x10}, {0xe1, 0x01}, | ||
35 | }; | ||
36 | |||
37 | static const struct cxd2880_reg_value rf_init1_seq4[] = { | ||
38 | {0x15, 0x00}, {0x00, 0x16} | ||
39 | }; | ||
40 | |||
41 | static const struct cxd2880_reg_value rf_init1_seq5[] = { | ||
42 | {0x00, 0x00}, {0x25, 0x00} | ||
43 | }; | ||
44 | |||
45 | static const struct cxd2880_reg_value rf_init1_seq6[] = { | ||
46 | {0x02, 0x00}, {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, | ||
47 | {0x8f, 0x16}, {0x67, 0x60}, {0x6a, 0x0f}, {0x6c, 0x17} | ||
48 | }; | ||
49 | |||
50 | static const struct cxd2880_reg_value rf_init1_seq7[] = { | ||
51 | {0x00, 0xe2}, {0x41, 0xa0}, {0x4b, 0x68}, {0x00, 0x00}, | ||
52 | {0x21, 0x00}, {0x10, 0x01}, | ||
53 | }; | ||
54 | |||
55 | static const struct cxd2880_reg_value rf_init1_seq8[] = { | ||
56 | {0x00, 0x10}, {0x25, 0x01}, | ||
57 | }; | ||
58 | |||
59 | static const struct cxd2880_reg_value rf_init1_seq9[] = { | ||
60 | {0x00, 0x10}, {0x14, 0x01}, {0x00, 0x00}, {0x26, 0x00}, | ||
61 | }; | ||
62 | |||
63 | static const struct cxd2880_reg_value rf_init2_seq1[] = { | ||
64 | {0x00, 0x14}, {0x1b, 0x01}, | ||
65 | }; | ||
66 | |||
67 | static const struct cxd2880_reg_value rf_init2_seq2[] = { | ||
68 | {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, {0xd3, 0x00}, | ||
69 | {0x00, 0x00}, {0x21, 0x00}, | ||
70 | }; | ||
71 | |||
72 | static const struct cxd2880_reg_value x_tune1_seq1[] = { | ||
73 | {0x00, 0x00}, {0x10, 0x01}, | ||
74 | }; | ||
75 | |||
76 | static const struct cxd2880_reg_value x_tune1_seq2[] = { | ||
77 | {0x62, 0x00}, {0x00, 0x15}, | ||
78 | }; | ||
79 | |||
80 | static const struct cxd2880_reg_value x_tune2_seq1[] = { | ||
81 | {0x00, 0x1a}, {0x29, 0x01}, | ||
82 | }; | ||
83 | |||
84 | static const struct cxd2880_reg_value x_tune2_seq2[] = { | ||
85 | {0x62, 0x01}, {0x00, 0x11}, {0x2d, 0x00}, {0x2f, 0x00}, | ||
86 | }; | ||
87 | |||
88 | static const struct cxd2880_reg_value x_tune2_seq3[] = { | ||
89 | {0x00, 0x00}, {0x10, 0x00}, {0x21, 0x01}, | ||
90 | }; | ||
91 | |||
92 | static const struct cxd2880_reg_value x_tune2_seq4[] = { | ||
93 | {0x00, 0xe1}, {0x8a, 0x87}, | ||
94 | }; | ||
95 | |||
96 | static const struct cxd2880_reg_value x_tune2_seq5[] = { | ||
97 | {0x00, 0x00}, {0x21, 0x00}, | ||
98 | }; | ||
99 | |||
100 | static const struct cxd2880_reg_value x_tune3_seq[] = { | ||
101 | {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0xa0}, | ||
102 | {0x00, 0x00}, {0x21, 0x00}, {0xfe, 0x01}, | ||
103 | }; | ||
104 | |||
105 | static const struct cxd2880_reg_value x_tune4_seq[] = { | ||
106 | {0x00, 0x00}, {0xfe, 0x01}, | ||
107 | }; | ||
108 | |||
109 | static const struct cxd2880_reg_value x_sleep1_seq[] = { | ||
110 | {0x00, 0x00}, {0x57, 0x03}, | ||
111 | }; | ||
112 | |||
113 | static const struct cxd2880_reg_value x_sleep2_seq1[] = { | ||
114 | {0x00, 0x2d}, {0xb1, 0x01}, | ||
115 | }; | ||
116 | |||
117 | static const struct cxd2880_reg_value x_sleep2_seq2[] = { | ||
118 | {0x00, 0x10}, {0xf4, 0x00}, {0xf3, 0x00}, {0xf2, 0x00}, | ||
119 | {0xf1, 0x00}, {0xf0, 0x00}, {0xef, 0x00}, | ||
120 | }; | ||
121 | |||
122 | static const struct cxd2880_reg_value x_sleep3_seq[] = { | ||
123 | {0x00, 0x00}, {0xfd, 0x00}, | ||
124 | }; | ||
125 | |||
126 | static const struct cxd2880_reg_value x_sleep4_seq[] = { | ||
127 | {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0x00}, | ||
128 | {0x00, 0x00}, {0x21, 0x00}, | ||
129 | }; | ||
130 | |||
131 | static const struct cxd2880_reg_value spll_reset_seq1[] = { | ||
132 | {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01}, | ||
133 | {0x26, 0x01}, | ||
134 | }; | ||
135 | |||
136 | static const struct cxd2880_reg_value spll_reset_seq2[] = { | ||
137 | {0x00, 0x00}, {0x10, 0x00}, | ||
138 | }; | ||
139 | |||
140 | static const struct cxd2880_reg_value spll_reset_seq3[] = { | ||
141 | {0x00, 0x00}, {0x27, 0x00}, {0x22, 0x01}, | ||
142 | }; | ||
143 | |||
144 | static const struct cxd2880_reg_value spll_reset_seq4[] = { | ||
145 | {0x00, 0x00}, {0x27, 0x01}, | ||
146 | }; | ||
147 | |||
148 | static const struct cxd2880_reg_value spll_reset_seq5[] = { | ||
149 | {0x00, 0x00}, {0x10, 0x01}, | ||
150 | }; | ||
151 | |||
152 | static const struct cxd2880_reg_value t_power_x_seq1[] = { | ||
153 | {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01}, | ||
154 | }; | ||
155 | |||
156 | static const struct cxd2880_reg_value t_power_x_seq2[] = { | ||
157 | {0x00, 0x00}, {0x10, 0x00}, | ||
158 | }; | ||
159 | |||
160 | static const struct cxd2880_reg_value t_power_x_seq3[] = { | ||
161 | {0x00, 0x00}, {0x27, 0x00}, {0x25, 0x01}, | ||
162 | }; | ||
163 | |||
164 | static const struct cxd2880_reg_value t_power_x_seq4[] = { | ||
165 | {0x00, 0x00}, {0x2a, 0x00}, | ||
166 | }; | ||
167 | |||
168 | static const struct cxd2880_reg_value t_power_x_seq5[] = { | ||
169 | {0x00, 0x00}, {0x25, 0x00}, | ||
170 | }; | ||
171 | |||
172 | static const struct cxd2880_reg_value t_power_x_seq6[] = { | ||
173 | {0x00, 0x00}, {0x27, 0x01}, | ||
174 | }; | ||
175 | |||
176 | static const struct cxd2880_reg_value t_power_x_seq7[] = { | ||
177 | {0x00, 0x00}, {0x10, 0x01}, | ||
178 | }; | ||
179 | |||
180 | static const struct cxd2880_reg_value set_ts_pin_seq[] = { | ||
181 | {0x50, 0x3f}, {0x52, 0x1f}, | ||
182 | |||
183 | }; | ||
184 | |||
185 | static const struct cxd2880_reg_value set_ts_output_seq1[] = { | ||
186 | {0x00, 0x00}, {0x52, 0x00}, | ||
187 | }; | ||
188 | |||
189 | static const struct cxd2880_reg_value set_ts_output_seq2[] = { | ||
190 | {0x00, 0x00}, {0xc3, 0x00}, | ||
191 | |||
192 | }; | ||
193 | |||
194 | static const struct cxd2880_reg_value set_ts_output_seq3[] = { | ||
195 | {0x00, 0x00}, {0xc3, 0x01}, | ||
196 | |||
197 | }; | ||
198 | |||
199 | static const struct cxd2880_reg_value set_ts_output_seq4[] = { | ||
200 | {0x00, 0x00}, {0x52, 0x1f}, | ||
201 | |||
202 | }; | ||
203 | |||
204 | static int p_init1(struct cxd2880_tnrdmd *tnr_dmd) | ||
205 | { | ||
206 | u8 data = 0; | ||
207 | int ret; | ||
208 | |||
209 | if (!tnr_dmd) | ||
210 | return -EINVAL; | ||
211 | |||
212 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
213 | CXD2880_IO_TGT_SYS, | ||
214 | 0x00, 0x00); | ||
215 | if (ret) | ||
216 | return ret; | ||
217 | |||
218 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE || | ||
219 | tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
220 | switch (tnr_dmd->create_param.ts_output_if) { | ||
221 | case CXD2880_TNRDMD_TSOUT_IF_TS: | ||
222 | data = 0x00; | ||
223 | break; | ||
224 | case CXD2880_TNRDMD_TSOUT_IF_SPI: | ||
225 | data = 0x01; | ||
226 | break; | ||
227 | case CXD2880_TNRDMD_TSOUT_IF_SDIO: | ||
228 | data = 0x02; | ||
229 | break; | ||
230 | default: | ||
231 | return -EINVAL; | ||
232 | } | ||
233 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
234 | CXD2880_IO_TGT_SYS, | ||
235 | 0x10, data); | ||
236 | if (ret) | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
241 | CXD2880_IO_TGT_SYS, | ||
242 | p_init1_seq, | ||
243 | ARRAY_SIZE(p_init1_seq)); | ||
244 | if (ret) | ||
245 | return ret; | ||
246 | |||
247 | switch (tnr_dmd->chip_id) { | ||
248 | case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X: | ||
249 | data = 0x1a; | ||
250 | break; | ||
251 | case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11: | ||
252 | data = 0x16; | ||
253 | break; | ||
254 | default: | ||
255 | return -ENOTTY; | ||
256 | } | ||
257 | |||
258 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
259 | CXD2880_IO_TGT_SYS, | ||
260 | 0x10, data); | ||
261 | if (ret) | ||
262 | return ret; | ||
263 | |||
264 | if (tnr_dmd->create_param.en_internal_ldo) | ||
265 | data = 0x01; | ||
266 | else | ||
267 | data = 0x00; | ||
268 | |||
269 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
270 | CXD2880_IO_TGT_SYS, | ||
271 | 0x11, data); | ||
272 | if (ret) | ||
273 | return ret; | ||
274 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
275 | CXD2880_IO_TGT_SYS, | ||
276 | 0x13, data); | ||
277 | if (ret) | ||
278 | return ret; | ||
279 | |||
280 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
281 | CXD2880_IO_TGT_SYS, | ||
282 | 0x00, 0x00); | ||
283 | if (ret) | ||
284 | return ret; | ||
285 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
286 | CXD2880_IO_TGT_SYS, | ||
287 | 0x12, data); | ||
288 | if (ret) | ||
289 | return ret; | ||
290 | |||
291 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
292 | CXD2880_IO_TGT_SYS, | ||
293 | 0x00, 0x10); | ||
294 | if (ret) | ||
295 | return ret; | ||
296 | |||
297 | switch (tnr_dmd->chip_id) { | ||
298 | case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X: | ||
299 | data = 0x01; | ||
300 | break; | ||
301 | case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11: | ||
302 | data = 0x00; | ||
303 | break; | ||
304 | default: | ||
305 | return -ENOTTY; | ||
306 | } | ||
307 | |||
308 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
309 | CXD2880_IO_TGT_SYS, | ||
310 | 0x69, data); | ||
311 | } | ||
312 | |||
313 | static int p_init2(struct cxd2880_tnrdmd *tnr_dmd) | ||
314 | { | ||
315 | u8 data[6] = { 0 }; | ||
316 | int ret; | ||
317 | |||
318 | if (!tnr_dmd) | ||
319 | return -EINVAL; | ||
320 | |||
321 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
322 | CXD2880_IO_TGT_SYS, | ||
323 | 0x00, 0x00); | ||
324 | if (ret) | ||
325 | return ret; | ||
326 | data[0] = tnr_dmd->create_param.xosc_cap; | ||
327 | data[1] = tnr_dmd->create_param.xosc_i; | ||
328 | switch (tnr_dmd->create_param.xtal_share_type) { | ||
329 | case CXD2880_TNRDMD_XTAL_SHARE_NONE: | ||
330 | data[2] = 0x01; | ||
331 | data[3] = 0x00; | ||
332 | break; | ||
333 | case CXD2880_TNRDMD_XTAL_SHARE_EXTREF: | ||
334 | data[2] = 0x00; | ||
335 | data[3] = 0x00; | ||
336 | break; | ||
337 | case CXD2880_TNRDMD_XTAL_SHARE_MASTER: | ||
338 | data[2] = 0x01; | ||
339 | data[3] = 0x01; | ||
340 | break; | ||
341 | case CXD2880_TNRDMD_XTAL_SHARE_SLAVE: | ||
342 | data[2] = 0x00; | ||
343 | data[3] = 0x01; | ||
344 | break; | ||
345 | default: | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | data[4] = 0x06; | ||
349 | data[5] = 0x00; | ||
350 | |||
351 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
352 | CXD2880_IO_TGT_SYS, | ||
353 | 0x13, data, 6); | ||
354 | } | ||
355 | |||
356 | static int p_init3(struct cxd2880_tnrdmd *tnr_dmd) | ||
357 | { | ||
358 | u8 data[2] = { 0 }; | ||
359 | int ret; | ||
360 | |||
361 | if (!tnr_dmd) | ||
362 | return -EINVAL; | ||
363 | |||
364 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
365 | CXD2880_IO_TGT_SYS, | ||
366 | 0x00, 0x00); | ||
367 | if (ret) | ||
368 | return ret; | ||
369 | |||
370 | switch (tnr_dmd->diver_mode) { | ||
371 | case CXD2880_TNRDMD_DIVERMODE_SINGLE: | ||
372 | data[0] = 0x00; | ||
373 | break; | ||
374 | case CXD2880_TNRDMD_DIVERMODE_MAIN: | ||
375 | data[0] = 0x03; | ||
376 | break; | ||
377 | case CXD2880_TNRDMD_DIVERMODE_SUB: | ||
378 | data[0] = 0x02; | ||
379 | break; | ||
380 | default: | ||
381 | return -EINVAL; | ||
382 | } | ||
383 | |||
384 | data[1] = 0x01; | ||
385 | |||
386 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
387 | CXD2880_IO_TGT_SYS, | ||
388 | 0x1f, data, 2); | ||
389 | } | ||
390 | |||
391 | static int rf_init1(struct cxd2880_tnrdmd *tnr_dmd) | ||
392 | { | ||
393 | u8 data[8] = { 0 }; | ||
394 | static const u8 rf_init1_cdata1[40] = { | ||
395 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, | ||
396 | 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, | ||
397 | 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x02, | ||
398 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, | ||
399 | 0x02, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, | ||
400 | 0x02, 0x03, 0x04, 0x04, 0x04 | ||
401 | }; | ||
402 | |||
403 | static const u8 rf_init1_cdata2[5] = {0xff, 0x00, 0x00, 0x00, 0x00}; | ||
404 | static const u8 rf_init1_cdata3[80] = { | ||
405 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, | ||
406 | 0x01, 0x00, 0x02, 0x00, 0x63, 0x00, 0x00, | ||
407 | 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, | ||
408 | 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x09, | ||
409 | 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0d, 0x00, | ||
410 | 0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, | ||
411 | 0x00, 0x10, 0x00, 0x79, 0x00, 0x00, 0x00, | ||
412 | 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, | ||
413 | 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, | ||
414 | 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, | ||
415 | 0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00, | ||
416 | 0x0a, 0x03, 0xe0 | ||
417 | }; | ||
418 | |||
419 | static const u8 rf_init1_cdata4[8] = { | ||
420 | 0x20, 0x20, 0x30, 0x41, 0x50, 0x5f, 0x6f, 0x80 | ||
421 | }; | ||
422 | |||
423 | static const u8 rf_init1_cdata5[50] = { | ||
424 | 0x00, 0x09, 0x00, 0x08, 0x00, 0x07, 0x00, | ||
425 | 0x06, 0x00, 0x05, 0x00, 0x03, 0x00, 0x02, | ||
426 | 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, | ||
427 | 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c, | ||
428 | 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0f, 0x00, | ||
429 | 0x0e, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, | ||
430 | 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 0x00, | ||
431 | 0x0e | ||
432 | }; | ||
433 | |||
434 | u8 addr = 0; | ||
435 | int ret; | ||
436 | |||
437 | if (!tnr_dmd) | ||
438 | return -EINVAL; | ||
439 | |||
440 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
441 | CXD2880_IO_TGT_SYS, | ||
442 | 0x00, 0x00); | ||
443 | if (ret) | ||
444 | return ret; | ||
445 | data[0] = 0x01; | ||
446 | data[1] = 0x00; | ||
447 | data[2] = 0x01; | ||
448 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
449 | CXD2880_IO_TGT_SYS, | ||
450 | 0x21, data, 3); | ||
451 | if (ret) | ||
452 | return ret; | ||
453 | |||
454 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
455 | CXD2880_IO_TGT_SYS, | ||
456 | 0x00, 0x10); | ||
457 | if (ret) | ||
458 | return ret; | ||
459 | data[0] = 0x01; | ||
460 | data[1] = 0x01; | ||
461 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
462 | CXD2880_IO_TGT_SYS, | ||
463 | 0x17, data, 2); | ||
464 | if (ret) | ||
465 | return ret; | ||
466 | |||
467 | if (tnr_dmd->create_param.stationary_use) { | ||
468 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
469 | CXD2880_IO_TGT_SYS, | ||
470 | 0x1a, 0x06); | ||
471 | if (ret) | ||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
476 | CXD2880_IO_TGT_SYS, | ||
477 | rf_init1_seq1, | ||
478 | ARRAY_SIZE(rf_init1_seq1)); | ||
479 | if (ret) | ||
480 | return ret; | ||
481 | |||
482 | data[0] = 0x00; | ||
483 | if (tnr_dmd->create_param.is_cxd2881gg && | ||
484 | tnr_dmd->create_param.xtal_share_type == | ||
485 | CXD2880_TNRDMD_XTAL_SHARE_SLAVE) | ||
486 | data[1] = 0x00; | ||
487 | else | ||
488 | data[1] = 0x1f; | ||
489 | data[2] = 0x0a; | ||
490 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
491 | CXD2880_IO_TGT_SYS, | ||
492 | 0xb5, data, 3); | ||
493 | if (ret) | ||
494 | return ret; | ||
495 | |||
496 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
497 | CXD2880_IO_TGT_SYS, | ||
498 | rf_init1_seq2, | ||
499 | ARRAY_SIZE(rf_init1_seq2)); | ||
500 | if (ret) | ||
501 | return ret; | ||
502 | |||
503 | if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) { | ||
504 | data[0] = 0x34; | ||
505 | data[1] = 0x2c; | ||
506 | } else { | ||
507 | data[0] = 0x2f; | ||
508 | data[1] = 0x25; | ||
509 | } | ||
510 | data[2] = 0x15; | ||
511 | data[3] = 0x19; | ||
512 | data[4] = 0x1b; | ||
513 | data[5] = 0x15; | ||
514 | data[6] = 0x19; | ||
515 | data[7] = 0x1b; | ||
516 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
517 | CXD2880_IO_TGT_SYS, | ||
518 | 0xd9, data, 8); | ||
519 | if (ret) | ||
520 | return ret; | ||
521 | |||
522 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
523 | CXD2880_IO_TGT_SYS, | ||
524 | 0x00, 0x11); | ||
525 | if (ret) | ||
526 | return ret; | ||
527 | data[0] = 0x6c; | ||
528 | data[1] = 0x10; | ||
529 | data[2] = 0xa6; | ||
530 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
531 | CXD2880_IO_TGT_SYS, | ||
532 | 0x44, data, 3); | ||
533 | if (ret) | ||
534 | return ret; | ||
535 | data[0] = 0x16; | ||
536 | data[1] = 0xa8; | ||
537 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
538 | CXD2880_IO_TGT_SYS, | ||
539 | 0x50, data, 2); | ||
540 | if (ret) | ||
541 | return ret; | ||
542 | data[0] = 0x00; | ||
543 | data[1] = 0x22; | ||
544 | data[2] = 0x00; | ||
545 | data[3] = 0x88; | ||
546 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
547 | CXD2880_IO_TGT_SYS, | ||
548 | 0x62, data, 4); | ||
549 | if (ret) | ||
550 | return ret; | ||
551 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
552 | CXD2880_IO_TGT_SYS, | ||
553 | 0x74, 0x75); | ||
554 | if (ret) | ||
555 | return ret; | ||
556 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
557 | CXD2880_IO_TGT_SYS, | ||
558 | 0x7f, rf_init1_cdata1, 40); | ||
559 | if (ret) | ||
560 | return ret; | ||
561 | |||
562 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
563 | CXD2880_IO_TGT_SYS, | ||
564 | 0x00, 0x16); | ||
565 | if (ret) | ||
566 | return ret; | ||
567 | data[0] = 0x00; | ||
568 | data[1] = 0x71; | ||
569 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
570 | CXD2880_IO_TGT_SYS, | ||
571 | 0x10, data, 2); | ||
572 | if (ret) | ||
573 | return ret; | ||
574 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
575 | CXD2880_IO_TGT_SYS, | ||
576 | 0x23, 0x89); | ||
577 | if (ret) | ||
578 | return ret; | ||
579 | |||
580 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
581 | CXD2880_IO_TGT_SYS, | ||
582 | 0x27, rf_init1_cdata2, 5); | ||
583 | if (ret) | ||
584 | return ret; | ||
585 | |||
586 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
587 | CXD2880_IO_TGT_SYS, | ||
588 | 0x3a, rf_init1_cdata3, 80); | ||
589 | if (ret) | ||
590 | return ret; | ||
591 | |||
592 | data[0] = 0x03; | ||
593 | data[1] = 0xe0; | ||
594 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
595 | CXD2880_IO_TGT_SYS, | ||
596 | 0xbc, data, 2); | ||
597 | if (ret) | ||
598 | return ret; | ||
599 | |||
600 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
601 | CXD2880_IO_TGT_SYS, | ||
602 | rf_init1_seq3, | ||
603 | ARRAY_SIZE(rf_init1_seq3)); | ||
604 | if (ret) | ||
605 | return ret; | ||
606 | |||
607 | if (tnr_dmd->create_param.stationary_use) { | ||
608 | data[0] = 0x06; | ||
609 | data[1] = 0x07; | ||
610 | data[2] = 0x1a; | ||
611 | } else { | ||
612 | data[0] = 0x00; | ||
613 | data[1] = 0x08; | ||
614 | data[2] = 0x19; | ||
615 | } | ||
616 | data[3] = 0x0e; | ||
617 | data[4] = 0x09; | ||
618 | data[5] = 0x0e; | ||
619 | |||
620 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
621 | CXD2880_IO_TGT_SYS, | ||
622 | 0x00, 0x12); | ||
623 | if (ret) | ||
624 | return ret; | ||
625 | for (addr = 0x10; addr < 0x9f; addr += 6) { | ||
626 | if (tnr_dmd->lna_thrs_tbl_air) { | ||
627 | u8 idx = 0; | ||
628 | |||
629 | idx = (addr - 0x10) / 6; | ||
630 | data[0] = | ||
631 | tnr_dmd->lna_thrs_tbl_air->thrs[idx].off_on; | ||
632 | data[1] = | ||
633 | tnr_dmd->lna_thrs_tbl_air->thrs[idx].on_off; | ||
634 | } | ||
635 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
636 | CXD2880_IO_TGT_SYS, | ||
637 | addr, data, 6); | ||
638 | if (ret) | ||
639 | return ret; | ||
640 | } | ||
641 | |||
642 | data[0] = 0x00; | ||
643 | data[1] = 0x08; | ||
644 | if (tnr_dmd->create_param.stationary_use) | ||
645 | data[2] = 0x1a; | ||
646 | else | ||
647 | data[2] = 0x19; | ||
648 | data[3] = 0x0e; | ||
649 | data[4] = 0x09; | ||
650 | data[5] = 0x0e; | ||
651 | |||
652 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
653 | CXD2880_IO_TGT_SYS, | ||
654 | 0x00, 0x13); | ||
655 | if (ret) | ||
656 | return ret; | ||
657 | for (addr = 0x10; addr < 0xcf; addr += 6) { | ||
658 | if (tnr_dmd->lna_thrs_tbl_cable) { | ||
659 | u8 idx = 0; | ||
660 | |||
661 | idx = (addr - 0x10) / 6; | ||
662 | data[0] = | ||
663 | tnr_dmd->lna_thrs_tbl_cable->thrs[idx].off_on; | ||
664 | data[1] = | ||
665 | tnr_dmd->lna_thrs_tbl_cable->thrs[idx].on_off; | ||
666 | } | ||
667 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
668 | CXD2880_IO_TGT_SYS, | ||
669 | addr, data, 6); | ||
670 | if (ret) | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
675 | CXD2880_IO_TGT_SYS, | ||
676 | 0x00, 0x11); | ||
677 | if (ret) | ||
678 | return ret; | ||
679 | data[0] = 0x08; | ||
680 | data[1] = 0x09; | ||
681 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
682 | CXD2880_IO_TGT_SYS, | ||
683 | 0xbd, data, 2); | ||
684 | if (ret) | ||
685 | return ret; | ||
686 | data[0] = 0x08; | ||
687 | data[1] = 0x09; | ||
688 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
689 | CXD2880_IO_TGT_SYS, | ||
690 | 0xc4, data, 2); | ||
691 | if (ret) | ||
692 | return ret; | ||
693 | |||
694 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
695 | CXD2880_IO_TGT_SYS, | ||
696 | 0xc9, rf_init1_cdata4, 8); | ||
697 | if (ret) | ||
698 | return ret; | ||
699 | |||
700 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
701 | CXD2880_IO_TGT_SYS, | ||
702 | 0x00, 0x14); | ||
703 | if (ret) | ||
704 | return ret; | ||
705 | data[0] = 0x15; | ||
706 | data[1] = 0x18; | ||
707 | data[2] = 0x00; | ||
708 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
709 | CXD2880_IO_TGT_SYS, | ||
710 | 0x10, data, 3); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
715 | CXD2880_IO_TGT_SYS, | ||
716 | rf_init1_seq4, | ||
717 | ARRAY_SIZE(rf_init1_seq4)); | ||
718 | if (ret) | ||
719 | return ret; | ||
720 | |||
721 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
722 | CXD2880_IO_TGT_SYS, | ||
723 | 0x12, rf_init1_cdata5, 50); | ||
724 | if (ret) | ||
725 | return ret; | ||
726 | |||
727 | usleep_range(1000, 2000); | ||
728 | |||
729 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
730 | CXD2880_IO_TGT_SYS, | ||
731 | 0x00, 0x0a); | ||
732 | if (ret) | ||
733 | return ret; | ||
734 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
735 | CXD2880_IO_TGT_SYS, | ||
736 | 0x10, data, 1); | ||
737 | if (ret) | ||
738 | return ret; | ||
739 | if ((data[0] & 0x01) == 0x00) | ||
740 | return -EINVAL; | ||
741 | |||
742 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
743 | CXD2880_IO_TGT_SYS, | ||
744 | rf_init1_seq5, | ||
745 | ARRAY_SIZE(rf_init1_seq5)); | ||
746 | if (ret) | ||
747 | return ret; | ||
748 | |||
749 | usleep_range(1000, 2000); | ||
750 | |||
751 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
752 | CXD2880_IO_TGT_SYS, | ||
753 | 0x00, 0x0a); | ||
754 | if (ret) | ||
755 | return ret; | ||
756 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
757 | CXD2880_IO_TGT_SYS, | ||
758 | 0x11, data, 1); | ||
759 | if (ret) | ||
760 | return ret; | ||
761 | if ((data[0] & 0x01) == 0x00) | ||
762 | return -EINVAL; | ||
763 | |||
764 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
765 | CXD2880_IO_TGT_DMD, | ||
766 | rf_init1_seq6, | ||
767 | ARRAY_SIZE(rf_init1_seq6)); | ||
768 | if (ret) | ||
769 | return ret; | ||
770 | |||
771 | data[0] = 0x00; | ||
772 | data[1] = 0xfe; | ||
773 | data[2] = 0xee; | ||
774 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
775 | CXD2880_IO_TGT_DMD, | ||
776 | 0x6e, data, 3); | ||
777 | if (ret) | ||
778 | return ret; | ||
779 | data[0] = 0xa1; | ||
780 | data[1] = 0x8b; | ||
781 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
782 | CXD2880_IO_TGT_DMD, | ||
783 | 0x8d, data, 2); | ||
784 | if (ret) | ||
785 | return ret; | ||
786 | data[0] = 0x08; | ||
787 | data[1] = 0x09; | ||
788 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
789 | CXD2880_IO_TGT_DMD, | ||
790 | 0x77, data, 2); | ||
791 | if (ret) | ||
792 | return ret; | ||
793 | |||
794 | if (tnr_dmd->create_param.stationary_use) { | ||
795 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
796 | CXD2880_IO_TGT_DMD, | ||
797 | 0x80, 0xaa); | ||
798 | if (ret) | ||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
803 | CXD2880_IO_TGT_DMD, | ||
804 | rf_init1_seq7, | ||
805 | ARRAY_SIZE(rf_init1_seq7)); | ||
806 | if (ret) | ||
807 | return ret; | ||
808 | |||
809 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
810 | CXD2880_IO_TGT_SYS, | ||
811 | rf_init1_seq8, | ||
812 | ARRAY_SIZE(rf_init1_seq8)); | ||
813 | if (ret) | ||
814 | return ret; | ||
815 | |||
816 | usleep_range(1000, 2000); | ||
817 | |||
818 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
819 | CXD2880_IO_TGT_SYS, | ||
820 | 0x00, 0x1a); | ||
821 | if (ret) | ||
822 | return ret; | ||
823 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
824 | CXD2880_IO_TGT_SYS, | ||
825 | 0x10, data, 1); | ||
826 | if (ret) | ||
827 | return ret; | ||
828 | if ((data[0] & 0x01) == 0x00) | ||
829 | return -EINVAL; | ||
830 | |||
831 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
832 | CXD2880_IO_TGT_SYS, | ||
833 | rf_init1_seq9, | ||
834 | ARRAY_SIZE(rf_init1_seq9)); | ||
835 | } | ||
836 | |||
837 | static int rf_init2(struct cxd2880_tnrdmd *tnr_dmd) | ||
838 | { | ||
839 | u8 data[5] = { 0 }; | ||
840 | int ret; | ||
841 | |||
842 | if (!tnr_dmd) | ||
843 | return -EINVAL; | ||
844 | |||
845 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
846 | CXD2880_IO_TGT_SYS, | ||
847 | 0x00, 0x10); | ||
848 | if (ret) | ||
849 | return ret; | ||
850 | data[0] = 0x40; | ||
851 | data[1] = 0x40; | ||
852 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
853 | CXD2880_IO_TGT_SYS, | ||
854 | 0xea, data, 2); | ||
855 | if (ret) | ||
856 | return ret; | ||
857 | |||
858 | usleep_range(1000, 2000); | ||
859 | |||
860 | data[0] = 0x00; | ||
861 | if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) | ||
862 | data[1] = 0x00; | ||
863 | else | ||
864 | data[1] = 0x01; | ||
865 | data[2] = 0x01; | ||
866 | data[3] = 0x03; | ||
867 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
868 | CXD2880_IO_TGT_SYS, | ||
869 | 0x30, data, 4); | ||
870 | if (ret) | ||
871 | return ret; | ||
872 | |||
873 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
874 | CXD2880_IO_TGT_SYS, | ||
875 | rf_init2_seq1, | ||
876 | ARRAY_SIZE(rf_init2_seq1)); | ||
877 | if (ret) | ||
878 | return ret; | ||
879 | |||
880 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
881 | CXD2880_IO_TGT_DMD, | ||
882 | rf_init2_seq2, | ||
883 | ARRAY_SIZE(rf_init2_seq2)); | ||
884 | } | ||
885 | |||
886 | static int x_tune1(struct cxd2880_tnrdmd *tnr_dmd, | ||
887 | enum cxd2880_dtv_sys sys, u32 freq_khz, | ||
888 | enum cxd2880_dtv_bandwidth bandwidth, | ||
889 | u8 is_cable, int shift_frequency_khz) | ||
890 | { | ||
891 | u8 data[11] = { 0 }; | ||
892 | int ret; | ||
893 | |||
894 | if (!tnr_dmd) | ||
895 | return -EINVAL; | ||
896 | |||
897 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
898 | CXD2880_IO_TGT_DMD, | ||
899 | x_tune1_seq1, | ||
900 | ARRAY_SIZE(x_tune1_seq1)); | ||
901 | if (ret) | ||
902 | return ret; | ||
903 | |||
904 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
905 | CXD2880_IO_TGT_SYS, | ||
906 | 0x00, 0x10); | ||
907 | if (ret) | ||
908 | return ret; | ||
909 | |||
910 | data[2] = 0x0e; | ||
911 | data[4] = 0x03; | ||
912 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
913 | CXD2880_IO_TGT_SYS, | ||
914 | 0xe7, data, 5); | ||
915 | if (ret) | ||
916 | return ret; | ||
917 | |||
918 | data[0] = 0x1f; | ||
919 | data[1] = 0x80; | ||
920 | data[2] = 0x18; | ||
921 | data[3] = 0x00; | ||
922 | data[4] = 0x07; | ||
923 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
924 | CXD2880_IO_TGT_SYS, | ||
925 | 0xe7, data, 5); | ||
926 | if (ret) | ||
927 | return ret; | ||
928 | |||
929 | usleep_range(1000, 2000); | ||
930 | |||
931 | data[0] = 0x72; | ||
932 | data[1] = 0x81; | ||
933 | data[3] = 0x1d; | ||
934 | data[4] = 0x6f; | ||
935 | data[5] = 0x7e; | ||
936 | data[7] = 0x1c; | ||
937 | switch (sys) { | ||
938 | case CXD2880_DTV_SYS_DVBT: | ||
939 | data[2] = 0x94; | ||
940 | data[6] = 0x91; | ||
941 | break; | ||
942 | case CXD2880_DTV_SYS_DVBT2: | ||
943 | data[2] = 0x96; | ||
944 | data[6] = 0x93; | ||
945 | break; | ||
946 | default: | ||
947 | return -EINVAL; | ||
948 | } | ||
949 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
950 | CXD2880_IO_TGT_SYS, | ||
951 | 0x44, data, 8); | ||
952 | if (ret) | ||
953 | return ret; | ||
954 | |||
955 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
956 | CXD2880_IO_TGT_SYS, | ||
957 | x_tune1_seq2, | ||
958 | ARRAY_SIZE(x_tune1_seq2)); | ||
959 | if (ret) | ||
960 | return ret; | ||
961 | |||
962 | data[0] = 0x03; | ||
963 | data[1] = 0xe2; | ||
964 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
965 | CXD2880_IO_TGT_SYS, | ||
966 | 0x1e, data, 2); | ||
967 | if (ret) | ||
968 | return ret; | ||
969 | |||
970 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
971 | CXD2880_IO_TGT_SYS, | ||
972 | 0x00, 0x10); | ||
973 | if (ret) | ||
974 | return ret; | ||
975 | |||
976 | data[0] = is_cable ? 0x01 : 0x00; | ||
977 | data[1] = 0x00; | ||
978 | data[2] = 0x6b; | ||
979 | data[3] = 0x4d; | ||
980 | |||
981 | switch (bandwidth) { | ||
982 | case CXD2880_DTV_BW_1_7_MHZ: | ||
983 | data[4] = 0x03; | ||
984 | break; | ||
985 | case CXD2880_DTV_BW_5_MHZ: | ||
986 | case CXD2880_DTV_BW_6_MHZ: | ||
987 | data[4] = 0x00; | ||
988 | break; | ||
989 | case CXD2880_DTV_BW_7_MHZ: | ||
990 | data[4] = 0x01; | ||
991 | break; | ||
992 | case CXD2880_DTV_BW_8_MHZ: | ||
993 | data[4] = 0x02; | ||
994 | break; | ||
995 | default: | ||
996 | return -EINVAL; | ||
997 | } | ||
998 | |||
999 | data[5] = 0x00; | ||
1000 | |||
1001 | freq_khz += shift_frequency_khz; | ||
1002 | |||
1003 | data[6] = (freq_khz >> 16) & 0x0f; | ||
1004 | data[7] = (freq_khz >> 8) & 0xff; | ||
1005 | data[8] = freq_khz & 0xff; | ||
1006 | data[9] = 0xff; | ||
1007 | data[10] = 0xfe; | ||
1008 | |||
1009 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1010 | CXD2880_IO_TGT_SYS, | ||
1011 | 0x52, data, 11); | ||
1012 | } | ||
1013 | |||
1014 | static int x_tune2(struct cxd2880_tnrdmd *tnr_dmd, | ||
1015 | enum cxd2880_dtv_bandwidth bandwidth, | ||
1016 | enum cxd2880_tnrdmd_clockmode clk_mode, | ||
1017 | int shift_frequency_khz) | ||
1018 | { | ||
1019 | u8 data[3] = { 0 }; | ||
1020 | int ret; | ||
1021 | |||
1022 | if (!tnr_dmd) | ||
1023 | return -EINVAL; | ||
1024 | |||
1025 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1026 | CXD2880_IO_TGT_SYS, | ||
1027 | 0x00, 0x11); | ||
1028 | if (ret) | ||
1029 | return ret; | ||
1030 | |||
1031 | data[0] = 0x01; | ||
1032 | data[1] = 0x0e; | ||
1033 | data[2] = 0x01; | ||
1034 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1035 | CXD2880_IO_TGT_SYS, | ||
1036 | 0x2d, data, 3); | ||
1037 | if (ret) | ||
1038 | return ret; | ||
1039 | |||
1040 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1041 | CXD2880_IO_TGT_SYS, | ||
1042 | x_tune2_seq1, | ||
1043 | ARRAY_SIZE(x_tune2_seq1)); | ||
1044 | if (ret) | ||
1045 | return ret; | ||
1046 | |||
1047 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1048 | CXD2880_IO_TGT_SYS, | ||
1049 | 0x2c, data, 1); | ||
1050 | if (ret) | ||
1051 | return ret; | ||
1052 | |||
1053 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1054 | CXD2880_IO_TGT_SYS, | ||
1055 | 0x00, 0x10); | ||
1056 | if (ret) | ||
1057 | return ret; | ||
1058 | |||
1059 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1060 | CXD2880_IO_TGT_SYS, | ||
1061 | 0x60, data[0]); | ||
1062 | if (ret) | ||
1063 | return ret; | ||
1064 | |||
1065 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1066 | CXD2880_IO_TGT_SYS, | ||
1067 | x_tune2_seq2, | ||
1068 | ARRAY_SIZE(x_tune2_seq2)); | ||
1069 | if (ret) | ||
1070 | return ret; | ||
1071 | |||
1072 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1073 | CXD2880_IO_TGT_DMD, | ||
1074 | x_tune2_seq3, | ||
1075 | ARRAY_SIZE(x_tune2_seq3)); | ||
1076 | if (ret) | ||
1077 | return ret; | ||
1078 | |||
1079 | if (shift_frequency_khz != 0) { | ||
1080 | int shift_freq = 0; | ||
1081 | |||
1082 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1083 | CXD2880_IO_TGT_DMD, | ||
1084 | 0x00, 0xe1); | ||
1085 | if (ret) | ||
1086 | return ret; | ||
1087 | |||
1088 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1089 | CXD2880_IO_TGT_DMD, | ||
1090 | 0x60, data, 2); | ||
1091 | if (ret) | ||
1092 | return ret; | ||
1093 | |||
1094 | shift_freq = shift_frequency_khz * 1000; | ||
1095 | |||
1096 | switch (clk_mode) { | ||
1097 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
1098 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
1099 | default: | ||
1100 | if (shift_freq >= 0) | ||
1101 | shift_freq = (shift_freq + 183 / 2) / 183; | ||
1102 | else | ||
1103 | shift_freq = (shift_freq - 183 / 2) / 183; | ||
1104 | break; | ||
1105 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
1106 | if (shift_freq >= 0) | ||
1107 | shift_freq = (shift_freq + 178 / 2) / 178; | ||
1108 | else | ||
1109 | shift_freq = (shift_freq - 178 / 2) / 178; | ||
1110 | break; | ||
1111 | } | ||
1112 | |||
1113 | shift_freq += | ||
1114 | cxd2880_convert2s_complement((data[0] << 8) | data[1], 16); | ||
1115 | |||
1116 | if (shift_freq > 32767) | ||
1117 | shift_freq = 32767; | ||
1118 | else if (shift_freq < -32768) | ||
1119 | shift_freq = -32768; | ||
1120 | |||
1121 | data[0] = (shift_freq >> 8) & 0xff; | ||
1122 | data[1] = shift_freq & 0xff; | ||
1123 | |||
1124 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1125 | CXD2880_IO_TGT_DMD, | ||
1126 | 0x60, data, 2); | ||
1127 | if (ret) | ||
1128 | return ret; | ||
1129 | |||
1130 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1131 | CXD2880_IO_TGT_DMD, | ||
1132 | 0x69, data, 1); | ||
1133 | if (ret) | ||
1134 | return ret; | ||
1135 | |||
1136 | shift_freq = -shift_frequency_khz; | ||
1137 | |||
1138 | if (bandwidth == CXD2880_DTV_BW_1_7_MHZ) { | ||
1139 | switch (clk_mode) { | ||
1140 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
1141 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
1142 | default: | ||
1143 | if (shift_freq >= 0) | ||
1144 | shift_freq = | ||
1145 | (shift_freq * 1000 + | ||
1146 | 17578 / 2) / 17578; | ||
1147 | else | ||
1148 | shift_freq = | ||
1149 | (shift_freq * 1000 - | ||
1150 | 17578 / 2) / 17578; | ||
1151 | break; | ||
1152 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
1153 | if (shift_freq >= 0) | ||
1154 | shift_freq = | ||
1155 | (shift_freq * 1000 + | ||
1156 | 17090 / 2) / 17090; | ||
1157 | else | ||
1158 | shift_freq = | ||
1159 | (shift_freq * 1000 - | ||
1160 | 17090 / 2) / 17090; | ||
1161 | break; | ||
1162 | } | ||
1163 | } else { | ||
1164 | switch (clk_mode) { | ||
1165 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
1166 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
1167 | default: | ||
1168 | if (shift_freq >= 0) | ||
1169 | shift_freq = | ||
1170 | (shift_freq * 1000 + | ||
1171 | 35156 / 2) / 35156; | ||
1172 | else | ||
1173 | shift_freq = | ||
1174 | (shift_freq * 1000 - | ||
1175 | 35156 / 2) / 35156; | ||
1176 | break; | ||
1177 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
1178 | if (shift_freq >= 0) | ||
1179 | shift_freq = | ||
1180 | (shift_freq * 1000 + | ||
1181 | 34180 / 2) / 34180; | ||
1182 | else | ||
1183 | shift_freq = | ||
1184 | (shift_freq * 1000 - | ||
1185 | 34180 / 2) / 34180; | ||
1186 | break; | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | shift_freq += cxd2880_convert2s_complement(data[0], 8); | ||
1191 | |||
1192 | if (shift_freq > 127) | ||
1193 | shift_freq = 127; | ||
1194 | else if (shift_freq < -128) | ||
1195 | shift_freq = -128; | ||
1196 | |||
1197 | data[0] = shift_freq & 0xff; | ||
1198 | |||
1199 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1200 | CXD2880_IO_TGT_DMD, | ||
1201 | 0x69, data[0]); | ||
1202 | if (ret) | ||
1203 | return ret; | ||
1204 | } | ||
1205 | |||
1206 | if (tnr_dmd->create_param.stationary_use) { | ||
1207 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1208 | CXD2880_IO_TGT_DMD, | ||
1209 | x_tune2_seq4, | ||
1210 | ARRAY_SIZE(x_tune2_seq4)); | ||
1211 | if (ret) | ||
1212 | return ret; | ||
1213 | } | ||
1214 | |||
1215 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1216 | CXD2880_IO_TGT_DMD, | ||
1217 | x_tune2_seq5, | ||
1218 | ARRAY_SIZE(x_tune2_seq5)); | ||
1219 | } | ||
1220 | |||
1221 | static int x_tune3(struct cxd2880_tnrdmd *tnr_dmd, | ||
1222 | enum cxd2880_dtv_sys sys, | ||
1223 | u8 en_fef_intmtnt_ctrl) | ||
1224 | { | ||
1225 | u8 data[6] = { 0 }; | ||
1226 | int ret; | ||
1227 | |||
1228 | if (!tnr_dmd) | ||
1229 | return -EINVAL; | ||
1230 | |||
1231 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1232 | CXD2880_IO_TGT_DMD, | ||
1233 | x_tune3_seq, | ||
1234 | ARRAY_SIZE(x_tune3_seq)); | ||
1235 | if (ret) | ||
1236 | return ret; | ||
1237 | |||
1238 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1239 | CXD2880_IO_TGT_SYS, | ||
1240 | 0x00, 0x10); | ||
1241 | if (ret) | ||
1242 | return ret; | ||
1243 | |||
1244 | if (sys == CXD2880_DTV_SYS_DVBT2 && en_fef_intmtnt_ctrl) | ||
1245 | memset(data, 0x01, sizeof(data)); | ||
1246 | else | ||
1247 | memset(data, 0x00, sizeof(data)); | ||
1248 | |||
1249 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1250 | CXD2880_IO_TGT_SYS, | ||
1251 | 0xef, data, 6); | ||
1252 | if (ret) | ||
1253 | return ret; | ||
1254 | |||
1255 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1256 | CXD2880_IO_TGT_DMD, | ||
1257 | 0x00, 0x2d); | ||
1258 | if (ret) | ||
1259 | return ret; | ||
1260 | if (sys == CXD2880_DTV_SYS_DVBT2 && en_fef_intmtnt_ctrl) | ||
1261 | data[0] = 0x00; | ||
1262 | else | ||
1263 | data[0] = 0x01; | ||
1264 | |||
1265 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1266 | CXD2880_IO_TGT_DMD, | ||
1267 | 0xb1, data[0]); | ||
1268 | } | ||
1269 | |||
1270 | static int x_tune4(struct cxd2880_tnrdmd *tnr_dmd) | ||
1271 | { | ||
1272 | u8 data[2] = { 0 }; | ||
1273 | int ret; | ||
1274 | |||
1275 | if (!tnr_dmd) | ||
1276 | return -EINVAL; | ||
1277 | |||
1278 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1279 | return -EINVAL; | ||
1280 | |||
1281 | ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, | ||
1282 | CXD2880_IO_TGT_SYS, | ||
1283 | 0x00, 0x00); | ||
1284 | if (ret) | ||
1285 | return ret; | ||
1286 | data[0] = 0x14; | ||
1287 | data[1] = 0x00; | ||
1288 | ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, | ||
1289 | CXD2880_IO_TGT_SYS, | ||
1290 | 0x55, data, 2); | ||
1291 | if (ret) | ||
1292 | return ret; | ||
1293 | |||
1294 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1295 | CXD2880_IO_TGT_SYS, | ||
1296 | 0x00, 0x00); | ||
1297 | if (ret) | ||
1298 | return ret; | ||
1299 | data[0] = 0x0b; | ||
1300 | data[1] = 0xff; | ||
1301 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1302 | CXD2880_IO_TGT_SYS, | ||
1303 | 0x53, data, 2); | ||
1304 | if (ret) | ||
1305 | return ret; | ||
1306 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1307 | CXD2880_IO_TGT_SYS, | ||
1308 | 0x57, 0x01); | ||
1309 | if (ret) | ||
1310 | return ret; | ||
1311 | data[0] = 0x0b; | ||
1312 | data[1] = 0xff; | ||
1313 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1314 | CXD2880_IO_TGT_SYS, | ||
1315 | 0x55, data, 2); | ||
1316 | if (ret) | ||
1317 | return ret; | ||
1318 | |||
1319 | ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, | ||
1320 | CXD2880_IO_TGT_SYS, | ||
1321 | 0x00, 0x00); | ||
1322 | if (ret) | ||
1323 | return ret; | ||
1324 | data[0] = 0x14; | ||
1325 | data[1] = 0x00; | ||
1326 | ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, | ||
1327 | CXD2880_IO_TGT_SYS, | ||
1328 | 0x53, data, 2); | ||
1329 | if (ret) | ||
1330 | return ret; | ||
1331 | ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, | ||
1332 | CXD2880_IO_TGT_SYS, | ||
1333 | 0x57, 0x02); | ||
1334 | if (ret) | ||
1335 | return ret; | ||
1336 | |||
1337 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1338 | CXD2880_IO_TGT_DMD, | ||
1339 | x_tune4_seq, | ||
1340 | ARRAY_SIZE(x_tune4_seq)); | ||
1341 | if (ret) | ||
1342 | return ret; | ||
1343 | |||
1344 | return cxd2880_io_write_multi_regs(tnr_dmd->diver_sub->io, | ||
1345 | CXD2880_IO_TGT_DMD, | ||
1346 | x_tune4_seq, | ||
1347 | ARRAY_SIZE(x_tune4_seq)); | ||
1348 | } | ||
1349 | |||
1350 | static int x_sleep1(struct cxd2880_tnrdmd *tnr_dmd) | ||
1351 | { | ||
1352 | u8 data[3] = { 0 }; | ||
1353 | int ret; | ||
1354 | |||
1355 | if (!tnr_dmd) | ||
1356 | return -EINVAL; | ||
1357 | |||
1358 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1359 | return -EINVAL; | ||
1360 | |||
1361 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1362 | CXD2880_IO_TGT_SYS, | ||
1363 | x_sleep1_seq, | ||
1364 | ARRAY_SIZE(x_sleep1_seq)); | ||
1365 | if (ret) | ||
1366 | return ret; | ||
1367 | |||
1368 | data[0] = 0x00; | ||
1369 | data[1] = 0x00; | ||
1370 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1371 | CXD2880_IO_TGT_SYS, | ||
1372 | 0x53, data, 2); | ||
1373 | if (ret) | ||
1374 | return ret; | ||
1375 | |||
1376 | ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, | ||
1377 | CXD2880_IO_TGT_SYS, | ||
1378 | 0x00, 0x00); | ||
1379 | if (ret) | ||
1380 | return ret; | ||
1381 | data[0] = 0x1f; | ||
1382 | data[1] = 0xff; | ||
1383 | data[2] = 0x03; | ||
1384 | ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, | ||
1385 | CXD2880_IO_TGT_SYS, | ||
1386 | 0x55, data, 3); | ||
1387 | if (ret) | ||
1388 | return ret; | ||
1389 | data[0] = 0x00; | ||
1390 | data[1] = 0x00; | ||
1391 | ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, | ||
1392 | CXD2880_IO_TGT_SYS, | ||
1393 | 0x53, data, 2); | ||
1394 | if (ret) | ||
1395 | return ret; | ||
1396 | |||
1397 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1398 | CXD2880_IO_TGT_SYS, | ||
1399 | 0x00, 0x00); | ||
1400 | if (ret) | ||
1401 | return ret; | ||
1402 | data[0] = 0x1f; | ||
1403 | data[1] = 0xff; | ||
1404 | |||
1405 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1406 | CXD2880_IO_TGT_SYS, | ||
1407 | 0x55, data, 2); | ||
1408 | } | ||
1409 | |||
1410 | static int x_sleep2(struct cxd2880_tnrdmd *tnr_dmd) | ||
1411 | { | ||
1412 | u8 data = 0; | ||
1413 | int ret; | ||
1414 | |||
1415 | if (!tnr_dmd) | ||
1416 | return -EINVAL; | ||
1417 | |||
1418 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1419 | CXD2880_IO_TGT_DMD, | ||
1420 | x_sleep2_seq1, | ||
1421 | ARRAY_SIZE(x_sleep2_seq1)); | ||
1422 | if (ret) | ||
1423 | return ret; | ||
1424 | |||
1425 | usleep_range(1000, 2000); | ||
1426 | |||
1427 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1428 | CXD2880_IO_TGT_DMD, | ||
1429 | 0xb2, &data, 1); | ||
1430 | if (ret) | ||
1431 | return ret; | ||
1432 | |||
1433 | if ((data & 0x01) == 0x00) | ||
1434 | return -EINVAL; | ||
1435 | |||
1436 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1437 | CXD2880_IO_TGT_SYS, | ||
1438 | x_sleep2_seq2, | ||
1439 | ARRAY_SIZE(x_sleep2_seq2)); | ||
1440 | } | ||
1441 | |||
1442 | static int x_sleep3(struct cxd2880_tnrdmd *tnr_dmd) | ||
1443 | { | ||
1444 | if (!tnr_dmd) | ||
1445 | return -EINVAL; | ||
1446 | |||
1447 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1448 | CXD2880_IO_TGT_DMD, | ||
1449 | x_sleep3_seq, | ||
1450 | ARRAY_SIZE(x_sleep3_seq)); | ||
1451 | } | ||
1452 | |||
1453 | static int x_sleep4(struct cxd2880_tnrdmd *tnr_dmd) | ||
1454 | { | ||
1455 | if (!tnr_dmd) | ||
1456 | return -EINVAL; | ||
1457 | |||
1458 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1459 | CXD2880_IO_TGT_DMD, | ||
1460 | x_sleep4_seq, | ||
1461 | ARRAY_SIZE(x_sleep4_seq)); | ||
1462 | } | ||
1463 | |||
1464 | static int spll_reset(struct cxd2880_tnrdmd *tnr_dmd, | ||
1465 | enum cxd2880_tnrdmd_clockmode clockmode) | ||
1466 | { | ||
1467 | u8 data[4] = { 0 }; | ||
1468 | int ret; | ||
1469 | |||
1470 | if (!tnr_dmd) | ||
1471 | return -EINVAL; | ||
1472 | |||
1473 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1474 | CXD2880_IO_TGT_SYS, | ||
1475 | spll_reset_seq1, | ||
1476 | ARRAY_SIZE(spll_reset_seq1)); | ||
1477 | if (ret) | ||
1478 | return ret; | ||
1479 | |||
1480 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1481 | CXD2880_IO_TGT_DMD, | ||
1482 | spll_reset_seq2, | ||
1483 | ARRAY_SIZE(spll_reset_seq2)); | ||
1484 | if (ret) | ||
1485 | return ret; | ||
1486 | |||
1487 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1488 | CXD2880_IO_TGT_SYS, | ||
1489 | spll_reset_seq3, | ||
1490 | ARRAY_SIZE(spll_reset_seq3)); | ||
1491 | if (ret) | ||
1492 | return ret; | ||
1493 | |||
1494 | switch (clockmode) { | ||
1495 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
1496 | data[0] = 0x00; | ||
1497 | break; | ||
1498 | |||
1499 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
1500 | data[0] = 0x01; | ||
1501 | break; | ||
1502 | |||
1503 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
1504 | data[0] = 0x02; | ||
1505 | break; | ||
1506 | |||
1507 | default: | ||
1508 | return -EINVAL; | ||
1509 | } | ||
1510 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1511 | CXD2880_IO_TGT_SYS, | ||
1512 | 0x30, data[0]); | ||
1513 | if (ret) | ||
1514 | return ret; | ||
1515 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1516 | CXD2880_IO_TGT_SYS, | ||
1517 | 0x22, 0x00); | ||
1518 | if (ret) | ||
1519 | return ret; | ||
1520 | |||
1521 | usleep_range(2000, 3000); | ||
1522 | |||
1523 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1524 | CXD2880_IO_TGT_SYS, | ||
1525 | 0x00, 0x0a); | ||
1526 | if (ret) | ||
1527 | return ret; | ||
1528 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1529 | CXD2880_IO_TGT_SYS, | ||
1530 | 0x10, data, 1); | ||
1531 | if (ret) | ||
1532 | return ret; | ||
1533 | if ((data[0] & 0x01) == 0x00) | ||
1534 | return -EINVAL; | ||
1535 | |||
1536 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1537 | CXD2880_IO_TGT_SYS, | ||
1538 | spll_reset_seq4, | ||
1539 | ARRAY_SIZE(spll_reset_seq4)); | ||
1540 | if (ret) | ||
1541 | return ret; | ||
1542 | |||
1543 | usleep_range(1000, 2000); | ||
1544 | |||
1545 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1546 | CXD2880_IO_TGT_DMD, | ||
1547 | spll_reset_seq5, | ||
1548 | ARRAY_SIZE(spll_reset_seq5)); | ||
1549 | if (ret) | ||
1550 | return ret; | ||
1551 | |||
1552 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1553 | CXD2880_IO_TGT_SYS, | ||
1554 | 0x00, 0x10); | ||
1555 | if (ret) | ||
1556 | return ret; | ||
1557 | |||
1558 | memset(data, 0x00, sizeof(data)); | ||
1559 | |||
1560 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1561 | CXD2880_IO_TGT_SYS, | ||
1562 | 0x26, data, 4); | ||
1563 | } | ||
1564 | |||
1565 | static int t_power_x(struct cxd2880_tnrdmd *tnr_dmd, u8 on) | ||
1566 | { | ||
1567 | u8 data[3] = { 0 }; | ||
1568 | int ret; | ||
1569 | |||
1570 | if (!tnr_dmd) | ||
1571 | return -EINVAL; | ||
1572 | |||
1573 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1574 | CXD2880_IO_TGT_SYS, | ||
1575 | t_power_x_seq1, | ||
1576 | ARRAY_SIZE(t_power_x_seq1)); | ||
1577 | if (ret) | ||
1578 | return ret; | ||
1579 | |||
1580 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1581 | CXD2880_IO_TGT_DMD, | ||
1582 | t_power_x_seq2, | ||
1583 | ARRAY_SIZE(t_power_x_seq2)); | ||
1584 | if (ret) | ||
1585 | return ret; | ||
1586 | |||
1587 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1588 | CXD2880_IO_TGT_SYS, | ||
1589 | t_power_x_seq3, | ||
1590 | ARRAY_SIZE(t_power_x_seq3)); | ||
1591 | if (ret) | ||
1592 | return ret; | ||
1593 | |||
1594 | if (on) { | ||
1595 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1596 | CXD2880_IO_TGT_SYS, | ||
1597 | 0x2b, 0x01); | ||
1598 | if (ret) | ||
1599 | return ret; | ||
1600 | |||
1601 | usleep_range(1000, 2000); | ||
1602 | |||
1603 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1604 | CXD2880_IO_TGT_SYS, | ||
1605 | 0x00, 0x0a); | ||
1606 | if (ret) | ||
1607 | return ret; | ||
1608 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1609 | CXD2880_IO_TGT_SYS, | ||
1610 | 0x12, data, 1); | ||
1611 | if (ret) | ||
1612 | return ret; | ||
1613 | if ((data[0] & 0x01) == 0) | ||
1614 | return -EINVAL; | ||
1615 | |||
1616 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1617 | CXD2880_IO_TGT_SYS, | ||
1618 | t_power_x_seq4, | ||
1619 | ARRAY_SIZE(t_power_x_seq4)); | ||
1620 | if (ret) | ||
1621 | return ret; | ||
1622 | } else { | ||
1623 | data[0] = 0x03; | ||
1624 | data[1] = 0x00; | ||
1625 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1626 | CXD2880_IO_TGT_SYS, | ||
1627 | 0x2a, data, 2); | ||
1628 | if (ret) | ||
1629 | return ret; | ||
1630 | |||
1631 | usleep_range(1000, 2000); | ||
1632 | |||
1633 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1634 | CXD2880_IO_TGT_SYS, | ||
1635 | 0x00, 0x0a); | ||
1636 | if (ret) | ||
1637 | return ret; | ||
1638 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1639 | CXD2880_IO_TGT_SYS, | ||
1640 | 0x13, data, 1); | ||
1641 | if (ret) | ||
1642 | return ret; | ||
1643 | if ((data[0] & 0x01) == 0) | ||
1644 | return -EINVAL; | ||
1645 | } | ||
1646 | |||
1647 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1648 | CXD2880_IO_TGT_SYS, | ||
1649 | t_power_x_seq5, | ||
1650 | ARRAY_SIZE(t_power_x_seq5)); | ||
1651 | if (ret) | ||
1652 | return ret; | ||
1653 | |||
1654 | usleep_range(1000, 2000); | ||
1655 | |||
1656 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1657 | CXD2880_IO_TGT_SYS, | ||
1658 | 0x00, 0x0a); | ||
1659 | if (ret) | ||
1660 | return ret; | ||
1661 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1662 | CXD2880_IO_TGT_SYS, | ||
1663 | 0x11, data, 1); | ||
1664 | if (ret) | ||
1665 | return ret; | ||
1666 | if ((data[0] & 0x01) == 0) | ||
1667 | return -EINVAL; | ||
1668 | |||
1669 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1670 | CXD2880_IO_TGT_SYS, | ||
1671 | t_power_x_seq6, | ||
1672 | ARRAY_SIZE(t_power_x_seq6)); | ||
1673 | if (ret) | ||
1674 | return ret; | ||
1675 | |||
1676 | usleep_range(1000, 2000); | ||
1677 | |||
1678 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
1679 | CXD2880_IO_TGT_DMD, | ||
1680 | t_power_x_seq7, | ||
1681 | ARRAY_SIZE(t_power_x_seq7)); | ||
1682 | if (ret) | ||
1683 | return ret; | ||
1684 | |||
1685 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1686 | CXD2880_IO_TGT_SYS, | ||
1687 | 0x00, 0x10); | ||
1688 | if (ret) | ||
1689 | return ret; | ||
1690 | |||
1691 | memset(data, 0x00, sizeof(data)); | ||
1692 | |||
1693 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1694 | CXD2880_IO_TGT_SYS, | ||
1695 | 0x27, data, 3); | ||
1696 | } | ||
1697 | |||
1698 | struct cxd2880_tnrdmd_ts_clk_cfg { | ||
1699 | u8 srl_clk_mode; | ||
1700 | u8 srl_duty_mode; | ||
1701 | u8 ts_clk_period; | ||
1702 | }; | ||
1703 | |||
1704 | static int set_ts_clk_mode_and_freq(struct cxd2880_tnrdmd *tnr_dmd, | ||
1705 | enum cxd2880_dtv_sys sys) | ||
1706 | { | ||
1707 | int ret; | ||
1708 | u8 backwards_compatible = 0; | ||
1709 | struct cxd2880_tnrdmd_ts_clk_cfg ts_clk_cfg; | ||
1710 | u8 ts_rate_ctrl_off = 0; | ||
1711 | u8 ts_in_off = 0; | ||
1712 | u8 ts_clk_manaul_on = 0; | ||
1713 | u8 data = 0; | ||
1714 | |||
1715 | static const struct cxd2880_tnrdmd_ts_clk_cfg srl_ts_clk_stgs[2][2] = { | ||
1716 | { | ||
1717 | {3, 1, 8,}, | ||
1718 | {0, 2, 16,} | ||
1719 | }, { | ||
1720 | {1, 1, 8,}, | ||
1721 | {2, 2, 16,} | ||
1722 | } | ||
1723 | }; | ||
1724 | |||
1725 | if (!tnr_dmd) | ||
1726 | return -EINVAL; | ||
1727 | |||
1728 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1729 | CXD2880_IO_TGT_DMD, | ||
1730 | 0x00, 0x00); | ||
1731 | if (ret) | ||
1732 | return ret; | ||
1733 | |||
1734 | if (tnr_dmd->is_ts_backwards_compatible_mode) { | ||
1735 | backwards_compatible = 1; | ||
1736 | ts_rate_ctrl_off = 1; | ||
1737 | ts_in_off = 1; | ||
1738 | } else { | ||
1739 | backwards_compatible = 0; | ||
1740 | ts_rate_ctrl_off = 0; | ||
1741 | ts_in_off = 0; | ||
1742 | } | ||
1743 | |||
1744 | if (tnr_dmd->ts_byte_clk_manual_setting) { | ||
1745 | ts_clk_manaul_on = 1; | ||
1746 | ts_rate_ctrl_off = 0; | ||
1747 | } | ||
1748 | |||
1749 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1750 | CXD2880_IO_TGT_DMD, | ||
1751 | 0xd3, ts_rate_ctrl_off, 0x01); | ||
1752 | if (ret) | ||
1753 | return ret; | ||
1754 | |||
1755 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1756 | CXD2880_IO_TGT_DMD, | ||
1757 | 0xde, ts_in_off, 0x01); | ||
1758 | if (ret) | ||
1759 | return ret; | ||
1760 | |||
1761 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1762 | CXD2880_IO_TGT_DMD, | ||
1763 | 0xda, ts_clk_manaul_on, 0x01); | ||
1764 | if (ret) | ||
1765 | return ret; | ||
1766 | |||
1767 | ts_clk_cfg = srl_ts_clk_stgs[tnr_dmd->srl_ts_clk_mod_cnts] | ||
1768 | [tnr_dmd->srl_ts_clk_frq]; | ||
1769 | |||
1770 | if (tnr_dmd->ts_byte_clk_manual_setting) | ||
1771 | ts_clk_cfg.ts_clk_period = tnr_dmd->ts_byte_clk_manual_setting; | ||
1772 | |||
1773 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1774 | CXD2880_IO_TGT_DMD, | ||
1775 | 0xc4, ts_clk_cfg.srl_clk_mode, 0x03); | ||
1776 | if (ret) | ||
1777 | return ret; | ||
1778 | |||
1779 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1780 | CXD2880_IO_TGT_DMD, | ||
1781 | 0xd1, ts_clk_cfg.srl_duty_mode, 0x03); | ||
1782 | if (ret) | ||
1783 | return ret; | ||
1784 | |||
1785 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1786 | CXD2880_IO_TGT_DMD, 0xd9, | ||
1787 | ts_clk_cfg.ts_clk_period); | ||
1788 | if (ret) | ||
1789 | return ret; | ||
1790 | |||
1791 | data = backwards_compatible ? 0x00 : 0x01; | ||
1792 | |||
1793 | if (sys == CXD2880_DTV_SYS_DVBT) { | ||
1794 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1795 | CXD2880_IO_TGT_DMD, | ||
1796 | 0x00, 0x10); | ||
1797 | if (ret) | ||
1798 | return ret; | ||
1799 | |||
1800 | ret = | ||
1801 | cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1802 | CXD2880_IO_TGT_DMD, | ||
1803 | 0x66, data, 0x01); | ||
1804 | } | ||
1805 | |||
1806 | return ret; | ||
1807 | } | ||
1808 | |||
1809 | static int pid_ftr_setting(struct cxd2880_tnrdmd *tnr_dmd, | ||
1810 | struct cxd2880_tnrdmd_pid_ftr_cfg | ||
1811 | *pid_ftr_cfg) | ||
1812 | { | ||
1813 | int i; | ||
1814 | int ret; | ||
1815 | u8 data[65]; | ||
1816 | |||
1817 | if (!tnr_dmd) | ||
1818 | return -EINVAL; | ||
1819 | |||
1820 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1821 | CXD2880_IO_TGT_DMD, | ||
1822 | 0x00, 0x00); | ||
1823 | if (ret) | ||
1824 | return ret; | ||
1825 | |||
1826 | if (!pid_ftr_cfg) | ||
1827 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1828 | CXD2880_IO_TGT_DMD, | ||
1829 | 0x50, 0x02); | ||
1830 | |||
1831 | data[0] = pid_ftr_cfg->is_negative ? 0x01 : 0x00; | ||
1832 | |||
1833 | for (i = 0; i < 32; i++) { | ||
1834 | if (pid_ftr_cfg->pid_cfg[i].is_en) { | ||
1835 | data[1 + (i * 2)] = (pid_ftr_cfg->pid_cfg[i].pid >> 8) | 0x20; | ||
1836 | data[2 + (i * 2)] = pid_ftr_cfg->pid_cfg[i].pid & 0xff; | ||
1837 | } else { | ||
1838 | data[1 + (i * 2)] = 0x00; | ||
1839 | data[2 + (i * 2)] = 0x00; | ||
1840 | } | ||
1841 | } | ||
1842 | |||
1843 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1844 | CXD2880_IO_TGT_DMD, | ||
1845 | 0x50, data, 65); | ||
1846 | } | ||
1847 | |||
1848 | static int load_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd) | ||
1849 | { | ||
1850 | int ret; | ||
1851 | u8 i; | ||
1852 | |||
1853 | if (!tnr_dmd) | ||
1854 | return -EINVAL; | ||
1855 | |||
1856 | for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) { | ||
1857 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1858 | tnr_dmd->cfg_mem[i].tgt, | ||
1859 | 0x00, tnr_dmd->cfg_mem[i].bank); | ||
1860 | if (ret) | ||
1861 | return ret; | ||
1862 | |||
1863 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
1864 | tnr_dmd->cfg_mem[i].tgt, | ||
1865 | tnr_dmd->cfg_mem[i].address, | ||
1866 | tnr_dmd->cfg_mem[i].value, | ||
1867 | tnr_dmd->cfg_mem[i].bit_mask); | ||
1868 | if (ret) | ||
1869 | return ret; | ||
1870 | } | ||
1871 | |||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | static int set_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd, | ||
1876 | enum cxd2880_io_tgt tgt, | ||
1877 | u8 bank, u8 address, u8 value, u8 bit_mask) | ||
1878 | { | ||
1879 | u8 i; | ||
1880 | u8 value_stored = 0; | ||
1881 | |||
1882 | if (!tnr_dmd) | ||
1883 | return -EINVAL; | ||
1884 | |||
1885 | for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) { | ||
1886 | if (value_stored == 0 && | ||
1887 | tnr_dmd->cfg_mem[i].tgt == tgt && | ||
1888 | tnr_dmd->cfg_mem[i].bank == bank && | ||
1889 | tnr_dmd->cfg_mem[i].address == address) { | ||
1890 | tnr_dmd->cfg_mem[i].value &= ~bit_mask; | ||
1891 | tnr_dmd->cfg_mem[i].value |= (value & bit_mask); | ||
1892 | |||
1893 | tnr_dmd->cfg_mem[i].bit_mask |= bit_mask; | ||
1894 | |||
1895 | value_stored = 1; | ||
1896 | } | ||
1897 | } | ||
1898 | |||
1899 | if (value_stored) | ||
1900 | return 0; | ||
1901 | |||
1902 | if (tnr_dmd->cfg_mem_last_entry < CXD2880_TNRDMD_MAX_CFG_MEM_COUNT) { | ||
1903 | tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].tgt = tgt; | ||
1904 | tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bank = bank; | ||
1905 | tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].address = address; | ||
1906 | tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].value = (value & bit_mask); | ||
1907 | tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bit_mask = bit_mask; | ||
1908 | tnr_dmd->cfg_mem_last_entry++; | ||
1909 | } else { | ||
1910 | return -ENOMEM; | ||
1911 | } | ||
1912 | |||
1913 | return 0; | ||
1914 | } | ||
1915 | |||
1916 | int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd, | ||
1917 | struct cxd2880_io *io, | ||
1918 | struct cxd2880_tnrdmd_create_param | ||
1919 | *create_param) | ||
1920 | { | ||
1921 | if (!tnr_dmd || !io || !create_param) | ||
1922 | return -EINVAL; | ||
1923 | |||
1924 | memset(tnr_dmd, 0, sizeof(struct cxd2880_tnrdmd)); | ||
1925 | |||
1926 | tnr_dmd->io = io; | ||
1927 | tnr_dmd->create_param = *create_param; | ||
1928 | |||
1929 | tnr_dmd->diver_mode = CXD2880_TNRDMD_DIVERMODE_SINGLE; | ||
1930 | tnr_dmd->diver_sub = NULL; | ||
1931 | |||
1932 | tnr_dmd->srl_ts_clk_mod_cnts = 1; | ||
1933 | tnr_dmd->en_fef_intmtnt_base = 1; | ||
1934 | tnr_dmd->en_fef_intmtnt_lite = 1; | ||
1935 | tnr_dmd->rf_lvl_cmpstn = NULL; | ||
1936 | tnr_dmd->lna_thrs_tbl_air = NULL; | ||
1937 | tnr_dmd->lna_thrs_tbl_cable = NULL; | ||
1938 | atomic_set(&tnr_dmd->cancel, 0); | ||
1939 | |||
1940 | return 0; | ||
1941 | } | ||
1942 | |||
1943 | int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd | ||
1944 | *tnr_dmd_main, | ||
1945 | struct cxd2880_io *io_main, | ||
1946 | struct cxd2880_tnrdmd *tnr_dmd_sub, | ||
1947 | struct cxd2880_io *io_sub, | ||
1948 | struct | ||
1949 | cxd2880_tnrdmd_diver_create_param | ||
1950 | *create_param) | ||
1951 | { | ||
1952 | struct cxd2880_tnrdmd_create_param *main_param, *sub_param; | ||
1953 | |||
1954 | if (!tnr_dmd_main || !io_main || !tnr_dmd_sub || !io_sub || | ||
1955 | !create_param) | ||
1956 | return -EINVAL; | ||
1957 | |||
1958 | memset(tnr_dmd_main, 0, sizeof(struct cxd2880_tnrdmd)); | ||
1959 | memset(tnr_dmd_sub, 0, sizeof(struct cxd2880_tnrdmd)); | ||
1960 | |||
1961 | main_param = &tnr_dmd_main->create_param; | ||
1962 | sub_param = &tnr_dmd_sub->create_param; | ||
1963 | |||
1964 | tnr_dmd_main->io = io_main; | ||
1965 | tnr_dmd_main->diver_mode = CXD2880_TNRDMD_DIVERMODE_MAIN; | ||
1966 | tnr_dmd_main->diver_sub = tnr_dmd_sub; | ||
1967 | tnr_dmd_main->create_param.en_internal_ldo = | ||
1968 | create_param->en_internal_ldo; | ||
1969 | |||
1970 | main_param->ts_output_if = create_param->ts_output_if; | ||
1971 | main_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_MASTER; | ||
1972 | main_param->xosc_cap = create_param->xosc_cap_main; | ||
1973 | main_param->xosc_i = create_param->xosc_i_main; | ||
1974 | main_param->is_cxd2881gg = create_param->is_cxd2881gg; | ||
1975 | main_param->stationary_use = create_param->stationary_use; | ||
1976 | |||
1977 | tnr_dmd_sub->io = io_sub; | ||
1978 | tnr_dmd_sub->diver_mode = CXD2880_TNRDMD_DIVERMODE_SUB; | ||
1979 | tnr_dmd_sub->diver_sub = NULL; | ||
1980 | |||
1981 | sub_param->en_internal_ldo = create_param->en_internal_ldo; | ||
1982 | sub_param->ts_output_if = create_param->ts_output_if; | ||
1983 | sub_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_SLAVE; | ||
1984 | sub_param->xosc_cap = 0; | ||
1985 | sub_param->xosc_i = create_param->xosc_i_sub; | ||
1986 | sub_param->is_cxd2881gg = create_param->is_cxd2881gg; | ||
1987 | sub_param->stationary_use = create_param->stationary_use; | ||
1988 | |||
1989 | tnr_dmd_main->srl_ts_clk_mod_cnts = 1; | ||
1990 | tnr_dmd_main->en_fef_intmtnt_base = 1; | ||
1991 | tnr_dmd_main->en_fef_intmtnt_lite = 1; | ||
1992 | tnr_dmd_main->rf_lvl_cmpstn = NULL; | ||
1993 | tnr_dmd_main->lna_thrs_tbl_air = NULL; | ||
1994 | tnr_dmd_main->lna_thrs_tbl_cable = NULL; | ||
1995 | |||
1996 | tnr_dmd_sub->srl_ts_clk_mod_cnts = 1; | ||
1997 | tnr_dmd_sub->en_fef_intmtnt_base = 1; | ||
1998 | tnr_dmd_sub->en_fef_intmtnt_lite = 1; | ||
1999 | tnr_dmd_sub->rf_lvl_cmpstn = NULL; | ||
2000 | tnr_dmd_sub->lna_thrs_tbl_air = NULL; | ||
2001 | tnr_dmd_sub->lna_thrs_tbl_cable = NULL; | ||
2002 | |||
2003 | return 0; | ||
2004 | } | ||
2005 | |||
2006 | int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd) | ||
2007 | { | ||
2008 | int ret; | ||
2009 | |||
2010 | if (!tnr_dmd || tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
2011 | return -EINVAL; | ||
2012 | |||
2013 | tnr_dmd->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN; | ||
2014 | tnr_dmd->state = CXD2880_TNRDMD_STATE_UNKNOWN; | ||
2015 | tnr_dmd->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN; | ||
2016 | tnr_dmd->frequency_khz = 0; | ||
2017 | tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN; | ||
2018 | tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN; | ||
2019 | tnr_dmd->scan_mode = 0; | ||
2020 | atomic_set(&tnr_dmd->cancel, 0); | ||
2021 | |||
2022 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2023 | tnr_dmd->diver_sub->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN; | ||
2024 | tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_UNKNOWN; | ||
2025 | tnr_dmd->diver_sub->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN; | ||
2026 | tnr_dmd->diver_sub->frequency_khz = 0; | ||
2027 | tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN; | ||
2028 | tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN; | ||
2029 | tnr_dmd->diver_sub->scan_mode = 0; | ||
2030 | atomic_set(&tnr_dmd->diver_sub->cancel, 0); | ||
2031 | } | ||
2032 | |||
2033 | ret = cxd2880_tnrdmd_chip_id(tnr_dmd, &tnr_dmd->chip_id); | ||
2034 | if (ret) | ||
2035 | return ret; | ||
2036 | |||
2037 | if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->chip_id)) | ||
2038 | return -ENOTTY; | ||
2039 | |||
2040 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2041 | ret = | ||
2042 | cxd2880_tnrdmd_chip_id(tnr_dmd->diver_sub, | ||
2043 | &tnr_dmd->diver_sub->chip_id); | ||
2044 | if (ret) | ||
2045 | return ret; | ||
2046 | |||
2047 | if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->diver_sub->chip_id)) | ||
2048 | return -ENOTTY; | ||
2049 | } | ||
2050 | |||
2051 | ret = p_init1(tnr_dmd); | ||
2052 | if (ret) | ||
2053 | return ret; | ||
2054 | |||
2055 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2056 | ret = p_init1(tnr_dmd->diver_sub); | ||
2057 | if (ret) | ||
2058 | return ret; | ||
2059 | } | ||
2060 | |||
2061 | usleep_range(1000, 2000); | ||
2062 | |||
2063 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2064 | ret = p_init2(tnr_dmd->diver_sub); | ||
2065 | if (ret) | ||
2066 | return ret; | ||
2067 | } | ||
2068 | |||
2069 | ret = p_init2(tnr_dmd); | ||
2070 | if (ret) | ||
2071 | return ret; | ||
2072 | |||
2073 | usleep_range(5000, 6000); | ||
2074 | |||
2075 | ret = p_init3(tnr_dmd); | ||
2076 | if (ret) | ||
2077 | return ret; | ||
2078 | |||
2079 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2080 | ret = p_init3(tnr_dmd->diver_sub); | ||
2081 | if (ret) | ||
2082 | return ret; | ||
2083 | } | ||
2084 | |||
2085 | ret = rf_init1(tnr_dmd); | ||
2086 | if (ret) | ||
2087 | return ret; | ||
2088 | |||
2089 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
2090 | ret = rf_init1(tnr_dmd->diver_sub); | ||
2091 | |||
2092 | return ret; | ||
2093 | } | ||
2094 | |||
2095 | int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd) | ||
2096 | { | ||
2097 | u8 cpu_task_completed; | ||
2098 | int ret; | ||
2099 | |||
2100 | if (!tnr_dmd) | ||
2101 | return -EINVAL; | ||
2102 | |||
2103 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
2104 | return -EINVAL; | ||
2105 | |||
2106 | ret = cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd, | ||
2107 | &cpu_task_completed); | ||
2108 | if (ret) | ||
2109 | return ret; | ||
2110 | |||
2111 | if (!cpu_task_completed) | ||
2112 | return -EINVAL; | ||
2113 | |||
2114 | ret = rf_init2(tnr_dmd); | ||
2115 | if (ret) | ||
2116 | return ret; | ||
2117 | |||
2118 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2119 | ret = rf_init2(tnr_dmd->diver_sub); | ||
2120 | if (ret) | ||
2121 | return ret; | ||
2122 | } | ||
2123 | |||
2124 | ret = load_cfg_mem(tnr_dmd); | ||
2125 | if (ret) | ||
2126 | return ret; | ||
2127 | |||
2128 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2129 | ret = load_cfg_mem(tnr_dmd->diver_sub); | ||
2130 | if (ret) | ||
2131 | return ret; | ||
2132 | } | ||
2133 | |||
2134 | tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP; | ||
2135 | |||
2136 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
2137 | tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP; | ||
2138 | |||
2139 | return ret; | ||
2140 | } | ||
2141 | |||
2142 | int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd | ||
2143 | *tnr_dmd, | ||
2144 | u8 *task_completed) | ||
2145 | { | ||
2146 | u16 cpu_status = 0; | ||
2147 | int ret; | ||
2148 | |||
2149 | if (!tnr_dmd || !task_completed) | ||
2150 | return -EINVAL; | ||
2151 | |||
2152 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
2153 | return -EINVAL; | ||
2154 | |||
2155 | ret = cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd, &cpu_status); | ||
2156 | if (ret) | ||
2157 | return ret; | ||
2158 | |||
2159 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
2160 | if (cpu_status == 0) | ||
2161 | *task_completed = 1; | ||
2162 | else | ||
2163 | *task_completed = 0; | ||
2164 | |||
2165 | return ret; | ||
2166 | } | ||
2167 | if (cpu_status != 0) { | ||
2168 | *task_completed = 0; | ||
2169 | return ret; | ||
2170 | } | ||
2171 | |||
2172 | ret = cxd2880_tnrdmd_mon_internal_cpu_status_sub(tnr_dmd, &cpu_status); | ||
2173 | if (ret) | ||
2174 | return ret; | ||
2175 | |||
2176 | if (cpu_status == 0) | ||
2177 | *task_completed = 1; | ||
2178 | else | ||
2179 | *task_completed = 0; | ||
2180 | |||
2181 | return ret; | ||
2182 | } | ||
2183 | |||
2184 | int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd *tnr_dmd, | ||
2185 | enum cxd2880_dtv_sys sys, | ||
2186 | u32 frequency_khz, | ||
2187 | enum cxd2880_dtv_bandwidth | ||
2188 | bandwidth, u8 one_seg_opt, | ||
2189 | u8 one_seg_opt_shft_dir) | ||
2190 | { | ||
2191 | u8 data; | ||
2192 | enum cxd2880_tnrdmd_clockmode new_clk_mode = | ||
2193 | CXD2880_TNRDMD_CLOCKMODE_A; | ||
2194 | int shift_frequency_khz; | ||
2195 | u8 cpu_task_completed; | ||
2196 | int ret; | ||
2197 | |||
2198 | if (!tnr_dmd) | ||
2199 | return -EINVAL; | ||
2200 | |||
2201 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
2202 | return -EINVAL; | ||
2203 | |||
2204 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
2205 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
2206 | return -EINVAL; | ||
2207 | |||
2208 | if (frequency_khz < 4000) | ||
2209 | return -EINVAL; | ||
2210 | |||
2211 | ret = cxd2880_tnrdmd_sleep(tnr_dmd); | ||
2212 | if (ret) | ||
2213 | return ret; | ||
2214 | |||
2215 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
2216 | CXD2880_IO_TGT_SYS, | ||
2217 | 0x00, | ||
2218 | 0x00); | ||
2219 | if (ret) | ||
2220 | return ret; | ||
2221 | |||
2222 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
2223 | CXD2880_IO_TGT_SYS, | ||
2224 | 0x2b, | ||
2225 | &data, | ||
2226 | 1); | ||
2227 | if (ret) | ||
2228 | return ret; | ||
2229 | |||
2230 | switch (sys) { | ||
2231 | case CXD2880_DTV_SYS_DVBT: | ||
2232 | if (data == 0x00) { | ||
2233 | ret = t_power_x(tnr_dmd, 1); | ||
2234 | if (ret) | ||
2235 | return ret; | ||
2236 | |||
2237 | if (tnr_dmd->diver_mode == | ||
2238 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2239 | ret = t_power_x(tnr_dmd->diver_sub, 1); | ||
2240 | if (ret) | ||
2241 | return ret; | ||
2242 | } | ||
2243 | } | ||
2244 | break; | ||
2245 | |||
2246 | case CXD2880_DTV_SYS_DVBT2: | ||
2247 | if (data == 0x01) { | ||
2248 | ret = t_power_x(tnr_dmd, 0); | ||
2249 | if (ret) | ||
2250 | return ret; | ||
2251 | |||
2252 | if (tnr_dmd->diver_mode == | ||
2253 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2254 | ret = t_power_x(tnr_dmd->diver_sub, 0); | ||
2255 | if (ret) | ||
2256 | return ret; | ||
2257 | } | ||
2258 | } | ||
2259 | break; | ||
2260 | |||
2261 | default: | ||
2262 | return -EINVAL; | ||
2263 | } | ||
2264 | |||
2265 | ret = spll_reset(tnr_dmd, new_clk_mode); | ||
2266 | if (ret) | ||
2267 | return ret; | ||
2268 | |||
2269 | tnr_dmd->clk_mode = new_clk_mode; | ||
2270 | |||
2271 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2272 | ret = spll_reset(tnr_dmd->diver_sub, new_clk_mode); | ||
2273 | if (ret) | ||
2274 | return ret; | ||
2275 | |||
2276 | tnr_dmd->diver_sub->clk_mode = new_clk_mode; | ||
2277 | } | ||
2278 | |||
2279 | ret = load_cfg_mem(tnr_dmd); | ||
2280 | if (ret) | ||
2281 | return ret; | ||
2282 | |||
2283 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2284 | ret = load_cfg_mem(tnr_dmd->diver_sub); | ||
2285 | if (ret) | ||
2286 | return ret; | ||
2287 | } | ||
2288 | |||
2289 | if (one_seg_opt) { | ||
2290 | if (tnr_dmd->diver_mode == | ||
2291 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2292 | shift_frequency_khz = 350; | ||
2293 | } else { | ||
2294 | if (one_seg_opt_shft_dir) | ||
2295 | shift_frequency_khz = 350; | ||
2296 | else | ||
2297 | shift_frequency_khz = -350; | ||
2298 | |||
2299 | if (tnr_dmd->create_param.xtal_share_type == | ||
2300 | CXD2880_TNRDMD_XTAL_SHARE_SLAVE) | ||
2301 | shift_frequency_khz *= -1; | ||
2302 | } | ||
2303 | } else { | ||
2304 | if (tnr_dmd->diver_mode == | ||
2305 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2306 | shift_frequency_khz = 150; | ||
2307 | } else { | ||
2308 | switch (tnr_dmd->create_param.xtal_share_type) { | ||
2309 | case CXD2880_TNRDMD_XTAL_SHARE_NONE: | ||
2310 | case CXD2880_TNRDMD_XTAL_SHARE_EXTREF: | ||
2311 | default: | ||
2312 | shift_frequency_khz = 0; | ||
2313 | break; | ||
2314 | case CXD2880_TNRDMD_XTAL_SHARE_MASTER: | ||
2315 | shift_frequency_khz = 150; | ||
2316 | break; | ||
2317 | case CXD2880_TNRDMD_XTAL_SHARE_SLAVE: | ||
2318 | shift_frequency_khz = -150; | ||
2319 | break; | ||
2320 | } | ||
2321 | } | ||
2322 | } | ||
2323 | |||
2324 | ret = | ||
2325 | x_tune1(tnr_dmd, sys, frequency_khz, bandwidth, | ||
2326 | tnr_dmd->is_cable_input, shift_frequency_khz); | ||
2327 | if (ret) | ||
2328 | return ret; | ||
2329 | |||
2330 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2331 | ret = | ||
2332 | x_tune1(tnr_dmd->diver_sub, sys, frequency_khz, | ||
2333 | bandwidth, tnr_dmd->is_cable_input, | ||
2334 | -shift_frequency_khz); | ||
2335 | if (ret) | ||
2336 | return ret; | ||
2337 | } | ||
2338 | |||
2339 | usleep_range(10000, 11000); | ||
2340 | |||
2341 | ret = | ||
2342 | cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd, | ||
2343 | &cpu_task_completed); | ||
2344 | if (ret) | ||
2345 | return ret; | ||
2346 | |||
2347 | if (!cpu_task_completed) | ||
2348 | return -EINVAL; | ||
2349 | |||
2350 | ret = | ||
2351 | x_tune2(tnr_dmd, bandwidth, tnr_dmd->clk_mode, | ||
2352 | shift_frequency_khz); | ||
2353 | if (ret) | ||
2354 | return ret; | ||
2355 | |||
2356 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2357 | ret = | ||
2358 | x_tune2(tnr_dmd->diver_sub, bandwidth, | ||
2359 | tnr_dmd->diver_sub->clk_mode, | ||
2360 | -shift_frequency_khz); | ||
2361 | if (ret) | ||
2362 | return ret; | ||
2363 | } | ||
2364 | |||
2365 | if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS) { | ||
2366 | ret = set_ts_clk_mode_and_freq(tnr_dmd, sys); | ||
2367 | } else { | ||
2368 | struct cxd2880_tnrdmd_pid_ftr_cfg *pid_ftr_cfg; | ||
2369 | |||
2370 | if (tnr_dmd->pid_ftr_cfg_en) | ||
2371 | pid_ftr_cfg = &tnr_dmd->pid_ftr_cfg; | ||
2372 | else | ||
2373 | pid_ftr_cfg = NULL; | ||
2374 | |||
2375 | ret = pid_ftr_setting(tnr_dmd, pid_ftr_cfg); | ||
2376 | } | ||
2377 | |||
2378 | return ret; | ||
2379 | } | ||
2380 | |||
2381 | int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd | ||
2382 | *tnr_dmd, | ||
2383 | enum cxd2880_dtv_sys sys, | ||
2384 | u8 en_fef_intmtnt_ctrl) | ||
2385 | { | ||
2386 | int ret; | ||
2387 | |||
2388 | if (!tnr_dmd) | ||
2389 | return -EINVAL; | ||
2390 | |||
2391 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
2392 | return -EINVAL; | ||
2393 | |||
2394 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
2395 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
2396 | return -EINVAL; | ||
2397 | |||
2398 | ret = x_tune3(tnr_dmd, sys, en_fef_intmtnt_ctrl); | ||
2399 | if (ret) | ||
2400 | return ret; | ||
2401 | |||
2402 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2403 | ret = x_tune3(tnr_dmd->diver_sub, sys, en_fef_intmtnt_ctrl); | ||
2404 | if (ret) | ||
2405 | return ret; | ||
2406 | ret = x_tune4(tnr_dmd); | ||
2407 | if (ret) | ||
2408 | return ret; | ||
2409 | } | ||
2410 | |||
2411 | return cxd2880_tnrdmd_set_ts_output(tnr_dmd, 1); | ||
2412 | } | ||
2413 | |||
2414 | int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd) | ||
2415 | { | ||
2416 | int ret; | ||
2417 | |||
2418 | if (!tnr_dmd) | ||
2419 | return -EINVAL; | ||
2420 | |||
2421 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
2422 | return -EINVAL; | ||
2423 | |||
2424 | if (tnr_dmd->state == CXD2880_TNRDMD_STATE_SLEEP) | ||
2425 | return 0; | ||
2426 | |||
2427 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
2428 | return -EINVAL; | ||
2429 | |||
2430 | ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 0); | ||
2431 | if (ret) | ||
2432 | return ret; | ||
2433 | |||
2434 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2435 | ret = x_sleep1(tnr_dmd); | ||
2436 | if (ret) | ||
2437 | return ret; | ||
2438 | } | ||
2439 | |||
2440 | ret = x_sleep2(tnr_dmd); | ||
2441 | if (ret) | ||
2442 | return ret; | ||
2443 | |||
2444 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2445 | ret = x_sleep2(tnr_dmd->diver_sub); | ||
2446 | if (ret) | ||
2447 | return ret; | ||
2448 | } | ||
2449 | |||
2450 | switch (tnr_dmd->sys) { | ||
2451 | case CXD2880_DTV_SYS_DVBT: | ||
2452 | ret = cxd2880_tnrdmd_dvbt_sleep_setting(tnr_dmd); | ||
2453 | if (ret) | ||
2454 | return ret; | ||
2455 | break; | ||
2456 | |||
2457 | case CXD2880_DTV_SYS_DVBT2: | ||
2458 | ret = cxd2880_tnrdmd_dvbt2_sleep_setting(tnr_dmd); | ||
2459 | if (ret) | ||
2460 | return ret; | ||
2461 | break; | ||
2462 | |||
2463 | default: | ||
2464 | return -EINVAL; | ||
2465 | } | ||
2466 | |||
2467 | ret = x_sleep3(tnr_dmd); | ||
2468 | if (ret) | ||
2469 | return ret; | ||
2470 | |||
2471 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2472 | ret = x_sleep3(tnr_dmd->diver_sub); | ||
2473 | if (ret) | ||
2474 | return ret; | ||
2475 | } | ||
2476 | |||
2477 | ret = x_sleep4(tnr_dmd); | ||
2478 | if (ret) | ||
2479 | return ret; | ||
2480 | |||
2481 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2482 | ret = x_sleep4(tnr_dmd->diver_sub); | ||
2483 | if (ret) | ||
2484 | return ret; | ||
2485 | } | ||
2486 | |||
2487 | tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP; | ||
2488 | tnr_dmd->frequency_khz = 0; | ||
2489 | tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN; | ||
2490 | tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN; | ||
2491 | |||
2492 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
2493 | tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP; | ||
2494 | tnr_dmd->diver_sub->frequency_khz = 0; | ||
2495 | tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN; | ||
2496 | tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN; | ||
2497 | } | ||
2498 | |||
2499 | return 0; | ||
2500 | } | ||
2501 | |||
2502 | int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, | ||
2503 | enum cxd2880_tnrdmd_cfg_id id, | ||
2504 | int value) | ||
2505 | { | ||
2506 | int ret = 0; | ||
2507 | u8 data[2] = { 0 }; | ||
2508 | u8 need_sub_setting = 0; | ||
2509 | |||
2510 | if (!tnr_dmd) | ||
2511 | return -EINVAL; | ||
2512 | |||
2513 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
2514 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
2515 | return -EINVAL; | ||
2516 | |||
2517 | switch (id) { | ||
2518 | case CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB: | ||
2519 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2520 | return -EINVAL; | ||
2521 | |||
2522 | ret = | ||
2523 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2524 | CXD2880_IO_TGT_DMD, | ||
2525 | 0x00, 0xc4, | ||
2526 | value ? 0x00 : 0x10, | ||
2527 | 0x10); | ||
2528 | if (ret) | ||
2529 | return ret; | ||
2530 | break; | ||
2531 | |||
2532 | case CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI: | ||
2533 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2534 | return -EINVAL; | ||
2535 | |||
2536 | ret = | ||
2537 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2538 | CXD2880_IO_TGT_DMD, | ||
2539 | 0x00, 0xc5, | ||
2540 | value ? 0x00 : 0x02, | ||
2541 | 0x02); | ||
2542 | if (ret) | ||
2543 | return ret; | ||
2544 | break; | ||
2545 | |||
2546 | case CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI: | ||
2547 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2548 | return -EINVAL; | ||
2549 | |||
2550 | ret = | ||
2551 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2552 | CXD2880_IO_TGT_DMD, | ||
2553 | 0x00, 0xc5, | ||
2554 | value ? 0x00 : 0x04, | ||
2555 | 0x04); | ||
2556 | if (ret) | ||
2557 | return ret; | ||
2558 | break; | ||
2559 | |||
2560 | case CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI: | ||
2561 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2562 | return -EINVAL; | ||
2563 | |||
2564 | ret = | ||
2565 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2566 | CXD2880_IO_TGT_DMD, | ||
2567 | 0x00, 0xcb, | ||
2568 | value ? 0x00 : 0x01, | ||
2569 | 0x01); | ||
2570 | if (ret) | ||
2571 | return ret; | ||
2572 | break; | ||
2573 | |||
2574 | case CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE: | ||
2575 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2576 | return -EINVAL; | ||
2577 | |||
2578 | ret = | ||
2579 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2580 | CXD2880_IO_TGT_DMD, | ||
2581 | 0x00, 0xc5, | ||
2582 | value ? 0x01 : 0x00, | ||
2583 | 0x01); | ||
2584 | if (ret) | ||
2585 | return ret; | ||
2586 | break; | ||
2587 | |||
2588 | case CXD2880_TNRDMD_CFG_TSCLK_CONT: | ||
2589 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2590 | return -EINVAL; | ||
2591 | |||
2592 | tnr_dmd->srl_ts_clk_mod_cnts = value ? 0x01 : 0x00; | ||
2593 | break; | ||
2594 | |||
2595 | case CXD2880_TNRDMD_CFG_TSCLK_MASK: | ||
2596 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2597 | return -EINVAL; | ||
2598 | |||
2599 | if (value < 0 || value > 0x1f) | ||
2600 | return -EINVAL; | ||
2601 | |||
2602 | ret = | ||
2603 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2604 | CXD2880_IO_TGT_DMD, | ||
2605 | 0x00, 0xc6, value, | ||
2606 | 0x1f); | ||
2607 | if (ret) | ||
2608 | return ret; | ||
2609 | break; | ||
2610 | |||
2611 | case CXD2880_TNRDMD_CFG_TSVALID_MASK: | ||
2612 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2613 | return -EINVAL; | ||
2614 | |||
2615 | if (value < 0 || value > 0x1f) | ||
2616 | return -EINVAL; | ||
2617 | |||
2618 | ret = | ||
2619 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2620 | CXD2880_IO_TGT_DMD, | ||
2621 | 0x00, 0xc8, value, | ||
2622 | 0x1f); | ||
2623 | if (ret) | ||
2624 | return ret; | ||
2625 | break; | ||
2626 | |||
2627 | case CXD2880_TNRDMD_CFG_TSERR_MASK: | ||
2628 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2629 | return -EINVAL; | ||
2630 | |||
2631 | if (value < 0 || value > 0x1f) | ||
2632 | return -EINVAL; | ||
2633 | |||
2634 | ret = | ||
2635 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2636 | CXD2880_IO_TGT_DMD, | ||
2637 | 0x00, 0xc9, value, | ||
2638 | 0x1f); | ||
2639 | if (ret) | ||
2640 | return ret; | ||
2641 | break; | ||
2642 | |||
2643 | case CXD2880_TNRDMD_CFG_TSERR_VALID_DIS: | ||
2644 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2645 | return -EINVAL; | ||
2646 | |||
2647 | ret = | ||
2648 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2649 | CXD2880_IO_TGT_DMD, | ||
2650 | 0x00, 0x91, | ||
2651 | value ? 0x01 : 0x00, | ||
2652 | 0x01); | ||
2653 | if (ret) | ||
2654 | return ret; | ||
2655 | break; | ||
2656 | |||
2657 | case CXD2880_TNRDMD_CFG_TSPIN_CURRENT: | ||
2658 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2659 | return -EINVAL; | ||
2660 | |||
2661 | ret = | ||
2662 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2663 | CXD2880_IO_TGT_SYS, | ||
2664 | 0x00, 0x51, value, | ||
2665 | 0x3f); | ||
2666 | if (ret) | ||
2667 | return ret; | ||
2668 | break; | ||
2669 | |||
2670 | case CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL: | ||
2671 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2672 | return -EINVAL; | ||
2673 | |||
2674 | ret = | ||
2675 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2676 | CXD2880_IO_TGT_SYS, | ||
2677 | 0x00, 0x50, | ||
2678 | value ? 0x80 : 0x00, | ||
2679 | 0x80); | ||
2680 | if (ret) | ||
2681 | return ret; | ||
2682 | break; | ||
2683 | |||
2684 | case CXD2880_TNRDMD_CFG_TSPIN_PULLUP: | ||
2685 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2686 | return -EINVAL; | ||
2687 | |||
2688 | ret = | ||
2689 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2690 | CXD2880_IO_TGT_SYS, | ||
2691 | 0x00, 0x50, value, | ||
2692 | 0x3f); | ||
2693 | if (ret) | ||
2694 | return ret; | ||
2695 | break; | ||
2696 | |||
2697 | case CXD2880_TNRDMD_CFG_TSCLK_FREQ: | ||
2698 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2699 | return -EINVAL; | ||
2700 | |||
2701 | if (value < 0 || value > 1) | ||
2702 | return -EINVAL; | ||
2703 | |||
2704 | tnr_dmd->srl_ts_clk_frq = | ||
2705 | (enum cxd2880_tnrdmd_serial_ts_clk)value; | ||
2706 | break; | ||
2707 | |||
2708 | case CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL: | ||
2709 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2710 | return -EINVAL; | ||
2711 | |||
2712 | if (value < 0 || value > 0xff) | ||
2713 | return -EINVAL; | ||
2714 | |||
2715 | tnr_dmd->ts_byte_clk_manual_setting = value; | ||
2716 | |||
2717 | break; | ||
2718 | |||
2719 | case CXD2880_TNRDMD_CFG_TS_PACKET_GAP: | ||
2720 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2721 | return -EINVAL; | ||
2722 | |||
2723 | if (value < 0 || value > 7) | ||
2724 | return -EINVAL; | ||
2725 | |||
2726 | ret = | ||
2727 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2728 | CXD2880_IO_TGT_DMD, | ||
2729 | 0x00, 0xd6, value, | ||
2730 | 0x07); | ||
2731 | if (ret) | ||
2732 | return ret; | ||
2733 | |||
2734 | break; | ||
2735 | |||
2736 | case CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE: | ||
2737 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
2738 | return -EINVAL; | ||
2739 | |||
2740 | tnr_dmd->is_ts_backwards_compatible_mode = value ? 1 : 0; | ||
2741 | |||
2742 | break; | ||
2743 | |||
2744 | case CXD2880_TNRDMD_CFG_PWM_VALUE: | ||
2745 | if (value < 0 || value > 0x1000) | ||
2746 | return -EINVAL; | ||
2747 | |||
2748 | ret = | ||
2749 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2750 | CXD2880_IO_TGT_DMD, | ||
2751 | 0x00, 0x22, | ||
2752 | value ? 0x01 : 0x00, | ||
2753 | 0x01); | ||
2754 | if (ret) | ||
2755 | return ret; | ||
2756 | |||
2757 | data[0] = (value >> 8) & 0x1f; | ||
2758 | data[1] = value & 0xff; | ||
2759 | |||
2760 | ret = | ||
2761 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2762 | CXD2880_IO_TGT_DMD, | ||
2763 | 0x00, 0x23, | ||
2764 | data[0], 0x1f); | ||
2765 | if (ret) | ||
2766 | return ret; | ||
2767 | |||
2768 | ret = | ||
2769 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2770 | CXD2880_IO_TGT_DMD, | ||
2771 | 0x00, 0x24, | ||
2772 | data[1], 0xff); | ||
2773 | if (ret) | ||
2774 | return ret; | ||
2775 | |||
2776 | break; | ||
2777 | |||
2778 | case CXD2880_TNRDMD_CFG_INTERRUPT: | ||
2779 | data[0] = (value >> 8) & 0xff; | ||
2780 | data[1] = value & 0xff; | ||
2781 | ret = | ||
2782 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2783 | CXD2880_IO_TGT_SYS, | ||
2784 | 0x00, 0x48, data[0], | ||
2785 | 0xff); | ||
2786 | if (ret) | ||
2787 | return ret; | ||
2788 | ret = | ||
2789 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2790 | CXD2880_IO_TGT_SYS, | ||
2791 | 0x00, 0x49, data[1], | ||
2792 | 0xff); | ||
2793 | if (ret) | ||
2794 | return ret; | ||
2795 | break; | ||
2796 | |||
2797 | case CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL: | ||
2798 | data[0] = value & 0x07; | ||
2799 | ret = | ||
2800 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2801 | CXD2880_IO_TGT_SYS, | ||
2802 | 0x00, 0x4a, data[0], | ||
2803 | 0x07); | ||
2804 | if (ret) | ||
2805 | return ret; | ||
2806 | break; | ||
2807 | |||
2808 | case CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL: | ||
2809 | data[0] = (value & 0x07) << 3; | ||
2810 | ret = | ||
2811 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2812 | CXD2880_IO_TGT_SYS, | ||
2813 | 0x00, 0x4a, data[0], | ||
2814 | 0x38); | ||
2815 | if (ret) | ||
2816 | return ret; | ||
2817 | break; | ||
2818 | |||
2819 | case CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE: | ||
2820 | if (value < CXD2880_TNRDMD_CLOCKMODE_UNKNOWN || | ||
2821 | value > CXD2880_TNRDMD_CLOCKMODE_C) | ||
2822 | return -EINVAL; | ||
2823 | tnr_dmd->fixed_clk_mode = (enum cxd2880_tnrdmd_clockmode)value; | ||
2824 | break; | ||
2825 | |||
2826 | case CXD2880_TNRDMD_CFG_CABLE_INPUT: | ||
2827 | tnr_dmd->is_cable_input = value ? 1 : 0; | ||
2828 | break; | ||
2829 | |||
2830 | case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE: | ||
2831 | tnr_dmd->en_fef_intmtnt_base = value ? 1 : 0; | ||
2832 | break; | ||
2833 | |||
2834 | case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE: | ||
2835 | tnr_dmd->en_fef_intmtnt_lite = value ? 1 : 0; | ||
2836 | break; | ||
2837 | |||
2838 | case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS: | ||
2839 | data[0] = (value >> 8) & 0x07; | ||
2840 | data[1] = value & 0xff; | ||
2841 | ret = | ||
2842 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2843 | CXD2880_IO_TGT_DMD, | ||
2844 | 0x00, 0x99, data[0], | ||
2845 | 0x07); | ||
2846 | if (ret) | ||
2847 | return ret; | ||
2848 | ret = | ||
2849 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2850 | CXD2880_IO_TGT_DMD, | ||
2851 | 0x00, 0x9a, data[1], | ||
2852 | 0xff); | ||
2853 | if (ret) | ||
2854 | return ret; | ||
2855 | break; | ||
2856 | |||
2857 | case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS: | ||
2858 | data[0] = (value >> 8) & 0x07; | ||
2859 | data[1] = value & 0xff; | ||
2860 | ret = | ||
2861 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2862 | CXD2880_IO_TGT_DMD, | ||
2863 | 0x00, 0x9b, data[0], | ||
2864 | 0x07); | ||
2865 | if (ret) | ||
2866 | return ret; | ||
2867 | ret = | ||
2868 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2869 | CXD2880_IO_TGT_DMD, | ||
2870 | 0x00, 0x9c, data[1], | ||
2871 | 0xff); | ||
2872 | if (ret) | ||
2873 | return ret; | ||
2874 | break; | ||
2875 | |||
2876 | case CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS: | ||
2877 | data[0] = (value >> 8) & 0x07; | ||
2878 | data[1] = value & 0xff; | ||
2879 | ret = | ||
2880 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2881 | CXD2880_IO_TGT_DMD, | ||
2882 | 0x00, 0x9d, data[0], | ||
2883 | 0x07); | ||
2884 | if (ret) | ||
2885 | return ret; | ||
2886 | ret = | ||
2887 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2888 | CXD2880_IO_TGT_DMD, | ||
2889 | 0x00, 0x9e, data[1], | ||
2890 | 0xff); | ||
2891 | if (ret) | ||
2892 | return ret; | ||
2893 | break; | ||
2894 | |||
2895 | case CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST: | ||
2896 | tnr_dmd->blind_tune_dvbt2_first = value ? 1 : 0; | ||
2897 | break; | ||
2898 | |||
2899 | case CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD: | ||
2900 | if (value < 0 || value > 31) | ||
2901 | return -EINVAL; | ||
2902 | |||
2903 | ret = | ||
2904 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2905 | CXD2880_IO_TGT_DMD, | ||
2906 | 0x10, 0x60, | ||
2907 | value & 0x1f, 0x1f); | ||
2908 | if (ret) | ||
2909 | return ret; | ||
2910 | break; | ||
2911 | |||
2912 | case CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD: | ||
2913 | if (value < 0 || value > 7) | ||
2914 | return -EINVAL; | ||
2915 | |||
2916 | ret = | ||
2917 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2918 | CXD2880_IO_TGT_DMD, | ||
2919 | 0x10, 0x6f, | ||
2920 | value & 0x07, 0x07); | ||
2921 | if (ret) | ||
2922 | return ret; | ||
2923 | break; | ||
2924 | |||
2925 | case CXD2880_TNRDMD_CFG_DVBT2_BBER_MES: | ||
2926 | if (value < 0 || value > 15) | ||
2927 | return -EINVAL; | ||
2928 | |||
2929 | ret = | ||
2930 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2931 | CXD2880_IO_TGT_DMD, | ||
2932 | 0x20, 0x72, | ||
2933 | value & 0x0f, 0x0f); | ||
2934 | if (ret) | ||
2935 | return ret; | ||
2936 | break; | ||
2937 | |||
2938 | case CXD2880_TNRDMD_CFG_DVBT2_LBER_MES: | ||
2939 | if (value < 0 || value > 15) | ||
2940 | return -EINVAL; | ||
2941 | |||
2942 | ret = | ||
2943 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2944 | CXD2880_IO_TGT_DMD, | ||
2945 | 0x20, 0x6f, | ||
2946 | value & 0x0f, 0x0f); | ||
2947 | if (ret) | ||
2948 | return ret; | ||
2949 | break; | ||
2950 | |||
2951 | case CXD2880_TNRDMD_CFG_DVBT_PER_MES: | ||
2952 | if (value < 0 || value > 15) | ||
2953 | return -EINVAL; | ||
2954 | |||
2955 | ret = | ||
2956 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2957 | CXD2880_IO_TGT_DMD, | ||
2958 | 0x10, 0x5c, | ||
2959 | value & 0x0f, 0x0f); | ||
2960 | if (ret) | ||
2961 | return ret; | ||
2962 | break; | ||
2963 | |||
2964 | case CXD2880_TNRDMD_CFG_DVBT2_PER_MES: | ||
2965 | if (value < 0 || value > 15) | ||
2966 | return -EINVAL; | ||
2967 | |||
2968 | ret = | ||
2969 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
2970 | CXD2880_IO_TGT_DMD, | ||
2971 | 0x24, 0xdc, | ||
2972 | value & 0x0f, 0x0f); | ||
2973 | if (ret) | ||
2974 | return ret; | ||
2975 | break; | ||
2976 | |||
2977 | default: | ||
2978 | return -EINVAL; | ||
2979 | } | ||
2980 | |||
2981 | if (need_sub_setting && | ||
2982 | tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
2983 | ret = cxd2880_tnrdmd_set_cfg(tnr_dmd->diver_sub, id, value); | ||
2984 | |||
2985 | return ret; | ||
2986 | } | ||
2987 | |||
2988 | int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, | ||
2989 | u8 id, | ||
2990 | u8 en, | ||
2991 | enum cxd2880_tnrdmd_gpio_mode mode, | ||
2992 | u8 open_drain, u8 invert) | ||
2993 | { | ||
2994 | int ret; | ||
2995 | |||
2996 | if (!tnr_dmd) | ||
2997 | return -EINVAL; | ||
2998 | |||
2999 | if (id > 2) | ||
3000 | return -EINVAL; | ||
3001 | |||
3002 | if (mode > CXD2880_TNRDMD_GPIO_MODE_EEW) | ||
3003 | return -EINVAL; | ||
3004 | |||
3005 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3006 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3007 | return -EINVAL; | ||
3008 | |||
3009 | ret = | ||
3010 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS, | ||
3011 | 0x00, 0x40 + id, mode, | ||
3012 | 0x0f); | ||
3013 | if (ret) | ||
3014 | return ret; | ||
3015 | |||
3016 | ret = | ||
3017 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS, | ||
3018 | 0x00, 0x43, | ||
3019 | open_drain ? (1 << id) : 0, | ||
3020 | 1 << id); | ||
3021 | if (ret) | ||
3022 | return ret; | ||
3023 | |||
3024 | ret = | ||
3025 | cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS, | ||
3026 | 0x00, 0x44, | ||
3027 | invert ? (1 << id) : 0, | ||
3028 | 1 << id); | ||
3029 | if (ret) | ||
3030 | return ret; | ||
3031 | |||
3032 | return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
3033 | CXD2880_IO_TGT_SYS, | ||
3034 | 0x00, 0x45, | ||
3035 | en ? 0 : (1 << id), | ||
3036 | 1 << id); | ||
3037 | } | ||
3038 | |||
3039 | int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
3040 | u8 id, | ||
3041 | u8 en, | ||
3042 | enum cxd2880_tnrdmd_gpio_mode | ||
3043 | mode, u8 open_drain, u8 invert) | ||
3044 | { | ||
3045 | if (!tnr_dmd) | ||
3046 | return -EINVAL; | ||
3047 | |||
3048 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
3049 | return -EINVAL; | ||
3050 | |||
3051 | return cxd2880_tnrdmd_gpio_set_cfg(tnr_dmd->diver_sub, id, en, mode, | ||
3052 | open_drain, invert); | ||
3053 | } | ||
3054 | |||
3055 | int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd, | ||
3056 | u8 id, u8 *value) | ||
3057 | { | ||
3058 | u8 data = 0; | ||
3059 | int ret; | ||
3060 | |||
3061 | if (!tnr_dmd || !value) | ||
3062 | return -EINVAL; | ||
3063 | |||
3064 | if (id > 2) | ||
3065 | return -EINVAL; | ||
3066 | |||
3067 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3068 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3069 | return -EINVAL; | ||
3070 | |||
3071 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3072 | CXD2880_IO_TGT_SYS, | ||
3073 | 0x00, 0x0a); | ||
3074 | if (ret) | ||
3075 | return ret; | ||
3076 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
3077 | CXD2880_IO_TGT_SYS, | ||
3078 | 0x20, &data, 1); | ||
3079 | if (ret) | ||
3080 | return ret; | ||
3081 | |||
3082 | *value = (data >> id) & 0x01; | ||
3083 | |||
3084 | return 0; | ||
3085 | } | ||
3086 | |||
3087 | int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
3088 | u8 id, u8 *value) | ||
3089 | { | ||
3090 | if (!tnr_dmd) | ||
3091 | return -EINVAL; | ||
3092 | |||
3093 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
3094 | return -EINVAL; | ||
3095 | |||
3096 | return cxd2880_tnrdmd_gpio_read(tnr_dmd->diver_sub, id, value); | ||
3097 | } | ||
3098 | |||
3099 | int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd, | ||
3100 | u8 id, u8 value) | ||
3101 | { | ||
3102 | if (!tnr_dmd) | ||
3103 | return -EINVAL; | ||
3104 | |||
3105 | if (id > 2) | ||
3106 | return -EINVAL; | ||
3107 | |||
3108 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3109 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3110 | return -EINVAL; | ||
3111 | |||
3112 | return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, | ||
3113 | CXD2880_IO_TGT_SYS, | ||
3114 | 0x00, 0x46, | ||
3115 | value ? (1 << id) : 0, | ||
3116 | 1 << id); | ||
3117 | } | ||
3118 | |||
3119 | int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
3120 | u8 id, u8 value) | ||
3121 | { | ||
3122 | if (!tnr_dmd) | ||
3123 | return -EINVAL; | ||
3124 | |||
3125 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
3126 | return -EINVAL; | ||
3127 | |||
3128 | return cxd2880_tnrdmd_gpio_write(tnr_dmd->diver_sub, id, value); | ||
3129 | } | ||
3130 | |||
3131 | int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd, | ||
3132 | u16 *value) | ||
3133 | { | ||
3134 | int ret; | ||
3135 | u8 data[2] = { 0 }; | ||
3136 | |||
3137 | if (!tnr_dmd || !value) | ||
3138 | return -EINVAL; | ||
3139 | |||
3140 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3141 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3142 | return -EINVAL; | ||
3143 | |||
3144 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3145 | CXD2880_IO_TGT_SYS, | ||
3146 | 0x00, 0x0a); | ||
3147 | if (ret) | ||
3148 | return ret; | ||
3149 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
3150 | CXD2880_IO_TGT_SYS, | ||
3151 | 0x15, data, 2); | ||
3152 | if (ret) | ||
3153 | return ret; | ||
3154 | |||
3155 | *value = (data[0] << 8) | data[1]; | ||
3156 | |||
3157 | return 0; | ||
3158 | } | ||
3159 | |||
3160 | int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd, | ||
3161 | u16 value) | ||
3162 | { | ||
3163 | int ret; | ||
3164 | u8 data[2] = { 0 }; | ||
3165 | |||
3166 | if (!tnr_dmd) | ||
3167 | return -EINVAL; | ||
3168 | |||
3169 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3170 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3171 | return -EINVAL; | ||
3172 | |||
3173 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3174 | CXD2880_IO_TGT_SYS, | ||
3175 | 0x00, 0x00); | ||
3176 | if (ret) | ||
3177 | return ret; | ||
3178 | |||
3179 | data[0] = (value >> 8) & 0xff; | ||
3180 | data[1] = value & 0xff; | ||
3181 | |||
3182 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
3183 | CXD2880_IO_TGT_SYS, | ||
3184 | 0x3c, data, 2); | ||
3185 | } | ||
3186 | |||
3187 | int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd, | ||
3188 | u8 clear_overflow_flag, | ||
3189 | u8 clear_underflow_flag, | ||
3190 | u8 clear_buf) | ||
3191 | { | ||
3192 | int ret; | ||
3193 | u8 data[2] = { 0 }; | ||
3194 | |||
3195 | if (!tnr_dmd) | ||
3196 | return -EINVAL; | ||
3197 | |||
3198 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
3199 | return -EINVAL; | ||
3200 | |||
3201 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3202 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3203 | return -EINVAL; | ||
3204 | |||
3205 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3206 | CXD2880_IO_TGT_DMD, | ||
3207 | 0x00, 0x00); | ||
3208 | if (ret) | ||
3209 | return ret; | ||
3210 | |||
3211 | data[0] = clear_overflow_flag ? 0x02 : 0x00; | ||
3212 | data[0] |= clear_underflow_flag ? 0x01 : 0x00; | ||
3213 | data[1] = clear_buf ? 0x01 : 0x00; | ||
3214 | |||
3215 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
3216 | CXD2880_IO_TGT_DMD, | ||
3217 | 0x9f, data, 2); | ||
3218 | } | ||
3219 | |||
3220 | int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd, | ||
3221 | enum cxd2880_tnrdmd_chip_id *chip_id) | ||
3222 | { | ||
3223 | int ret; | ||
3224 | u8 data = 0; | ||
3225 | |||
3226 | if (!tnr_dmd || !chip_id) | ||
3227 | return -EINVAL; | ||
3228 | |||
3229 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3230 | CXD2880_IO_TGT_SYS, | ||
3231 | 0x00, 0x00); | ||
3232 | if (ret) | ||
3233 | return ret; | ||
3234 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
3235 | CXD2880_IO_TGT_SYS, | ||
3236 | 0xfd, &data, 1); | ||
3237 | if (ret) | ||
3238 | return ret; | ||
3239 | |||
3240 | *chip_id = (enum cxd2880_tnrdmd_chip_id)data; | ||
3241 | |||
3242 | return 0; | ||
3243 | } | ||
3244 | |||
3245 | int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd | ||
3246 | *tnr_dmd, | ||
3247 | enum cxd2880_io_tgt tgt, | ||
3248 | u8 bank, u8 address, | ||
3249 | u8 value, u8 bit_mask) | ||
3250 | { | ||
3251 | int ret; | ||
3252 | |||
3253 | if (!tnr_dmd) | ||
3254 | return -EINVAL; | ||
3255 | |||
3256 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3257 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3258 | return -EINVAL; | ||
3259 | |||
3260 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, tgt, 0x00, bank); | ||
3261 | if (ret) | ||
3262 | return ret; | ||
3263 | |||
3264 | ret = cxd2880_io_set_reg_bits(tnr_dmd->io, | ||
3265 | tgt, address, value, bit_mask); | ||
3266 | if (ret) | ||
3267 | return ret; | ||
3268 | |||
3269 | return set_cfg_mem(tnr_dmd, tgt, bank, address, value, bit_mask); | ||
3270 | } | ||
3271 | |||
3272 | int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd, | ||
3273 | enum cxd2880_dtv_sys sys, | ||
3274 | u8 scan_mode_end) | ||
3275 | { | ||
3276 | if (!tnr_dmd) | ||
3277 | return -EINVAL; | ||
3278 | |||
3279 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3280 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3281 | return -EINVAL; | ||
3282 | |||
3283 | tnr_dmd->scan_mode = scan_mode_end; | ||
3284 | |||
3285 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
3286 | return cxd2880_tnrdmd_set_scan_mode(tnr_dmd->diver_sub, sys, | ||
3287 | scan_mode_end); | ||
3288 | else | ||
3289 | return 0; | ||
3290 | } | ||
3291 | |||
3292 | int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd, | ||
3293 | struct cxd2880_tnrdmd_pid_ftr_cfg | ||
3294 | *pid_ftr_cfg) | ||
3295 | { | ||
3296 | if (!tnr_dmd) | ||
3297 | return -EINVAL; | ||
3298 | |||
3299 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
3300 | return -EINVAL; | ||
3301 | |||
3302 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3303 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3304 | return -EINVAL; | ||
3305 | |||
3306 | if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS) | ||
3307 | return -ENOTTY; | ||
3308 | |||
3309 | if (pid_ftr_cfg) { | ||
3310 | tnr_dmd->pid_ftr_cfg = *pid_ftr_cfg; | ||
3311 | tnr_dmd->pid_ftr_cfg_en = 1; | ||
3312 | } else { | ||
3313 | tnr_dmd->pid_ftr_cfg_en = 0; | ||
3314 | } | ||
3315 | |||
3316 | if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE) | ||
3317 | return pid_ftr_setting(tnr_dmd, pid_ftr_cfg); | ||
3318 | else | ||
3319 | return 0; | ||
3320 | } | ||
3321 | |||
3322 | int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd | ||
3323 | *tnr_dmd, | ||
3324 | int (*rf_lvl_cmpstn) | ||
3325 | (struct cxd2880_tnrdmd *, | ||
3326 | int *)) | ||
3327 | { | ||
3328 | if (!tnr_dmd) | ||
3329 | return -EINVAL; | ||
3330 | |||
3331 | tnr_dmd->rf_lvl_cmpstn = rf_lvl_cmpstn; | ||
3332 | |||
3333 | return 0; | ||
3334 | } | ||
3335 | |||
3336 | int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd | ||
3337 | *tnr_dmd, | ||
3338 | int (*rf_lvl_cmpstn) | ||
3339 | (struct cxd2880_tnrdmd *, | ||
3340 | int *)) | ||
3341 | { | ||
3342 | if (!tnr_dmd) | ||
3343 | return -EINVAL; | ||
3344 | |||
3345 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
3346 | return -EINVAL; | ||
3347 | |||
3348 | return cxd2880_tnrdmd_set_rf_lvl_cmpstn(tnr_dmd->diver_sub, | ||
3349 | rf_lvl_cmpstn); | ||
3350 | } | ||
3351 | |||
3352 | int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd, | ||
3353 | struct cxd2880_tnrdmd_lna_thrs_tbl_air | ||
3354 | *tbl_air, | ||
3355 | struct cxd2880_tnrdmd_lna_thrs_tbl_cable | ||
3356 | *tbl_cable) | ||
3357 | { | ||
3358 | if (!tnr_dmd) | ||
3359 | return -EINVAL; | ||
3360 | |||
3361 | tnr_dmd->lna_thrs_tbl_air = tbl_air; | ||
3362 | tnr_dmd->lna_thrs_tbl_cable = tbl_cable; | ||
3363 | |||
3364 | return 0; | ||
3365 | } | ||
3366 | |||
3367 | int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
3368 | struct | ||
3369 | cxd2880_tnrdmd_lna_thrs_tbl_air | ||
3370 | *tbl_air, | ||
3371 | struct cxd2880_tnrdmd_lna_thrs_tbl_cable | ||
3372 | *tbl_cable) | ||
3373 | { | ||
3374 | if (!tnr_dmd) | ||
3375 | return -EINVAL; | ||
3376 | |||
3377 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
3378 | return -EINVAL; | ||
3379 | |||
3380 | return cxd2880_tnrdmd_set_lna_thrs(tnr_dmd->diver_sub, | ||
3381 | tbl_air, tbl_cable); | ||
3382 | } | ||
3383 | |||
3384 | int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd | ||
3385 | *tnr_dmd, u8 en, u8 value) | ||
3386 | { | ||
3387 | int ret; | ||
3388 | |||
3389 | if (!tnr_dmd) | ||
3390 | return -EINVAL; | ||
3391 | |||
3392 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
3393 | return -EINVAL; | ||
3394 | |||
3395 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) | ||
3396 | return -EINVAL; | ||
3397 | |||
3398 | if (tnr_dmd->create_param.ts_output_if != CXD2880_TNRDMD_TSOUT_IF_TS) | ||
3399 | return -ENOTTY; | ||
3400 | |||
3401 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3402 | CXD2880_IO_TGT_SYS, | ||
3403 | 0x00, 0x00); | ||
3404 | if (ret) | ||
3405 | return ret; | ||
3406 | |||
3407 | if (en) { | ||
3408 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3409 | CXD2880_IO_TGT_SYS, | ||
3410 | 0x50, ((value & 0x1f) | 0x80)); | ||
3411 | if (ret) | ||
3412 | return ret; | ||
3413 | |||
3414 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3415 | CXD2880_IO_TGT_SYS, | ||
3416 | 0x52, (value & 0x1f)); | ||
3417 | } else { | ||
3418 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
3419 | CXD2880_IO_TGT_SYS, | ||
3420 | set_ts_pin_seq, | ||
3421 | ARRAY_SIZE(set_ts_pin_seq)); | ||
3422 | if (ret) | ||
3423 | return ret; | ||
3424 | |||
3425 | ret = load_cfg_mem(tnr_dmd); | ||
3426 | } | ||
3427 | |||
3428 | return ret; | ||
3429 | } | ||
3430 | |||
3431 | int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd, | ||
3432 | u8 en) | ||
3433 | { | ||
3434 | int ret; | ||
3435 | |||
3436 | if (!tnr_dmd) | ||
3437 | return -EINVAL; | ||
3438 | |||
3439 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
3440 | return -EINVAL; | ||
3441 | |||
3442 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
3443 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
3444 | return -EINVAL; | ||
3445 | |||
3446 | switch (tnr_dmd->create_param.ts_output_if) { | ||
3447 | case CXD2880_TNRDMD_TSOUT_IF_TS: | ||
3448 | if (en) { | ||
3449 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
3450 | CXD2880_IO_TGT_SYS, | ||
3451 | set_ts_output_seq1, | ||
3452 | ARRAY_SIZE(set_ts_output_seq1)); | ||
3453 | if (ret) | ||
3454 | return ret; | ||
3455 | |||
3456 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
3457 | CXD2880_IO_TGT_DMD, | ||
3458 | set_ts_output_seq2, | ||
3459 | ARRAY_SIZE(set_ts_output_seq2)); | ||
3460 | if (ret) | ||
3461 | return ret; | ||
3462 | } else { | ||
3463 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
3464 | CXD2880_IO_TGT_DMD, | ||
3465 | set_ts_output_seq3, | ||
3466 | ARRAY_SIZE(set_ts_output_seq3)); | ||
3467 | if (ret) | ||
3468 | return ret; | ||
3469 | |||
3470 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
3471 | CXD2880_IO_TGT_SYS, | ||
3472 | set_ts_output_seq4, | ||
3473 | ARRAY_SIZE(set_ts_output_seq4)); | ||
3474 | if (ret) | ||
3475 | return ret; | ||
3476 | } | ||
3477 | break; | ||
3478 | |||
3479 | case CXD2880_TNRDMD_TSOUT_IF_SPI: | ||
3480 | break; | ||
3481 | |||
3482 | case CXD2880_TNRDMD_TSOUT_IF_SDIO: | ||
3483 | break; | ||
3484 | |||
3485 | default: | ||
3486 | return -EINVAL; | ||
3487 | } | ||
3488 | |||
3489 | return 0; | ||
3490 | } | ||
3491 | |||
3492 | int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd) | ||
3493 | { | ||
3494 | u8 data; | ||
3495 | int ret; | ||
3496 | |||
3497 | if (!tnr_dmd) | ||
3498 | return -EINVAL; | ||
3499 | |||
3500 | switch (tnr_dmd->create_param.ts_output_if) { | ||
3501 | case CXD2880_TNRDMD_TSOUT_IF_SPI: | ||
3502 | case CXD2880_TNRDMD_TSOUT_IF_SDIO: | ||
3503 | |||
3504 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
3505 | CXD2880_IO_TGT_DMD, | ||
3506 | 0x00, &data, 1); | ||
3507 | if (ret) | ||
3508 | return ret; | ||
3509 | |||
3510 | break; | ||
3511 | case CXD2880_TNRDMD_TSOUT_IF_TS: | ||
3512 | default: | ||
3513 | break; | ||
3514 | } | ||
3515 | |||
3516 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
3517 | CXD2880_IO_TGT_DMD, | ||
3518 | 0x01, 0x01); | ||
3519 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h new file mode 100644 index 000000000000..9d809a251fc7 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h | |||
@@ -0,0 +1,365 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * common control interface | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_TNRDMD_H | ||
11 | #define CXD2880_TNRDMD_H | ||
12 | |||
13 | #include <linux/atomic.h> | ||
14 | |||
15 | #include "cxd2880_common.h" | ||
16 | #include "cxd2880_io.h" | ||
17 | #include "cxd2880_dtv.h" | ||
18 | #include "cxd2880_dvbt.h" | ||
19 | #include "cxd2880_dvbt2.h" | ||
20 | |||
21 | #define CXD2880_TNRDMD_MAX_CFG_MEM_COUNT 100 | ||
22 | |||
23 | #define slvt_unfreeze_reg(tnr_dmd) ((void)((tnr_dmd)->io->write_reg\ | ||
24 | ((tnr_dmd)->io, CXD2880_IO_TGT_DMD, 0x01, 0x00))) | ||
25 | |||
26 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_UNDERFLOW 0x0001 | ||
27 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_OVERFLOW 0x0002 | ||
28 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_EMPTY 0x0004 | ||
29 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_ALMOST_FULL 0x0008 | ||
30 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_BUF_RRDY 0x0010 | ||
31 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_COMMAND 0x0020 | ||
32 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_ILLEGAL_ACCESS 0x0040 | ||
33 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_CPU_ERROR 0x0100 | ||
34 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_LOCK 0x0200 | ||
35 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_INV_LOCK 0x0400 | ||
36 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_NOOFDM 0x0800 | ||
37 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_EWS 0x1000 | ||
38 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_EEW 0x2000 | ||
39 | #define CXD2880_TNRDMD_INTERRUPT_TYPE_FEC_FAIL 0x4000 | ||
40 | |||
41 | #define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_L1POST_OK 0x01 | ||
42 | #define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_DMD_LOCK 0x02 | ||
43 | #define CXD2880_TNRDMD_INTERRUPT_LOCK_SEL_TS_LOCK 0x04 | ||
44 | |||
45 | enum cxd2880_tnrdmd_chip_id { | ||
46 | CXD2880_TNRDMD_CHIP_ID_UNKNOWN = 0x00, | ||
47 | CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X = 0x62, | ||
48 | CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11 = 0x6a | ||
49 | }; | ||
50 | |||
51 | #define CXD2880_TNRDMD_CHIP_ID_VALID(chip_id) \ | ||
52 | (((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) || \ | ||
53 | ((chip_id) == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11)) | ||
54 | |||
55 | enum cxd2880_tnrdmd_state { | ||
56 | CXD2880_TNRDMD_STATE_UNKNOWN, | ||
57 | CXD2880_TNRDMD_STATE_SLEEP, | ||
58 | CXD2880_TNRDMD_STATE_ACTIVE, | ||
59 | CXD2880_TNRDMD_STATE_INVALID | ||
60 | }; | ||
61 | |||
62 | enum cxd2880_tnrdmd_divermode { | ||
63 | CXD2880_TNRDMD_DIVERMODE_SINGLE, | ||
64 | CXD2880_TNRDMD_DIVERMODE_MAIN, | ||
65 | CXD2880_TNRDMD_DIVERMODE_SUB | ||
66 | }; | ||
67 | |||
68 | enum cxd2880_tnrdmd_clockmode { | ||
69 | CXD2880_TNRDMD_CLOCKMODE_UNKNOWN, | ||
70 | CXD2880_TNRDMD_CLOCKMODE_A, | ||
71 | CXD2880_TNRDMD_CLOCKMODE_B, | ||
72 | CXD2880_TNRDMD_CLOCKMODE_C | ||
73 | }; | ||
74 | |||
75 | enum cxd2880_tnrdmd_tsout_if { | ||
76 | CXD2880_TNRDMD_TSOUT_IF_TS, | ||
77 | CXD2880_TNRDMD_TSOUT_IF_SPI, | ||
78 | CXD2880_TNRDMD_TSOUT_IF_SDIO | ||
79 | }; | ||
80 | |||
81 | enum cxd2880_tnrdmd_xtal_share { | ||
82 | CXD2880_TNRDMD_XTAL_SHARE_NONE, | ||
83 | CXD2880_TNRDMD_XTAL_SHARE_EXTREF, | ||
84 | CXD2880_TNRDMD_XTAL_SHARE_MASTER, | ||
85 | CXD2880_TNRDMD_XTAL_SHARE_SLAVE | ||
86 | }; | ||
87 | |||
88 | enum cxd2880_tnrdmd_spectrum_sense { | ||
89 | CXD2880_TNRDMD_SPECTRUM_NORMAL, | ||
90 | CXD2880_TNRDMD_SPECTRUM_INV | ||
91 | }; | ||
92 | |||
93 | enum cxd2880_tnrdmd_cfg_id { | ||
94 | CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB, | ||
95 | CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI, | ||
96 | CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI, | ||
97 | CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI, | ||
98 | CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE, | ||
99 | CXD2880_TNRDMD_CFG_TSCLK_CONT, | ||
100 | CXD2880_TNRDMD_CFG_TSCLK_MASK, | ||
101 | CXD2880_TNRDMD_CFG_TSVALID_MASK, | ||
102 | CXD2880_TNRDMD_CFG_TSERR_MASK, | ||
103 | CXD2880_TNRDMD_CFG_TSERR_VALID_DIS, | ||
104 | CXD2880_TNRDMD_CFG_TSPIN_CURRENT, | ||
105 | CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL, | ||
106 | CXD2880_TNRDMD_CFG_TSPIN_PULLUP, | ||
107 | CXD2880_TNRDMD_CFG_TSCLK_FREQ, | ||
108 | CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL, | ||
109 | CXD2880_TNRDMD_CFG_TS_PACKET_GAP, | ||
110 | CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE, | ||
111 | CXD2880_TNRDMD_CFG_PWM_VALUE, | ||
112 | CXD2880_TNRDMD_CFG_INTERRUPT, | ||
113 | CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL, | ||
114 | CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL, | ||
115 | CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS, | ||
116 | CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS, | ||
117 | CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS, | ||
118 | CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE, | ||
119 | CXD2880_TNRDMD_CFG_CABLE_INPUT, | ||
120 | CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE, | ||
121 | CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE, | ||
122 | CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST, | ||
123 | CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD, | ||
124 | CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD, | ||
125 | CXD2880_TNRDMD_CFG_DVBT_PER_MES, | ||
126 | CXD2880_TNRDMD_CFG_DVBT2_BBER_MES, | ||
127 | CXD2880_TNRDMD_CFG_DVBT2_LBER_MES, | ||
128 | CXD2880_TNRDMD_CFG_DVBT2_PER_MES, | ||
129 | }; | ||
130 | |||
131 | enum cxd2880_tnrdmd_lock_result { | ||
132 | CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT, | ||
133 | CXD2880_TNRDMD_LOCK_RESULT_LOCKED, | ||
134 | CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED | ||
135 | }; | ||
136 | |||
137 | enum cxd2880_tnrdmd_gpio_mode { | ||
138 | CXD2880_TNRDMD_GPIO_MODE_OUTPUT = 0x00, | ||
139 | CXD2880_TNRDMD_GPIO_MODE_INPUT = 0x01, | ||
140 | CXD2880_TNRDMD_GPIO_MODE_INT = 0x02, | ||
141 | CXD2880_TNRDMD_GPIO_MODE_FEC_FAIL = 0x03, | ||
142 | CXD2880_TNRDMD_GPIO_MODE_PWM = 0x04, | ||
143 | CXD2880_TNRDMD_GPIO_MODE_EWS = 0x05, | ||
144 | CXD2880_TNRDMD_GPIO_MODE_EEW = 0x06 | ||
145 | }; | ||
146 | |||
147 | enum cxd2880_tnrdmd_serial_ts_clk { | ||
148 | CXD2880_TNRDMD_SERIAL_TS_CLK_FULL, | ||
149 | CXD2880_TNRDMD_SERIAL_TS_CLK_HALF | ||
150 | }; | ||
151 | |||
152 | struct cxd2880_tnrdmd_cfg_mem { | ||
153 | enum cxd2880_io_tgt tgt; | ||
154 | u8 bank; | ||
155 | u8 address; | ||
156 | u8 value; | ||
157 | u8 bit_mask; | ||
158 | }; | ||
159 | |||
160 | struct cxd2880_tnrdmd_pid_cfg { | ||
161 | u8 is_en; | ||
162 | u16 pid; | ||
163 | }; | ||
164 | |||
165 | struct cxd2880_tnrdmd_pid_ftr_cfg { | ||
166 | u8 is_negative; | ||
167 | struct cxd2880_tnrdmd_pid_cfg pid_cfg[32]; | ||
168 | }; | ||
169 | |||
170 | struct cxd2880_tnrdmd_lna_thrs { | ||
171 | u8 off_on; | ||
172 | u8 on_off; | ||
173 | }; | ||
174 | |||
175 | struct cxd2880_tnrdmd_lna_thrs_tbl_air { | ||
176 | struct cxd2880_tnrdmd_lna_thrs thrs[24]; | ||
177 | }; | ||
178 | |||
179 | struct cxd2880_tnrdmd_lna_thrs_tbl_cable { | ||
180 | struct cxd2880_tnrdmd_lna_thrs thrs[32]; | ||
181 | }; | ||
182 | |||
183 | struct cxd2880_tnrdmd_create_param { | ||
184 | enum cxd2880_tnrdmd_tsout_if ts_output_if; | ||
185 | u8 en_internal_ldo; | ||
186 | enum cxd2880_tnrdmd_xtal_share xtal_share_type; | ||
187 | u8 xosc_cap; | ||
188 | u8 xosc_i; | ||
189 | u8 is_cxd2881gg; | ||
190 | u8 stationary_use; | ||
191 | }; | ||
192 | |||
193 | struct cxd2880_tnrdmd_diver_create_param { | ||
194 | enum cxd2880_tnrdmd_tsout_if ts_output_if; | ||
195 | u8 en_internal_ldo; | ||
196 | u8 xosc_cap_main; | ||
197 | u8 xosc_i_main; | ||
198 | u8 xosc_i_sub; | ||
199 | u8 is_cxd2881gg; | ||
200 | u8 stationary_use; | ||
201 | }; | ||
202 | |||
203 | struct cxd2880_tnrdmd { | ||
204 | struct cxd2880_tnrdmd *diver_sub; | ||
205 | struct cxd2880_io *io; | ||
206 | struct cxd2880_tnrdmd_create_param create_param; | ||
207 | enum cxd2880_tnrdmd_divermode diver_mode; | ||
208 | enum cxd2880_tnrdmd_clockmode fixed_clk_mode; | ||
209 | u8 is_cable_input; | ||
210 | u8 en_fef_intmtnt_base; | ||
211 | u8 en_fef_intmtnt_lite; | ||
212 | u8 blind_tune_dvbt2_first; | ||
213 | int (*rf_lvl_cmpstn)(struct cxd2880_tnrdmd *tnr_dmd, | ||
214 | int *rf_lvl_db); | ||
215 | struct cxd2880_tnrdmd_lna_thrs_tbl_air *lna_thrs_tbl_air; | ||
216 | struct cxd2880_tnrdmd_lna_thrs_tbl_cable *lna_thrs_tbl_cable; | ||
217 | u8 srl_ts_clk_mod_cnts; | ||
218 | enum cxd2880_tnrdmd_serial_ts_clk srl_ts_clk_frq; | ||
219 | u8 ts_byte_clk_manual_setting; | ||
220 | u8 is_ts_backwards_compatible_mode; | ||
221 | struct cxd2880_tnrdmd_cfg_mem cfg_mem[CXD2880_TNRDMD_MAX_CFG_MEM_COUNT]; | ||
222 | u8 cfg_mem_last_entry; | ||
223 | struct cxd2880_tnrdmd_pid_ftr_cfg pid_ftr_cfg; | ||
224 | u8 pid_ftr_cfg_en; | ||
225 | void *user; | ||
226 | enum cxd2880_tnrdmd_chip_id chip_id; | ||
227 | enum cxd2880_tnrdmd_state state; | ||
228 | enum cxd2880_tnrdmd_clockmode clk_mode; | ||
229 | u32 frequency_khz; | ||
230 | enum cxd2880_dtv_sys sys; | ||
231 | enum cxd2880_dtv_bandwidth bandwidth; | ||
232 | u8 scan_mode; | ||
233 | atomic_t cancel; | ||
234 | }; | ||
235 | |||
236 | int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd, | ||
237 | struct cxd2880_io *io, | ||
238 | struct cxd2880_tnrdmd_create_param | ||
239 | *create_param); | ||
240 | |||
241 | int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd | ||
242 | *tnr_dmd_main, | ||
243 | struct cxd2880_io *io_main, | ||
244 | struct cxd2880_tnrdmd *tnr_dmd_sub, | ||
245 | struct cxd2880_io *io_sub, | ||
246 | struct | ||
247 | cxd2880_tnrdmd_diver_create_param | ||
248 | *create_param); | ||
249 | |||
250 | int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd); | ||
251 | |||
252 | int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd); | ||
253 | |||
254 | int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd | ||
255 | *tnr_dmd, | ||
256 | u8 *task_completed); | ||
257 | |||
258 | int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd | ||
259 | *tnr_dmd, | ||
260 | enum cxd2880_dtv_sys sys, | ||
261 | u32 frequency_khz, | ||
262 | enum cxd2880_dtv_bandwidth | ||
263 | bandwidth, u8 one_seg_opt, | ||
264 | u8 one_seg_opt_shft_dir); | ||
265 | |||
266 | int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd | ||
267 | *tnr_dmd, | ||
268 | enum cxd2880_dtv_sys sys, | ||
269 | u8 en_fef_intmtnt_ctrl); | ||
270 | |||
271 | int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd); | ||
272 | |||
273 | int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, | ||
274 | enum cxd2880_tnrdmd_cfg_id id, | ||
275 | int value); | ||
276 | |||
277 | int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, | ||
278 | u8 id, | ||
279 | u8 en, | ||
280 | enum cxd2880_tnrdmd_gpio_mode mode, | ||
281 | u8 open_drain, u8 invert); | ||
282 | |||
283 | int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
284 | u8 id, | ||
285 | u8 en, | ||
286 | enum cxd2880_tnrdmd_gpio_mode | ||
287 | mode, u8 open_drain, | ||
288 | u8 invert); | ||
289 | |||
290 | int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd, | ||
291 | u8 id, u8 *value); | ||
292 | |||
293 | int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
294 | u8 id, u8 *value); | ||
295 | |||
296 | int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd, | ||
297 | u8 id, u8 value); | ||
298 | |||
299 | int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
300 | u8 id, u8 value); | ||
301 | |||
302 | int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd, | ||
303 | u16 *value); | ||
304 | |||
305 | int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd, | ||
306 | u16 value); | ||
307 | |||
308 | int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd, | ||
309 | u8 clear_overflow_flag, | ||
310 | u8 clear_underflow_flag, | ||
311 | u8 clear_buf); | ||
312 | |||
313 | int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd, | ||
314 | enum cxd2880_tnrdmd_chip_id *chip_id); | ||
315 | |||
316 | int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd | ||
317 | *tnr_dmd, | ||
318 | enum cxd2880_io_tgt tgt, | ||
319 | u8 bank, u8 address, | ||
320 | u8 value, u8 bit_mask); | ||
321 | |||
322 | int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd, | ||
323 | enum cxd2880_dtv_sys sys, | ||
324 | u8 scan_mode_end); | ||
325 | |||
326 | int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd, | ||
327 | struct cxd2880_tnrdmd_pid_ftr_cfg | ||
328 | *pid_ftr_cfg); | ||
329 | |||
330 | int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd | ||
331 | *tnr_dmd, | ||
332 | int (*rf_lvl_cmpstn) | ||
333 | (struct cxd2880_tnrdmd *, | ||
334 | int *)); | ||
335 | |||
336 | int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
337 | int (*rf_lvl_cmpstn) | ||
338 | (struct cxd2880_tnrdmd *, | ||
339 | int *)); | ||
340 | |||
341 | int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd, | ||
342 | struct | ||
343 | cxd2880_tnrdmd_lna_thrs_tbl_air | ||
344 | *tbl_air, | ||
345 | struct | ||
346 | cxd2880_tnrdmd_lna_thrs_tbl_cable | ||
347 | *tbl_cable); | ||
348 | |||
349 | int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
350 | struct | ||
351 | cxd2880_tnrdmd_lna_thrs_tbl_air | ||
352 | *tbl_air, | ||
353 | struct | ||
354 | cxd2880_tnrdmd_lna_thrs_tbl_cable | ||
355 | *tbl_cable); | ||
356 | |||
357 | int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd | ||
358 | *tnr_dmd, u8 en, u8 value); | ||
359 | |||
360 | int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd, | ||
361 | u8 en); | ||
362 | |||
363 | int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd); | ||
364 | |||
365 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h new file mode 100644 index 000000000000..fab55038b37b --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_driver_version.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * version information | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #define CXD2880_TNRDMD_DRIVER_VERSION "1.4.1 - 1.0.4" | ||
11 | |||
12 | #define CXD2880_TNRDMD_DRIVER_RELEASE_DATE "2018-01-17" | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c new file mode 100644 index 000000000000..fe3c6f8b1b3e --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c | |||
@@ -0,0 +1,919 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * control functions for DVB-T | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include <media/dvb_frontend.h> | ||
11 | |||
12 | #include "cxd2880_tnrdmd_dvbt.h" | ||
13 | #include "cxd2880_tnrdmd_dvbt_mon.h" | ||
14 | |||
15 | static const struct cxd2880_reg_value tune_dmd_setting_seq1[] = { | ||
16 | {0x00, 0x00}, {0x31, 0x01}, | ||
17 | }; | ||
18 | |||
19 | static const struct cxd2880_reg_value tune_dmd_setting_seq2[] = { | ||
20 | {0x00, 0x04}, {0x5c, 0xfb}, {0x00, 0x10}, {0xa4, 0x03}, | ||
21 | {0x00, 0x14}, {0xb0, 0x00}, {0x00, 0x25}, | ||
22 | }; | ||
23 | |||
24 | static const struct cxd2880_reg_value tune_dmd_setting_seq3[] = { | ||
25 | {0x00, 0x12}, {0x44, 0x00}, | ||
26 | }; | ||
27 | |||
28 | static const struct cxd2880_reg_value tune_dmd_setting_seq4[] = { | ||
29 | {0x00, 0x11}, {0x87, 0xd2}, | ||
30 | }; | ||
31 | |||
32 | static const struct cxd2880_reg_value tune_dmd_setting_seq5[] = { | ||
33 | {0x00, 0x00}, {0xfd, 0x01}, | ||
34 | }; | ||
35 | |||
36 | static const struct cxd2880_reg_value sleep_dmd_setting_seq1[] = { | ||
37 | {0x00, 0x04}, {0x5c, 0xd8}, {0x00, 0x10}, {0xa4, 0x00}, | ||
38 | }; | ||
39 | |||
40 | static const struct cxd2880_reg_value sleep_dmd_setting_seq2[] = { | ||
41 | {0x00, 0x11}, {0x87, 0x04}, | ||
42 | }; | ||
43 | |||
44 | static int x_tune_dvbt_demod_setting(struct cxd2880_tnrdmd | ||
45 | *tnr_dmd, | ||
46 | enum cxd2880_dtv_bandwidth | ||
47 | bandwidth, | ||
48 | enum cxd2880_tnrdmd_clockmode | ||
49 | clk_mode) | ||
50 | { | ||
51 | static const u8 clk_mode_ckffrq_a[2] = { 0x52, 0x49 }; | ||
52 | static const u8 clk_mode_ckffrq_b[2] = { 0x5d, 0x55 }; | ||
53 | static const u8 clk_mode_ckffrq_c[2] = { 0x60, 0x00 }; | ||
54 | static const u8 ratectl_margin[2] = { 0x01, 0xf0 }; | ||
55 | static const u8 maxclkcnt_a[3] = { 0x73, 0xca, 0x49 }; | ||
56 | static const u8 maxclkcnt_b[3] = { 0xc8, 0x13, 0xaa }; | ||
57 | static const u8 maxclkcnt_c[3] = { 0xdc, 0x6c, 0x00 }; | ||
58 | |||
59 | static const u8 bw8_nomi_ac[5] = { 0x15, 0x00, 0x00, 0x00, 0x00}; | ||
60 | static const u8 bw8_nomi_b[5] = { 0x14, 0x6a, 0xaa, 0xaa, 0xaa}; | ||
61 | static const u8 bw8_gtdofst_a[2] = { 0x01, 0x28 }; | ||
62 | static const u8 bw8_gtdofst_b[2] = { 0x11, 0x44 }; | ||
63 | static const u8 bw8_gtdofst_c[2] = { 0x15, 0x28 }; | ||
64 | static const u8 bw8_mrc_a[5] = { 0x30, 0x00, 0x00, 0x90, 0x00 }; | ||
65 | static const u8 bw8_mrc_b[5] = { 0x36, 0x71, 0x00, 0xa3, 0x55 }; | ||
66 | static const u8 bw8_mrc_c[5] = { 0x38, 0x00, 0x00, 0xa8, 0x00 }; | ||
67 | static const u8 bw8_notch[4] = { 0xb3, 0x00, 0x01, 0x02 }; | ||
68 | |||
69 | static const u8 bw7_nomi_ac[5] = { 0x18, 0x00, 0x00, 0x00, 0x00}; | ||
70 | static const u8 bw7_nomi_b[5] = { 0x17, 0x55, 0x55, 0x55, 0x55}; | ||
71 | static const u8 bw7_gtdofst_a[2] = { 0x12, 0x4c }; | ||
72 | static const u8 bw7_gtdofst_b[2] = { 0x1f, 0x15 }; | ||
73 | static const u8 bw7_gtdofst_c[2] = { 0x1f, 0xf8 }; | ||
74 | static const u8 bw7_mrc_a[5] = { 0x36, 0xdb, 0x00, 0xa4, 0x92 }; | ||
75 | static const u8 bw7_mrc_b[5] = { 0x3e, 0x38, 0x00, 0xba, 0xaa }; | ||
76 | static const u8 bw7_mrc_c[5] = { 0x40, 0x00, 0x00, 0xc0, 0x00 }; | ||
77 | static const u8 bw7_notch[4] = { 0xb8, 0x00, 0x00, 0x03 }; | ||
78 | |||
79 | static const u8 bw6_nomi_ac[5] = { 0x1c, 0x00, 0x00, 0x00, 0x00}; | ||
80 | static const u8 bw6_nomi_b[5] = { 0x1b, 0x38, 0xe3, 0x8e, 0x38}; | ||
81 | static const u8 bw6_gtdofst_a[2] = { 0x1f, 0xf8 }; | ||
82 | static const u8 bw6_gtdofst_b[2] = { 0x24, 0x43 }; | ||
83 | static const u8 bw6_gtdofst_c[2] = { 0x25, 0x4c }; | ||
84 | static const u8 bw6_mrc_a[5] = { 0x40, 0x00, 0x00, 0xc0, 0x00 }; | ||
85 | static const u8 bw6_mrc_b[5] = { 0x48, 0x97, 0x00, 0xd9, 0xc7 }; | ||
86 | static const u8 bw6_mrc_c[5] = { 0x4a, 0xaa, 0x00, 0xdf, 0xff }; | ||
87 | static const u8 bw6_notch[4] = { 0xbe, 0xab, 0x00, 0x03 }; | ||
88 | |||
89 | static const u8 bw5_nomi_ac[5] = { 0x21, 0x99, 0x99, 0x99, 0x99}; | ||
90 | static const u8 bw5_nomi_b[5] = { 0x20, 0xaa, 0xaa, 0xaa, 0xaa}; | ||
91 | static const u8 bw5_gtdofst_a[2] = { 0x26, 0x5d }; | ||
92 | static const u8 bw5_gtdofst_b[2] = { 0x2b, 0x84 }; | ||
93 | static const u8 bw5_gtdofst_c[2] = { 0x2c, 0xc2 }; | ||
94 | static const u8 bw5_mrc_a[5] = { 0x4c, 0xcc, 0x00, 0xe6, 0x66 }; | ||
95 | static const u8 bw5_mrc_b[5] = { 0x57, 0x1c, 0x01, 0x05, 0x55 }; | ||
96 | static const u8 bw5_mrc_c[5] = { 0x59, 0x99, 0x01, 0x0c, 0xcc }; | ||
97 | static const u8 bw5_notch[4] = { 0xc8, 0x01, 0x00, 0x03 }; | ||
98 | const u8 *data = NULL; | ||
99 | u8 sst_data; | ||
100 | int ret; | ||
101 | |||
102 | if (!tnr_dmd) | ||
103 | return -EINVAL; | ||
104 | |||
105 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
106 | CXD2880_IO_TGT_SYS, | ||
107 | tune_dmd_setting_seq1, | ||
108 | ARRAY_SIZE(tune_dmd_setting_seq1)); | ||
109 | if (ret) | ||
110 | return ret; | ||
111 | |||
112 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
113 | CXD2880_IO_TGT_DMD, | ||
114 | 0x00, 0x04); | ||
115 | if (ret) | ||
116 | return ret; | ||
117 | |||
118 | switch (clk_mode) { | ||
119 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
120 | data = clk_mode_ckffrq_a; | ||
121 | break; | ||
122 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
123 | data = clk_mode_ckffrq_b; | ||
124 | break; | ||
125 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
126 | data = clk_mode_ckffrq_c; | ||
127 | break; | ||
128 | default: | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
133 | CXD2880_IO_TGT_DMD, | ||
134 | 0x65, data, 2); | ||
135 | if (ret) | ||
136 | return ret; | ||
137 | |||
138 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
139 | CXD2880_IO_TGT_DMD, | ||
140 | 0x5d, 0x07); | ||
141 | if (ret) | ||
142 | return ret; | ||
143 | |||
144 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) { | ||
145 | u8 data[2] = { 0x01, 0x01 }; | ||
146 | |||
147 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
148 | CXD2880_IO_TGT_DMD, | ||
149 | 0x00, 0x00); | ||
150 | if (ret) | ||
151 | return ret; | ||
152 | |||
153 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
154 | CXD2880_IO_TGT_DMD, | ||
155 | 0xce, data, 2); | ||
156 | if (ret) | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
161 | CXD2880_IO_TGT_DMD, | ||
162 | tune_dmd_setting_seq2, | ||
163 | ARRAY_SIZE(tune_dmd_setting_seq2)); | ||
164 | if (ret) | ||
165 | return ret; | ||
166 | |||
167 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
168 | CXD2880_IO_TGT_DMD, | ||
169 | 0xf0, ratectl_margin, 2); | ||
170 | if (ret) | ||
171 | return ret; | ||
172 | |||
173 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN || | ||
174 | tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) { | ||
175 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
176 | CXD2880_IO_TGT_DMD, | ||
177 | tune_dmd_setting_seq3, | ||
178 | ARRAY_SIZE(tune_dmd_setting_seq3)); | ||
179 | if (ret) | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) { | ||
184 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
185 | CXD2880_IO_TGT_DMD, | ||
186 | tune_dmd_setting_seq4, | ||
187 | ARRAY_SIZE(tune_dmd_setting_seq4)); | ||
188 | if (ret) | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) { | ||
193 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
194 | CXD2880_IO_TGT_DMD, | ||
195 | 0x00, 0x04); | ||
196 | if (ret) | ||
197 | return ret; | ||
198 | |||
199 | switch (clk_mode) { | ||
200 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
201 | data = maxclkcnt_a; | ||
202 | break; | ||
203 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
204 | data = maxclkcnt_b; | ||
205 | break; | ||
206 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
207 | data = maxclkcnt_c; | ||
208 | break; | ||
209 | default: | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
214 | CXD2880_IO_TGT_DMD, | ||
215 | 0x68, data, 3); | ||
216 | if (ret) | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
221 | CXD2880_IO_TGT_DMD, | ||
222 | 0x00, 0x04); | ||
223 | if (ret) | ||
224 | return ret; | ||
225 | |||
226 | switch (bandwidth) { | ||
227 | case CXD2880_DTV_BW_8_MHZ: | ||
228 | switch (clk_mode) { | ||
229 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
230 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
231 | data = bw8_nomi_ac; | ||
232 | break; | ||
233 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
234 | data = bw8_nomi_b; | ||
235 | break; | ||
236 | default: | ||
237 | return -EINVAL; | ||
238 | } | ||
239 | |||
240 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
241 | CXD2880_IO_TGT_DMD, | ||
242 | 0x60, data, 5); | ||
243 | if (ret) | ||
244 | return ret; | ||
245 | |||
246 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
247 | CXD2880_IO_TGT_DMD, | ||
248 | 0x4a, 0x00); | ||
249 | if (ret) | ||
250 | return ret; | ||
251 | |||
252 | switch (clk_mode) { | ||
253 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
254 | data = bw8_gtdofst_a; | ||
255 | break; | ||
256 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
257 | data = bw8_gtdofst_b; | ||
258 | break; | ||
259 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
260 | data = bw8_gtdofst_c; | ||
261 | break; | ||
262 | default: | ||
263 | return -EINVAL; | ||
264 | } | ||
265 | |||
266 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
267 | CXD2880_IO_TGT_DMD, | ||
268 | 0x7d, data, 2); | ||
269 | if (ret) | ||
270 | return ret; | ||
271 | |||
272 | switch (clk_mode) { | ||
273 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
274 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
275 | sst_data = 0x35; | ||
276 | break; | ||
277 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
278 | sst_data = 0x34; | ||
279 | break; | ||
280 | default: | ||
281 | return -EINVAL; | ||
282 | } | ||
283 | |||
284 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
285 | CXD2880_IO_TGT_DMD, | ||
286 | 0x71, sst_data); | ||
287 | if (ret) | ||
288 | return ret; | ||
289 | |||
290 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
291 | switch (clk_mode) { | ||
292 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
293 | data = bw8_mrc_a; | ||
294 | break; | ||
295 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
296 | data = bw8_mrc_b; | ||
297 | break; | ||
298 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
299 | data = bw8_mrc_c; | ||
300 | break; | ||
301 | default: | ||
302 | return -EINVAL; | ||
303 | } | ||
304 | |||
305 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
306 | CXD2880_IO_TGT_DMD, | ||
307 | 0x4b, &data[0], 2); | ||
308 | if (ret) | ||
309 | return ret; | ||
310 | |||
311 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
312 | CXD2880_IO_TGT_DMD, | ||
313 | 0x51, &data[2], 3); | ||
314 | if (ret) | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
319 | CXD2880_IO_TGT_DMD, | ||
320 | 0x72, &bw8_notch[0], 2); | ||
321 | if (ret) | ||
322 | return ret; | ||
323 | |||
324 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
325 | CXD2880_IO_TGT_DMD, | ||
326 | 0x6b, &bw8_notch[2], 2); | ||
327 | if (ret) | ||
328 | return ret; | ||
329 | break; | ||
330 | |||
331 | case CXD2880_DTV_BW_7_MHZ: | ||
332 | switch (clk_mode) { | ||
333 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
334 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
335 | data = bw7_nomi_ac; | ||
336 | break; | ||
337 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
338 | data = bw7_nomi_b; | ||
339 | break; | ||
340 | default: | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
345 | CXD2880_IO_TGT_DMD, | ||
346 | 0x60, data, 5); | ||
347 | if (ret) | ||
348 | return ret; | ||
349 | |||
350 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
351 | CXD2880_IO_TGT_DMD, | ||
352 | 0x4a, 0x02); | ||
353 | if (ret) | ||
354 | return ret; | ||
355 | |||
356 | switch (clk_mode) { | ||
357 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
358 | data = bw7_gtdofst_a; | ||
359 | break; | ||
360 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
361 | data = bw7_gtdofst_b; | ||
362 | break; | ||
363 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
364 | data = bw7_gtdofst_c; | ||
365 | break; | ||
366 | default: | ||
367 | return -EINVAL; | ||
368 | } | ||
369 | |||
370 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
371 | CXD2880_IO_TGT_DMD, | ||
372 | 0x7d, data, 2); | ||
373 | if (ret) | ||
374 | return ret; | ||
375 | |||
376 | switch (clk_mode) { | ||
377 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
378 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
379 | sst_data = 0x2f; | ||
380 | break; | ||
381 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
382 | sst_data = 0x2e; | ||
383 | break; | ||
384 | default: | ||
385 | return -EINVAL; | ||
386 | } | ||
387 | |||
388 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
389 | CXD2880_IO_TGT_DMD, | ||
390 | 0x71, sst_data); | ||
391 | if (ret) | ||
392 | return ret; | ||
393 | |||
394 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
395 | switch (clk_mode) { | ||
396 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
397 | data = bw7_mrc_a; | ||
398 | break; | ||
399 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
400 | data = bw7_mrc_b; | ||
401 | break; | ||
402 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
403 | data = bw7_mrc_c; | ||
404 | break; | ||
405 | default: | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | |||
409 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
410 | CXD2880_IO_TGT_DMD, | ||
411 | 0x4b, &data[0], 2); | ||
412 | if (ret) | ||
413 | return ret; | ||
414 | |||
415 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
416 | CXD2880_IO_TGT_DMD, | ||
417 | 0x51, &data[2], 3); | ||
418 | if (ret) | ||
419 | return ret; | ||
420 | } | ||
421 | |||
422 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
423 | CXD2880_IO_TGT_DMD, | ||
424 | 0x72, &bw7_notch[0], 2); | ||
425 | if (ret) | ||
426 | return ret; | ||
427 | |||
428 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
429 | CXD2880_IO_TGT_DMD, | ||
430 | 0x6b, &bw7_notch[2], 2); | ||
431 | if (ret) | ||
432 | return ret; | ||
433 | break; | ||
434 | |||
435 | case CXD2880_DTV_BW_6_MHZ: | ||
436 | switch (clk_mode) { | ||
437 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
438 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
439 | data = bw6_nomi_ac; | ||
440 | break; | ||
441 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
442 | data = bw6_nomi_b; | ||
443 | break; | ||
444 | default: | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
449 | CXD2880_IO_TGT_DMD, | ||
450 | 0x60, data, 5); | ||
451 | if (ret) | ||
452 | return ret; | ||
453 | |||
454 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
455 | CXD2880_IO_TGT_DMD, | ||
456 | 0x4a, 0x04); | ||
457 | if (ret) | ||
458 | return ret; | ||
459 | |||
460 | switch (clk_mode) { | ||
461 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
462 | data = bw6_gtdofst_a; | ||
463 | break; | ||
464 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
465 | data = bw6_gtdofst_b; | ||
466 | break; | ||
467 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
468 | data = bw6_gtdofst_c; | ||
469 | break; | ||
470 | default: | ||
471 | return -EINVAL; | ||
472 | } | ||
473 | |||
474 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
475 | CXD2880_IO_TGT_DMD, | ||
476 | 0x7d, data, 2); | ||
477 | if (ret) | ||
478 | return ret; | ||
479 | |||
480 | switch (clk_mode) { | ||
481 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
482 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
483 | sst_data = 0x29; | ||
484 | break; | ||
485 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
486 | sst_data = 0x2a; | ||
487 | break; | ||
488 | default: | ||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
493 | CXD2880_IO_TGT_DMD, | ||
494 | 0x71, sst_data); | ||
495 | if (ret) | ||
496 | return ret; | ||
497 | |||
498 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
499 | switch (clk_mode) { | ||
500 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
501 | data = bw6_mrc_a; | ||
502 | break; | ||
503 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
504 | data = bw6_mrc_b; | ||
505 | break; | ||
506 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
507 | data = bw6_mrc_c; | ||
508 | break; | ||
509 | default: | ||
510 | return -EINVAL; | ||
511 | } | ||
512 | |||
513 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
514 | CXD2880_IO_TGT_DMD, | ||
515 | 0x4b, &data[0], 2); | ||
516 | if (ret) | ||
517 | return ret; | ||
518 | |||
519 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
520 | CXD2880_IO_TGT_DMD, | ||
521 | 0x51, &data[2], 3); | ||
522 | if (ret) | ||
523 | return ret; | ||
524 | } | ||
525 | |||
526 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
527 | CXD2880_IO_TGT_DMD, | ||
528 | 0x72, &bw6_notch[0], 2); | ||
529 | if (ret) | ||
530 | return ret; | ||
531 | |||
532 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
533 | CXD2880_IO_TGT_DMD, | ||
534 | 0x6b, &bw6_notch[2], 2); | ||
535 | if (ret) | ||
536 | return ret; | ||
537 | break; | ||
538 | |||
539 | case CXD2880_DTV_BW_5_MHZ: | ||
540 | switch (clk_mode) { | ||
541 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
542 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
543 | data = bw5_nomi_ac; | ||
544 | break; | ||
545 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
546 | data = bw5_nomi_b; | ||
547 | break; | ||
548 | default: | ||
549 | return -EINVAL; | ||
550 | } | ||
551 | |||
552 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
553 | CXD2880_IO_TGT_DMD, | ||
554 | 0x60, data, 5); | ||
555 | if (ret) | ||
556 | return ret; | ||
557 | |||
558 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
559 | CXD2880_IO_TGT_DMD, | ||
560 | 0x4a, 0x06); | ||
561 | if (ret) | ||
562 | return ret; | ||
563 | |||
564 | switch (clk_mode) { | ||
565 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
566 | data = bw5_gtdofst_a; | ||
567 | break; | ||
568 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
569 | data = bw5_gtdofst_b; | ||
570 | break; | ||
571 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
572 | data = bw5_gtdofst_c; | ||
573 | break; | ||
574 | default: | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | |||
578 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
579 | CXD2880_IO_TGT_DMD, | ||
580 | 0x7d, data, 2); | ||
581 | if (ret) | ||
582 | return ret; | ||
583 | |||
584 | switch (clk_mode) { | ||
585 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
586 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
587 | sst_data = 0x24; | ||
588 | break; | ||
589 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
590 | sst_data = 0x23; | ||
591 | break; | ||
592 | default: | ||
593 | return -EINVAL; | ||
594 | } | ||
595 | |||
596 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
597 | CXD2880_IO_TGT_DMD, | ||
598 | 0x71, sst_data); | ||
599 | if (ret) | ||
600 | return ret; | ||
601 | |||
602 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
603 | switch (clk_mode) { | ||
604 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
605 | data = bw5_mrc_a; | ||
606 | break; | ||
607 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
608 | data = bw5_mrc_b; | ||
609 | break; | ||
610 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
611 | data = bw5_mrc_c; | ||
612 | break; | ||
613 | default: | ||
614 | return -EINVAL; | ||
615 | } | ||
616 | |||
617 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
618 | CXD2880_IO_TGT_DMD, | ||
619 | 0x4b, &data[0], 2); | ||
620 | if (ret) | ||
621 | return ret; | ||
622 | |||
623 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
624 | CXD2880_IO_TGT_DMD, | ||
625 | 0x51, &data[2], 3); | ||
626 | if (ret) | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
631 | CXD2880_IO_TGT_DMD, | ||
632 | 0x72, &bw5_notch[0], 2); | ||
633 | if (ret) | ||
634 | return ret; | ||
635 | |||
636 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
637 | CXD2880_IO_TGT_DMD, | ||
638 | 0x6b, &bw5_notch[2], 2); | ||
639 | if (ret) | ||
640 | return ret; | ||
641 | break; | ||
642 | |||
643 | default: | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | |||
647 | return cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
648 | CXD2880_IO_TGT_DMD, | ||
649 | tune_dmd_setting_seq5, | ||
650 | ARRAY_SIZE(tune_dmd_setting_seq5)); | ||
651 | } | ||
652 | |||
653 | static int x_sleep_dvbt_demod_setting(struct cxd2880_tnrdmd | ||
654 | *tnr_dmd) | ||
655 | { | ||
656 | int ret; | ||
657 | |||
658 | if (!tnr_dmd) | ||
659 | return -EINVAL; | ||
660 | |||
661 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
662 | CXD2880_IO_TGT_DMD, | ||
663 | sleep_dmd_setting_seq1, | ||
664 | ARRAY_SIZE(sleep_dmd_setting_seq1)); | ||
665 | if (ret) | ||
666 | return ret; | ||
667 | |||
668 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
669 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
670 | CXD2880_IO_TGT_DMD, | ||
671 | sleep_dmd_setting_seq2, | ||
672 | ARRAY_SIZE(sleep_dmd_setting_seq2)); | ||
673 | |||
674 | return ret; | ||
675 | } | ||
676 | |||
677 | static int dvbt_set_profile(struct cxd2880_tnrdmd *tnr_dmd, | ||
678 | enum cxd2880_dvbt_profile profile) | ||
679 | { | ||
680 | int ret; | ||
681 | |||
682 | if (!tnr_dmd) | ||
683 | return -EINVAL; | ||
684 | |||
685 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
686 | CXD2880_IO_TGT_DMD, | ||
687 | 0x00, 0x10); | ||
688 | if (ret) | ||
689 | return ret; | ||
690 | |||
691 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
692 | CXD2880_IO_TGT_DMD, | ||
693 | 0x67, | ||
694 | (profile == CXD2880_DVBT_PROFILE_HP) | ||
695 | ? 0x00 : 0x01); | ||
696 | } | ||
697 | |||
698 | int cxd2880_tnrdmd_dvbt_tune1(struct cxd2880_tnrdmd *tnr_dmd, | ||
699 | struct cxd2880_dvbt_tune_param | ||
700 | *tune_param) | ||
701 | { | ||
702 | int ret; | ||
703 | |||
704 | if (!tnr_dmd || !tune_param) | ||
705 | return -EINVAL; | ||
706 | |||
707 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
708 | return -EINVAL; | ||
709 | |||
710 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
711 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
712 | return -EINVAL; | ||
713 | |||
714 | ret = | ||
715 | cxd2880_tnrdmd_common_tune_setting1(tnr_dmd, CXD2880_DTV_SYS_DVBT, | ||
716 | tune_param->center_freq_khz, | ||
717 | tune_param->bandwidth, 0, 0); | ||
718 | if (ret) | ||
719 | return ret; | ||
720 | |||
721 | ret = | ||
722 | x_tune_dvbt_demod_setting(tnr_dmd, tune_param->bandwidth, | ||
723 | tnr_dmd->clk_mode); | ||
724 | if (ret) | ||
725 | return ret; | ||
726 | |||
727 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
728 | ret = | ||
729 | x_tune_dvbt_demod_setting(tnr_dmd->diver_sub, | ||
730 | tune_param->bandwidth, | ||
731 | tnr_dmd->diver_sub->clk_mode); | ||
732 | if (ret) | ||
733 | return ret; | ||
734 | } | ||
735 | |||
736 | return dvbt_set_profile(tnr_dmd, tune_param->profile); | ||
737 | } | ||
738 | |||
739 | int cxd2880_tnrdmd_dvbt_tune2(struct cxd2880_tnrdmd *tnr_dmd, | ||
740 | struct cxd2880_dvbt_tune_param | ||
741 | *tune_param) | ||
742 | { | ||
743 | int ret; | ||
744 | |||
745 | if (!tnr_dmd || !tune_param) | ||
746 | return -EINVAL; | ||
747 | |||
748 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
749 | return -EINVAL; | ||
750 | |||
751 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
752 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
753 | return -EINVAL; | ||
754 | |||
755 | ret = | ||
756 | cxd2880_tnrdmd_common_tune_setting2(tnr_dmd, CXD2880_DTV_SYS_DVBT, | ||
757 | 0); | ||
758 | if (ret) | ||
759 | return ret; | ||
760 | |||
761 | tnr_dmd->state = CXD2880_TNRDMD_STATE_ACTIVE; | ||
762 | tnr_dmd->frequency_khz = tune_param->center_freq_khz; | ||
763 | tnr_dmd->sys = CXD2880_DTV_SYS_DVBT; | ||
764 | tnr_dmd->bandwidth = tune_param->bandwidth; | ||
765 | |||
766 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
767 | tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_ACTIVE; | ||
768 | tnr_dmd->diver_sub->frequency_khz = tune_param->center_freq_khz; | ||
769 | tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_DVBT; | ||
770 | tnr_dmd->diver_sub->bandwidth = tune_param->bandwidth; | ||
771 | } | ||
772 | |||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | int cxd2880_tnrdmd_dvbt_sleep_setting(struct cxd2880_tnrdmd *tnr_dmd) | ||
777 | { | ||
778 | int ret; | ||
779 | |||
780 | if (!tnr_dmd) | ||
781 | return -EINVAL; | ||
782 | |||
783 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
784 | return -EINVAL; | ||
785 | |||
786 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
787 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
788 | return -EINVAL; | ||
789 | |||
790 | ret = x_sleep_dvbt_demod_setting(tnr_dmd); | ||
791 | if (ret) | ||
792 | return ret; | ||
793 | |||
794 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
795 | ret = x_sleep_dvbt_demod_setting(tnr_dmd->diver_sub); | ||
796 | |||
797 | return ret; | ||
798 | } | ||
799 | |||
800 | int cxd2880_tnrdmd_dvbt_check_demod_lock(struct cxd2880_tnrdmd | ||
801 | *tnr_dmd, | ||
802 | enum | ||
803 | cxd2880_tnrdmd_lock_result | ||
804 | *lock) | ||
805 | { | ||
806 | int ret; | ||
807 | |||
808 | u8 sync_stat = 0; | ||
809 | u8 ts_lock = 0; | ||
810 | u8 unlock_detected = 0; | ||
811 | u8 unlock_detected_sub = 0; | ||
812 | |||
813 | if (!tnr_dmd || !lock) | ||
814 | return -EINVAL; | ||
815 | |||
816 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
817 | return -EINVAL; | ||
818 | |||
819 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
820 | return -EINVAL; | ||
821 | |||
822 | ret = | ||
823 | cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock, | ||
824 | &unlock_detected); | ||
825 | if (ret) | ||
826 | return ret; | ||
827 | |||
828 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
829 | if (sync_stat == 6) | ||
830 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
831 | else if (unlock_detected) | ||
832 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
833 | else | ||
834 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
835 | |||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | if (sync_stat == 6) { | ||
840 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
841 | return ret; | ||
842 | } | ||
843 | |||
844 | ret = | ||
845 | cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(tnr_dmd, &sync_stat, | ||
846 | &unlock_detected_sub); | ||
847 | if (ret) | ||
848 | return ret; | ||
849 | |||
850 | if (sync_stat == 6) | ||
851 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
852 | else if (unlock_detected && unlock_detected_sub) | ||
853 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
854 | else | ||
855 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
856 | |||
857 | return ret; | ||
858 | } | ||
859 | |||
860 | int cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd | ||
861 | *tnr_dmd, | ||
862 | enum | ||
863 | cxd2880_tnrdmd_lock_result | ||
864 | *lock) | ||
865 | { | ||
866 | int ret; | ||
867 | |||
868 | u8 sync_stat = 0; | ||
869 | u8 ts_lock = 0; | ||
870 | u8 unlock_detected = 0; | ||
871 | u8 unlock_detected_sub = 0; | ||
872 | |||
873 | if (!tnr_dmd || !lock) | ||
874 | return -EINVAL; | ||
875 | |||
876 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
877 | return -EINVAL; | ||
878 | |||
879 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
880 | return -EINVAL; | ||
881 | |||
882 | ret = | ||
883 | cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock, | ||
884 | &unlock_detected); | ||
885 | if (ret) | ||
886 | return ret; | ||
887 | |||
888 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
889 | if (ts_lock) | ||
890 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
891 | else if (unlock_detected) | ||
892 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
893 | else | ||
894 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
895 | |||
896 | return ret; | ||
897 | } | ||
898 | |||
899 | if (ts_lock) { | ||
900 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
901 | return ret; | ||
902 | } else if (!unlock_detected) { | ||
903 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
904 | return ret; | ||
905 | } | ||
906 | |||
907 | ret = | ||
908 | cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(tnr_dmd, &sync_stat, | ||
909 | &unlock_detected_sub); | ||
910 | if (ret) | ||
911 | return ret; | ||
912 | |||
913 | if (unlock_detected && unlock_detected_sub) | ||
914 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
915 | else | ||
916 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
917 | |||
918 | return ret; | ||
919 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h new file mode 100644 index 000000000000..35d81ccc732b --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * control interface for DVB-T | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_TNRDMD_DVBT_H | ||
11 | #define CXD2880_TNRDMD_DVBT_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | #include "cxd2880_tnrdmd.h" | ||
15 | |||
16 | struct cxd2880_dvbt_tune_param { | ||
17 | u32 center_freq_khz; | ||
18 | enum cxd2880_dtv_bandwidth bandwidth; | ||
19 | enum cxd2880_dvbt_profile profile; | ||
20 | }; | ||
21 | |||
22 | int cxd2880_tnrdmd_dvbt_tune1(struct cxd2880_tnrdmd *tnr_dmd, | ||
23 | struct cxd2880_dvbt_tune_param | ||
24 | *tune_param); | ||
25 | |||
26 | int cxd2880_tnrdmd_dvbt_tune2(struct cxd2880_tnrdmd *tnr_dmd, | ||
27 | struct cxd2880_dvbt_tune_param | ||
28 | *tune_param); | ||
29 | |||
30 | int cxd2880_tnrdmd_dvbt_sleep_setting(struct cxd2880_tnrdmd | ||
31 | *tnr_dmd); | ||
32 | |||
33 | int cxd2880_tnrdmd_dvbt_check_demod_lock(struct cxd2880_tnrdmd | ||
34 | *tnr_dmd, | ||
35 | enum | ||
36 | cxd2880_tnrdmd_lock_result | ||
37 | *lock); | ||
38 | |||
39 | int cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd | ||
40 | *tnr_dmd, | ||
41 | enum | ||
42 | cxd2880_tnrdmd_lock_result | ||
43 | *lock); | ||
44 | |||
45 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c new file mode 100644 index 000000000000..dd32004a12d8 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c | |||
@@ -0,0 +1,1217 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt2.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * control functions for DVB-T2 | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include <media/dvb_frontend.h> | ||
11 | |||
12 | #include "cxd2880_tnrdmd_dvbt2.h" | ||
13 | #include "cxd2880_tnrdmd_dvbt2_mon.h" | ||
14 | |||
15 | static const struct cxd2880_reg_value tune_dmd_setting_seq1[] = { | ||
16 | {0x00, 0x00}, {0x31, 0x02}, | ||
17 | }; | ||
18 | |||
19 | static const struct cxd2880_reg_value tune_dmd_setting_seq2[] = { | ||
20 | {0x00, 0x04}, {0x5d, 0x0b}, | ||
21 | }; | ||
22 | |||
23 | static int x_tune_dvbt2_demod_setting(struct cxd2880_tnrdmd | ||
24 | *tnr_dmd, | ||
25 | enum cxd2880_dtv_bandwidth | ||
26 | bandwidth, | ||
27 | enum cxd2880_tnrdmd_clockmode | ||
28 | clk_mode) | ||
29 | { | ||
30 | static const u8 tsif_settings[2] = { 0x01, 0x01 }; | ||
31 | static const u8 init_settings[14] = { | ||
32 | 0x07, 0x06, 0x01, 0xf0, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, | ||
33 | 0x09, 0x9c, 0x0e, 0x4c | ||
34 | }; | ||
35 | static const u8 clk_mode_settings_a1[9] = { | ||
36 | 0x52, 0x49, 0x2c, 0x51, 0x51, 0x3d, 0x15, 0x29, 0x0c | ||
37 | }; | ||
38 | |||
39 | static const u8 clk_mode_settings_b1[9] = { | ||
40 | 0x5d, 0x55, 0x32, 0x5c, 0x5c, 0x45, 0x17, 0x2e, 0x0d | ||
41 | }; | ||
42 | |||
43 | static const u8 clk_mode_settings_c1[9] = { | ||
44 | 0x60, 0x00, 0x34, 0x5e, 0x5e, 0x47, 0x18, 0x2f, 0x0e | ||
45 | }; | ||
46 | |||
47 | static const u8 clk_mode_settings_a2[13] = { | ||
48 | 0x04, 0xe7, 0x94, 0x92, 0x09, 0xcf, 0x7e, 0xd0, 0x49, | ||
49 | 0xcd, 0xcd, 0x1f, 0x5b | ||
50 | }; | ||
51 | |||
52 | static const u8 clk_mode_settings_b2[13] = { | ||
53 | 0x05, 0x90, 0x27, 0x55, 0x0b, 0x20, 0x8f, 0xd6, 0xea, | ||
54 | 0xc8, 0xc8, 0x23, 0x91 | ||
55 | }; | ||
56 | |||
57 | static const u8 clk_mode_settings_c2[13] = { | ||
58 | 0x05, 0xb8, 0xd8, 0x00, 0x0b, 0x72, 0x93, 0xf3, 0x00, | ||
59 | 0xcd, 0xcd, 0x24, 0x95 | ||
60 | }; | ||
61 | |||
62 | static const u8 clk_mode_settings_a3[5] = { | ||
63 | 0x0b, 0x6a, 0xc9, 0x03, 0x33 | ||
64 | }; | ||
65 | static const u8 clk_mode_settings_b3[5] = { | ||
66 | 0x01, 0x02, 0xe4, 0x03, 0x39 | ||
67 | }; | ||
68 | static const u8 clk_mode_settings_c3[5] = { | ||
69 | 0x01, 0x02, 0xeb, 0x03, 0x3b | ||
70 | }; | ||
71 | |||
72 | static const u8 gtdofst[2] = { 0x3f, 0xff }; | ||
73 | |||
74 | static const u8 bw8_gtdofst_a[2] = { 0x19, 0xd2 }; | ||
75 | static const u8 bw8_nomi_ac[6] = { 0x15, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
76 | static const u8 bw8_nomi_b[6] = { 0x14, 0x6a, 0xaa, 0xaa, 0xab, 0x00 }; | ||
77 | static const u8 bw8_sst_a[2] = { 0x06, 0x2a }; | ||
78 | static const u8 bw8_sst_b[2] = { 0x06, 0x29 }; | ||
79 | static const u8 bw8_sst_c[2] = { 0x06, 0x28 }; | ||
80 | static const u8 bw8_mrc_a[9] = { | ||
81 | 0x28, 0x00, 0x50, 0x00, 0x60, 0x00, 0x00, 0x90, 0x00 | ||
82 | }; | ||
83 | static const u8 bw8_mrc_b[9] = { | ||
84 | 0x2d, 0x5e, 0x5a, 0xbd, 0x6c, 0xe3, 0x00, 0xa3, 0x55 | ||
85 | }; | ||
86 | static const u8 bw8_mrc_c[9] = { | ||
87 | 0x2e, 0xaa, 0x5d, 0x55, 0x70, 0x00, 0x00, 0xa8, 0x00 | ||
88 | }; | ||
89 | |||
90 | static const u8 bw7_nomi_ac[6] = { 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
91 | static const u8 bw7_nomi_b[6] = { 0x17, 0x55, 0x55, 0x55, 0x55, 0x00 }; | ||
92 | static const u8 bw7_sst_a[2] = { 0x06, 0x23 }; | ||
93 | static const u8 bw7_sst_b[2] = { 0x06, 0x22 }; | ||
94 | static const u8 bw7_sst_c[2] = { 0x06, 0x21 }; | ||
95 | static const u8 bw7_mrc_a[9] = { | ||
96 | 0x2d, 0xb6, 0x5b, 0x6d, 0x6d, 0xb6, 0x00, 0xa4, 0x92 | ||
97 | }; | ||
98 | static const u8 bw7_mrc_b[9] = { | ||
99 | 0x33, 0xda, 0x67, 0xb4, 0x7c, 0x71, 0x00, 0xba, 0xaa | ||
100 | }; | ||
101 | static const u8 bw7_mrc_c[9] = { | ||
102 | 0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00 | ||
103 | }; | ||
104 | |||
105 | static const u8 bw6_nomi_ac[6] = { 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
106 | static const u8 bw6_nomi_b[6] = { 0x1b, 0x38, 0xe3, 0x8e, 0x39, 0x00 }; | ||
107 | static const u8 bw6_sst_a[2] = { 0x06, 0x1c }; | ||
108 | static const u8 bw6_sst_b[2] = { 0x06, 0x1b }; | ||
109 | static const u8 bw6_sst_c[2] = { 0x06, 0x1a }; | ||
110 | static const u8 bw6_mrc_a[9] = { | ||
111 | 0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00 | ||
112 | }; | ||
113 | static const u8 bw6_mrc_b[9] = { | ||
114 | 0x3c, 0x7e, 0x78, 0xfc, 0x91, 0x2f, 0x00, 0xd9, 0xc7 | ||
115 | }; | ||
116 | static const u8 bw6_mrc_c[9] = { | ||
117 | 0x3e, 0x38, 0x7c, 0x71, 0x95, 0x55, 0x00, 0xdf, 0xff | ||
118 | }; | ||
119 | |||
120 | static const u8 bw5_nomi_ac[6] = { 0x21, 0x99, 0x99, 0x99, 0x9a, 0x00 }; | ||
121 | static const u8 bw5_nomi_b[6] = { 0x20, 0xaa, 0xaa, 0xaa, 0xab, 0x00 }; | ||
122 | static const u8 bw5_sst_a[2] = { 0x06, 0x15 }; | ||
123 | static const u8 bw5_sst_b[2] = { 0x06, 0x15 }; | ||
124 | static const u8 bw5_sst_c[2] = { 0x06, 0x14 }; | ||
125 | static const u8 bw5_mrc_a[9] = { | ||
126 | 0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xe6, 0x66 | ||
127 | }; | ||
128 | static const u8 bw5_mrc_b[9] = { | ||
129 | 0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x01, 0x05, 0x55 | ||
130 | }; | ||
131 | static const u8 bw5_mrc_c[9] = { | ||
132 | 0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x01, 0x0c, 0xcc | ||
133 | }; | ||
134 | |||
135 | static const u8 bw1_7_nomi_a[6] = { | ||
136 | 0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03 | ||
137 | }; | ||
138 | static const u8 bw1_7_nomi_c[6] = { | ||
139 | 0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03 | ||
140 | }; | ||
141 | static const u8 bw1_7_nomi_b[6] = { | ||
142 | 0x65, 0x2b, 0xa4, 0xcd, 0xd8, 0x03 | ||
143 | }; | ||
144 | static const u8 bw1_7_sst_a[2] = { 0x06, 0x0c }; | ||
145 | static const u8 bw1_7_sst_b[2] = { 0x06, 0x0c }; | ||
146 | static const u8 bw1_7_sst_c[2] = { 0x06, 0x0b }; | ||
147 | static const u8 bw1_7_mrc_a[9] = { | ||
148 | 0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x02, 0xc9, 0x8f | ||
149 | }; | ||
150 | static const u8 bw1_7_mrc_b[9] = { | ||
151 | 0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x03, 0x29, 0x5d | ||
152 | }; | ||
153 | static const u8 bw1_7_mrc_c[9] = { | ||
154 | 0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x03, 0x40, 0x7d | ||
155 | }; | ||
156 | |||
157 | const u8 *data = NULL; | ||
158 | const u8 *data2 = NULL; | ||
159 | const u8 *data3 = NULL; | ||
160 | int ret; | ||
161 | |||
162 | if (!tnr_dmd) | ||
163 | return -EINVAL; | ||
164 | |||
165 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
166 | CXD2880_IO_TGT_SYS, | ||
167 | tune_dmd_setting_seq1, | ||
168 | ARRAY_SIZE(tune_dmd_setting_seq1)); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | ret = cxd2880_io_write_multi_regs(tnr_dmd->io, | ||
173 | CXD2880_IO_TGT_DMD, | ||
174 | tune_dmd_setting_seq2, | ||
175 | ARRAY_SIZE(tune_dmd_setting_seq2)); | ||
176 | if (ret) | ||
177 | return ret; | ||
178 | |||
179 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) { | ||
180 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
181 | CXD2880_IO_TGT_DMD, | ||
182 | 0x00, 0x00); | ||
183 | if (ret) | ||
184 | return ret; | ||
185 | |||
186 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
187 | CXD2880_IO_TGT_DMD, | ||
188 | 0xce, tsif_settings, 2); | ||
189 | if (ret) | ||
190 | return ret; | ||
191 | } | ||
192 | |||
193 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
194 | CXD2880_IO_TGT_DMD, | ||
195 | 0x00, 0x20); | ||
196 | if (ret) | ||
197 | return ret; | ||
198 | |||
199 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
200 | CXD2880_IO_TGT_DMD, | ||
201 | 0x8a, init_settings[0]); | ||
202 | if (ret) | ||
203 | return ret; | ||
204 | |||
205 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
206 | CXD2880_IO_TGT_DMD, | ||
207 | 0x90, init_settings[1]); | ||
208 | if (ret) | ||
209 | return ret; | ||
210 | |||
211 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
212 | CXD2880_IO_TGT_DMD, | ||
213 | 0x00, 0x25); | ||
214 | if (ret) | ||
215 | return ret; | ||
216 | |||
217 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
218 | CXD2880_IO_TGT_DMD, | ||
219 | 0xf0, &init_settings[2], 2); | ||
220 | if (ret) | ||
221 | return ret; | ||
222 | |||
223 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
224 | CXD2880_IO_TGT_DMD, | ||
225 | 0x00, 0x2a); | ||
226 | if (ret) | ||
227 | return ret; | ||
228 | |||
229 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
230 | CXD2880_IO_TGT_DMD, | ||
231 | 0xdc, init_settings[4]); | ||
232 | if (ret) | ||
233 | return ret; | ||
234 | |||
235 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
236 | CXD2880_IO_TGT_DMD, | ||
237 | 0xde, init_settings[5]); | ||
238 | if (ret) | ||
239 | return ret; | ||
240 | |||
241 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
242 | CXD2880_IO_TGT_DMD, | ||
243 | 0x00, 0x2d); | ||
244 | if (ret) | ||
245 | return ret; | ||
246 | |||
247 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
248 | CXD2880_IO_TGT_DMD, | ||
249 | 0x73, &init_settings[6], 4); | ||
250 | if (ret) | ||
251 | return ret; | ||
252 | |||
253 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
254 | CXD2880_IO_TGT_DMD, | ||
255 | 0x8f, &init_settings[10], 4); | ||
256 | if (ret) | ||
257 | return ret; | ||
258 | |||
259 | switch (clk_mode) { | ||
260 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
261 | data = clk_mode_settings_a1; | ||
262 | data2 = clk_mode_settings_a2; | ||
263 | data3 = clk_mode_settings_a3; | ||
264 | break; | ||
265 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
266 | data = clk_mode_settings_b1; | ||
267 | data2 = clk_mode_settings_b2; | ||
268 | data3 = clk_mode_settings_b3; | ||
269 | break; | ||
270 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
271 | data = clk_mode_settings_c1; | ||
272 | data2 = clk_mode_settings_c2; | ||
273 | data3 = clk_mode_settings_c3; | ||
274 | break; | ||
275 | default: | ||
276 | return -EINVAL; | ||
277 | } | ||
278 | |||
279 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
280 | CXD2880_IO_TGT_DMD, | ||
281 | 0x00, 0x04); | ||
282 | if (ret) | ||
283 | return ret; | ||
284 | |||
285 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
286 | CXD2880_IO_TGT_DMD, | ||
287 | 0x1d, &data[0], 3); | ||
288 | if (ret) | ||
289 | return ret; | ||
290 | |||
291 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
292 | CXD2880_IO_TGT_DMD, | ||
293 | 0x22, data[3]); | ||
294 | if (ret) | ||
295 | return ret; | ||
296 | |||
297 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
298 | CXD2880_IO_TGT_DMD, | ||
299 | 0x24, data[4]); | ||
300 | if (ret) | ||
301 | return ret; | ||
302 | |||
303 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
304 | CXD2880_IO_TGT_DMD, | ||
305 | 0x26, data[5]); | ||
306 | if (ret) | ||
307 | return ret; | ||
308 | |||
309 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
310 | CXD2880_IO_TGT_DMD, | ||
311 | 0x29, &data[6], 2); | ||
312 | if (ret) | ||
313 | return ret; | ||
314 | |||
315 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
316 | CXD2880_IO_TGT_DMD, | ||
317 | 0x2d, data[8]); | ||
318 | if (ret) | ||
319 | return ret; | ||
320 | |||
321 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) { | ||
322 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
323 | CXD2880_IO_TGT_DMD, | ||
324 | 0x2e, &data2[0], 6); | ||
325 | if (ret) | ||
326 | return ret; | ||
327 | |||
328 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
329 | CXD2880_IO_TGT_DMD, | ||
330 | 0x35, &data2[6], 7); | ||
331 | if (ret) | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
336 | CXD2880_IO_TGT_DMD, | ||
337 | 0x3c, &data3[0], 2); | ||
338 | if (ret) | ||
339 | return ret; | ||
340 | |||
341 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
342 | CXD2880_IO_TGT_DMD, | ||
343 | 0x56, &data3[2], 3); | ||
344 | if (ret) | ||
345 | return ret; | ||
346 | |||
347 | switch (bandwidth) { | ||
348 | case CXD2880_DTV_BW_8_MHZ: | ||
349 | switch (clk_mode) { | ||
350 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
351 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
352 | data = bw8_nomi_ac; | ||
353 | break; | ||
354 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
355 | data = bw8_nomi_b; | ||
356 | break; | ||
357 | default: | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
362 | CXD2880_IO_TGT_DMD, | ||
363 | 0x10, data, 6); | ||
364 | if (ret) | ||
365 | return ret; | ||
366 | |||
367 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
368 | CXD2880_IO_TGT_DMD, | ||
369 | 0x4a, 0x00); | ||
370 | if (ret) | ||
371 | return ret; | ||
372 | |||
373 | switch (clk_mode) { | ||
374 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
375 | data = bw8_gtdofst_a; | ||
376 | break; | ||
377 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
378 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
379 | data = gtdofst; | ||
380 | break; | ||
381 | default: | ||
382 | return -EINVAL; | ||
383 | } | ||
384 | |||
385 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
386 | CXD2880_IO_TGT_DMD, | ||
387 | 0x19, data, 2); | ||
388 | if (ret) | ||
389 | return ret; | ||
390 | |||
391 | switch (clk_mode) { | ||
392 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
393 | data = bw8_sst_a; | ||
394 | break; | ||
395 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
396 | data = bw8_sst_b; | ||
397 | break; | ||
398 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
399 | data = bw8_sst_c; | ||
400 | break; | ||
401 | default: | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | |||
405 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
406 | CXD2880_IO_TGT_DMD, | ||
407 | 0x1b, data, 2); | ||
408 | if (ret) | ||
409 | return ret; | ||
410 | |||
411 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
412 | switch (clk_mode) { | ||
413 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
414 | data = bw8_mrc_a; | ||
415 | break; | ||
416 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
417 | data = bw8_mrc_b; | ||
418 | break; | ||
419 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
420 | data = bw8_mrc_c; | ||
421 | break; | ||
422 | default: | ||
423 | return -EINVAL; | ||
424 | } | ||
425 | |||
426 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
427 | CXD2880_IO_TGT_DMD, | ||
428 | 0x4b, data, 9); | ||
429 | if (ret) | ||
430 | return ret; | ||
431 | } | ||
432 | break; | ||
433 | |||
434 | case CXD2880_DTV_BW_7_MHZ: | ||
435 | switch (clk_mode) { | ||
436 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
437 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
438 | data = bw7_nomi_ac; | ||
439 | break; | ||
440 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
441 | data = bw7_nomi_b; | ||
442 | break; | ||
443 | default: | ||
444 | return -EINVAL; | ||
445 | } | ||
446 | |||
447 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
448 | CXD2880_IO_TGT_DMD, | ||
449 | 0x10, data, 6); | ||
450 | if (ret) | ||
451 | return ret; | ||
452 | |||
453 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
454 | CXD2880_IO_TGT_DMD, | ||
455 | 0x4a, 0x02); | ||
456 | if (ret) | ||
457 | return ret; | ||
458 | |||
459 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
460 | CXD2880_IO_TGT_DMD, | ||
461 | 0x19, gtdofst, 2); | ||
462 | if (ret) | ||
463 | return ret; | ||
464 | |||
465 | switch (clk_mode) { | ||
466 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
467 | data = bw7_sst_a; | ||
468 | break; | ||
469 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
470 | data = bw7_sst_b; | ||
471 | break; | ||
472 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
473 | data = bw7_sst_c; | ||
474 | break; | ||
475 | default: | ||
476 | return -EINVAL; | ||
477 | } | ||
478 | |||
479 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
480 | CXD2880_IO_TGT_DMD, | ||
481 | 0x1b, data, 2); | ||
482 | if (ret) | ||
483 | return ret; | ||
484 | |||
485 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
486 | switch (clk_mode) { | ||
487 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
488 | data = bw7_mrc_a; | ||
489 | break; | ||
490 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
491 | data = bw7_mrc_b; | ||
492 | break; | ||
493 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
494 | data = bw7_mrc_c; | ||
495 | break; | ||
496 | default: | ||
497 | return -EINVAL; | ||
498 | } | ||
499 | |||
500 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
501 | CXD2880_IO_TGT_DMD, | ||
502 | 0x4b, data, 9); | ||
503 | if (ret) | ||
504 | return ret; | ||
505 | } | ||
506 | break; | ||
507 | |||
508 | case CXD2880_DTV_BW_6_MHZ: | ||
509 | switch (clk_mode) { | ||
510 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
511 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
512 | data = bw6_nomi_ac; | ||
513 | break; | ||
514 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
515 | data = bw6_nomi_b; | ||
516 | break; | ||
517 | default: | ||
518 | return -EINVAL; | ||
519 | } | ||
520 | |||
521 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
522 | CXD2880_IO_TGT_DMD, | ||
523 | 0x10, data, 6); | ||
524 | if (ret) | ||
525 | return ret; | ||
526 | |||
527 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
528 | CXD2880_IO_TGT_DMD, | ||
529 | 0x4a, 0x04); | ||
530 | if (ret) | ||
531 | return ret; | ||
532 | |||
533 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
534 | CXD2880_IO_TGT_DMD, | ||
535 | 0x19, gtdofst, 2); | ||
536 | if (ret) | ||
537 | return ret; | ||
538 | |||
539 | switch (clk_mode) { | ||
540 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
541 | data = bw6_sst_a; | ||
542 | break; | ||
543 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
544 | data = bw6_sst_b; | ||
545 | break; | ||
546 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
547 | data = bw6_sst_c; | ||
548 | break; | ||
549 | default: | ||
550 | return -EINVAL; | ||
551 | } | ||
552 | |||
553 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
554 | CXD2880_IO_TGT_DMD, | ||
555 | 0x1b, data, 2); | ||
556 | if (ret) | ||
557 | return ret; | ||
558 | |||
559 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
560 | switch (clk_mode) { | ||
561 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
562 | data = bw6_mrc_a; | ||
563 | break; | ||
564 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
565 | data = bw6_mrc_b; | ||
566 | break; | ||
567 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
568 | data = bw6_mrc_c; | ||
569 | break; | ||
570 | default: | ||
571 | return -EINVAL; | ||
572 | } | ||
573 | |||
574 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
575 | CXD2880_IO_TGT_DMD, | ||
576 | 0x4b, data, 9); | ||
577 | if (ret) | ||
578 | return ret; | ||
579 | } | ||
580 | break; | ||
581 | |||
582 | case CXD2880_DTV_BW_5_MHZ: | ||
583 | switch (clk_mode) { | ||
584 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
585 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
586 | data = bw5_nomi_ac; | ||
587 | break; | ||
588 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
589 | data = bw5_nomi_b; | ||
590 | break; | ||
591 | default: | ||
592 | return -EINVAL; | ||
593 | } | ||
594 | |||
595 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
596 | CXD2880_IO_TGT_DMD, | ||
597 | 0x10, data, 6); | ||
598 | if (ret) | ||
599 | return ret; | ||
600 | |||
601 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
602 | CXD2880_IO_TGT_DMD, | ||
603 | 0x4a, 0x06); | ||
604 | if (ret) | ||
605 | return ret; | ||
606 | |||
607 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
608 | CXD2880_IO_TGT_DMD, | ||
609 | 0x19, gtdofst, 2); | ||
610 | if (ret) | ||
611 | return ret; | ||
612 | |||
613 | switch (clk_mode) { | ||
614 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
615 | data = bw5_sst_a; | ||
616 | break; | ||
617 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
618 | data = bw5_sst_b; | ||
619 | break; | ||
620 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
621 | data = bw5_sst_c; | ||
622 | break; | ||
623 | default: | ||
624 | return -EINVAL; | ||
625 | } | ||
626 | |||
627 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
628 | CXD2880_IO_TGT_DMD, | ||
629 | 0x1b, data, 2); | ||
630 | if (ret) | ||
631 | return ret; | ||
632 | |||
633 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
634 | switch (clk_mode) { | ||
635 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
636 | data = bw5_mrc_a; | ||
637 | break; | ||
638 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
639 | data = bw5_mrc_b; | ||
640 | break; | ||
641 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
642 | data = bw5_mrc_c; | ||
643 | break; | ||
644 | default: | ||
645 | return -EINVAL; | ||
646 | } | ||
647 | |||
648 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
649 | CXD2880_IO_TGT_DMD, | ||
650 | 0x4b, data, 9); | ||
651 | if (ret) | ||
652 | return ret; | ||
653 | } | ||
654 | break; | ||
655 | |||
656 | case CXD2880_DTV_BW_1_7_MHZ: | ||
657 | |||
658 | switch (clk_mode) { | ||
659 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
660 | data = bw1_7_nomi_a; | ||
661 | break; | ||
662 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
663 | data = bw1_7_nomi_c; | ||
664 | break; | ||
665 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
666 | data = bw1_7_nomi_b; | ||
667 | break; | ||
668 | default: | ||
669 | return -EINVAL; | ||
670 | } | ||
671 | |||
672 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
673 | CXD2880_IO_TGT_DMD, | ||
674 | 0x10, data, 6); | ||
675 | if (ret) | ||
676 | return ret; | ||
677 | |||
678 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
679 | CXD2880_IO_TGT_DMD, | ||
680 | 0x4a, 0x03); | ||
681 | if (ret) | ||
682 | return ret; | ||
683 | |||
684 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
685 | CXD2880_IO_TGT_DMD, | ||
686 | 0x19, gtdofst, 2); | ||
687 | if (ret) | ||
688 | return ret; | ||
689 | |||
690 | switch (clk_mode) { | ||
691 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
692 | data = bw1_7_sst_a; | ||
693 | break; | ||
694 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
695 | data = bw1_7_sst_b; | ||
696 | break; | ||
697 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
698 | data = bw1_7_sst_c; | ||
699 | break; | ||
700 | default: | ||
701 | return -EINVAL; | ||
702 | } | ||
703 | |||
704 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
705 | CXD2880_IO_TGT_DMD, | ||
706 | 0x1b, data, 2); | ||
707 | if (ret) | ||
708 | return ret; | ||
709 | |||
710 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
711 | switch (clk_mode) { | ||
712 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
713 | data = bw1_7_mrc_a; | ||
714 | break; | ||
715 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
716 | data = bw1_7_mrc_b; | ||
717 | break; | ||
718 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
719 | data = bw1_7_mrc_c; | ||
720 | break; | ||
721 | default: | ||
722 | return -EINVAL; | ||
723 | } | ||
724 | |||
725 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
726 | CXD2880_IO_TGT_DMD, | ||
727 | 0x4b, data, 9); | ||
728 | if (ret) | ||
729 | return ret; | ||
730 | } | ||
731 | break; | ||
732 | |||
733 | default: | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | |||
737 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
738 | CXD2880_IO_TGT_DMD, | ||
739 | 0x00, 0x00); | ||
740 | if (ret) | ||
741 | return ret; | ||
742 | |||
743 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
744 | CXD2880_IO_TGT_DMD, | ||
745 | 0xfd, 0x01); | ||
746 | } | ||
747 | |||
748 | static int x_sleep_dvbt2_demod_setting(struct cxd2880_tnrdmd | ||
749 | *tnr_dmd) | ||
750 | { | ||
751 | static const u8 difint_clip[] = { | ||
752 | 0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32 | ||
753 | }; | ||
754 | int ret = 0; | ||
755 | |||
756 | if (!tnr_dmd) | ||
757 | return -EINVAL; | ||
758 | |||
759 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
760 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
761 | CXD2880_IO_TGT_DMD, | ||
762 | 0x00, 0x1d); | ||
763 | if (ret) | ||
764 | return ret; | ||
765 | |||
766 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
767 | CXD2880_IO_TGT_DMD, | ||
768 | 0x47, difint_clip, 12); | ||
769 | } | ||
770 | |||
771 | return ret; | ||
772 | } | ||
773 | |||
774 | static int dvbt2_set_profile(struct cxd2880_tnrdmd *tnr_dmd, | ||
775 | enum cxd2880_dvbt2_profile profile) | ||
776 | { | ||
777 | u8 t2_mode_tune_mode = 0; | ||
778 | u8 seq_not2_dtime = 0; | ||
779 | u8 dtime1 = 0; | ||
780 | u8 dtime2 = 0; | ||
781 | int ret; | ||
782 | |||
783 | if (!tnr_dmd) | ||
784 | return -EINVAL; | ||
785 | |||
786 | switch (tnr_dmd->clk_mode) { | ||
787 | case CXD2880_TNRDMD_CLOCKMODE_A: | ||
788 | dtime1 = 0x27; | ||
789 | dtime2 = 0x0c; | ||
790 | break; | ||
791 | case CXD2880_TNRDMD_CLOCKMODE_B: | ||
792 | dtime1 = 0x2c; | ||
793 | dtime2 = 0x0d; | ||
794 | break; | ||
795 | case CXD2880_TNRDMD_CLOCKMODE_C: | ||
796 | dtime1 = 0x2e; | ||
797 | dtime2 = 0x0e; | ||
798 | break; | ||
799 | default: | ||
800 | return -EINVAL; | ||
801 | } | ||
802 | |||
803 | switch (profile) { | ||
804 | case CXD2880_DVBT2_PROFILE_BASE: | ||
805 | t2_mode_tune_mode = 0x01; | ||
806 | seq_not2_dtime = dtime2; | ||
807 | break; | ||
808 | |||
809 | case CXD2880_DVBT2_PROFILE_LITE: | ||
810 | t2_mode_tune_mode = 0x05; | ||
811 | seq_not2_dtime = dtime1; | ||
812 | break; | ||
813 | |||
814 | case CXD2880_DVBT2_PROFILE_ANY: | ||
815 | t2_mode_tune_mode = 0x00; | ||
816 | seq_not2_dtime = dtime1; | ||
817 | break; | ||
818 | |||
819 | default: | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | |||
823 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
824 | CXD2880_IO_TGT_DMD, | ||
825 | 0x00, 0x2e); | ||
826 | if (ret) | ||
827 | return ret; | ||
828 | |||
829 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
830 | CXD2880_IO_TGT_DMD, | ||
831 | 0x10, t2_mode_tune_mode); | ||
832 | if (ret) | ||
833 | return ret; | ||
834 | |||
835 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
836 | CXD2880_IO_TGT_DMD, | ||
837 | 0x00, 0x04); | ||
838 | if (ret) | ||
839 | return ret; | ||
840 | |||
841 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
842 | CXD2880_IO_TGT_DMD, | ||
843 | 0x2c, seq_not2_dtime); | ||
844 | } | ||
845 | |||
846 | int cxd2880_tnrdmd_dvbt2_tune1(struct cxd2880_tnrdmd *tnr_dmd, | ||
847 | struct cxd2880_dvbt2_tune_param | ||
848 | *tune_param) | ||
849 | { | ||
850 | int ret; | ||
851 | |||
852 | if (!tnr_dmd || !tune_param) | ||
853 | return -EINVAL; | ||
854 | |||
855 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
856 | return -EINVAL; | ||
857 | |||
858 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
859 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
860 | return -EINVAL; | ||
861 | |||
862 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN && | ||
863 | tune_param->profile == CXD2880_DVBT2_PROFILE_ANY) | ||
864 | return -ENOTTY; | ||
865 | |||
866 | ret = | ||
867 | cxd2880_tnrdmd_common_tune_setting1(tnr_dmd, CXD2880_DTV_SYS_DVBT2, | ||
868 | tune_param->center_freq_khz, | ||
869 | tune_param->bandwidth, 0, 0); | ||
870 | if (ret) | ||
871 | return ret; | ||
872 | |||
873 | ret = | ||
874 | x_tune_dvbt2_demod_setting(tnr_dmd, tune_param->bandwidth, | ||
875 | tnr_dmd->clk_mode); | ||
876 | if (ret) | ||
877 | return ret; | ||
878 | |||
879 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
880 | ret = | ||
881 | x_tune_dvbt2_demod_setting(tnr_dmd->diver_sub, | ||
882 | tune_param->bandwidth, | ||
883 | tnr_dmd->diver_sub->clk_mode); | ||
884 | if (ret) | ||
885 | return ret; | ||
886 | } | ||
887 | |||
888 | ret = dvbt2_set_profile(tnr_dmd, tune_param->profile); | ||
889 | if (ret) | ||
890 | return ret; | ||
891 | |||
892 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
893 | ret = | ||
894 | dvbt2_set_profile(tnr_dmd->diver_sub, tune_param->profile); | ||
895 | if (ret) | ||
896 | return ret; | ||
897 | } | ||
898 | |||
899 | if (tune_param->data_plp_id == CXD2880_DVBT2_TUNE_PARAM_PLPID_AUTO) | ||
900 | ret = cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 1, 0); | ||
901 | else | ||
902 | ret = | ||
903 | cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 0, | ||
904 | (u8)(tune_param->data_plp_id)); | ||
905 | |||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | int cxd2880_tnrdmd_dvbt2_tune2(struct cxd2880_tnrdmd *tnr_dmd, | ||
910 | struct cxd2880_dvbt2_tune_param | ||
911 | *tune_param) | ||
912 | { | ||
913 | u8 en_fef_intmtnt_ctrl = 1; | ||
914 | int ret; | ||
915 | |||
916 | if (!tnr_dmd || !tune_param) | ||
917 | return -EINVAL; | ||
918 | |||
919 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
920 | return -EINVAL; | ||
921 | |||
922 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
923 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
924 | return -EINVAL; | ||
925 | |||
926 | switch (tune_param->profile) { | ||
927 | case CXD2880_DVBT2_PROFILE_BASE: | ||
928 | en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_base; | ||
929 | break; | ||
930 | case CXD2880_DVBT2_PROFILE_LITE: | ||
931 | en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_lite; | ||
932 | break; | ||
933 | case CXD2880_DVBT2_PROFILE_ANY: | ||
934 | if (tnr_dmd->en_fef_intmtnt_base && | ||
935 | tnr_dmd->en_fef_intmtnt_lite) | ||
936 | en_fef_intmtnt_ctrl = 1; | ||
937 | else | ||
938 | en_fef_intmtnt_ctrl = 0; | ||
939 | break; | ||
940 | default: | ||
941 | return -EINVAL; | ||
942 | } | ||
943 | |||
944 | ret = | ||
945 | cxd2880_tnrdmd_common_tune_setting2(tnr_dmd, | ||
946 | CXD2880_DTV_SYS_DVBT2, | ||
947 | en_fef_intmtnt_ctrl); | ||
948 | if (ret) | ||
949 | return ret; | ||
950 | |||
951 | tnr_dmd->state = CXD2880_TNRDMD_STATE_ACTIVE; | ||
952 | tnr_dmd->frequency_khz = tune_param->center_freq_khz; | ||
953 | tnr_dmd->sys = CXD2880_DTV_SYS_DVBT2; | ||
954 | tnr_dmd->bandwidth = tune_param->bandwidth; | ||
955 | |||
956 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
957 | tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_ACTIVE; | ||
958 | tnr_dmd->diver_sub->frequency_khz = tune_param->center_freq_khz; | ||
959 | tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_DVBT2; | ||
960 | tnr_dmd->diver_sub->bandwidth = tune_param->bandwidth; | ||
961 | } | ||
962 | |||
963 | return 0; | ||
964 | } | ||
965 | |||
966 | int cxd2880_tnrdmd_dvbt2_sleep_setting(struct cxd2880_tnrdmd | ||
967 | *tnr_dmd) | ||
968 | { | ||
969 | int ret; | ||
970 | |||
971 | if (!tnr_dmd) | ||
972 | return -EINVAL; | ||
973 | |||
974 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
975 | return -EINVAL; | ||
976 | |||
977 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
978 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
979 | return -EINVAL; | ||
980 | |||
981 | ret = x_sleep_dvbt2_demod_setting(tnr_dmd); | ||
982 | if (ret) | ||
983 | return ret; | ||
984 | |||
985 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
986 | ret = x_sleep_dvbt2_demod_setting(tnr_dmd->diver_sub); | ||
987 | |||
988 | return ret; | ||
989 | } | ||
990 | |||
991 | int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd | ||
992 | *tnr_dmd, | ||
993 | enum | ||
994 | cxd2880_tnrdmd_lock_result | ||
995 | *lock) | ||
996 | { | ||
997 | int ret; | ||
998 | |||
999 | u8 sync_stat = 0; | ||
1000 | u8 ts_lock = 0; | ||
1001 | u8 unlock_detected = 0; | ||
1002 | u8 unlock_detected_sub = 0; | ||
1003 | |||
1004 | if (!tnr_dmd || !lock) | ||
1005 | return -EINVAL; | ||
1006 | |||
1007 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1008 | return -EINVAL; | ||
1009 | |||
1010 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1011 | return -EINVAL; | ||
1012 | |||
1013 | ret = | ||
1014 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock, | ||
1015 | &unlock_detected); | ||
1016 | if (ret) | ||
1017 | return ret; | ||
1018 | |||
1019 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
1020 | if (sync_stat == 6) | ||
1021 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
1022 | else if (unlock_detected) | ||
1023 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
1024 | else | ||
1025 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
1026 | |||
1027 | return ret; | ||
1028 | } | ||
1029 | |||
1030 | if (sync_stat == 6) { | ||
1031 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
1032 | return ret; | ||
1033 | } | ||
1034 | |||
1035 | ret = | ||
1036 | cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat, | ||
1037 | &unlock_detected_sub); | ||
1038 | if (ret) | ||
1039 | return ret; | ||
1040 | |||
1041 | if (sync_stat == 6) | ||
1042 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
1043 | else if (unlock_detected && unlock_detected_sub) | ||
1044 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
1045 | else | ||
1046 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
1047 | |||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd | ||
1052 | *tnr_dmd, | ||
1053 | enum | ||
1054 | cxd2880_tnrdmd_lock_result | ||
1055 | *lock) | ||
1056 | { | ||
1057 | int ret; | ||
1058 | |||
1059 | u8 sync_stat = 0; | ||
1060 | u8 ts_lock = 0; | ||
1061 | u8 unlock_detected = 0; | ||
1062 | u8 unlock_detected_sub = 0; | ||
1063 | |||
1064 | if (!tnr_dmd || !lock) | ||
1065 | return -EINVAL; | ||
1066 | |||
1067 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1068 | return -EINVAL; | ||
1069 | |||
1070 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1071 | return -EINVAL; | ||
1072 | |||
1073 | ret = | ||
1074 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock, | ||
1075 | &unlock_detected); | ||
1076 | if (ret) | ||
1077 | return ret; | ||
1078 | |||
1079 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
1080 | if (ts_lock) | ||
1081 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
1082 | else if (unlock_detected) | ||
1083 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
1084 | else | ||
1085 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
1086 | |||
1087 | return ret; | ||
1088 | } | ||
1089 | |||
1090 | if (ts_lock) { | ||
1091 | *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; | ||
1092 | return ret; | ||
1093 | } else if (!unlock_detected) { | ||
1094 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
1095 | return ret; | ||
1096 | } | ||
1097 | |||
1098 | ret = | ||
1099 | cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat, | ||
1100 | &unlock_detected_sub); | ||
1101 | if (ret) | ||
1102 | return ret; | ||
1103 | |||
1104 | if (unlock_detected && unlock_detected_sub) | ||
1105 | *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; | ||
1106 | else | ||
1107 | *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; | ||
1108 | |||
1109 | return ret; | ||
1110 | } | ||
1111 | |||
1112 | int cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd | ||
1113 | *tnr_dmd, u8 auto_plp, | ||
1114 | u8 plp_id) | ||
1115 | { | ||
1116 | int ret; | ||
1117 | |||
1118 | if (!tnr_dmd) | ||
1119 | return -EINVAL; | ||
1120 | |||
1121 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1122 | return -EINVAL; | ||
1123 | |||
1124 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
1125 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1126 | return -EINVAL; | ||
1127 | |||
1128 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1129 | CXD2880_IO_TGT_DMD, | ||
1130 | 0x00, 0x23); | ||
1131 | if (ret) | ||
1132 | return ret; | ||
1133 | |||
1134 | if (!auto_plp) { | ||
1135 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1136 | CXD2880_IO_TGT_DMD, | ||
1137 | 0xaf, plp_id); | ||
1138 | if (ret) | ||
1139 | return ret; | ||
1140 | } | ||
1141 | |||
1142 | return tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1143 | CXD2880_IO_TGT_DMD, | ||
1144 | 0xad, auto_plp ? 0x00 : 0x01); | ||
1145 | } | ||
1146 | |||
1147 | int cxd2880_tnrdmd_dvbt2_diver_fef_setting(struct cxd2880_tnrdmd | ||
1148 | *tnr_dmd) | ||
1149 | { | ||
1150 | struct cxd2880_dvbt2_ofdm ofdm; | ||
1151 | static const u8 data[] = { 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 1, 0}; | ||
1152 | int ret; | ||
1153 | |||
1154 | if (!tnr_dmd) | ||
1155 | return -EINVAL; | ||
1156 | |||
1157 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1158 | return -EINVAL; | ||
1159 | |||
1160 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1161 | return -EINVAL; | ||
1162 | |||
1163 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) | ||
1164 | return 0; | ||
1165 | |||
1166 | ret = cxd2880_tnrdmd_dvbt2_mon_ofdm(tnr_dmd, &ofdm); | ||
1167 | if (ret) | ||
1168 | return ret; | ||
1169 | |||
1170 | if (!ofdm.mixed) | ||
1171 | return 0; | ||
1172 | |||
1173 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1174 | CXD2880_IO_TGT_DMD, | ||
1175 | 0x00, 0x1d); | ||
1176 | if (ret) | ||
1177 | return ret; | ||
1178 | |||
1179 | return tnr_dmd->io->write_regs(tnr_dmd->io, | ||
1180 | CXD2880_IO_TGT_DMD, | ||
1181 | 0x47, data, 12); | ||
1182 | } | ||
1183 | |||
1184 | int cxd2880_tnrdmd_dvbt2_check_l1post_valid(struct cxd2880_tnrdmd | ||
1185 | *tnr_dmd, | ||
1186 | u8 *l1_post_valid) | ||
1187 | { | ||
1188 | int ret; | ||
1189 | |||
1190 | u8 data; | ||
1191 | |||
1192 | if (!tnr_dmd || !l1_post_valid) | ||
1193 | return -EINVAL; | ||
1194 | |||
1195 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1196 | return -EINVAL; | ||
1197 | |||
1198 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
1199 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1200 | return -EINVAL; | ||
1201 | |||
1202 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1203 | CXD2880_IO_TGT_DMD, | ||
1204 | 0x00, 0x0b); | ||
1205 | if (ret) | ||
1206 | return ret; | ||
1207 | |||
1208 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1209 | CXD2880_IO_TGT_DMD, | ||
1210 | 0x86, &data, 1); | ||
1211 | if (ret) | ||
1212 | return ret; | ||
1213 | |||
1214 | *l1_post_valid = data & 0x01; | ||
1215 | |||
1216 | return ret; | ||
1217 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h new file mode 100644 index 000000000000..7108e3540093 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt2.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * control interface for DVB-T2 | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_TNRDMD_DVBT2_H | ||
11 | #define CXD2880_TNRDMD_DVBT2_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | #include "cxd2880_tnrdmd.h" | ||
15 | |||
16 | enum cxd2880_tnrdmd_dvbt2_tune_info { | ||
17 | CXD2880_TNRDMD_DVBT2_TUNE_INFO_OK, | ||
18 | CXD2880_TNRDMD_DVBT2_TUNE_INFO_INVALID_PLP_ID | ||
19 | }; | ||
20 | |||
21 | struct cxd2880_dvbt2_tune_param { | ||
22 | u32 center_freq_khz; | ||
23 | enum cxd2880_dtv_bandwidth bandwidth; | ||
24 | u16 data_plp_id; | ||
25 | enum cxd2880_dvbt2_profile profile; | ||
26 | enum cxd2880_tnrdmd_dvbt2_tune_info tune_info; | ||
27 | }; | ||
28 | |||
29 | #define CXD2880_DVBT2_TUNE_PARAM_PLPID_AUTO 0xffff | ||
30 | |||
31 | int cxd2880_tnrdmd_dvbt2_tune1(struct cxd2880_tnrdmd *tnr_dmd, | ||
32 | struct cxd2880_dvbt2_tune_param | ||
33 | *tune_param); | ||
34 | |||
35 | int cxd2880_tnrdmd_dvbt2_tune2(struct cxd2880_tnrdmd *tnr_dmd, | ||
36 | struct cxd2880_dvbt2_tune_param | ||
37 | *tune_param); | ||
38 | |||
39 | int cxd2880_tnrdmd_dvbt2_sleep_setting(struct cxd2880_tnrdmd | ||
40 | *tnr_dmd); | ||
41 | |||
42 | int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd | ||
43 | *tnr_dmd, | ||
44 | enum | ||
45 | cxd2880_tnrdmd_lock_result | ||
46 | *lock); | ||
47 | |||
48 | int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd | ||
49 | *tnr_dmd, | ||
50 | enum | ||
51 | cxd2880_tnrdmd_lock_result | ||
52 | *lock); | ||
53 | |||
54 | int cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd | ||
55 | *tnr_dmd, u8 auto_plp, | ||
56 | u8 plp_id); | ||
57 | |||
58 | int cxd2880_tnrdmd_dvbt2_diver_fef_setting(struct cxd2880_tnrdmd | ||
59 | *tnr_dmd); | ||
60 | |||
61 | int cxd2880_tnrdmd_dvbt2_check_l1post_valid(struct cxd2880_tnrdmd | ||
62 | *tnr_dmd, | ||
63 | u8 *l1_post_valid); | ||
64 | |||
65 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c new file mode 100644 index 000000000000..604580bf7cf7 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c | |||
@@ -0,0 +1,1878 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt2_mon.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DVB-T2 monitor functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include "cxd2880_tnrdmd_mon.h" | ||
11 | #include "cxd2880_tnrdmd_dvbt2.h" | ||
12 | #include "cxd2880_tnrdmd_dvbt2_mon.h" | ||
13 | |||
14 | #include <media/dvb_math.h> | ||
15 | |||
16 | static const int ref_dbm_1000[4][8] = { | ||
17 | {-96000, -95000, -94000, -93000, -92000, -92000, -98000, -97000}, | ||
18 | {-91000, -89000, -88000, -87000, -86000, -86000, -93000, -92000}, | ||
19 | {-86000, -85000, -83000, -82000, -81000, -80000, -89000, -88000}, | ||
20 | {-82000, -80000, -78000, -76000, -75000, -74000, -86000, -84000}, | ||
21 | }; | ||
22 | |||
23 | int cxd2880_tnrdmd_dvbt2_mon_sync_stat(struct cxd2880_tnrdmd | ||
24 | *tnr_dmd, u8 *sync_stat, | ||
25 | u8 *ts_lock_stat, | ||
26 | u8 *unlock_detected) | ||
27 | { | ||
28 | u8 data; | ||
29 | int ret; | ||
30 | |||
31 | if (!tnr_dmd || !sync_stat || !ts_lock_stat || !unlock_detected) | ||
32 | return -EINVAL; | ||
33 | |||
34 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
35 | return -EINVAL; | ||
36 | |||
37 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
38 | return -EINVAL; | ||
39 | |||
40 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
41 | CXD2880_IO_TGT_DMD, | ||
42 | 0x00, 0x0b); | ||
43 | if (ret) | ||
44 | return ret; | ||
45 | |||
46 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
47 | CXD2880_IO_TGT_DMD, | ||
48 | 0x10, &data, sizeof(data)); | ||
49 | if (ret) | ||
50 | return ret; | ||
51 | |||
52 | *sync_stat = data & 0x07; | ||
53 | *ts_lock_stat = ((data & 0x20) ? 1 : 0); | ||
54 | *unlock_detected = ((data & 0x10) ? 1 : 0); | ||
55 | |||
56 | if (*sync_stat == 0x07) | ||
57 | return -EAGAIN; | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | int cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(struct cxd2880_tnrdmd | ||
63 | *tnr_dmd, | ||
64 | u8 *sync_stat, | ||
65 | u8 *unlock_detected) | ||
66 | { | ||
67 | u8 ts_lock_stat = 0; | ||
68 | |||
69 | if (!tnr_dmd || !sync_stat || !unlock_detected) | ||
70 | return -EINVAL; | ||
71 | |||
72 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
73 | return -EINVAL; | ||
74 | |||
75 | return cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd->diver_sub, | ||
76 | sync_stat, | ||
77 | &ts_lock_stat, | ||
78 | unlock_detected); | ||
79 | } | ||
80 | |||
81 | int cxd2880_tnrdmd_dvbt2_mon_carrier_offset(struct cxd2880_tnrdmd | ||
82 | *tnr_dmd, int *offset) | ||
83 | { | ||
84 | u8 data[4]; | ||
85 | u32 ctl_val = 0; | ||
86 | u8 sync_state = 0; | ||
87 | u8 ts_lock = 0; | ||
88 | u8 unlock_detected = 0; | ||
89 | int ret; | ||
90 | |||
91 | if (!tnr_dmd || !offset) | ||
92 | return -EINVAL; | ||
93 | |||
94 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
95 | return -EINVAL; | ||
96 | |||
97 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
98 | return -EINVAL; | ||
99 | |||
100 | ret = slvt_freeze_reg(tnr_dmd); | ||
101 | if (ret) | ||
102 | return ret; | ||
103 | |||
104 | ret = | ||
105 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
106 | &ts_lock, | ||
107 | &unlock_detected); | ||
108 | if (ret) { | ||
109 | slvt_unfreeze_reg(tnr_dmd); | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | if (sync_state != 6) { | ||
114 | slvt_unfreeze_reg(tnr_dmd); | ||
115 | return -EAGAIN; | ||
116 | } | ||
117 | |||
118 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
119 | CXD2880_IO_TGT_DMD, | ||
120 | 0x00, 0x0b); | ||
121 | if (ret) { | ||
122 | slvt_unfreeze_reg(tnr_dmd); | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
127 | CXD2880_IO_TGT_DMD, | ||
128 | 0x30, data, sizeof(data)); | ||
129 | if (ret) { | ||
130 | slvt_unfreeze_reg(tnr_dmd); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | slvt_unfreeze_reg(tnr_dmd); | ||
135 | |||
136 | ctl_val = | ||
137 | ((data[0] & 0x0f) << 24) | (data[1] << 16) | (data[2] << 8) | ||
138 | | (data[3]); | ||
139 | *offset = cxd2880_convert2s_complement(ctl_val, 28); | ||
140 | |||
141 | switch (tnr_dmd->bandwidth) { | ||
142 | case CXD2880_DTV_BW_1_7_MHZ: | ||
143 | *offset = -1 * ((*offset) / 582); | ||
144 | break; | ||
145 | case CXD2880_DTV_BW_5_MHZ: | ||
146 | case CXD2880_DTV_BW_6_MHZ: | ||
147 | case CXD2880_DTV_BW_7_MHZ: | ||
148 | case CXD2880_DTV_BW_8_MHZ: | ||
149 | *offset = -1 * ((*offset) * tnr_dmd->bandwidth / 940); | ||
150 | break; | ||
151 | default: | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | int cxd2880_tnrdmd_dvbt2_mon_carrier_offset_sub(struct | ||
159 | cxd2880_tnrdmd | ||
160 | *tnr_dmd, | ||
161 | int *offset) | ||
162 | { | ||
163 | if (!tnr_dmd || !offset) | ||
164 | return -EINVAL; | ||
165 | |||
166 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
167 | return -EINVAL; | ||
168 | |||
169 | return cxd2880_tnrdmd_dvbt2_mon_carrier_offset(tnr_dmd->diver_sub, | ||
170 | offset); | ||
171 | } | ||
172 | |||
173 | int cxd2880_tnrdmd_dvbt2_mon_l1_pre(struct cxd2880_tnrdmd *tnr_dmd, | ||
174 | struct cxd2880_dvbt2_l1pre | ||
175 | *l1_pre) | ||
176 | { | ||
177 | u8 data[37]; | ||
178 | u8 sync_state = 0; | ||
179 | u8 ts_lock = 0; | ||
180 | u8 unlock_detected = 0; | ||
181 | u8 version = 0; | ||
182 | enum cxd2880_dvbt2_profile profile; | ||
183 | int ret; | ||
184 | |||
185 | if (!tnr_dmd || !l1_pre) | ||
186 | return -EINVAL; | ||
187 | |||
188 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
189 | return -EINVAL; | ||
190 | |||
191 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
192 | return -EINVAL; | ||
193 | |||
194 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
195 | return -EINVAL; | ||
196 | |||
197 | ret = slvt_freeze_reg(tnr_dmd); | ||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | ret = | ||
202 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
203 | &ts_lock, | ||
204 | &unlock_detected); | ||
205 | if (ret) { | ||
206 | slvt_unfreeze_reg(tnr_dmd); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | if (sync_state < 5) { | ||
211 | if (tnr_dmd->diver_mode == | ||
212 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
213 | ret = | ||
214 | cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub | ||
215 | (tnr_dmd, &sync_state, &unlock_detected); | ||
216 | if (ret) { | ||
217 | slvt_unfreeze_reg(tnr_dmd); | ||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | if (sync_state < 5) { | ||
222 | slvt_unfreeze_reg(tnr_dmd); | ||
223 | return -EAGAIN; | ||
224 | } | ||
225 | } else { | ||
226 | slvt_unfreeze_reg(tnr_dmd); | ||
227 | return -EAGAIN; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | ret = cxd2880_tnrdmd_dvbt2_mon_profile(tnr_dmd, &profile); | ||
232 | if (ret) { | ||
233 | slvt_unfreeze_reg(tnr_dmd); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
238 | CXD2880_IO_TGT_DMD, | ||
239 | 0x00, 0x0b); | ||
240 | if (ret) { | ||
241 | slvt_unfreeze_reg(tnr_dmd); | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
246 | CXD2880_IO_TGT_DMD, | ||
247 | 0x61, data, sizeof(data)); | ||
248 | if (ret) { | ||
249 | slvt_unfreeze_reg(tnr_dmd); | ||
250 | return ret; | ||
251 | } | ||
252 | slvt_unfreeze_reg(tnr_dmd); | ||
253 | |||
254 | l1_pre->type = (enum cxd2880_dvbt2_l1pre_type)data[0]; | ||
255 | l1_pre->bw_ext = data[1] & 0x01; | ||
256 | l1_pre->s1 = (enum cxd2880_dvbt2_s1)(data[2] & 0x07); | ||
257 | l1_pre->s2 = data[3] & 0x0f; | ||
258 | l1_pre->l1_rep = data[4] & 0x01; | ||
259 | l1_pre->gi = (enum cxd2880_dvbt2_guard)(data[5] & 0x07); | ||
260 | l1_pre->papr = (enum cxd2880_dvbt2_papr)(data[6] & 0x0f); | ||
261 | l1_pre->mod = | ||
262 | (enum cxd2880_dvbt2_l1post_constell)(data[7] & 0x0f); | ||
263 | l1_pre->cr = (enum cxd2880_dvbt2_l1post_cr)(data[8] & 0x03); | ||
264 | l1_pre->fec = | ||
265 | (enum cxd2880_dvbt2_l1post_fec_type)(data[9] & 0x03); | ||
266 | l1_pre->l1_post_size = (data[10] & 0x03) << 16; | ||
267 | l1_pre->l1_post_size |= (data[11]) << 8; | ||
268 | l1_pre->l1_post_size |= (data[12]); | ||
269 | l1_pre->l1_post_info_size = (data[13] & 0x03) << 16; | ||
270 | l1_pre->l1_post_info_size |= (data[14]) << 8; | ||
271 | l1_pre->l1_post_info_size |= (data[15]); | ||
272 | l1_pre->pp = (enum cxd2880_dvbt2_pp)(data[16] & 0x0f); | ||
273 | l1_pre->tx_id_availability = data[17]; | ||
274 | l1_pre->cell_id = (data[18] << 8); | ||
275 | l1_pre->cell_id |= (data[19]); | ||
276 | l1_pre->network_id = (data[20] << 8); | ||
277 | l1_pre->network_id |= (data[21]); | ||
278 | l1_pre->sys_id = (data[22] << 8); | ||
279 | l1_pre->sys_id |= (data[23]); | ||
280 | l1_pre->num_frames = data[24]; | ||
281 | l1_pre->num_symbols = (data[25] & 0x0f) << 8; | ||
282 | l1_pre->num_symbols |= data[26]; | ||
283 | l1_pre->regen = data[27] & 0x07; | ||
284 | l1_pre->post_ext = data[28] & 0x01; | ||
285 | l1_pre->num_rf_freqs = data[29] & 0x07; | ||
286 | l1_pre->rf_idx = data[30] & 0x07; | ||
287 | version = (data[31] & 0x03) << 2; | ||
288 | version |= (data[32] & 0xc0) >> 6; | ||
289 | l1_pre->t2_version = (enum cxd2880_dvbt2_version)version; | ||
290 | l1_pre->l1_post_scrambled = (data[32] & 0x20) >> 5; | ||
291 | l1_pre->t2_base_lite = (data[32] & 0x10) >> 4; | ||
292 | l1_pre->crc32 = (data[33] << 24); | ||
293 | l1_pre->crc32 |= (data[34] << 16); | ||
294 | l1_pre->crc32 |= (data[35] << 8); | ||
295 | l1_pre->crc32 |= data[36]; | ||
296 | |||
297 | if (profile == CXD2880_DVBT2_PROFILE_BASE) { | ||
298 | switch ((l1_pre->s2 >> 1)) { | ||
299 | case CXD2880_DVBT2_BASE_S2_M1K_G_ANY: | ||
300 | l1_pre->fft_mode = CXD2880_DVBT2_M1K; | ||
301 | break; | ||
302 | case CXD2880_DVBT2_BASE_S2_M2K_G_ANY: | ||
303 | l1_pre->fft_mode = CXD2880_DVBT2_M2K; | ||
304 | break; | ||
305 | case CXD2880_DVBT2_BASE_S2_M4K_G_ANY: | ||
306 | l1_pre->fft_mode = CXD2880_DVBT2_M4K; | ||
307 | break; | ||
308 | case CXD2880_DVBT2_BASE_S2_M8K_G_DVBT: | ||
309 | case CXD2880_DVBT2_BASE_S2_M8K_G_DVBT2: | ||
310 | l1_pre->fft_mode = CXD2880_DVBT2_M8K; | ||
311 | break; | ||
312 | case CXD2880_DVBT2_BASE_S2_M16K_G_ANY: | ||
313 | l1_pre->fft_mode = CXD2880_DVBT2_M16K; | ||
314 | break; | ||
315 | case CXD2880_DVBT2_BASE_S2_M32K_G_DVBT: | ||
316 | case CXD2880_DVBT2_BASE_S2_M32K_G_DVBT2: | ||
317 | l1_pre->fft_mode = CXD2880_DVBT2_M32K; | ||
318 | break; | ||
319 | default: | ||
320 | return -EAGAIN; | ||
321 | } | ||
322 | } else if (profile == CXD2880_DVBT2_PROFILE_LITE) { | ||
323 | switch ((l1_pre->s2 >> 1)) { | ||
324 | case CXD2880_DVBT2_LITE_S2_M2K_G_ANY: | ||
325 | l1_pre->fft_mode = CXD2880_DVBT2_M2K; | ||
326 | break; | ||
327 | case CXD2880_DVBT2_LITE_S2_M4K_G_ANY: | ||
328 | l1_pre->fft_mode = CXD2880_DVBT2_M4K; | ||
329 | break; | ||
330 | case CXD2880_DVBT2_LITE_S2_M8K_G_DVBT: | ||
331 | case CXD2880_DVBT2_LITE_S2_M8K_G_DVBT2: | ||
332 | l1_pre->fft_mode = CXD2880_DVBT2_M8K; | ||
333 | break; | ||
334 | case CXD2880_DVBT2_LITE_S2_M16K_G_DVBT: | ||
335 | case CXD2880_DVBT2_LITE_S2_M16K_G_DVBT2: | ||
336 | l1_pre->fft_mode = CXD2880_DVBT2_M16K; | ||
337 | break; | ||
338 | default: | ||
339 | return -EAGAIN; | ||
340 | } | ||
341 | } else { | ||
342 | return -EAGAIN; | ||
343 | } | ||
344 | |||
345 | l1_pre->mixed = l1_pre->s2 & 0x01; | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | int cxd2880_tnrdmd_dvbt2_mon_version(struct cxd2880_tnrdmd | ||
351 | *tnr_dmd, | ||
352 | enum cxd2880_dvbt2_version | ||
353 | *ver) | ||
354 | { | ||
355 | u8 data[2]; | ||
356 | u8 sync_state = 0; | ||
357 | u8 ts_lock = 0; | ||
358 | u8 unlock_detected = 0; | ||
359 | u8 version = 0; | ||
360 | int ret; | ||
361 | |||
362 | if (!tnr_dmd || !ver) | ||
363 | return -EINVAL; | ||
364 | |||
365 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
366 | return -EINVAL; | ||
367 | |||
368 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
369 | return -EINVAL; | ||
370 | |||
371 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
372 | return -EINVAL; | ||
373 | |||
374 | ret = slvt_freeze_reg(tnr_dmd); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
378 | ret = | ||
379 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
380 | &ts_lock, | ||
381 | &unlock_detected); | ||
382 | if (ret) { | ||
383 | slvt_unfreeze_reg(tnr_dmd); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | if (sync_state < 5) { | ||
388 | if (tnr_dmd->diver_mode == | ||
389 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
390 | ret = | ||
391 | cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub | ||
392 | (tnr_dmd, &sync_state, &unlock_detected); | ||
393 | if (ret) { | ||
394 | slvt_unfreeze_reg(tnr_dmd); | ||
395 | return ret; | ||
396 | } | ||
397 | |||
398 | if (sync_state < 5) { | ||
399 | slvt_unfreeze_reg(tnr_dmd); | ||
400 | return -EAGAIN; | ||
401 | } | ||
402 | } else { | ||
403 | slvt_unfreeze_reg(tnr_dmd); | ||
404 | return -EAGAIN; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
409 | CXD2880_IO_TGT_DMD, | ||
410 | 0x00, 0x0b); | ||
411 | if (ret) { | ||
412 | slvt_unfreeze_reg(tnr_dmd); | ||
413 | return ret; | ||
414 | } | ||
415 | |||
416 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
417 | CXD2880_IO_TGT_DMD, | ||
418 | 0x80, data, sizeof(data)); | ||
419 | if (ret) { | ||
420 | slvt_unfreeze_reg(tnr_dmd); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | slvt_unfreeze_reg(tnr_dmd); | ||
425 | |||
426 | version = ((data[0] & 0x03) << 2); | ||
427 | version |= ((data[1] & 0xc0) >> 6); | ||
428 | *ver = (enum cxd2880_dvbt2_version)version; | ||
429 | |||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | int cxd2880_tnrdmd_dvbt2_mon_ofdm(struct cxd2880_tnrdmd *tnr_dmd, | ||
434 | struct cxd2880_dvbt2_ofdm *ofdm) | ||
435 | { | ||
436 | u8 data[5]; | ||
437 | u8 sync_state = 0; | ||
438 | u8 ts_lock = 0; | ||
439 | u8 unlock_detected = 0; | ||
440 | int ret; | ||
441 | |||
442 | if (!tnr_dmd || !ofdm) | ||
443 | return -EINVAL; | ||
444 | |||
445 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
446 | return -EINVAL; | ||
447 | |||
448 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
449 | return -EINVAL; | ||
450 | |||
451 | ret = slvt_freeze_reg(tnr_dmd); | ||
452 | if (ret) | ||
453 | return ret; | ||
454 | |||
455 | ret = | ||
456 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
457 | &ts_lock, | ||
458 | &unlock_detected); | ||
459 | if (ret) { | ||
460 | slvt_unfreeze_reg(tnr_dmd); | ||
461 | return ret; | ||
462 | } | ||
463 | |||
464 | if (sync_state != 6) { | ||
465 | slvt_unfreeze_reg(tnr_dmd); | ||
466 | |||
467 | ret = -EAGAIN; | ||
468 | |||
469 | if (tnr_dmd->diver_mode == | ||
470 | CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
471 | ret = | ||
472 | cxd2880_tnrdmd_dvbt2_mon_ofdm(tnr_dmd->diver_sub, | ||
473 | ofdm); | ||
474 | |||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
479 | CXD2880_IO_TGT_DMD, | ||
480 | 0x00, 0x0b); | ||
481 | if (ret) { | ||
482 | slvt_unfreeze_reg(tnr_dmd); | ||
483 | return ret; | ||
484 | } | ||
485 | |||
486 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
487 | CXD2880_IO_TGT_DMD, | ||
488 | 0x1d, data, sizeof(data)); | ||
489 | if (ret) { | ||
490 | slvt_unfreeze_reg(tnr_dmd); | ||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | slvt_unfreeze_reg(tnr_dmd); | ||
495 | |||
496 | ofdm->mixed = ((data[0] & 0x20) ? 1 : 0); | ||
497 | ofdm->is_miso = ((data[0] & 0x10) >> 4); | ||
498 | ofdm->mode = (enum cxd2880_dvbt2_mode)(data[0] & 0x07); | ||
499 | ofdm->gi = (enum cxd2880_dvbt2_guard)((data[1] & 0x70) >> 4); | ||
500 | ofdm->pp = (enum cxd2880_dvbt2_pp)(data[1] & 0x07); | ||
501 | ofdm->bw_ext = (data[2] & 0x10) >> 4; | ||
502 | ofdm->papr = (enum cxd2880_dvbt2_papr)(data[2] & 0x0f); | ||
503 | ofdm->num_symbols = (data[3] << 8) | data[4]; | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | int cxd2880_tnrdmd_dvbt2_mon_data_plps(struct cxd2880_tnrdmd | ||
509 | *tnr_dmd, u8 *plp_ids, | ||
510 | u8 *num_plps) | ||
511 | { | ||
512 | u8 l1_post_ok = 0; | ||
513 | int ret; | ||
514 | |||
515 | if (!tnr_dmd || !num_plps) | ||
516 | return -EINVAL; | ||
517 | |||
518 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
519 | return -EINVAL; | ||
520 | |||
521 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
522 | return -EINVAL; | ||
523 | |||
524 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
525 | return -EINVAL; | ||
526 | |||
527 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
528 | CXD2880_IO_TGT_DMD, | ||
529 | 0x00, 0x0b); | ||
530 | if (ret) | ||
531 | return ret; | ||
532 | |||
533 | ret = slvt_freeze_reg(tnr_dmd); | ||
534 | if (ret) | ||
535 | return ret; | ||
536 | |||
537 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
538 | CXD2880_IO_TGT_DMD, | ||
539 | 0x86, &l1_post_ok, 1); | ||
540 | if (ret) { | ||
541 | slvt_unfreeze_reg(tnr_dmd); | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | if (!(l1_post_ok & 0x01)) { | ||
546 | slvt_unfreeze_reg(tnr_dmd); | ||
547 | return -EAGAIN; | ||
548 | } | ||
549 | |||
550 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
551 | CXD2880_IO_TGT_DMD, | ||
552 | 0xc1, num_plps, 1); | ||
553 | if (ret) { | ||
554 | slvt_unfreeze_reg(tnr_dmd); | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | if (*num_plps == 0) { | ||
559 | slvt_unfreeze_reg(tnr_dmd); | ||
560 | return -EINVAL; | ||
561 | } | ||
562 | |||
563 | if (!plp_ids) { | ||
564 | slvt_unfreeze_reg(tnr_dmd); | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
569 | CXD2880_IO_TGT_DMD, | ||
570 | 0xc2, | ||
571 | plp_ids, | ||
572 | ((*num_plps > 62) ? | ||
573 | 62 : *num_plps)); | ||
574 | if (ret) { | ||
575 | slvt_unfreeze_reg(tnr_dmd); | ||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | if (*num_plps > 62) { | ||
580 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
581 | CXD2880_IO_TGT_DMD, | ||
582 | 0x00, 0x0c); | ||
583 | if (ret) { | ||
584 | slvt_unfreeze_reg(tnr_dmd); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
589 | CXD2880_IO_TGT_DMD, | ||
590 | 0x10, plp_ids + 62, | ||
591 | *num_plps - 62); | ||
592 | if (ret) { | ||
593 | slvt_unfreeze_reg(tnr_dmd); | ||
594 | return ret; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | slvt_unfreeze_reg(tnr_dmd); | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | int cxd2880_tnrdmd_dvbt2_mon_active_plp(struct cxd2880_tnrdmd | ||
604 | *tnr_dmd, | ||
605 | enum | ||
606 | cxd2880_dvbt2_plp_btype | ||
607 | type, | ||
608 | struct cxd2880_dvbt2_plp | ||
609 | *plp_info) | ||
610 | { | ||
611 | u8 data[20]; | ||
612 | u8 addr = 0; | ||
613 | u8 index = 0; | ||
614 | u8 l1_post_ok = 0; | ||
615 | int ret; | ||
616 | |||
617 | if (!tnr_dmd || !plp_info) | ||
618 | return -EINVAL; | ||
619 | |||
620 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
621 | return -EINVAL; | ||
622 | |||
623 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
624 | return -EINVAL; | ||
625 | |||
626 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
627 | return -EINVAL; | ||
628 | |||
629 | ret = slvt_freeze_reg(tnr_dmd); | ||
630 | if (ret) | ||
631 | return ret; | ||
632 | |||
633 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
634 | CXD2880_IO_TGT_DMD, | ||
635 | 0x00, 0x0b); | ||
636 | if (ret) { | ||
637 | slvt_unfreeze_reg(tnr_dmd); | ||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
642 | CXD2880_IO_TGT_DMD, | ||
643 | 0x86, &l1_post_ok, 1); | ||
644 | if (ret) { | ||
645 | slvt_unfreeze_reg(tnr_dmd); | ||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | if (!l1_post_ok) { | ||
650 | slvt_unfreeze_reg(tnr_dmd); | ||
651 | return -EAGAIN; | ||
652 | } | ||
653 | |||
654 | if (type == CXD2880_DVBT2_PLP_COMMON) | ||
655 | addr = 0xa9; | ||
656 | else | ||
657 | addr = 0x96; | ||
658 | |||
659 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
660 | CXD2880_IO_TGT_DMD, | ||
661 | addr, data, sizeof(data)); | ||
662 | if (ret) { | ||
663 | slvt_unfreeze_reg(tnr_dmd); | ||
664 | return ret; | ||
665 | } | ||
666 | |||
667 | slvt_unfreeze_reg(tnr_dmd); | ||
668 | |||
669 | if (type == CXD2880_DVBT2_PLP_COMMON && !data[13]) | ||
670 | return -EAGAIN; | ||
671 | |||
672 | plp_info->id = data[index++]; | ||
673 | plp_info->type = | ||
674 | (enum cxd2880_dvbt2_plp_type)(data[index++] & 0x07); | ||
675 | plp_info->payload = | ||
676 | (enum cxd2880_dvbt2_plp_payload)(data[index++] & 0x1f); | ||
677 | plp_info->ff = data[index++] & 0x01; | ||
678 | plp_info->first_rf_idx = data[index++] & 0x07; | ||
679 | plp_info->first_frm_idx = data[index++]; | ||
680 | plp_info->group_id = data[index++]; | ||
681 | plp_info->plp_cr = | ||
682 | (enum cxd2880_dvbt2_plp_code_rate)(data[index++] & 0x07); | ||
683 | plp_info->constell = | ||
684 | (enum cxd2880_dvbt2_plp_constell)(data[index++] & 0x07); | ||
685 | plp_info->rot = data[index++] & 0x01; | ||
686 | plp_info->fec = | ||
687 | (enum cxd2880_dvbt2_plp_fec)(data[index++] & 0x03); | ||
688 | plp_info->num_blocks_max = (data[index++] & 0x03) << 8; | ||
689 | plp_info->num_blocks_max |= data[index++]; | ||
690 | plp_info->frm_int = data[index++]; | ||
691 | plp_info->til_len = data[index++]; | ||
692 | plp_info->til_type = data[index++] & 0x01; | ||
693 | |||
694 | plp_info->in_band_a_flag = data[index++] & 0x01; | ||
695 | plp_info->rsvd = data[index++] << 8; | ||
696 | plp_info->rsvd |= data[index++]; | ||
697 | |||
698 | plp_info->in_band_b_flag = | ||
699 | (plp_info->rsvd & 0x8000) >> 15; | ||
700 | plp_info->plp_mode = | ||
701 | (enum cxd2880_dvbt2_plp_mode)((plp_info->rsvd & 0x000c) >> 2); | ||
702 | plp_info->static_flag = (plp_info->rsvd & 0x0002) >> 1; | ||
703 | plp_info->static_padding_flag = plp_info->rsvd & 0x0001; | ||
704 | plp_info->rsvd = (plp_info->rsvd & 0x7ff0) >> 4; | ||
705 | |||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | int cxd2880_tnrdmd_dvbt2_mon_data_plp_error(struct cxd2880_tnrdmd | ||
710 | *tnr_dmd, | ||
711 | u8 *plp_error) | ||
712 | { | ||
713 | u8 data; | ||
714 | int ret; | ||
715 | |||
716 | if (!tnr_dmd || !plp_error) | ||
717 | return -EINVAL; | ||
718 | |||
719 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
720 | return -EINVAL; | ||
721 | |||
722 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
723 | return -EINVAL; | ||
724 | |||
725 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
726 | return -EINVAL; | ||
727 | |||
728 | ret = slvt_freeze_reg(tnr_dmd); | ||
729 | if (ret) | ||
730 | return ret; | ||
731 | |||
732 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
733 | CXD2880_IO_TGT_DMD, | ||
734 | 0x00, 0x0b); | ||
735 | if (ret) { | ||
736 | slvt_unfreeze_reg(tnr_dmd); | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
741 | CXD2880_IO_TGT_DMD, | ||
742 | 0x86, &data, 1); | ||
743 | if (ret) { | ||
744 | slvt_unfreeze_reg(tnr_dmd); | ||
745 | return ret; | ||
746 | } | ||
747 | |||
748 | if ((data & 0x01) == 0x00) { | ||
749 | slvt_unfreeze_reg(tnr_dmd); | ||
750 | return -EAGAIN; | ||
751 | } | ||
752 | |||
753 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
754 | CXD2880_IO_TGT_DMD, | ||
755 | 0xc0, &data, 1); | ||
756 | if (ret) { | ||
757 | slvt_unfreeze_reg(tnr_dmd); | ||
758 | return ret; | ||
759 | } | ||
760 | |||
761 | slvt_unfreeze_reg(tnr_dmd); | ||
762 | |||
763 | *plp_error = data & 0x01; | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | int cxd2880_tnrdmd_dvbt2_mon_l1_change(struct cxd2880_tnrdmd | ||
769 | *tnr_dmd, u8 *l1_change) | ||
770 | { | ||
771 | u8 data; | ||
772 | u8 sync_state = 0; | ||
773 | u8 ts_lock = 0; | ||
774 | u8 unlock_detected = 0; | ||
775 | int ret; | ||
776 | |||
777 | if (!tnr_dmd || !l1_change) | ||
778 | return -EINVAL; | ||
779 | |||
780 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
781 | return -EINVAL; | ||
782 | |||
783 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
784 | return -EINVAL; | ||
785 | |||
786 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
787 | return -EINVAL; | ||
788 | |||
789 | ret = slvt_freeze_reg(tnr_dmd); | ||
790 | if (ret) | ||
791 | return ret; | ||
792 | |||
793 | ret = | ||
794 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
795 | &ts_lock, | ||
796 | &unlock_detected); | ||
797 | if (ret) { | ||
798 | slvt_unfreeze_reg(tnr_dmd); | ||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | if (sync_state < 5) { | ||
803 | if (tnr_dmd->diver_mode == | ||
804 | CXD2880_TNRDMD_DIVERMODE_MAIN) { | ||
805 | ret = | ||
806 | cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub | ||
807 | (tnr_dmd, &sync_state, &unlock_detected); | ||
808 | if (ret) { | ||
809 | slvt_unfreeze_reg(tnr_dmd); | ||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | if (sync_state < 5) { | ||
814 | slvt_unfreeze_reg(tnr_dmd); | ||
815 | return -EAGAIN; | ||
816 | } | ||
817 | } else { | ||
818 | slvt_unfreeze_reg(tnr_dmd); | ||
819 | return -EAGAIN; | ||
820 | } | ||
821 | } | ||
822 | |||
823 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
824 | CXD2880_IO_TGT_DMD, | ||
825 | 0x00, 0x0b); | ||
826 | if (ret) { | ||
827 | slvt_unfreeze_reg(tnr_dmd); | ||
828 | return ret; | ||
829 | } | ||
830 | |||
831 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
832 | CXD2880_IO_TGT_DMD, | ||
833 | 0x5f, &data, sizeof(data)); | ||
834 | if (ret) { | ||
835 | slvt_unfreeze_reg(tnr_dmd); | ||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | *l1_change = data & 0x01; | ||
840 | if (*l1_change) { | ||
841 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
842 | CXD2880_IO_TGT_DMD, | ||
843 | 0x00, 0x22); | ||
844 | if (ret) { | ||
845 | slvt_unfreeze_reg(tnr_dmd); | ||
846 | return ret; | ||
847 | } | ||
848 | |||
849 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
850 | CXD2880_IO_TGT_DMD, | ||
851 | 0x16, 0x01); | ||
852 | if (ret) { | ||
853 | slvt_unfreeze_reg(tnr_dmd); | ||
854 | return ret; | ||
855 | } | ||
856 | } | ||
857 | slvt_unfreeze_reg(tnr_dmd); | ||
858 | |||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | int cxd2880_tnrdmd_dvbt2_mon_l1_post(struct cxd2880_tnrdmd | ||
863 | *tnr_dmd, | ||
864 | struct cxd2880_dvbt2_l1post | ||
865 | *l1_post) | ||
866 | { | ||
867 | u8 data[16]; | ||
868 | int ret; | ||
869 | |||
870 | if (!tnr_dmd || !l1_post) | ||
871 | return -EINVAL; | ||
872 | |||
873 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
874 | return -EINVAL; | ||
875 | |||
876 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
877 | return -EINVAL; | ||
878 | |||
879 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
880 | return -EINVAL; | ||
881 | |||
882 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
883 | CXD2880_IO_TGT_DMD, | ||
884 | 0x00, 0x0b); | ||
885 | if (ret) | ||
886 | return ret; | ||
887 | |||
888 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
889 | CXD2880_IO_TGT_DMD, | ||
890 | 0x86, data, sizeof(data)); | ||
891 | if (ret) | ||
892 | return ret; | ||
893 | |||
894 | if (!(data[0] & 0x01)) | ||
895 | return -EAGAIN; | ||
896 | |||
897 | l1_post->sub_slices_per_frame = (data[1] & 0x7f) << 8; | ||
898 | l1_post->sub_slices_per_frame |= data[2]; | ||
899 | l1_post->num_plps = data[3]; | ||
900 | l1_post->num_aux = data[4] & 0x0f; | ||
901 | l1_post->aux_cfg_rfu = data[5]; | ||
902 | l1_post->rf_idx = data[6] & 0x07; | ||
903 | l1_post->freq = data[7] << 24; | ||
904 | l1_post->freq |= data[8] << 16; | ||
905 | l1_post->freq |= data[9] << 8; | ||
906 | l1_post->freq |= data[10]; | ||
907 | l1_post->fef_type = data[11] & 0x0f; | ||
908 | l1_post->fef_length = data[12] << 16; | ||
909 | l1_post->fef_length |= data[13] << 8; | ||
910 | l1_post->fef_length |= data[14]; | ||
911 | l1_post->fef_intvl = data[15]; | ||
912 | |||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | int cxd2880_tnrdmd_dvbt2_mon_bbheader(struct cxd2880_tnrdmd | ||
917 | *tnr_dmd, | ||
918 | enum cxd2880_dvbt2_plp_btype | ||
919 | type, | ||
920 | struct cxd2880_dvbt2_bbheader | ||
921 | *bbheader) | ||
922 | { | ||
923 | u8 sync_state = 0; | ||
924 | u8 ts_lock = 0; | ||
925 | u8 unlock_detected = 0; | ||
926 | u8 data[14]; | ||
927 | u8 addr = 0; | ||
928 | int ret; | ||
929 | |||
930 | if (!tnr_dmd || !bbheader) | ||
931 | return -EINVAL; | ||
932 | |||
933 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
934 | return -EINVAL; | ||
935 | |||
936 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
937 | return -EINVAL; | ||
938 | |||
939 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
940 | return -EINVAL; | ||
941 | |||
942 | ret = slvt_freeze_reg(tnr_dmd); | ||
943 | if (ret) | ||
944 | return ret; | ||
945 | |||
946 | ret = | ||
947 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
948 | &ts_lock, | ||
949 | &unlock_detected); | ||
950 | if (ret) { | ||
951 | slvt_unfreeze_reg(tnr_dmd); | ||
952 | return ret; | ||
953 | } | ||
954 | |||
955 | if (!ts_lock) { | ||
956 | slvt_unfreeze_reg(tnr_dmd); | ||
957 | return -EAGAIN; | ||
958 | } | ||
959 | |||
960 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
961 | CXD2880_IO_TGT_DMD, | ||
962 | 0x00, 0x0b); | ||
963 | if (ret) { | ||
964 | slvt_unfreeze_reg(tnr_dmd); | ||
965 | return ret; | ||
966 | } | ||
967 | |||
968 | if (type == CXD2880_DVBT2_PLP_COMMON) { | ||
969 | u8 l1_post_ok; | ||
970 | u8 data; | ||
971 | |||
972 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
973 | CXD2880_IO_TGT_DMD, | ||
974 | 0x86, &l1_post_ok, 1); | ||
975 | if (ret) { | ||
976 | slvt_unfreeze_reg(tnr_dmd); | ||
977 | return ret; | ||
978 | } | ||
979 | |||
980 | if (!(l1_post_ok & 0x01)) { | ||
981 | slvt_unfreeze_reg(tnr_dmd); | ||
982 | return -EAGAIN; | ||
983 | } | ||
984 | |||
985 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
986 | CXD2880_IO_TGT_DMD, | ||
987 | 0xb6, &data, 1); | ||
988 | if (ret) { | ||
989 | slvt_unfreeze_reg(tnr_dmd); | ||
990 | return ret; | ||
991 | } | ||
992 | |||
993 | if (data == 0) { | ||
994 | slvt_unfreeze_reg(tnr_dmd); | ||
995 | return -EAGAIN; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | if (type == CXD2880_DVBT2_PLP_COMMON) | ||
1000 | addr = 0x51; | ||
1001 | else | ||
1002 | addr = 0x42; | ||
1003 | |||
1004 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1005 | CXD2880_IO_TGT_DMD, | ||
1006 | addr, data, sizeof(data)); | ||
1007 | if (ret) { | ||
1008 | slvt_unfreeze_reg(tnr_dmd); | ||
1009 | return ret; | ||
1010 | } | ||
1011 | |||
1012 | slvt_unfreeze_reg(tnr_dmd); | ||
1013 | |||
1014 | bbheader->stream_input = | ||
1015 | (enum cxd2880_dvbt2_stream)((data[0] >> 6) & 0x03); | ||
1016 | bbheader->is_single_input_stream = (data[0] >> 5) & 0x01; | ||
1017 | bbheader->is_constant_coding_modulation = | ||
1018 | (data[0] >> 4) & 0x01; | ||
1019 | bbheader->issy_indicator = (data[0] >> 3) & 0x01; | ||
1020 | bbheader->null_packet_deletion = (data[0] >> 2) & 0x01; | ||
1021 | bbheader->ext = data[0] & 0x03; | ||
1022 | |||
1023 | bbheader->input_stream_identifier = data[1]; | ||
1024 | bbheader->plp_mode = | ||
1025 | (data[3] & 0x01) ? CXD2880_DVBT2_PLP_MODE_HEM : | ||
1026 | CXD2880_DVBT2_PLP_MODE_NM; | ||
1027 | bbheader->data_field_length = (data[4] << 8) | data[5]; | ||
1028 | |||
1029 | if (bbheader->plp_mode == CXD2880_DVBT2_PLP_MODE_NM) { | ||
1030 | bbheader->user_packet_length = | ||
1031 | (data[6] << 8) | data[7]; | ||
1032 | bbheader->sync_byte = data[8]; | ||
1033 | bbheader->issy = 0; | ||
1034 | } else { | ||
1035 | bbheader->user_packet_length = 0; | ||
1036 | bbheader->sync_byte = 0; | ||
1037 | bbheader->issy = | ||
1038 | (data[11] << 16) | (data[12] << 8) | data[13]; | ||
1039 | } | ||
1040 | |||
1041 | return 0; | ||
1042 | } | ||
1043 | |||
1044 | int cxd2880_tnrdmd_dvbt2_mon_in_bandb_ts_rate(struct cxd2880_tnrdmd | ||
1045 | *tnr_dmd, | ||
1046 | enum | ||
1047 | cxd2880_dvbt2_plp_btype | ||
1048 | type, | ||
1049 | u32 *ts_rate_bps) | ||
1050 | { | ||
1051 | u8 sync_state = 0; | ||
1052 | u8 ts_lock = 0; | ||
1053 | u8 unlock_detected = 0; | ||
1054 | u8 l1_post_ok = 0; | ||
1055 | u8 data[4]; | ||
1056 | u8 addr = 0; | ||
1057 | |||
1058 | int ret; | ||
1059 | |||
1060 | if (!tnr_dmd || !ts_rate_bps) | ||
1061 | return -EINVAL; | ||
1062 | |||
1063 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1064 | return -EINVAL; | ||
1065 | |||
1066 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1067 | return -EINVAL; | ||
1068 | |||
1069 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1070 | return -EINVAL; | ||
1071 | |||
1072 | ret = slvt_freeze_reg(tnr_dmd); | ||
1073 | if (ret) | ||
1074 | return ret; | ||
1075 | |||
1076 | ret = | ||
1077 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
1078 | &ts_lock, | ||
1079 | &unlock_detected); | ||
1080 | if (ret) { | ||
1081 | slvt_unfreeze_reg(tnr_dmd); | ||
1082 | return ret; | ||
1083 | } | ||
1084 | |||
1085 | if (!ts_lock) { | ||
1086 | slvt_unfreeze_reg(tnr_dmd); | ||
1087 | return -EAGAIN; | ||
1088 | } | ||
1089 | |||
1090 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1091 | CXD2880_IO_TGT_DMD, | ||
1092 | 0x00, 0x0b); | ||
1093 | if (ret) { | ||
1094 | slvt_unfreeze_reg(tnr_dmd); | ||
1095 | return ret; | ||
1096 | } | ||
1097 | |||
1098 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1099 | CXD2880_IO_TGT_DMD, | ||
1100 | 0x86, &l1_post_ok, 1); | ||
1101 | if (ret) { | ||
1102 | slvt_unfreeze_reg(tnr_dmd); | ||
1103 | return ret; | ||
1104 | } | ||
1105 | |||
1106 | if (!(l1_post_ok & 0x01)) { | ||
1107 | slvt_unfreeze_reg(tnr_dmd); | ||
1108 | return -EAGAIN; | ||
1109 | } | ||
1110 | |||
1111 | if (type == CXD2880_DVBT2_PLP_COMMON) | ||
1112 | addr = 0xba; | ||
1113 | else | ||
1114 | addr = 0xa7; | ||
1115 | |||
1116 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1117 | CXD2880_IO_TGT_DMD, | ||
1118 | addr, &data[0], 1); | ||
1119 | if (ret) { | ||
1120 | slvt_unfreeze_reg(tnr_dmd); | ||
1121 | return ret; | ||
1122 | } | ||
1123 | |||
1124 | if ((data[0] & 0x80) == 0x00) { | ||
1125 | slvt_unfreeze_reg(tnr_dmd); | ||
1126 | return -EAGAIN; | ||
1127 | } | ||
1128 | |||
1129 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1130 | CXD2880_IO_TGT_DMD, | ||
1131 | 0x00, 0x25); | ||
1132 | if (ret) { | ||
1133 | slvt_unfreeze_reg(tnr_dmd); | ||
1134 | return ret; | ||
1135 | } | ||
1136 | |||
1137 | if (type == CXD2880_DVBT2_PLP_COMMON) | ||
1138 | addr = 0xa6; | ||
1139 | else | ||
1140 | addr = 0xaa; | ||
1141 | |||
1142 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1143 | CXD2880_IO_TGT_DMD, | ||
1144 | addr, &data[0], 4); | ||
1145 | if (ret) { | ||
1146 | slvt_unfreeze_reg(tnr_dmd); | ||
1147 | return ret; | ||
1148 | } | ||
1149 | |||
1150 | *ts_rate_bps = ((data[0] & 0x07) << 24) | (data[1] << 16) | | ||
1151 | (data[2] << 8) | data[3]; | ||
1152 | |||
1153 | return 0; | ||
1154 | } | ||
1155 | |||
1156 | int cxd2880_tnrdmd_dvbt2_mon_spectrum_sense(struct cxd2880_tnrdmd | ||
1157 | *tnr_dmd, | ||
1158 | enum | ||
1159 | cxd2880_tnrdmd_spectrum_sense | ||
1160 | *sense) | ||
1161 | { | ||
1162 | u8 sync_state = 0; | ||
1163 | u8 ts_lock = 0; | ||
1164 | u8 early_unlock = 0; | ||
1165 | u8 data = 0; | ||
1166 | int ret; | ||
1167 | |||
1168 | if (!tnr_dmd || !sense) | ||
1169 | return -EINVAL; | ||
1170 | |||
1171 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1172 | return -EINVAL; | ||
1173 | |||
1174 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1175 | return -EINVAL; | ||
1176 | |||
1177 | ret = slvt_freeze_reg(tnr_dmd); | ||
1178 | if (ret) | ||
1179 | return ret; | ||
1180 | |||
1181 | ret = | ||
1182 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, &ts_lock, | ||
1183 | &early_unlock); | ||
1184 | if (ret) { | ||
1185 | slvt_unfreeze_reg(tnr_dmd); | ||
1186 | return ret; | ||
1187 | } | ||
1188 | |||
1189 | if (sync_state != 6) { | ||
1190 | slvt_unfreeze_reg(tnr_dmd); | ||
1191 | |||
1192 | ret = -EAGAIN; | ||
1193 | |||
1194 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1195 | ret = | ||
1196 | cxd2880_tnrdmd_dvbt2_mon_spectrum_sense(tnr_dmd->diver_sub, | ||
1197 | sense); | ||
1198 | |||
1199 | return ret; | ||
1200 | } | ||
1201 | |||
1202 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1203 | CXD2880_IO_TGT_DMD, | ||
1204 | 0x00, 0x0b); | ||
1205 | if (ret) { | ||
1206 | slvt_unfreeze_reg(tnr_dmd); | ||
1207 | return ret; | ||
1208 | } | ||
1209 | |||
1210 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1211 | CXD2880_IO_TGT_DMD, | ||
1212 | 0x2f, &data, sizeof(data)); | ||
1213 | if (ret) { | ||
1214 | slvt_unfreeze_reg(tnr_dmd); | ||
1215 | return ret; | ||
1216 | } | ||
1217 | |||
1218 | slvt_unfreeze_reg(tnr_dmd); | ||
1219 | |||
1220 | *sense = | ||
1221 | (data & 0x01) ? CXD2880_TNRDMD_SPECTRUM_INV : | ||
1222 | CXD2880_TNRDMD_SPECTRUM_NORMAL; | ||
1223 | |||
1224 | return 0; | ||
1225 | } | ||
1226 | |||
1227 | static int dvbt2_read_snr_reg(struct cxd2880_tnrdmd *tnr_dmd, | ||
1228 | u16 *reg_value) | ||
1229 | { | ||
1230 | u8 sync_state = 0; | ||
1231 | u8 ts_lock = 0; | ||
1232 | u8 unlock_detected = 0; | ||
1233 | u8 data[2]; | ||
1234 | int ret; | ||
1235 | |||
1236 | if (!tnr_dmd || !reg_value) | ||
1237 | return -EINVAL; | ||
1238 | |||
1239 | ret = slvt_freeze_reg(tnr_dmd); | ||
1240 | if (ret) | ||
1241 | return ret; | ||
1242 | |||
1243 | ret = | ||
1244 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
1245 | &ts_lock, | ||
1246 | &unlock_detected); | ||
1247 | if (ret) { | ||
1248 | slvt_unfreeze_reg(tnr_dmd); | ||
1249 | return ret; | ||
1250 | } | ||
1251 | |||
1252 | if (sync_state != 6) { | ||
1253 | slvt_unfreeze_reg(tnr_dmd); | ||
1254 | return -EAGAIN; | ||
1255 | } | ||
1256 | |||
1257 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1258 | CXD2880_IO_TGT_DMD, | ||
1259 | 0x00, 0x0b); | ||
1260 | if (ret) { | ||
1261 | slvt_unfreeze_reg(tnr_dmd); | ||
1262 | return ret; | ||
1263 | } | ||
1264 | |||
1265 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1266 | CXD2880_IO_TGT_DMD, | ||
1267 | 0x13, data, sizeof(data)); | ||
1268 | if (ret) { | ||
1269 | slvt_unfreeze_reg(tnr_dmd); | ||
1270 | return ret; | ||
1271 | } | ||
1272 | |||
1273 | slvt_unfreeze_reg(tnr_dmd); | ||
1274 | |||
1275 | *reg_value = (data[0] << 8) | data[1]; | ||
1276 | |||
1277 | return ret; | ||
1278 | } | ||
1279 | |||
1280 | static int dvbt2_calc_snr(struct cxd2880_tnrdmd *tnr_dmd, | ||
1281 | u32 reg_value, int *snr) | ||
1282 | { | ||
1283 | if (!tnr_dmd || !snr) | ||
1284 | return -EINVAL; | ||
1285 | |||
1286 | if (reg_value == 0) | ||
1287 | return -EAGAIN; | ||
1288 | |||
1289 | if (reg_value > 10876) | ||
1290 | reg_value = 10876; | ||
1291 | |||
1292 | *snr = intlog10(reg_value) - intlog10(12600 - reg_value); | ||
1293 | *snr = (*snr + 839) / 1678 + 32000; | ||
1294 | |||
1295 | return 0; | ||
1296 | } | ||
1297 | |||
1298 | int cxd2880_tnrdmd_dvbt2_mon_snr(struct cxd2880_tnrdmd *tnr_dmd, | ||
1299 | int *snr) | ||
1300 | { | ||
1301 | u16 reg_value = 0; | ||
1302 | int ret; | ||
1303 | |||
1304 | if (!tnr_dmd || !snr) | ||
1305 | return -EINVAL; | ||
1306 | |||
1307 | *snr = -1000 * 1000; | ||
1308 | |||
1309 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1310 | return -EINVAL; | ||
1311 | |||
1312 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1313 | return -EINVAL; | ||
1314 | |||
1315 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1316 | return -EINVAL; | ||
1317 | |||
1318 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
1319 | ret = dvbt2_read_snr_reg(tnr_dmd, ®_value); | ||
1320 | if (ret) | ||
1321 | return ret; | ||
1322 | |||
1323 | ret = dvbt2_calc_snr(tnr_dmd, reg_value, snr); | ||
1324 | } else { | ||
1325 | int snr_main = 0; | ||
1326 | int snr_sub = 0; | ||
1327 | |||
1328 | ret = | ||
1329 | cxd2880_tnrdmd_dvbt2_mon_snr_diver(tnr_dmd, snr, &snr_main, | ||
1330 | &snr_sub); | ||
1331 | } | ||
1332 | |||
1333 | return ret; | ||
1334 | } | ||
1335 | |||
1336 | int cxd2880_tnrdmd_dvbt2_mon_snr_diver(struct cxd2880_tnrdmd | ||
1337 | *tnr_dmd, int *snr, | ||
1338 | int *snr_main, int *snr_sub) | ||
1339 | { | ||
1340 | u16 reg_value = 0; | ||
1341 | u32 reg_value_sum = 0; | ||
1342 | int ret; | ||
1343 | |||
1344 | if (!tnr_dmd || !snr || !snr_main || !snr_sub) | ||
1345 | return -EINVAL; | ||
1346 | |||
1347 | *snr = -1000 * 1000; | ||
1348 | *snr_main = -1000 * 1000; | ||
1349 | *snr_sub = -1000 * 1000; | ||
1350 | |||
1351 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1352 | return -EINVAL; | ||
1353 | |||
1354 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1355 | return -EINVAL; | ||
1356 | |||
1357 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1358 | return -EINVAL; | ||
1359 | |||
1360 | ret = dvbt2_read_snr_reg(tnr_dmd, ®_value); | ||
1361 | if (!ret) { | ||
1362 | ret = dvbt2_calc_snr(tnr_dmd, reg_value, snr_main); | ||
1363 | if (ret) | ||
1364 | reg_value = 0; | ||
1365 | } else if (ret == -EAGAIN) { | ||
1366 | reg_value = 0; | ||
1367 | } else { | ||
1368 | return ret; | ||
1369 | } | ||
1370 | |||
1371 | reg_value_sum += reg_value; | ||
1372 | |||
1373 | ret = dvbt2_read_snr_reg(tnr_dmd->diver_sub, ®_value); | ||
1374 | if (!ret) { | ||
1375 | ret = dvbt2_calc_snr(tnr_dmd->diver_sub, reg_value, snr_sub); | ||
1376 | if (ret) | ||
1377 | reg_value = 0; | ||
1378 | } else if (ret == -EAGAIN) { | ||
1379 | reg_value = 0; | ||
1380 | } else { | ||
1381 | return ret; | ||
1382 | } | ||
1383 | |||
1384 | reg_value_sum += reg_value; | ||
1385 | |||
1386 | return dvbt2_calc_snr(tnr_dmd, reg_value_sum, snr); | ||
1387 | } | ||
1388 | |||
1389 | int cxd2880_tnrdmd_dvbt2_mon_packet_error_number(struct | ||
1390 | cxd2880_tnrdmd | ||
1391 | *tnr_dmd, | ||
1392 | u32 *pen) | ||
1393 | { | ||
1394 | int ret; | ||
1395 | u8 data[3]; | ||
1396 | |||
1397 | if (!tnr_dmd || !pen) | ||
1398 | return -EINVAL; | ||
1399 | |||
1400 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1401 | return -EINVAL; | ||
1402 | |||
1403 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1404 | return -EINVAL; | ||
1405 | |||
1406 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1407 | return -EINVAL; | ||
1408 | |||
1409 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1410 | CXD2880_IO_TGT_DMD, | ||
1411 | 0x00, 0x0b); | ||
1412 | if (ret) | ||
1413 | return ret; | ||
1414 | |||
1415 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1416 | CXD2880_IO_TGT_DMD, | ||
1417 | 0x39, data, sizeof(data)); | ||
1418 | if (ret) | ||
1419 | return ret; | ||
1420 | |||
1421 | if (!(data[0] & 0x01)) | ||
1422 | return -EAGAIN; | ||
1423 | |||
1424 | *pen = ((data[1] << 8) | data[2]); | ||
1425 | |||
1426 | return ret; | ||
1427 | } | ||
1428 | |||
1429 | int cxd2880_tnrdmd_dvbt2_mon_sampling_offset(struct cxd2880_tnrdmd | ||
1430 | *tnr_dmd, int *ppm) | ||
1431 | { | ||
1432 | u8 ctl_val_reg[5]; | ||
1433 | u8 nominal_rate_reg[5]; | ||
1434 | u32 trl_ctl_val = 0; | ||
1435 | u32 trcg_nominal_rate = 0; | ||
1436 | int num; | ||
1437 | int den; | ||
1438 | int ret; | ||
1439 | u8 sync_state = 0; | ||
1440 | u8 ts_lock = 0; | ||
1441 | u8 unlock_detected = 0; | ||
1442 | s8 diff_upper = 0; | ||
1443 | |||
1444 | if (!tnr_dmd || !ppm) | ||
1445 | return -EINVAL; | ||
1446 | |||
1447 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1448 | return -EINVAL; | ||
1449 | |||
1450 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1451 | return -EINVAL; | ||
1452 | |||
1453 | ret = slvt_freeze_reg(tnr_dmd); | ||
1454 | if (ret) | ||
1455 | return ret; | ||
1456 | |||
1457 | ret = | ||
1458 | cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_state, | ||
1459 | &ts_lock, | ||
1460 | &unlock_detected); | ||
1461 | if (ret) { | ||
1462 | slvt_unfreeze_reg(tnr_dmd); | ||
1463 | return ret; | ||
1464 | } | ||
1465 | |||
1466 | if (sync_state != 6) { | ||
1467 | slvt_unfreeze_reg(tnr_dmd); | ||
1468 | return -EAGAIN; | ||
1469 | } | ||
1470 | |||
1471 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1472 | CXD2880_IO_TGT_DMD, | ||
1473 | 0x00, 0x0b); | ||
1474 | if (ret) { | ||
1475 | slvt_unfreeze_reg(tnr_dmd); | ||
1476 | return ret; | ||
1477 | } | ||
1478 | |||
1479 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1480 | CXD2880_IO_TGT_DMD, | ||
1481 | 0x34, ctl_val_reg, | ||
1482 | sizeof(ctl_val_reg)); | ||
1483 | if (ret) { | ||
1484 | slvt_unfreeze_reg(tnr_dmd); | ||
1485 | return ret; | ||
1486 | } | ||
1487 | |||
1488 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1489 | CXD2880_IO_TGT_DMD, | ||
1490 | 0x00, 0x04); | ||
1491 | if (ret) { | ||
1492 | slvt_unfreeze_reg(tnr_dmd); | ||
1493 | return ret; | ||
1494 | } | ||
1495 | |||
1496 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1497 | CXD2880_IO_TGT_DMD, | ||
1498 | 0x10, nominal_rate_reg, | ||
1499 | sizeof(nominal_rate_reg)); | ||
1500 | if (ret) { | ||
1501 | slvt_unfreeze_reg(tnr_dmd); | ||
1502 | return ret; | ||
1503 | } | ||
1504 | |||
1505 | slvt_unfreeze_reg(tnr_dmd); | ||
1506 | |||
1507 | diff_upper = | ||
1508 | (ctl_val_reg[0] & 0x7f) - (nominal_rate_reg[0] & 0x7f); | ||
1509 | |||
1510 | if (diff_upper < -1 || diff_upper > 1) | ||
1511 | return -EAGAIN; | ||
1512 | |||
1513 | trl_ctl_val = ctl_val_reg[1] << 24; | ||
1514 | trl_ctl_val |= ctl_val_reg[2] << 16; | ||
1515 | trl_ctl_val |= ctl_val_reg[3] << 8; | ||
1516 | trl_ctl_val |= ctl_val_reg[4]; | ||
1517 | |||
1518 | trcg_nominal_rate = nominal_rate_reg[1] << 24; | ||
1519 | trcg_nominal_rate |= nominal_rate_reg[2] << 16; | ||
1520 | trcg_nominal_rate |= nominal_rate_reg[3] << 8; | ||
1521 | trcg_nominal_rate |= nominal_rate_reg[4]; | ||
1522 | |||
1523 | trl_ctl_val >>= 1; | ||
1524 | trcg_nominal_rate >>= 1; | ||
1525 | |||
1526 | if (diff_upper == 1) | ||
1527 | num = | ||
1528 | (int)((trl_ctl_val + 0x80000000u) - | ||
1529 | trcg_nominal_rate); | ||
1530 | else if (diff_upper == -1) | ||
1531 | num = | ||
1532 | -(int)((trcg_nominal_rate + 0x80000000u) - | ||
1533 | trl_ctl_val); | ||
1534 | else | ||
1535 | num = (int)(trl_ctl_val - trcg_nominal_rate); | ||
1536 | |||
1537 | den = (nominal_rate_reg[0] & 0x7f) << 24; | ||
1538 | den |= nominal_rate_reg[1] << 16; | ||
1539 | den |= nominal_rate_reg[2] << 8; | ||
1540 | den |= nominal_rate_reg[3]; | ||
1541 | den = (den + (390625 / 2)) / 390625; | ||
1542 | |||
1543 | den >>= 1; | ||
1544 | |||
1545 | if (num >= 0) | ||
1546 | *ppm = (num + (den / 2)) / den; | ||
1547 | else | ||
1548 | *ppm = (num - (den / 2)) / den; | ||
1549 | |||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1553 | int cxd2880_tnrdmd_dvbt2_mon_sampling_offset_sub(struct | ||
1554 | cxd2880_tnrdmd | ||
1555 | *tnr_dmd, | ||
1556 | int *ppm) | ||
1557 | { | ||
1558 | if (!tnr_dmd || !ppm) | ||
1559 | return -EINVAL; | ||
1560 | |||
1561 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1562 | return -EINVAL; | ||
1563 | |||
1564 | return cxd2880_tnrdmd_dvbt2_mon_sampling_offset(tnr_dmd->diver_sub, | ||
1565 | ppm); | ||
1566 | } | ||
1567 | |||
1568 | int cxd2880_tnrdmd_dvbt2_mon_qam(struct cxd2880_tnrdmd *tnr_dmd, | ||
1569 | enum cxd2880_dvbt2_plp_btype type, | ||
1570 | enum cxd2880_dvbt2_plp_constell *qam) | ||
1571 | { | ||
1572 | u8 data; | ||
1573 | u8 l1_post_ok = 0; | ||
1574 | int ret; | ||
1575 | |||
1576 | if (!tnr_dmd || !qam) | ||
1577 | return -EINVAL; | ||
1578 | |||
1579 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1580 | return -EINVAL; | ||
1581 | |||
1582 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1583 | return -EINVAL; | ||
1584 | |||
1585 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1586 | return -EINVAL; | ||
1587 | |||
1588 | ret = slvt_freeze_reg(tnr_dmd); | ||
1589 | if (ret) | ||
1590 | return ret; | ||
1591 | |||
1592 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1593 | CXD2880_IO_TGT_DMD, | ||
1594 | 0x00, 0x0b); | ||
1595 | if (ret) { | ||
1596 | slvt_unfreeze_reg(tnr_dmd); | ||
1597 | return ret; | ||
1598 | } | ||
1599 | |||
1600 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1601 | CXD2880_IO_TGT_DMD, | ||
1602 | 0x86, &l1_post_ok, 1); | ||
1603 | if (ret) { | ||
1604 | slvt_unfreeze_reg(tnr_dmd); | ||
1605 | return ret; | ||
1606 | } | ||
1607 | |||
1608 | if (!(l1_post_ok & 0x01)) { | ||
1609 | slvt_unfreeze_reg(tnr_dmd); | ||
1610 | return -EAGAIN; | ||
1611 | } | ||
1612 | |||
1613 | if (type == CXD2880_DVBT2_PLP_COMMON) { | ||
1614 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1615 | CXD2880_IO_TGT_DMD, | ||
1616 | 0xb6, &data, 1); | ||
1617 | if (ret) { | ||
1618 | slvt_unfreeze_reg(tnr_dmd); | ||
1619 | return ret; | ||
1620 | } | ||
1621 | |||
1622 | if (data == 0) { | ||
1623 | slvt_unfreeze_reg(tnr_dmd); | ||
1624 | return -EAGAIN; | ||
1625 | } | ||
1626 | |||
1627 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1628 | CXD2880_IO_TGT_DMD, | ||
1629 | 0xb1, &data, 1); | ||
1630 | if (ret) { | ||
1631 | slvt_unfreeze_reg(tnr_dmd); | ||
1632 | return ret; | ||
1633 | } | ||
1634 | } else { | ||
1635 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1636 | CXD2880_IO_TGT_DMD, | ||
1637 | 0x9e, &data, 1); | ||
1638 | if (ret) { | ||
1639 | slvt_unfreeze_reg(tnr_dmd); | ||
1640 | return ret; | ||
1641 | } | ||
1642 | } | ||
1643 | |||
1644 | slvt_unfreeze_reg(tnr_dmd); | ||
1645 | |||
1646 | *qam = (enum cxd2880_dvbt2_plp_constell)(data & 0x07); | ||
1647 | |||
1648 | return ret; | ||
1649 | } | ||
1650 | |||
1651 | int cxd2880_tnrdmd_dvbt2_mon_code_rate(struct cxd2880_tnrdmd | ||
1652 | *tnr_dmd, | ||
1653 | enum cxd2880_dvbt2_plp_btype | ||
1654 | type, | ||
1655 | enum | ||
1656 | cxd2880_dvbt2_plp_code_rate | ||
1657 | *code_rate) | ||
1658 | { | ||
1659 | u8 data; | ||
1660 | u8 l1_post_ok = 0; | ||
1661 | int ret; | ||
1662 | |||
1663 | if (!tnr_dmd || !code_rate) | ||
1664 | return -EINVAL; | ||
1665 | |||
1666 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1667 | return -EINVAL; | ||
1668 | |||
1669 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1670 | return -EINVAL; | ||
1671 | |||
1672 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1673 | return -EINVAL; | ||
1674 | |||
1675 | ret = slvt_freeze_reg(tnr_dmd); | ||
1676 | if (ret) | ||
1677 | return ret; | ||
1678 | |||
1679 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1680 | CXD2880_IO_TGT_DMD, | ||
1681 | 0x00, 0x0b); | ||
1682 | if (ret) { | ||
1683 | slvt_unfreeze_reg(tnr_dmd); | ||
1684 | return ret; | ||
1685 | } | ||
1686 | |||
1687 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1688 | CXD2880_IO_TGT_DMD, | ||
1689 | 0x86, &l1_post_ok, 1); | ||
1690 | if (ret) { | ||
1691 | slvt_unfreeze_reg(tnr_dmd); | ||
1692 | return ret; | ||
1693 | } | ||
1694 | |||
1695 | if (!(l1_post_ok & 0x01)) { | ||
1696 | slvt_unfreeze_reg(tnr_dmd); | ||
1697 | return -EAGAIN; | ||
1698 | } | ||
1699 | |||
1700 | if (type == CXD2880_DVBT2_PLP_COMMON) { | ||
1701 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1702 | CXD2880_IO_TGT_DMD, | ||
1703 | 0xb6, &data, 1); | ||
1704 | if (ret) { | ||
1705 | slvt_unfreeze_reg(tnr_dmd); | ||
1706 | return ret; | ||
1707 | } | ||
1708 | |||
1709 | if (data == 0) { | ||
1710 | slvt_unfreeze_reg(tnr_dmd); | ||
1711 | return -EAGAIN; | ||
1712 | } | ||
1713 | |||
1714 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1715 | CXD2880_IO_TGT_DMD, | ||
1716 | 0xb0, &data, 1); | ||
1717 | if (ret) { | ||
1718 | slvt_unfreeze_reg(tnr_dmd); | ||
1719 | return ret; | ||
1720 | } | ||
1721 | } else { | ||
1722 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1723 | CXD2880_IO_TGT_DMD, | ||
1724 | 0x9d, &data, 1); | ||
1725 | if (ret) { | ||
1726 | slvt_unfreeze_reg(tnr_dmd); | ||
1727 | return ret; | ||
1728 | } | ||
1729 | } | ||
1730 | |||
1731 | slvt_unfreeze_reg(tnr_dmd); | ||
1732 | |||
1733 | *code_rate = (enum cxd2880_dvbt2_plp_code_rate)(data & 0x07); | ||
1734 | |||
1735 | return ret; | ||
1736 | } | ||
1737 | |||
1738 | int cxd2880_tnrdmd_dvbt2_mon_profile(struct cxd2880_tnrdmd | ||
1739 | *tnr_dmd, | ||
1740 | enum cxd2880_dvbt2_profile | ||
1741 | *profile) | ||
1742 | { | ||
1743 | u8 data; | ||
1744 | int ret; | ||
1745 | |||
1746 | if (!tnr_dmd || !profile) | ||
1747 | return -EINVAL; | ||
1748 | |||
1749 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1750 | return -EINVAL; | ||
1751 | |||
1752 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1753 | return -EINVAL; | ||
1754 | |||
1755 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
1756 | CXD2880_IO_TGT_DMD, | ||
1757 | 0x00, 0x0b); | ||
1758 | if (ret) | ||
1759 | return ret; | ||
1760 | |||
1761 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
1762 | CXD2880_IO_TGT_DMD, | ||
1763 | 0x22, &data, sizeof(data)); | ||
1764 | if (ret) | ||
1765 | return ret; | ||
1766 | |||
1767 | if (data & 0x02) { | ||
1768 | if (data & 0x01) | ||
1769 | *profile = CXD2880_DVBT2_PROFILE_LITE; | ||
1770 | else | ||
1771 | *profile = CXD2880_DVBT2_PROFILE_BASE; | ||
1772 | } else { | ||
1773 | ret = -EAGAIN; | ||
1774 | if (tnr_dmd->diver_mode == | ||
1775 | CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1776 | ret = | ||
1777 | cxd2880_tnrdmd_dvbt2_mon_profile(tnr_dmd->diver_sub, | ||
1778 | profile); | ||
1779 | |||
1780 | return ret; | ||
1781 | } | ||
1782 | |||
1783 | return 0; | ||
1784 | } | ||
1785 | |||
1786 | static int dvbt2_calc_ssi(struct cxd2880_tnrdmd *tnr_dmd, | ||
1787 | int rf_lvl, u8 *ssi) | ||
1788 | { | ||
1789 | enum cxd2880_dvbt2_plp_constell qam; | ||
1790 | enum cxd2880_dvbt2_plp_code_rate code_rate; | ||
1791 | int prel; | ||
1792 | int temp_ssi = 0; | ||
1793 | int ret; | ||
1794 | |||
1795 | if (!tnr_dmd || !ssi) | ||
1796 | return -EINVAL; | ||
1797 | |||
1798 | ret = | ||
1799 | cxd2880_tnrdmd_dvbt2_mon_qam(tnr_dmd, CXD2880_DVBT2_PLP_DATA, &qam); | ||
1800 | if (ret) | ||
1801 | return ret; | ||
1802 | |||
1803 | ret = | ||
1804 | cxd2880_tnrdmd_dvbt2_mon_code_rate(tnr_dmd, CXD2880_DVBT2_PLP_DATA, | ||
1805 | &code_rate); | ||
1806 | if (ret) | ||
1807 | return ret; | ||
1808 | |||
1809 | if (code_rate > CXD2880_DVBT2_R2_5 || qam > CXD2880_DVBT2_QAM256) | ||
1810 | return -EINVAL; | ||
1811 | |||
1812 | prel = rf_lvl - ref_dbm_1000[qam][code_rate]; | ||
1813 | |||
1814 | if (prel < -15000) | ||
1815 | temp_ssi = 0; | ||
1816 | else if (prel < 0) | ||
1817 | temp_ssi = ((2 * (prel + 15000)) + 1500) / 3000; | ||
1818 | else if (prel < 20000) | ||
1819 | temp_ssi = (((4 * prel) + 500) / 1000) + 10; | ||
1820 | else if (prel < 35000) | ||
1821 | temp_ssi = (((2 * (prel - 20000)) + 1500) / 3000) + 90; | ||
1822 | else | ||
1823 | temp_ssi = 100; | ||
1824 | |||
1825 | *ssi = (temp_ssi > 100) ? 100 : (u8)temp_ssi; | ||
1826 | |||
1827 | return ret; | ||
1828 | } | ||
1829 | |||
1830 | int cxd2880_tnrdmd_dvbt2_mon_ssi(struct cxd2880_tnrdmd *tnr_dmd, | ||
1831 | u8 *ssi) | ||
1832 | { | ||
1833 | int rf_lvl = 0; | ||
1834 | int ret; | ||
1835 | |||
1836 | if (!tnr_dmd || !ssi) | ||
1837 | return -EINVAL; | ||
1838 | |||
1839 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
1840 | return -EINVAL; | ||
1841 | |||
1842 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1843 | return -EINVAL; | ||
1844 | |||
1845 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1846 | return -EINVAL; | ||
1847 | |||
1848 | ret = cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd, &rf_lvl); | ||
1849 | if (ret) | ||
1850 | return ret; | ||
1851 | |||
1852 | return dvbt2_calc_ssi(tnr_dmd, rf_lvl, ssi); | ||
1853 | } | ||
1854 | |||
1855 | int cxd2880_tnrdmd_dvbt2_mon_ssi_sub(struct cxd2880_tnrdmd | ||
1856 | *tnr_dmd, u8 *ssi) | ||
1857 | { | ||
1858 | int rf_lvl = 0; | ||
1859 | int ret; | ||
1860 | |||
1861 | if (!tnr_dmd || !ssi) | ||
1862 | return -EINVAL; | ||
1863 | |||
1864 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
1865 | return -EINVAL; | ||
1866 | |||
1867 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
1868 | return -EINVAL; | ||
1869 | |||
1870 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
1871 | return -EINVAL; | ||
1872 | |||
1873 | ret = cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd->diver_sub, &rf_lvl); | ||
1874 | if (ret) | ||
1875 | return ret; | ||
1876 | |||
1877 | return dvbt2_calc_ssi(tnr_dmd, rf_lvl, ssi); | ||
1878 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h new file mode 100644 index 000000000000..5b7adaceff22 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h | |||
@@ -0,0 +1,135 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt2_mon.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DVB-T2 monitor interface | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_TNRDMD_DVBT2_MON_H | ||
11 | #define CXD2880_TNRDMD_DVBT2_MON_H | ||
12 | |||
13 | #include "cxd2880_tnrdmd.h" | ||
14 | #include "cxd2880_dvbt2.h" | ||
15 | |||
16 | int cxd2880_tnrdmd_dvbt2_mon_sync_stat(struct cxd2880_tnrdmd | ||
17 | *tnr_dmd, u8 *sync_stat, | ||
18 | u8 *ts_lock_stat, | ||
19 | u8 *unlock_detected); | ||
20 | |||
21 | int cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(struct cxd2880_tnrdmd | ||
22 | *tnr_dmd, | ||
23 | u8 *sync_stat, | ||
24 | u8 *unlock_detected); | ||
25 | |||
26 | int cxd2880_tnrdmd_dvbt2_mon_carrier_offset(struct cxd2880_tnrdmd | ||
27 | *tnr_dmd, int *offset); | ||
28 | |||
29 | int cxd2880_tnrdmd_dvbt2_mon_carrier_offset_sub(struct | ||
30 | cxd2880_tnrdmd | ||
31 | *tnr_dmd, | ||
32 | int *offset); | ||
33 | |||
34 | int cxd2880_tnrdmd_dvbt2_mon_l1_pre(struct cxd2880_tnrdmd *tnr_dmd, | ||
35 | struct cxd2880_dvbt2_l1pre | ||
36 | *l1_pre); | ||
37 | |||
38 | int cxd2880_tnrdmd_dvbt2_mon_version(struct cxd2880_tnrdmd | ||
39 | *tnr_dmd, | ||
40 | enum cxd2880_dvbt2_version | ||
41 | *ver); | ||
42 | |||
43 | int cxd2880_tnrdmd_dvbt2_mon_ofdm(struct cxd2880_tnrdmd *tnr_dmd, | ||
44 | struct cxd2880_dvbt2_ofdm *ofdm); | ||
45 | |||
46 | int cxd2880_tnrdmd_dvbt2_mon_data_plps(struct cxd2880_tnrdmd | ||
47 | *tnr_dmd, u8 *plp_ids, | ||
48 | u8 *num_plps); | ||
49 | |||
50 | int cxd2880_tnrdmd_dvbt2_mon_active_plp(struct cxd2880_tnrdmd | ||
51 | *tnr_dmd, | ||
52 | enum | ||
53 | cxd2880_dvbt2_plp_btype | ||
54 | type, | ||
55 | struct cxd2880_dvbt2_plp | ||
56 | *plp_info); | ||
57 | |||
58 | int cxd2880_tnrdmd_dvbt2_mon_data_plp_error(struct cxd2880_tnrdmd | ||
59 | *tnr_dmd, | ||
60 | u8 *plp_error); | ||
61 | |||
62 | int cxd2880_tnrdmd_dvbt2_mon_l1_change(struct cxd2880_tnrdmd | ||
63 | *tnr_dmd, u8 *l1_change); | ||
64 | |||
65 | int cxd2880_tnrdmd_dvbt2_mon_l1_post(struct cxd2880_tnrdmd | ||
66 | *tnr_dmd, | ||
67 | struct cxd2880_dvbt2_l1post | ||
68 | *l1_post); | ||
69 | |||
70 | int cxd2880_tnrdmd_dvbt2_mon_bbheader(struct cxd2880_tnrdmd | ||
71 | *tnr_dmd, | ||
72 | enum cxd2880_dvbt2_plp_btype | ||
73 | type, | ||
74 | struct cxd2880_dvbt2_bbheader | ||
75 | *bbheader); | ||
76 | |||
77 | int cxd2880_tnrdmd_dvbt2_mon_in_bandb_ts_rate(struct cxd2880_tnrdmd | ||
78 | *tnr_dmd, | ||
79 | enum | ||
80 | cxd2880_dvbt2_plp_btype | ||
81 | type, | ||
82 | u32 *ts_rate_bps); | ||
83 | |||
84 | int cxd2880_tnrdmd_dvbt2_mon_spectrum_sense(struct cxd2880_tnrdmd | ||
85 | *tnr_dmd, | ||
86 | enum | ||
87 | cxd2880_tnrdmd_spectrum_sense | ||
88 | *sense); | ||
89 | |||
90 | int cxd2880_tnrdmd_dvbt2_mon_snr(struct cxd2880_tnrdmd *tnr_dmd, | ||
91 | int *snr); | ||
92 | |||
93 | int cxd2880_tnrdmd_dvbt2_mon_snr_diver(struct cxd2880_tnrdmd | ||
94 | *tnr_dmd, int *snr, | ||
95 | int *snr_main, | ||
96 | int *snr_sub); | ||
97 | |||
98 | int cxd2880_tnrdmd_dvbt2_mon_packet_error_number(struct | ||
99 | cxd2880_tnrdmd | ||
100 | *tnr_dmd, | ||
101 | u32 *pen); | ||
102 | |||
103 | int cxd2880_tnrdmd_dvbt2_mon_sampling_offset(struct cxd2880_tnrdmd | ||
104 | *tnr_dmd, int *ppm); | ||
105 | |||
106 | int cxd2880_tnrdmd_dvbt2_mon_sampling_offset_sub(struct | ||
107 | cxd2880_tnrdmd | ||
108 | *tnr_dmd, | ||
109 | int *ppm); | ||
110 | |||
111 | int cxd2880_tnrdmd_dvbt2_mon_qam(struct cxd2880_tnrdmd *tnr_dmd, | ||
112 | enum cxd2880_dvbt2_plp_btype type, | ||
113 | enum cxd2880_dvbt2_plp_constell | ||
114 | *qam); | ||
115 | |||
116 | int cxd2880_tnrdmd_dvbt2_mon_code_rate(struct cxd2880_tnrdmd | ||
117 | *tnr_dmd, | ||
118 | enum cxd2880_dvbt2_plp_btype | ||
119 | type, | ||
120 | enum | ||
121 | cxd2880_dvbt2_plp_code_rate | ||
122 | *code_rate); | ||
123 | |||
124 | int cxd2880_tnrdmd_dvbt2_mon_profile(struct cxd2880_tnrdmd | ||
125 | *tnr_dmd, | ||
126 | enum cxd2880_dvbt2_profile | ||
127 | *profile); | ||
128 | |||
129 | int cxd2880_tnrdmd_dvbt2_mon_ssi(struct cxd2880_tnrdmd *tnr_dmd, | ||
130 | u8 *ssi); | ||
131 | |||
132 | int cxd2880_tnrdmd_dvbt2_mon_ssi_sub(struct cxd2880_tnrdmd | ||
133 | *tnr_dmd, u8 *ssi); | ||
134 | |||
135 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c new file mode 100644 index 000000000000..fedc3b4a2fa0 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c | |||
@@ -0,0 +1,775 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt_mon.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DVB-T monitor functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include "cxd2880_tnrdmd_mon.h" | ||
11 | #include "cxd2880_tnrdmd_dvbt.h" | ||
12 | #include "cxd2880_tnrdmd_dvbt_mon.h" | ||
13 | |||
14 | #include <media/dvb_math.h> | ||
15 | |||
16 | static const int ref_dbm_1000[3][5] = { | ||
17 | {-93000, -91000, -90000, -89000, -88000}, | ||
18 | {-87000, -85000, -84000, -83000, -82000}, | ||
19 | {-82000, -80000, -78000, -77000, -76000}, | ||
20 | }; | ||
21 | |||
22 | static int is_tps_locked(struct cxd2880_tnrdmd *tnr_dmd); | ||
23 | |||
24 | int cxd2880_tnrdmd_dvbt_mon_sync_stat(struct cxd2880_tnrdmd | ||
25 | *tnr_dmd, u8 *sync_stat, | ||
26 | u8 *ts_lock_stat, | ||
27 | u8 *unlock_detected) | ||
28 | { | ||
29 | u8 rdata = 0x00; | ||
30 | int ret; | ||
31 | |||
32 | if (!tnr_dmd || !sync_stat || !ts_lock_stat || !unlock_detected) | ||
33 | return -EINVAL; | ||
34 | |||
35 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
36 | return -EINVAL; | ||
37 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
38 | return -EINVAL; | ||
39 | |||
40 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
41 | CXD2880_IO_TGT_DMD, | ||
42 | 0x00, 0x0d); | ||
43 | if (ret) | ||
44 | return ret; | ||
45 | |||
46 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
47 | CXD2880_IO_TGT_DMD, | ||
48 | 0x10, &rdata, 1); | ||
49 | if (ret) | ||
50 | return ret; | ||
51 | |||
52 | *unlock_detected = (rdata & 0x10) ? 1 : 0; | ||
53 | *sync_stat = rdata & 0x07; | ||
54 | *ts_lock_stat = (rdata & 0x20) ? 1 : 0; | ||
55 | |||
56 | if (*sync_stat == 0x07) | ||
57 | return -EAGAIN; | ||
58 | |||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | int cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(struct cxd2880_tnrdmd | ||
63 | *tnr_dmd, u8 *sync_stat, | ||
64 | u8 *unlock_detected) | ||
65 | { | ||
66 | u8 ts_lock_stat = 0; | ||
67 | |||
68 | if (!tnr_dmd || !sync_stat || !unlock_detected) | ||
69 | return -EINVAL; | ||
70 | |||
71 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
72 | return -EINVAL; | ||
73 | |||
74 | return cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd->diver_sub, | ||
75 | sync_stat, | ||
76 | &ts_lock_stat, | ||
77 | unlock_detected); | ||
78 | } | ||
79 | |||
80 | int cxd2880_tnrdmd_dvbt_mon_mode_guard(struct cxd2880_tnrdmd | ||
81 | *tnr_dmd, | ||
82 | enum cxd2880_dvbt_mode | ||
83 | *mode, | ||
84 | enum cxd2880_dvbt_guard | ||
85 | *guard) | ||
86 | { | ||
87 | u8 rdata = 0x00; | ||
88 | int ret; | ||
89 | |||
90 | if (!tnr_dmd || !mode || !guard) | ||
91 | return -EINVAL; | ||
92 | |||
93 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
94 | return -EINVAL; | ||
95 | |||
96 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
97 | return -EINVAL; | ||
98 | |||
99 | ret = slvt_freeze_reg(tnr_dmd); | ||
100 | if (ret) | ||
101 | return ret; | ||
102 | |||
103 | ret = is_tps_locked(tnr_dmd); | ||
104 | if (ret) { | ||
105 | slvt_unfreeze_reg(tnr_dmd); | ||
106 | |||
107 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
108 | ret = | ||
109 | cxd2880_tnrdmd_dvbt_mon_mode_guard(tnr_dmd->diver_sub, | ||
110 | mode, guard); | ||
111 | |||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
116 | CXD2880_IO_TGT_DMD, | ||
117 | 0x00, 0x0d); | ||
118 | if (ret) { | ||
119 | slvt_unfreeze_reg(tnr_dmd); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
124 | CXD2880_IO_TGT_DMD, | ||
125 | 0x1b, &rdata, 1); | ||
126 | if (ret) { | ||
127 | slvt_unfreeze_reg(tnr_dmd); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | slvt_unfreeze_reg(tnr_dmd); | ||
132 | |||
133 | *mode = (enum cxd2880_dvbt_mode)((rdata >> 2) & 0x03); | ||
134 | *guard = (enum cxd2880_dvbt_guard)(rdata & 0x03); | ||
135 | |||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | int cxd2880_tnrdmd_dvbt_mon_carrier_offset(struct cxd2880_tnrdmd | ||
140 | *tnr_dmd, int *offset) | ||
141 | { | ||
142 | u8 rdata[4]; | ||
143 | u32 ctl_val = 0; | ||
144 | int ret; | ||
145 | |||
146 | if (!tnr_dmd || !offset) | ||
147 | return -EINVAL; | ||
148 | |||
149 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
150 | return -EINVAL; | ||
151 | |||
152 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
153 | return -EINVAL; | ||
154 | |||
155 | ret = slvt_freeze_reg(tnr_dmd); | ||
156 | if (ret) | ||
157 | return ret; | ||
158 | |||
159 | ret = is_tps_locked(tnr_dmd); | ||
160 | if (ret) { | ||
161 | slvt_unfreeze_reg(tnr_dmd); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
166 | CXD2880_IO_TGT_DMD, | ||
167 | 0x00, 0x0d); | ||
168 | if (ret) { | ||
169 | slvt_unfreeze_reg(tnr_dmd); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
174 | CXD2880_IO_TGT_DMD, | ||
175 | 0x1d, rdata, 4); | ||
176 | if (ret) { | ||
177 | slvt_unfreeze_reg(tnr_dmd); | ||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | slvt_unfreeze_reg(tnr_dmd); | ||
182 | |||
183 | ctl_val = | ||
184 | ((rdata[0] & 0x1f) << 24) | (rdata[1] << 16) | (rdata[2] << 8) | | ||
185 | (rdata[3]); | ||
186 | *offset = cxd2880_convert2s_complement(ctl_val, 29); | ||
187 | *offset = -1 * ((*offset) * tnr_dmd->bandwidth / 235); | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | int cxd2880_tnrdmd_dvbt_mon_carrier_offset_sub(struct | ||
193 | cxd2880_tnrdmd | ||
194 | *tnr_dmd, | ||
195 | int *offset) | ||
196 | { | ||
197 | if (!tnr_dmd || !offset) | ||
198 | return -EINVAL; | ||
199 | |||
200 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
201 | return -EINVAL; | ||
202 | |||
203 | return cxd2880_tnrdmd_dvbt_mon_carrier_offset(tnr_dmd->diver_sub, | ||
204 | offset); | ||
205 | } | ||
206 | |||
207 | int cxd2880_tnrdmd_dvbt_mon_tps_info(struct cxd2880_tnrdmd | ||
208 | *tnr_dmd, | ||
209 | struct cxd2880_dvbt_tpsinfo | ||
210 | *info) | ||
211 | { | ||
212 | u8 rdata[7]; | ||
213 | u8 cell_id_ok = 0; | ||
214 | int ret; | ||
215 | |||
216 | if (!tnr_dmd || !info) | ||
217 | return -EINVAL; | ||
218 | |||
219 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
220 | return -EINVAL; | ||
221 | |||
222 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
223 | return -EINVAL; | ||
224 | |||
225 | ret = slvt_freeze_reg(tnr_dmd); | ||
226 | if (ret) | ||
227 | return ret; | ||
228 | |||
229 | ret = is_tps_locked(tnr_dmd); | ||
230 | if (ret) { | ||
231 | slvt_unfreeze_reg(tnr_dmd); | ||
232 | |||
233 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
234 | ret = | ||
235 | cxd2880_tnrdmd_dvbt_mon_tps_info(tnr_dmd->diver_sub, | ||
236 | info); | ||
237 | |||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
242 | CXD2880_IO_TGT_DMD, | ||
243 | 0x00, 0x0d); | ||
244 | if (ret) { | ||
245 | slvt_unfreeze_reg(tnr_dmd); | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
250 | CXD2880_IO_TGT_DMD, | ||
251 | 0x29, rdata, 7); | ||
252 | if (ret) { | ||
253 | slvt_unfreeze_reg(tnr_dmd); | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
258 | CXD2880_IO_TGT_DMD, | ||
259 | 0x00, 0x11); | ||
260 | if (ret) { | ||
261 | slvt_unfreeze_reg(tnr_dmd); | ||
262 | return ret; | ||
263 | } | ||
264 | |||
265 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
266 | CXD2880_IO_TGT_DMD, | ||
267 | 0xd5, &cell_id_ok, 1); | ||
268 | if (ret) { | ||
269 | slvt_unfreeze_reg(tnr_dmd); | ||
270 | return ret; | ||
271 | } | ||
272 | |||
273 | slvt_unfreeze_reg(tnr_dmd); | ||
274 | |||
275 | info->constellation = | ||
276 | (enum cxd2880_dvbt_constellation)((rdata[0] >> 6) & 0x03); | ||
277 | info->hierarchy = (enum cxd2880_dvbt_hierarchy)((rdata[0] >> 3) & 0x07); | ||
278 | info->rate_hp = (enum cxd2880_dvbt_coderate)(rdata[0] & 0x07); | ||
279 | info->rate_lp = (enum cxd2880_dvbt_coderate)((rdata[1] >> 5) & 0x07); | ||
280 | info->guard = (enum cxd2880_dvbt_guard)((rdata[1] >> 3) & 0x03); | ||
281 | info->mode = (enum cxd2880_dvbt_mode)((rdata[1] >> 1) & 0x03); | ||
282 | info->fnum = (rdata[2] >> 6) & 0x03; | ||
283 | info->length_indicator = rdata[2] & 0x3f; | ||
284 | info->cell_id = (rdata[3] << 8) | rdata[4]; | ||
285 | info->reserved_even = rdata[5] & 0x3f; | ||
286 | info->reserved_odd = rdata[6] & 0x3f; | ||
287 | |||
288 | info->cell_id_ok = cell_id_ok & 0x01; | ||
289 | |||
290 | return ret; | ||
291 | } | ||
292 | |||
293 | int cxd2880_tnrdmd_dvbt_mon_packet_error_number(struct | ||
294 | cxd2880_tnrdmd | ||
295 | *tnr_dmd, | ||
296 | u32 *pen) | ||
297 | { | ||
298 | u8 rdata[3]; | ||
299 | int ret; | ||
300 | |||
301 | if (!tnr_dmd || !pen) | ||
302 | return -EINVAL; | ||
303 | |||
304 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
305 | return -EINVAL; | ||
306 | |||
307 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
308 | return -EINVAL; | ||
309 | |||
310 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
311 | return -EINVAL; | ||
312 | |||
313 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
314 | CXD2880_IO_TGT_DMD, | ||
315 | 0x00, 0x0d); | ||
316 | if (ret) | ||
317 | return ret; | ||
318 | |||
319 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
320 | CXD2880_IO_TGT_DMD, | ||
321 | 0x26, rdata, 3); | ||
322 | if (ret) | ||
323 | return ret; | ||
324 | |||
325 | if (!(rdata[0] & 0x01)) | ||
326 | return -EAGAIN; | ||
327 | |||
328 | *pen = (rdata[1] << 8) | rdata[2]; | ||
329 | |||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | int cxd2880_tnrdmd_dvbt_mon_spectrum_sense(struct cxd2880_tnrdmd | ||
334 | *tnr_dmd, | ||
335 | enum | ||
336 | cxd2880_tnrdmd_spectrum_sense | ||
337 | *sense) | ||
338 | { | ||
339 | u8 data = 0; | ||
340 | int ret; | ||
341 | |||
342 | if (!tnr_dmd || !sense) | ||
343 | return -EINVAL; | ||
344 | |||
345 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
346 | return -EINVAL; | ||
347 | |||
348 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
349 | return -EINVAL; | ||
350 | |||
351 | ret = slvt_freeze_reg(tnr_dmd); | ||
352 | if (ret) | ||
353 | return ret; | ||
354 | |||
355 | ret = is_tps_locked(tnr_dmd); | ||
356 | if (ret) { | ||
357 | slvt_unfreeze_reg(tnr_dmd); | ||
358 | |||
359 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
360 | ret = cxd2880_tnrdmd_dvbt_mon_spectrum_sense(tnr_dmd->diver_sub, | ||
361 | sense); | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
367 | CXD2880_IO_TGT_DMD, | ||
368 | 0x00, 0x0d); | ||
369 | if (ret) { | ||
370 | slvt_unfreeze_reg(tnr_dmd); | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
375 | CXD2880_IO_TGT_DMD, | ||
376 | 0x1c, &data, sizeof(data)); | ||
377 | if (ret) { | ||
378 | slvt_unfreeze_reg(tnr_dmd); | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | slvt_unfreeze_reg(tnr_dmd); | ||
383 | |||
384 | *sense = | ||
385 | (data & 0x01) ? CXD2880_TNRDMD_SPECTRUM_INV : | ||
386 | CXD2880_TNRDMD_SPECTRUM_NORMAL; | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | static int dvbt_read_snr_reg(struct cxd2880_tnrdmd *tnr_dmd, | ||
392 | u16 *reg_value) | ||
393 | { | ||
394 | u8 rdata[2]; | ||
395 | int ret; | ||
396 | |||
397 | if (!tnr_dmd || !reg_value) | ||
398 | return -EINVAL; | ||
399 | |||
400 | ret = slvt_freeze_reg(tnr_dmd); | ||
401 | if (ret) | ||
402 | return ret; | ||
403 | |||
404 | ret = is_tps_locked(tnr_dmd); | ||
405 | if (ret) { | ||
406 | slvt_unfreeze_reg(tnr_dmd); | ||
407 | return ret; | ||
408 | } | ||
409 | |||
410 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
411 | CXD2880_IO_TGT_DMD, | ||
412 | 0x00, 0x0d); | ||
413 | if (ret) { | ||
414 | slvt_unfreeze_reg(tnr_dmd); | ||
415 | return ret; | ||
416 | } | ||
417 | |||
418 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
419 | CXD2880_IO_TGT_DMD, | ||
420 | 0x13, rdata, 2); | ||
421 | if (ret) { | ||
422 | slvt_unfreeze_reg(tnr_dmd); | ||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | slvt_unfreeze_reg(tnr_dmd); | ||
427 | |||
428 | *reg_value = (rdata[0] << 8) | rdata[1]; | ||
429 | |||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static int dvbt_calc_snr(struct cxd2880_tnrdmd *tnr_dmd, | ||
434 | u32 reg_value, int *snr) | ||
435 | { | ||
436 | if (!tnr_dmd || !snr) | ||
437 | return -EINVAL; | ||
438 | |||
439 | if (reg_value == 0) | ||
440 | return -EAGAIN; | ||
441 | |||
442 | if (reg_value > 4996) | ||
443 | reg_value = 4996; | ||
444 | |||
445 | *snr = intlog10(reg_value) - intlog10(5350 - reg_value); | ||
446 | *snr = (*snr + 839) / 1678 + 28500; | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | int cxd2880_tnrdmd_dvbt_mon_snr(struct cxd2880_tnrdmd *tnr_dmd, | ||
452 | int *snr) | ||
453 | { | ||
454 | u16 reg_value = 0; | ||
455 | int ret; | ||
456 | |||
457 | if (!tnr_dmd || !snr) | ||
458 | return -EINVAL; | ||
459 | |||
460 | *snr = -1000 * 1000; | ||
461 | |||
462 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
463 | return -EINVAL; | ||
464 | |||
465 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
466 | return -EINVAL; | ||
467 | |||
468 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
469 | return -EINVAL; | ||
470 | |||
471 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { | ||
472 | ret = dvbt_read_snr_reg(tnr_dmd, ®_value); | ||
473 | if (ret) | ||
474 | return ret; | ||
475 | |||
476 | ret = dvbt_calc_snr(tnr_dmd, reg_value, snr); | ||
477 | } else { | ||
478 | int snr_main = 0; | ||
479 | int snr_sub = 0; | ||
480 | |||
481 | ret = | ||
482 | cxd2880_tnrdmd_dvbt_mon_snr_diver(tnr_dmd, snr, &snr_main, | ||
483 | &snr_sub); | ||
484 | } | ||
485 | |||
486 | return ret; | ||
487 | } | ||
488 | |||
489 | int cxd2880_tnrdmd_dvbt_mon_snr_diver(struct cxd2880_tnrdmd | ||
490 | *tnr_dmd, int *snr, | ||
491 | int *snr_main, int *snr_sub) | ||
492 | { | ||
493 | u16 reg_value = 0; | ||
494 | u32 reg_value_sum = 0; | ||
495 | int ret; | ||
496 | |||
497 | if (!tnr_dmd || !snr || !snr_main || !snr_sub) | ||
498 | return -EINVAL; | ||
499 | |||
500 | *snr = -1000 * 1000; | ||
501 | *snr_main = -1000 * 1000; | ||
502 | *snr_sub = -1000 * 1000; | ||
503 | |||
504 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
505 | return -EINVAL; | ||
506 | |||
507 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
508 | return -EINVAL; | ||
509 | |||
510 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
511 | return -EINVAL; | ||
512 | |||
513 | ret = dvbt_read_snr_reg(tnr_dmd, ®_value); | ||
514 | if (!ret) { | ||
515 | ret = dvbt_calc_snr(tnr_dmd, reg_value, snr_main); | ||
516 | if (ret) | ||
517 | reg_value = 0; | ||
518 | } else if (ret == -EAGAIN) { | ||
519 | reg_value = 0; | ||
520 | } else { | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | reg_value_sum += reg_value; | ||
525 | |||
526 | ret = dvbt_read_snr_reg(tnr_dmd->diver_sub, ®_value); | ||
527 | if (!ret) { | ||
528 | ret = dvbt_calc_snr(tnr_dmd->diver_sub, reg_value, snr_sub); | ||
529 | if (ret) | ||
530 | reg_value = 0; | ||
531 | } else if (ret == -EAGAIN) { | ||
532 | reg_value = 0; | ||
533 | } else { | ||
534 | return ret; | ||
535 | } | ||
536 | |||
537 | reg_value_sum += reg_value; | ||
538 | |||
539 | return dvbt_calc_snr(tnr_dmd, reg_value_sum, snr); | ||
540 | } | ||
541 | |||
542 | int cxd2880_tnrdmd_dvbt_mon_sampling_offset(struct cxd2880_tnrdmd | ||
543 | *tnr_dmd, int *ppm) | ||
544 | { | ||
545 | u8 ctl_val_reg[5]; | ||
546 | u8 nominal_rate_reg[5]; | ||
547 | u32 trl_ctl_val = 0; | ||
548 | u32 trcg_nominal_rate = 0; | ||
549 | int num; | ||
550 | int den; | ||
551 | s8 diff_upper = 0; | ||
552 | int ret; | ||
553 | |||
554 | if (!tnr_dmd || !ppm) | ||
555 | return -EINVAL; | ||
556 | |||
557 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
558 | return -EINVAL; | ||
559 | |||
560 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
561 | return -EINVAL; | ||
562 | |||
563 | ret = slvt_freeze_reg(tnr_dmd); | ||
564 | if (ret) | ||
565 | return ret; | ||
566 | |||
567 | ret = is_tps_locked(tnr_dmd); | ||
568 | if (ret) { | ||
569 | slvt_unfreeze_reg(tnr_dmd); | ||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
574 | CXD2880_IO_TGT_DMD, | ||
575 | 0x00, 0x0d); | ||
576 | if (ret) { | ||
577 | slvt_unfreeze_reg(tnr_dmd); | ||
578 | return ret; | ||
579 | } | ||
580 | |||
581 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
582 | CXD2880_IO_TGT_DMD, | ||
583 | 0x21, ctl_val_reg, | ||
584 | sizeof(ctl_val_reg)); | ||
585 | if (ret) { | ||
586 | slvt_unfreeze_reg(tnr_dmd); | ||
587 | return ret; | ||
588 | } | ||
589 | |||
590 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
591 | CXD2880_IO_TGT_DMD, | ||
592 | 0x00, 0x04); | ||
593 | if (ret) { | ||
594 | slvt_unfreeze_reg(tnr_dmd); | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
599 | CXD2880_IO_TGT_DMD, | ||
600 | 0x60, nominal_rate_reg, | ||
601 | sizeof(nominal_rate_reg)); | ||
602 | if (ret) { | ||
603 | slvt_unfreeze_reg(tnr_dmd); | ||
604 | return ret; | ||
605 | } | ||
606 | |||
607 | slvt_unfreeze_reg(tnr_dmd); | ||
608 | |||
609 | diff_upper = | ||
610 | (ctl_val_reg[0] & 0x7f) - (nominal_rate_reg[0] & 0x7f); | ||
611 | |||
612 | if (diff_upper < -1 || diff_upper > 1) | ||
613 | return -EAGAIN; | ||
614 | |||
615 | trl_ctl_val = ctl_val_reg[1] << 24; | ||
616 | trl_ctl_val |= ctl_val_reg[2] << 16; | ||
617 | trl_ctl_val |= ctl_val_reg[3] << 8; | ||
618 | trl_ctl_val |= ctl_val_reg[4]; | ||
619 | |||
620 | trcg_nominal_rate = nominal_rate_reg[1] << 24; | ||
621 | trcg_nominal_rate |= nominal_rate_reg[2] << 16; | ||
622 | trcg_nominal_rate |= nominal_rate_reg[3] << 8; | ||
623 | trcg_nominal_rate |= nominal_rate_reg[4]; | ||
624 | |||
625 | trl_ctl_val >>= 1; | ||
626 | trcg_nominal_rate >>= 1; | ||
627 | |||
628 | if (diff_upper == 1) | ||
629 | num = | ||
630 | (int)((trl_ctl_val + 0x80000000u) - | ||
631 | trcg_nominal_rate); | ||
632 | else if (diff_upper == -1) | ||
633 | num = | ||
634 | -(int)((trcg_nominal_rate + 0x80000000u) - | ||
635 | trl_ctl_val); | ||
636 | else | ||
637 | num = (int)(trl_ctl_val - trcg_nominal_rate); | ||
638 | |||
639 | den = (nominal_rate_reg[0] & 0x7f) << 24; | ||
640 | den |= nominal_rate_reg[1] << 16; | ||
641 | den |= nominal_rate_reg[2] << 8; | ||
642 | den |= nominal_rate_reg[3]; | ||
643 | den = (den + (390625 / 2)) / 390625; | ||
644 | |||
645 | den >>= 1; | ||
646 | |||
647 | if (num >= 0) | ||
648 | *ppm = (num + (den / 2)) / den; | ||
649 | else | ||
650 | *ppm = (num - (den / 2)) / den; | ||
651 | |||
652 | return ret; | ||
653 | } | ||
654 | |||
655 | int cxd2880_tnrdmd_dvbt_mon_sampling_offset_sub(struct | ||
656 | cxd2880_tnrdmd | ||
657 | *tnr_dmd, int *ppm) | ||
658 | { | ||
659 | if (!tnr_dmd || !ppm) | ||
660 | return -EINVAL; | ||
661 | |||
662 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
663 | return -EINVAL; | ||
664 | |||
665 | return cxd2880_tnrdmd_dvbt_mon_sampling_offset(tnr_dmd->diver_sub, ppm); | ||
666 | } | ||
667 | |||
668 | static int dvbt_calc_ssi(struct cxd2880_tnrdmd *tnr_dmd, | ||
669 | int rf_lvl, u8 *ssi) | ||
670 | { | ||
671 | struct cxd2880_dvbt_tpsinfo tps; | ||
672 | int prel; | ||
673 | int temp_ssi = 0; | ||
674 | int ret; | ||
675 | |||
676 | if (!tnr_dmd || !ssi) | ||
677 | return -EINVAL; | ||
678 | |||
679 | ret = cxd2880_tnrdmd_dvbt_mon_tps_info(tnr_dmd, &tps); | ||
680 | if (ret) | ||
681 | return ret; | ||
682 | |||
683 | if (tps.constellation >= CXD2880_DVBT_CONSTELLATION_RESERVED_3 || | ||
684 | tps.rate_hp >= CXD2880_DVBT_CODERATE_RESERVED_5) | ||
685 | return -EINVAL; | ||
686 | |||
687 | prel = rf_lvl - ref_dbm_1000[tps.constellation][tps.rate_hp]; | ||
688 | |||
689 | if (prel < -15000) | ||
690 | temp_ssi = 0; | ||
691 | else if (prel < 0) | ||
692 | temp_ssi = ((2 * (prel + 15000)) + 1500) / 3000; | ||
693 | else if (prel < 20000) | ||
694 | temp_ssi = (((4 * prel) + 500) / 1000) + 10; | ||
695 | else if (prel < 35000) | ||
696 | temp_ssi = (((2 * (prel - 20000)) + 1500) / 3000) + 90; | ||
697 | else | ||
698 | temp_ssi = 100; | ||
699 | |||
700 | *ssi = (temp_ssi > 100) ? 100 : (u8)temp_ssi; | ||
701 | |||
702 | return ret; | ||
703 | } | ||
704 | |||
705 | int cxd2880_tnrdmd_dvbt_mon_ssi(struct cxd2880_tnrdmd *tnr_dmd, | ||
706 | u8 *ssi) | ||
707 | { | ||
708 | int rf_lvl = 0; | ||
709 | int ret; | ||
710 | |||
711 | if (!tnr_dmd || !ssi) | ||
712 | return -EINVAL; | ||
713 | |||
714 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
715 | return -EINVAL; | ||
716 | |||
717 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
718 | return -EINVAL; | ||
719 | |||
720 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
721 | return -EINVAL; | ||
722 | |||
723 | ret = cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd, &rf_lvl); | ||
724 | if (ret) | ||
725 | return ret; | ||
726 | |||
727 | return dvbt_calc_ssi(tnr_dmd, rf_lvl, ssi); | ||
728 | } | ||
729 | |||
730 | int cxd2880_tnrdmd_dvbt_mon_ssi_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
731 | u8 *ssi) | ||
732 | { | ||
733 | int rf_lvl = 0; | ||
734 | int ret; | ||
735 | |||
736 | if (!tnr_dmd || !ssi) | ||
737 | return -EINVAL; | ||
738 | |||
739 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
740 | return -EINVAL; | ||
741 | |||
742 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
743 | return -EINVAL; | ||
744 | |||
745 | if (tnr_dmd->sys != CXD2880_DTV_SYS_DVBT) | ||
746 | return -EINVAL; | ||
747 | |||
748 | ret = cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd->diver_sub, &rf_lvl); | ||
749 | if (ret) | ||
750 | return ret; | ||
751 | |||
752 | return dvbt_calc_ssi(tnr_dmd, rf_lvl, ssi); | ||
753 | } | ||
754 | |||
755 | static int is_tps_locked(struct cxd2880_tnrdmd *tnr_dmd) | ||
756 | { | ||
757 | u8 sync = 0; | ||
758 | u8 tslock = 0; | ||
759 | u8 early_unlock = 0; | ||
760 | int ret; | ||
761 | |||
762 | if (!tnr_dmd) | ||
763 | return -EINVAL; | ||
764 | |||
765 | ret = | ||
766 | cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd, &sync, &tslock, | ||
767 | &early_unlock); | ||
768 | if (ret) | ||
769 | return ret; | ||
770 | |||
771 | if (sync != 6) | ||
772 | return -EAGAIN; | ||
773 | |||
774 | return 0; | ||
775 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h new file mode 100644 index 000000000000..f4c31725fa48 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_dvbt_mon.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * DVB-T monitor interface | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_TNRDMD_DVBT_MON_H | ||
11 | #define CXD2880_TNRDMD_DVBT_MON_H | ||
12 | |||
13 | #include "cxd2880_tnrdmd.h" | ||
14 | #include "cxd2880_dvbt.h" | ||
15 | |||
16 | int cxd2880_tnrdmd_dvbt_mon_sync_stat(struct cxd2880_tnrdmd | ||
17 | *tnr_dmd, u8 *sync_stat, | ||
18 | u8 *ts_lock_stat, | ||
19 | u8 *unlock_detected); | ||
20 | |||
21 | int cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(struct cxd2880_tnrdmd | ||
22 | *tnr_dmd, u8 *sync_stat, | ||
23 | u8 *unlock_detected); | ||
24 | |||
25 | int cxd2880_tnrdmd_dvbt_mon_mode_guard(struct cxd2880_tnrdmd | ||
26 | *tnr_dmd, | ||
27 | enum cxd2880_dvbt_mode | ||
28 | *mode, | ||
29 | enum cxd2880_dvbt_guard | ||
30 | *guard); | ||
31 | |||
32 | int cxd2880_tnrdmd_dvbt_mon_carrier_offset(struct cxd2880_tnrdmd | ||
33 | *tnr_dmd, int *offset); | ||
34 | |||
35 | int cxd2880_tnrdmd_dvbt_mon_carrier_offset_sub(struct | ||
36 | cxd2880_tnrdmd | ||
37 | *tnr_dmd, | ||
38 | int *offset); | ||
39 | |||
40 | int cxd2880_tnrdmd_dvbt_mon_tps_info(struct cxd2880_tnrdmd | ||
41 | *tnr_dmd, | ||
42 | struct cxd2880_dvbt_tpsinfo | ||
43 | *info); | ||
44 | |||
45 | int cxd2880_tnrdmd_dvbt_mon_packet_error_number(struct | ||
46 | cxd2880_tnrdmd | ||
47 | *tnr_dmd, | ||
48 | u32 *pen); | ||
49 | |||
50 | int cxd2880_tnrdmd_dvbt_mon_spectrum_sense(struct cxd2880_tnrdmd | ||
51 | *tnr_dmd, | ||
52 | enum | ||
53 | cxd2880_tnrdmd_spectrum_sense | ||
54 | *sense); | ||
55 | |||
56 | int cxd2880_tnrdmd_dvbt_mon_snr(struct cxd2880_tnrdmd *tnr_dmd, | ||
57 | int *snr); | ||
58 | |||
59 | int cxd2880_tnrdmd_dvbt_mon_snr_diver(struct cxd2880_tnrdmd | ||
60 | *tnr_dmd, int *snr, | ||
61 | int *snr_main, int *snr_sub); | ||
62 | |||
63 | int cxd2880_tnrdmd_dvbt_mon_sampling_offset(struct cxd2880_tnrdmd | ||
64 | *tnr_dmd, int *ppm); | ||
65 | |||
66 | int cxd2880_tnrdmd_dvbt_mon_sampling_offset_sub(struct | ||
67 | cxd2880_tnrdmd | ||
68 | *tnr_dmd, | ||
69 | int *ppm); | ||
70 | |||
71 | int cxd2880_tnrdmd_dvbt_mon_ssi(struct cxd2880_tnrdmd *tnr_dmd, | ||
72 | u8 *ssi); | ||
73 | |||
74 | int cxd2880_tnrdmd_dvbt_mon_ssi_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
75 | u8 *ssi); | ||
76 | |||
77 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c new file mode 100644 index 000000000000..3d8012c18e3f --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c | |||
@@ -0,0 +1,150 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_mon.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * common monitor functions | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #include "cxd2880_common.h" | ||
11 | #include "cxd2880_tnrdmd_mon.h" | ||
12 | |||
13 | static const u8 rf_lvl_seq[2] = { | ||
14 | 0x80, 0x00, | ||
15 | }; | ||
16 | |||
17 | int cxd2880_tnrdmd_mon_rf_lvl(struct cxd2880_tnrdmd *tnr_dmd, | ||
18 | int *rf_lvl_db) | ||
19 | { | ||
20 | u8 rdata[2]; | ||
21 | int ret; | ||
22 | |||
23 | if (!tnr_dmd || !rf_lvl_db) | ||
24 | return -EINVAL; | ||
25 | |||
26 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
27 | return -EINVAL; | ||
28 | |||
29 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
30 | CXD2880_IO_TGT_DMD, | ||
31 | 0x00, 0x00); | ||
32 | if (ret) | ||
33 | return ret; | ||
34 | |||
35 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
36 | CXD2880_IO_TGT_DMD, | ||
37 | 0x10, 0x01); | ||
38 | if (ret) | ||
39 | return ret; | ||
40 | |||
41 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
42 | CXD2880_IO_TGT_SYS, | ||
43 | 0x00, 0x10); | ||
44 | if (ret) | ||
45 | return ret; | ||
46 | |||
47 | ret = tnr_dmd->io->write_regs(tnr_dmd->io, | ||
48 | CXD2880_IO_TGT_SYS, | ||
49 | 0x5b, rf_lvl_seq, 2); | ||
50 | if (ret) | ||
51 | return ret; | ||
52 | |||
53 | usleep_range(2000, 3000); | ||
54 | |||
55 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
56 | CXD2880_IO_TGT_SYS, | ||
57 | 0x00, 0x1a); | ||
58 | if (ret) | ||
59 | return ret; | ||
60 | |||
61 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
62 | CXD2880_IO_TGT_SYS, | ||
63 | 0x15, rdata, 2); | ||
64 | if (ret) | ||
65 | return ret; | ||
66 | |||
67 | if (rdata[0] || rdata[1]) | ||
68 | return -EINVAL; | ||
69 | |||
70 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
71 | CXD2880_IO_TGT_SYS, | ||
72 | 0x11, rdata, 2); | ||
73 | if (ret) | ||
74 | return ret; | ||
75 | |||
76 | *rf_lvl_db = | ||
77 | cxd2880_convert2s_complement((rdata[0] << 3) | | ||
78 | ((rdata[1] & 0xe0) >> 5), 11); | ||
79 | |||
80 | *rf_lvl_db *= 125; | ||
81 | |||
82 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
83 | CXD2880_IO_TGT_DMD, | ||
84 | 0x00, 0x00); | ||
85 | if (ret) | ||
86 | return ret; | ||
87 | |||
88 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
89 | CXD2880_IO_TGT_DMD, | ||
90 | 0x10, 0x00); | ||
91 | if (ret) | ||
92 | return ret; | ||
93 | |||
94 | if (tnr_dmd->rf_lvl_cmpstn) | ||
95 | ret = tnr_dmd->rf_lvl_cmpstn(tnr_dmd, rf_lvl_db); | ||
96 | |||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | int cxd2880_tnrdmd_mon_rf_lvl_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
101 | int *rf_lvl_db) | ||
102 | { | ||
103 | if (!tnr_dmd || !rf_lvl_db) | ||
104 | return -EINVAL; | ||
105 | |||
106 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
107 | return -EINVAL; | ||
108 | |||
109 | return cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd->diver_sub, rf_lvl_db); | ||
110 | } | ||
111 | |||
112 | int cxd2880_tnrdmd_mon_internal_cpu_status(struct cxd2880_tnrdmd | ||
113 | *tnr_dmd, u16 *status) | ||
114 | { | ||
115 | u8 data[2] = { 0 }; | ||
116 | int ret; | ||
117 | |||
118 | if (!tnr_dmd || !status) | ||
119 | return -EINVAL; | ||
120 | |||
121 | ret = tnr_dmd->io->write_reg(tnr_dmd->io, | ||
122 | CXD2880_IO_TGT_SYS, | ||
123 | 0x00, 0x1a); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | ret = tnr_dmd->io->read_regs(tnr_dmd->io, | ||
127 | CXD2880_IO_TGT_SYS, | ||
128 | 0x15, data, 2); | ||
129 | if (ret) | ||
130 | return ret; | ||
131 | |||
132 | *status = (data[0] << 8) | data[1]; | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | int cxd2880_tnrdmd_mon_internal_cpu_status_sub(struct | ||
138 | cxd2880_tnrdmd | ||
139 | *tnr_dmd, | ||
140 | u16 *status) | ||
141 | { | ||
142 | if (!tnr_dmd || !status) | ||
143 | return -EINVAL; | ||
144 | |||
145 | if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) | ||
146 | return -EINVAL; | ||
147 | |||
148 | return cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd->diver_sub, | ||
149 | status); | ||
150 | } | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h new file mode 100644 index 000000000000..570360925f87 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * cxd2880_tnrdmd_mon.h | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * common monitor interface | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #ifndef CXD2880_TNRDMD_MON_H | ||
11 | #define CXD2880_TNRDMD_MON_H | ||
12 | |||
13 | #include "cxd2880_common.h" | ||
14 | #include "cxd2880_tnrdmd.h" | ||
15 | |||
16 | int cxd2880_tnrdmd_mon_rf_lvl(struct cxd2880_tnrdmd *tnr_dmd, | ||
17 | int *rf_lvl_db); | ||
18 | |||
19 | int cxd2880_tnrdmd_mon_rf_lvl_sub(struct cxd2880_tnrdmd *tnr_dmd, | ||
20 | int *rf_lvl_db); | ||
21 | |||
22 | int cxd2880_tnrdmd_mon_internal_cpu_status(struct cxd2880_tnrdmd | ||
23 | *tnr_dmd, u16 *status); | ||
24 | |||
25 | int cxd2880_tnrdmd_mon_internal_cpu_status_sub(struct | ||
26 | cxd2880_tnrdmd | ||
27 | *tnr_dmd, | ||
28 | u16 *status); | ||
29 | #endif | ||
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c new file mode 100644 index 000000000000..d474dc1b05da --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c | |||
@@ -0,0 +1,1947 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880_top.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * | ||
6 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
7 | */ | ||
8 | |||
9 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ | ||
10 | |||
11 | #include <linux/spi/spi.h> | ||
12 | |||
13 | #include <media/dvb_frontend.h> | ||
14 | #include <media/dvb_math.h> | ||
15 | |||
16 | #include "cxd2880.h" | ||
17 | #include "cxd2880_tnrdmd_mon.h" | ||
18 | #include "cxd2880_tnrdmd_dvbt2_mon.h" | ||
19 | #include "cxd2880_tnrdmd_dvbt_mon.h" | ||
20 | #include "cxd2880_integ.h" | ||
21 | #include "cxd2880_tnrdmd_dvbt2.h" | ||
22 | #include "cxd2880_tnrdmd_dvbt.h" | ||
23 | #include "cxd2880_devio_spi.h" | ||
24 | #include "cxd2880_spi_device.h" | ||
25 | #include "cxd2880_tnrdmd_driver_version.h" | ||
26 | |||
27 | struct cxd2880_priv { | ||
28 | struct cxd2880_tnrdmd tnrdmd; | ||
29 | struct spi_device *spi; | ||
30 | struct cxd2880_io regio; | ||
31 | struct cxd2880_spi_device spi_device; | ||
32 | struct cxd2880_spi cxd2880_spi; | ||
33 | struct cxd2880_dvbt_tune_param dvbt_tune_param; | ||
34 | struct cxd2880_dvbt2_tune_param dvbt2_tune_param; | ||
35 | struct mutex *spi_mutex; /* For SPI access exclusive control */ | ||
36 | unsigned long pre_ber_update; | ||
37 | unsigned long pre_ber_interval; | ||
38 | unsigned long post_ber_update; | ||
39 | unsigned long post_ber_interval; | ||
40 | unsigned long ucblock_update; | ||
41 | unsigned long ucblock_interval; | ||
42 | enum fe_status s; | ||
43 | }; | ||
44 | |||
45 | static int cxd2880_pre_bit_err_t(struct cxd2880_tnrdmd *tnrdmd, | ||
46 | u32 *pre_bit_err, u32 *pre_bit_count) | ||
47 | { | ||
48 | u8 rdata[2]; | ||
49 | int ret; | ||
50 | |||
51 | if (!tnrdmd || !pre_bit_err || !pre_bit_count) | ||
52 | return -EINVAL; | ||
53 | |||
54 | if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
55 | return -EINVAL; | ||
56 | |||
57 | if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
58 | return -EINVAL; | ||
59 | |||
60 | if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT) | ||
61 | return -EINVAL; | ||
62 | |||
63 | ret = slvt_freeze_reg(tnrdmd); | ||
64 | if (ret) | ||
65 | return ret; | ||
66 | |||
67 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
68 | CXD2880_IO_TGT_DMD, | ||
69 | 0x00, 0x10); | ||
70 | if (ret) { | ||
71 | slvt_unfreeze_reg(tnrdmd); | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
76 | CXD2880_IO_TGT_DMD, | ||
77 | 0x39, rdata, 1); | ||
78 | if (ret) { | ||
79 | slvt_unfreeze_reg(tnrdmd); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | if ((rdata[0] & 0x01) == 0) { | ||
84 | slvt_unfreeze_reg(tnrdmd); | ||
85 | return -EAGAIN; | ||
86 | } | ||
87 | |||
88 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
89 | CXD2880_IO_TGT_DMD, | ||
90 | 0x22, rdata, 2); | ||
91 | if (ret) { | ||
92 | slvt_unfreeze_reg(tnrdmd); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | *pre_bit_err = (rdata[0] << 8) | rdata[1]; | ||
97 | |||
98 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
99 | CXD2880_IO_TGT_DMD, | ||
100 | 0x6f, rdata, 1); | ||
101 | if (ret) { | ||
102 | slvt_unfreeze_reg(tnrdmd); | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | slvt_unfreeze_reg(tnrdmd); | ||
107 | |||
108 | *pre_bit_count = ((rdata[0] & 0x07) == 0) ? | ||
109 | 256 : (0x1000 << (rdata[0] & 0x07)); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int cxd2880_pre_bit_err_t2(struct cxd2880_tnrdmd *tnrdmd, | ||
115 | u32 *pre_bit_err, | ||
116 | u32 *pre_bit_count) | ||
117 | { | ||
118 | u32 period_exp = 0; | ||
119 | u32 n_ldpc = 0; | ||
120 | u8 data[5]; | ||
121 | int ret; | ||
122 | |||
123 | if (!tnrdmd || !pre_bit_err || !pre_bit_count) | ||
124 | return -EINVAL; | ||
125 | |||
126 | if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
127 | return -EINVAL; | ||
128 | |||
129 | if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
130 | return -EINVAL; | ||
131 | |||
132 | if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
133 | return -EINVAL; | ||
134 | |||
135 | ret = slvt_freeze_reg(tnrdmd); | ||
136 | if (ret) | ||
137 | return ret; | ||
138 | |||
139 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
140 | CXD2880_IO_TGT_DMD, | ||
141 | 0x00, 0x0b); | ||
142 | if (ret) { | ||
143 | slvt_unfreeze_reg(tnrdmd); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
148 | CXD2880_IO_TGT_DMD, | ||
149 | 0x3c, data, sizeof(data)); | ||
150 | if (ret) { | ||
151 | slvt_unfreeze_reg(tnrdmd); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | if (!(data[0] & 0x01)) { | ||
156 | slvt_unfreeze_reg(tnrdmd); | ||
157 | return -EAGAIN; | ||
158 | } | ||
159 | *pre_bit_err = | ||
160 | ((data[1] & 0x0f) << 24) | (data[2] << 16) | (data[3] << 8) | data[4]; | ||
161 | |||
162 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
163 | CXD2880_IO_TGT_DMD, | ||
164 | 0xa0, data, 1); | ||
165 | if (ret) { | ||
166 | slvt_unfreeze_reg(tnrdmd); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | if (((enum cxd2880_dvbt2_plp_fec)(data[0] & 0x03)) == | ||
171 | CXD2880_DVBT2_FEC_LDPC_16K) | ||
172 | n_ldpc = 16200; | ||
173 | else | ||
174 | n_ldpc = 64800; | ||
175 | slvt_unfreeze_reg(tnrdmd); | ||
176 | |||
177 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
178 | CXD2880_IO_TGT_DMD, | ||
179 | 0x00, 0x20); | ||
180 | if (ret) | ||
181 | return ret; | ||
182 | |||
183 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
184 | CXD2880_IO_TGT_DMD, | ||
185 | 0x6f, data, 1); | ||
186 | if (ret) | ||
187 | return ret; | ||
188 | |||
189 | period_exp = data[0] & 0x0f; | ||
190 | |||
191 | *pre_bit_count = (1U << period_exp) * n_ldpc; | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int cxd2880_post_bit_err_t(struct cxd2880_tnrdmd *tnrdmd, | ||
197 | u32 *post_bit_err, | ||
198 | u32 *post_bit_count) | ||
199 | { | ||
200 | u8 rdata[3]; | ||
201 | u32 bit_error = 0; | ||
202 | u32 period_exp = 0; | ||
203 | int ret; | ||
204 | |||
205 | if (!tnrdmd || !post_bit_err || !post_bit_count) | ||
206 | return -EINVAL; | ||
207 | |||
208 | if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
209 | return -EINVAL; | ||
210 | |||
211 | if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
212 | return -EINVAL; | ||
213 | |||
214 | if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT) | ||
215 | return -EINVAL; | ||
216 | |||
217 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
218 | CXD2880_IO_TGT_DMD, | ||
219 | 0x00, 0x0d); | ||
220 | if (ret) | ||
221 | return ret; | ||
222 | |||
223 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
224 | CXD2880_IO_TGT_DMD, | ||
225 | 0x15, rdata, 3); | ||
226 | if (ret) | ||
227 | return ret; | ||
228 | |||
229 | if ((rdata[0] & 0x40) == 0) | ||
230 | return -EAGAIN; | ||
231 | |||
232 | *post_bit_err = ((rdata[0] & 0x3f) << 16) | (rdata[1] << 8) | rdata[2]; | ||
233 | |||
234 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
235 | CXD2880_IO_TGT_DMD, | ||
236 | 0x00, 0x10); | ||
237 | if (ret) | ||
238 | return ret; | ||
239 | |||
240 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
241 | CXD2880_IO_TGT_DMD, | ||
242 | 0x60, rdata, 1); | ||
243 | if (ret) | ||
244 | return ret; | ||
245 | |||
246 | period_exp = (rdata[0] & 0x1f); | ||
247 | |||
248 | if (period_exp <= 11 && (bit_error > (1U << period_exp) * 204 * 8)) | ||
249 | return -EAGAIN; | ||
250 | |||
251 | *post_bit_count = (1U << period_exp) * 204 * 8; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int cxd2880_post_bit_err_t2(struct cxd2880_tnrdmd *tnrdmd, | ||
257 | u32 *post_bit_err, | ||
258 | u32 *post_bit_count) | ||
259 | { | ||
260 | u32 period_exp = 0; | ||
261 | u32 n_bch = 0; | ||
262 | u8 data[3]; | ||
263 | enum cxd2880_dvbt2_plp_fec plp_fec_type = | ||
264 | CXD2880_DVBT2_FEC_LDPC_16K; | ||
265 | enum cxd2880_dvbt2_plp_code_rate plp_code_rate = | ||
266 | CXD2880_DVBT2_R1_2; | ||
267 | int ret; | ||
268 | static const u16 n_bch_bits_lookup[2][8] = { | ||
269 | {7200, 9720, 10800, 11880, 12600, 13320, 5400, 6480}, | ||
270 | {32400, 38880, 43200, 48600, 51840, 54000, 21600, 25920} | ||
271 | }; | ||
272 | |||
273 | if (!tnrdmd || !post_bit_err || !post_bit_count) | ||
274 | return -EINVAL; | ||
275 | |||
276 | if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
277 | return -EINVAL; | ||
278 | |||
279 | if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
280 | return -EINVAL; | ||
281 | |||
282 | if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
283 | return -EINVAL; | ||
284 | |||
285 | ret = slvt_freeze_reg(tnrdmd); | ||
286 | if (ret) | ||
287 | return ret; | ||
288 | |||
289 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
290 | CXD2880_IO_TGT_DMD, | ||
291 | 0x00, 0x0b); | ||
292 | if (ret) { | ||
293 | slvt_unfreeze_reg(tnrdmd); | ||
294 | return ret; | ||
295 | } | ||
296 | |||
297 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
298 | CXD2880_IO_TGT_DMD, | ||
299 | 0x15, data, 3); | ||
300 | if (ret) { | ||
301 | slvt_unfreeze_reg(tnrdmd); | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | if (!(data[0] & 0x40)) { | ||
306 | slvt_unfreeze_reg(tnrdmd); | ||
307 | return -EAGAIN; | ||
308 | } | ||
309 | |||
310 | *post_bit_err = | ||
311 | ((data[0] & 0x3f) << 16) | (data[1] << 8) | data[2]; | ||
312 | |||
313 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
314 | CXD2880_IO_TGT_DMD, | ||
315 | 0x9d, data, 1); | ||
316 | if (ret) { | ||
317 | slvt_unfreeze_reg(tnrdmd); | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | plp_code_rate = | ||
322 | (enum cxd2880_dvbt2_plp_code_rate)(data[0] & 0x07); | ||
323 | |||
324 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
325 | CXD2880_IO_TGT_DMD, | ||
326 | 0xa0, data, 1); | ||
327 | if (ret) { | ||
328 | slvt_unfreeze_reg(tnrdmd); | ||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | plp_fec_type = (enum cxd2880_dvbt2_plp_fec)(data[0] & 0x03); | ||
333 | |||
334 | slvt_unfreeze_reg(tnrdmd); | ||
335 | |||
336 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
337 | CXD2880_IO_TGT_DMD, | ||
338 | 0x00, 0x20); | ||
339 | if (ret) | ||
340 | return ret; | ||
341 | |||
342 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
343 | CXD2880_IO_TGT_DMD, | ||
344 | 0x72, data, 1); | ||
345 | if (ret) | ||
346 | return ret; | ||
347 | |||
348 | period_exp = data[0] & 0x0f; | ||
349 | |||
350 | if (plp_fec_type > CXD2880_DVBT2_FEC_LDPC_64K || | ||
351 | plp_code_rate > CXD2880_DVBT2_R2_5) | ||
352 | return -EAGAIN; | ||
353 | |||
354 | n_bch = n_bch_bits_lookup[plp_fec_type][plp_code_rate]; | ||
355 | |||
356 | if (*post_bit_err > ((1U << period_exp) * n_bch)) | ||
357 | return -EAGAIN; | ||
358 | |||
359 | *post_bit_count = (1U << period_exp) * n_bch; | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static int cxd2880_read_block_err_t(struct cxd2880_tnrdmd *tnrdmd, | ||
365 | u32 *block_err, | ||
366 | u32 *block_count) | ||
367 | { | ||
368 | u8 rdata[3]; | ||
369 | int ret; | ||
370 | |||
371 | if (!tnrdmd || !block_err || !block_count) | ||
372 | return -EINVAL; | ||
373 | |||
374 | if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
375 | return -EINVAL; | ||
376 | |||
377 | if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
378 | return -EINVAL; | ||
379 | |||
380 | if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT) | ||
381 | return -EINVAL; | ||
382 | |||
383 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
384 | CXD2880_IO_TGT_DMD, | ||
385 | 0x00, 0x0d); | ||
386 | if (ret) | ||
387 | return ret; | ||
388 | |||
389 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
390 | CXD2880_IO_TGT_DMD, | ||
391 | 0x18, rdata, 3); | ||
392 | if (ret) | ||
393 | return ret; | ||
394 | |||
395 | if ((rdata[0] & 0x01) == 0) | ||
396 | return -EAGAIN; | ||
397 | |||
398 | *block_err = (rdata[1] << 8) | rdata[2]; | ||
399 | |||
400 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
401 | CXD2880_IO_TGT_DMD, | ||
402 | 0x00, 0x10); | ||
403 | if (ret) | ||
404 | return ret; | ||
405 | |||
406 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
407 | CXD2880_IO_TGT_DMD, | ||
408 | 0x5c, rdata, 1); | ||
409 | if (ret) | ||
410 | return ret; | ||
411 | |||
412 | *block_count = 1U << (rdata[0] & 0x0f); | ||
413 | |||
414 | if ((*block_count == 0) || (*block_err > *block_count)) | ||
415 | return -EAGAIN; | ||
416 | |||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | static int cxd2880_read_block_err_t2(struct cxd2880_tnrdmd *tnrdmd, | ||
421 | u32 *block_err, | ||
422 | u32 *block_count) | ||
423 | { | ||
424 | u8 rdata[3]; | ||
425 | int ret; | ||
426 | |||
427 | if (!tnrdmd || !block_err || !block_count) | ||
428 | return -EINVAL; | ||
429 | |||
430 | if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
431 | return -EINVAL; | ||
432 | |||
433 | if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
434 | return -EINVAL; | ||
435 | if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT2) | ||
436 | return -EINVAL; | ||
437 | |||
438 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
439 | CXD2880_IO_TGT_DMD, | ||
440 | 0x00, 0x0b); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | |||
444 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
445 | CXD2880_IO_TGT_DMD, | ||
446 | 0x18, rdata, 3); | ||
447 | if (ret) | ||
448 | return ret; | ||
449 | |||
450 | if ((rdata[0] & 0x01) == 0) | ||
451 | return -EAGAIN; | ||
452 | |||
453 | *block_err = (rdata[1] << 8) | rdata[2]; | ||
454 | |||
455 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
456 | CXD2880_IO_TGT_DMD, | ||
457 | 0x00, 0x24); | ||
458 | if (ret) | ||
459 | return ret; | ||
460 | |||
461 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
462 | CXD2880_IO_TGT_DMD, | ||
463 | 0xdc, rdata, 1); | ||
464 | if (ret) | ||
465 | return ret; | ||
466 | |||
467 | *block_count = 1U << (rdata[0] & 0x0f); | ||
468 | |||
469 | if ((*block_count == 0) || (*block_err > *block_count)) | ||
470 | return -EAGAIN; | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static void cxd2880_release(struct dvb_frontend *fe) | ||
476 | { | ||
477 | struct cxd2880_priv *priv = NULL; | ||
478 | |||
479 | if (!fe) { | ||
480 | pr_err("invalid arg.\n"); | ||
481 | return; | ||
482 | } | ||
483 | priv = fe->demodulator_priv; | ||
484 | kfree(priv); | ||
485 | } | ||
486 | |||
487 | static int cxd2880_init(struct dvb_frontend *fe) | ||
488 | { | ||
489 | int ret; | ||
490 | struct cxd2880_priv *priv = NULL; | ||
491 | struct cxd2880_tnrdmd_create_param create_param; | ||
492 | |||
493 | if (!fe) { | ||
494 | pr_err("invalid arg.\n"); | ||
495 | return -EINVAL; | ||
496 | } | ||
497 | |||
498 | priv = fe->demodulator_priv; | ||
499 | |||
500 | create_param.ts_output_if = CXD2880_TNRDMD_TSOUT_IF_SPI; | ||
501 | create_param.xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_NONE; | ||
502 | create_param.en_internal_ldo = 1; | ||
503 | create_param.xosc_cap = 18; | ||
504 | create_param.xosc_i = 8; | ||
505 | create_param.stationary_use = 1; | ||
506 | |||
507 | mutex_lock(priv->spi_mutex); | ||
508 | if (priv->tnrdmd.io != &priv->regio) { | ||
509 | ret = cxd2880_tnrdmd_create(&priv->tnrdmd, | ||
510 | &priv->regio, &create_param); | ||
511 | if (ret) { | ||
512 | mutex_unlock(priv->spi_mutex); | ||
513 | pr_info("cxd2880 tnrdmd create failed %d\n", ret); | ||
514 | return ret; | ||
515 | } | ||
516 | } | ||
517 | ret = cxd2880_integ_init(&priv->tnrdmd); | ||
518 | if (ret) { | ||
519 | mutex_unlock(priv->spi_mutex); | ||
520 | pr_err("cxd2880 integ init failed %d\n", ret); | ||
521 | return ret; | ||
522 | } | ||
523 | mutex_unlock(priv->spi_mutex); | ||
524 | |||
525 | pr_debug("OK.\n"); | ||
526 | |||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | static int cxd2880_sleep(struct dvb_frontend *fe) | ||
531 | { | ||
532 | int ret; | ||
533 | struct cxd2880_priv *priv = NULL; | ||
534 | |||
535 | if (!fe) { | ||
536 | pr_err("invalid arg\n"); | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | |||
540 | priv = fe->demodulator_priv; | ||
541 | |||
542 | mutex_lock(priv->spi_mutex); | ||
543 | ret = cxd2880_tnrdmd_sleep(&priv->tnrdmd); | ||
544 | mutex_unlock(priv->spi_mutex); | ||
545 | |||
546 | pr_debug("tnrdmd_sleep ret %d\n", ret); | ||
547 | |||
548 | return ret; | ||
549 | } | ||
550 | |||
551 | static int cxd2880_read_signal_strength(struct dvb_frontend *fe, | ||
552 | u16 *strength) | ||
553 | { | ||
554 | int ret; | ||
555 | struct cxd2880_priv *priv = NULL; | ||
556 | struct dtv_frontend_properties *c = NULL; | ||
557 | int level = 0; | ||
558 | |||
559 | if (!fe || !strength) { | ||
560 | pr_err("invalid arg\n"); | ||
561 | return -EINVAL; | ||
562 | } | ||
563 | |||
564 | priv = fe->demodulator_priv; | ||
565 | c = &fe->dtv_property_cache; | ||
566 | |||
567 | mutex_lock(priv->spi_mutex); | ||
568 | if (c->delivery_system == SYS_DVBT || | ||
569 | c->delivery_system == SYS_DVBT2) { | ||
570 | ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &level); | ||
571 | } else { | ||
572 | pr_debug("invalid system\n"); | ||
573 | mutex_unlock(priv->spi_mutex); | ||
574 | return -EINVAL; | ||
575 | } | ||
576 | mutex_unlock(priv->spi_mutex); | ||
577 | |||
578 | level /= 125; | ||
579 | /* | ||
580 | * level should be between -105dBm and -30dBm. | ||
581 | * E.g. they should be between: | ||
582 | * -105000/125 = -840 and -30000/125 = -240 | ||
583 | */ | ||
584 | level = clamp(level, -840, -240); | ||
585 | /* scale value to 0x0000-0xffff */ | ||
586 | *strength = ((level + 840) * 0xffff) / (-240 + 840); | ||
587 | |||
588 | if (ret) | ||
589 | pr_debug("ret = %d\n", ret); | ||
590 | |||
591 | return ret; | ||
592 | } | ||
593 | |||
594 | static int cxd2880_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
595 | { | ||
596 | int ret; | ||
597 | int snrvalue = 0; | ||
598 | struct cxd2880_priv *priv = NULL; | ||
599 | struct dtv_frontend_properties *c = NULL; | ||
600 | |||
601 | if (!fe || !snr) { | ||
602 | pr_err("invalid arg\n"); | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | priv = fe->demodulator_priv; | ||
607 | c = &fe->dtv_property_cache; | ||
608 | |||
609 | mutex_lock(priv->spi_mutex); | ||
610 | if (c->delivery_system == SYS_DVBT) { | ||
611 | ret = cxd2880_tnrdmd_dvbt_mon_snr(&priv->tnrdmd, | ||
612 | &snrvalue); | ||
613 | } else if (c->delivery_system == SYS_DVBT2) { | ||
614 | ret = cxd2880_tnrdmd_dvbt2_mon_snr(&priv->tnrdmd, | ||
615 | &snrvalue); | ||
616 | } else { | ||
617 | pr_err("invalid system\n"); | ||
618 | mutex_unlock(priv->spi_mutex); | ||
619 | return -EINVAL; | ||
620 | } | ||
621 | mutex_unlock(priv->spi_mutex); | ||
622 | |||
623 | if (snrvalue < 0) | ||
624 | snrvalue = 0; | ||
625 | *snr = snrvalue; | ||
626 | |||
627 | if (ret) | ||
628 | pr_debug("ret = %d\n", ret); | ||
629 | |||
630 | return ret; | ||
631 | } | ||
632 | |||
633 | static int cxd2880_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
634 | { | ||
635 | int ret; | ||
636 | struct cxd2880_priv *priv = NULL; | ||
637 | struct dtv_frontend_properties *c = NULL; | ||
638 | |||
639 | if (!fe || !ucblocks) { | ||
640 | pr_err("invalid arg\n"); | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | priv = fe->demodulator_priv; | ||
645 | c = &fe->dtv_property_cache; | ||
646 | |||
647 | mutex_lock(priv->spi_mutex); | ||
648 | if (c->delivery_system == SYS_DVBT) { | ||
649 | ret = cxd2880_tnrdmd_dvbt_mon_packet_error_number(&priv->tnrdmd, | ||
650 | ucblocks); | ||
651 | } else if (c->delivery_system == SYS_DVBT2) { | ||
652 | ret = cxd2880_tnrdmd_dvbt2_mon_packet_error_number(&priv->tnrdmd, | ||
653 | ucblocks); | ||
654 | } else { | ||
655 | pr_err("invalid system\n"); | ||
656 | mutex_unlock(priv->spi_mutex); | ||
657 | return -EINVAL; | ||
658 | } | ||
659 | mutex_unlock(priv->spi_mutex); | ||
660 | |||
661 | if (ret) | ||
662 | pr_debug("ret = %d\n", ret); | ||
663 | |||
664 | return ret; | ||
665 | } | ||
666 | |||
667 | static int cxd2880_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
668 | { | ||
669 | *ber = 0; | ||
670 | |||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | static int cxd2880_set_ber_per_period_t(struct dvb_frontend *fe) | ||
675 | { | ||
676 | int ret; | ||
677 | struct cxd2880_priv *priv; | ||
678 | struct cxd2880_dvbt_tpsinfo info; | ||
679 | enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ; | ||
680 | u32 pre_ber_rate = 0; | ||
681 | u32 post_ber_rate = 0; | ||
682 | u32 ucblock_rate = 0; | ||
683 | u32 mes_exp = 0; | ||
684 | static const int cr_table[5] = {31500, 42000, 47250, 52500, 55125}; | ||
685 | static const int denominator_tbl[4] = {125664, 129472, 137088, 152320}; | ||
686 | |||
687 | if (!fe) { | ||
688 | pr_err("invalid arg\n"); | ||
689 | return -EINVAL; | ||
690 | } | ||
691 | |||
692 | priv = fe->demodulator_priv; | ||
693 | bw = priv->dvbt_tune_param.bandwidth; | ||
694 | |||
695 | ret = cxd2880_tnrdmd_dvbt_mon_tps_info(&priv->tnrdmd, | ||
696 | &info); | ||
697 | if (ret) { | ||
698 | pr_err("tps monitor error ret = %d\n", ret); | ||
699 | info.hierarchy = CXD2880_DVBT_HIERARCHY_NON; | ||
700 | info.constellation = CXD2880_DVBT_CONSTELLATION_QPSK; | ||
701 | info.guard = CXD2880_DVBT_GUARD_1_4; | ||
702 | info.rate_hp = CXD2880_DVBT_CODERATE_1_2; | ||
703 | info.rate_lp = CXD2880_DVBT_CODERATE_1_2; | ||
704 | } | ||
705 | |||
706 | if (info.hierarchy == CXD2880_DVBT_HIERARCHY_NON) { | ||
707 | pre_ber_rate = 63000000 * bw * (info.constellation * 2 + 2) / | ||
708 | denominator_tbl[info.guard]; | ||
709 | |||
710 | post_ber_rate = 1000 * cr_table[info.rate_hp] * bw * | ||
711 | (info.constellation * 2 + 2) / | ||
712 | denominator_tbl[info.guard]; | ||
713 | |||
714 | ucblock_rate = 875 * cr_table[info.rate_hp] * bw * | ||
715 | (info.constellation * 2 + 2) / | ||
716 | denominator_tbl[info.guard]; | ||
717 | } else { | ||
718 | u8 data = 0; | ||
719 | struct cxd2880_tnrdmd *tnrdmd = &priv->tnrdmd; | ||
720 | |||
721 | ret = tnrdmd->io->write_reg(tnrdmd->io, | ||
722 | CXD2880_IO_TGT_DMD, | ||
723 | 0x00, 0x10); | ||
724 | if (!ret) { | ||
725 | ret = tnrdmd->io->read_regs(tnrdmd->io, | ||
726 | CXD2880_IO_TGT_DMD, | ||
727 | 0x67, &data, 1); | ||
728 | if (ret) | ||
729 | data = 0x00; | ||
730 | } else { | ||
731 | data = 0x00; | ||
732 | } | ||
733 | |||
734 | if (data & 0x01) { /* Low priority */ | ||
735 | pre_ber_rate = | ||
736 | 63000000 * bw * (info.constellation * 2 + 2) / | ||
737 | denominator_tbl[info.guard]; | ||
738 | |||
739 | post_ber_rate = 1000 * cr_table[info.rate_lp] * bw * | ||
740 | (info.constellation * 2 + 2) / | ||
741 | denominator_tbl[info.guard]; | ||
742 | |||
743 | ucblock_rate = (1000 * 7 / 8) * cr_table[info.rate_lp] * | ||
744 | bw * (info.constellation * 2 + 2) / | ||
745 | denominator_tbl[info.guard]; | ||
746 | } else { /* High priority */ | ||
747 | pre_ber_rate = | ||
748 | 63000000 * bw * 2 / denominator_tbl[info.guard]; | ||
749 | |||
750 | post_ber_rate = 1000 * cr_table[info.rate_hp] * bw * 2 / | ||
751 | denominator_tbl[info.guard]; | ||
752 | |||
753 | ucblock_rate = (1000 * 7 / 8) * cr_table[info.rate_hp] * | ||
754 | bw * 2 / denominator_tbl[info.guard]; | ||
755 | } | ||
756 | } | ||
757 | |||
758 | mes_exp = pre_ber_rate < 8192 ? 8 : intlog2(pre_ber_rate) >> 24; | ||
759 | priv->pre_ber_interval = | ||
760 | ((1U << mes_exp) * 1000 + (pre_ber_rate / 2)) / | ||
761 | pre_ber_rate; | ||
762 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
763 | CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD, | ||
764 | mes_exp == 8 ? 0 : mes_exp - 12); | ||
765 | |||
766 | mes_exp = intlog2(post_ber_rate) >> 24; | ||
767 | priv->post_ber_interval = | ||
768 | ((1U << mes_exp) * 1000 + (post_ber_rate / 2)) / | ||
769 | post_ber_rate; | ||
770 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
771 | CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD, | ||
772 | mes_exp); | ||
773 | |||
774 | mes_exp = intlog2(ucblock_rate) >> 24; | ||
775 | priv->ucblock_interval = | ||
776 | ((1U << mes_exp) * 1000 + (ucblock_rate / 2)) / | ||
777 | ucblock_rate; | ||
778 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
779 | CXD2880_TNRDMD_CFG_DVBT_PER_MES, | ||
780 | mes_exp); | ||
781 | |||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static int cxd2880_set_ber_per_period_t2(struct dvb_frontend *fe) | ||
786 | { | ||
787 | int ret; | ||
788 | struct cxd2880_priv *priv; | ||
789 | struct cxd2880_dvbt2_l1pre l1pre; | ||
790 | struct cxd2880_dvbt2_l1post l1post; | ||
791 | struct cxd2880_dvbt2_plp plp; | ||
792 | struct cxd2880_dvbt2_bbheader bbheader; | ||
793 | enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ; | ||
794 | u32 pre_ber_rate = 0; | ||
795 | u32 post_ber_rate = 0; | ||
796 | u32 ucblock_rate = 0; | ||
797 | u32 mes_exp = 0; | ||
798 | u32 term_a = 0; | ||
799 | u32 term_b = 0; | ||
800 | u32 denominator = 0; | ||
801 | static const u32 gi_tbl[7] = {32, 64, 128, 256, 8, 152, 76}; | ||
802 | static const u8 n_tbl[6] = {8, 2, 4, 16, 1, 1}; | ||
803 | static const u8 mode_tbl[6] = {2, 8, 4, 1, 16, 32}; | ||
804 | static const u32 kbch_tbl[2][8] = { | ||
805 | {6952, 9472, 10552, 11632, 12352, 13072, 5152, 6232}, | ||
806 | {32128, 38608, 42960, 48328, 51568, 53760, 0, 0} | ||
807 | }; | ||
808 | |||
809 | if (!fe) { | ||
810 | pr_err("invalid arg\n"); | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | |||
814 | priv = fe->demodulator_priv; | ||
815 | bw = priv->dvbt2_tune_param.bandwidth; | ||
816 | |||
817 | ret = cxd2880_tnrdmd_dvbt2_mon_l1_pre(&priv->tnrdmd, &l1pre); | ||
818 | if (ret) { | ||
819 | pr_info("l1 pre error\n"); | ||
820 | goto error_ber_setting; | ||
821 | } | ||
822 | |||
823 | ret = cxd2880_tnrdmd_dvbt2_mon_active_plp(&priv->tnrdmd, | ||
824 | CXD2880_DVBT2_PLP_DATA, &plp); | ||
825 | if (ret) { | ||
826 | pr_info("plp info error\n"); | ||
827 | goto error_ber_setting; | ||
828 | } | ||
829 | |||
830 | ret = cxd2880_tnrdmd_dvbt2_mon_l1_post(&priv->tnrdmd, &l1post); | ||
831 | if (ret) { | ||
832 | pr_info("l1 post error\n"); | ||
833 | goto error_ber_setting; | ||
834 | } | ||
835 | |||
836 | term_a = | ||
837 | (mode_tbl[l1pre.fft_mode] * (1024 + gi_tbl[l1pre.gi])) * | ||
838 | (l1pre.num_symbols + n_tbl[l1pre.fft_mode]) + 2048; | ||
839 | |||
840 | if (l1pre.mixed && l1post.fef_intvl) { | ||
841 | term_b = (l1post.fef_length + (l1post.fef_intvl / 2)) / | ||
842 | l1post.fef_intvl; | ||
843 | } else { | ||
844 | term_b = 0; | ||
845 | } | ||
846 | |||
847 | switch (bw) { | ||
848 | case CXD2880_DTV_BW_1_7_MHZ: | ||
849 | denominator = ((term_a + term_b) * 71 + (131 / 2)) / 131; | ||
850 | break; | ||
851 | case CXD2880_DTV_BW_5_MHZ: | ||
852 | denominator = ((term_a + term_b) * 7 + 20) / 40; | ||
853 | break; | ||
854 | case CXD2880_DTV_BW_6_MHZ: | ||
855 | denominator = ((term_a + term_b) * 7 + 24) / 48; | ||
856 | break; | ||
857 | case CXD2880_DTV_BW_7_MHZ: | ||
858 | denominator = ((term_a + term_b) + 4) / 8; | ||
859 | break; | ||
860 | case CXD2880_DTV_BW_8_MHZ: | ||
861 | default: | ||
862 | denominator = ((term_a + term_b) * 7 + 32) / 64; | ||
863 | break; | ||
864 | } | ||
865 | |||
866 | if (plp.til_type && plp.til_len) { | ||
867 | pre_ber_rate = | ||
868 | (plp.num_blocks_max * 1000000 + (denominator / 2)) / | ||
869 | denominator; | ||
870 | pre_ber_rate = (pre_ber_rate + (plp.til_len / 2)) / | ||
871 | plp.til_len; | ||
872 | } else { | ||
873 | pre_ber_rate = | ||
874 | (plp.num_blocks_max * 1000000 + (denominator / 2)) / | ||
875 | denominator; | ||
876 | } | ||
877 | |||
878 | post_ber_rate = pre_ber_rate; | ||
879 | |||
880 | mes_exp = intlog2(pre_ber_rate) >> 24; | ||
881 | priv->pre_ber_interval = | ||
882 | ((1U << mes_exp) * 1000 + (pre_ber_rate / 2)) / | ||
883 | pre_ber_rate; | ||
884 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
885 | CXD2880_TNRDMD_CFG_DVBT2_LBER_MES, | ||
886 | mes_exp); | ||
887 | |||
888 | mes_exp = intlog2(post_ber_rate) >> 24; | ||
889 | priv->post_ber_interval = | ||
890 | ((1U << mes_exp) * 1000 + (post_ber_rate / 2)) / | ||
891 | post_ber_rate; | ||
892 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
893 | CXD2880_TNRDMD_CFG_DVBT2_BBER_MES, | ||
894 | mes_exp); | ||
895 | |||
896 | ret = cxd2880_tnrdmd_dvbt2_mon_bbheader(&priv->tnrdmd, | ||
897 | CXD2880_DVBT2_PLP_DATA, | ||
898 | &bbheader); | ||
899 | if (ret) { | ||
900 | pr_info("bb header error\n"); | ||
901 | goto error_ucblock_setting; | ||
902 | } | ||
903 | |||
904 | if (bbheader.plp_mode == CXD2880_DVBT2_PLP_MODE_NM) { | ||
905 | if (!bbheader.issy_indicator) { | ||
906 | ucblock_rate = | ||
907 | (pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] + | ||
908 | 752) / 1504; | ||
909 | } else { | ||
910 | ucblock_rate = | ||
911 | (pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] + | ||
912 | 764) / 1528; | ||
913 | } | ||
914 | } else if (bbheader.plp_mode == CXD2880_DVBT2_PLP_MODE_HEM) { | ||
915 | ucblock_rate = | ||
916 | (pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] + 748) / | ||
917 | 1496; | ||
918 | } else { | ||
919 | pr_info("plp mode is not Normal or HEM\n"); | ||
920 | goto error_ucblock_setting; | ||
921 | } | ||
922 | |||
923 | mes_exp = intlog2(ucblock_rate) >> 24; | ||
924 | priv->ucblock_interval = | ||
925 | ((1U << mes_exp) * 1000 + (ucblock_rate / 2)) / | ||
926 | ucblock_rate; | ||
927 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
928 | CXD2880_TNRDMD_CFG_DVBT2_PER_MES, | ||
929 | mes_exp); | ||
930 | |||
931 | return 0; | ||
932 | |||
933 | error_ber_setting: | ||
934 | priv->pre_ber_interval = 1000; | ||
935 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
936 | CXD2880_TNRDMD_CFG_DVBT2_LBER_MES, 0); | ||
937 | |||
938 | priv->post_ber_interval = 1000; | ||
939 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
940 | CXD2880_TNRDMD_CFG_DVBT2_BBER_MES, 0); | ||
941 | |||
942 | error_ucblock_setting: | ||
943 | priv->ucblock_interval = 1000; | ||
944 | cxd2880_tnrdmd_set_cfg(&priv->tnrdmd, | ||
945 | CXD2880_TNRDMD_CFG_DVBT2_PER_MES, 8); | ||
946 | |||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static int cxd2880_dvbt_tune(struct cxd2880_tnrdmd *tnr_dmd, | ||
951 | struct cxd2880_dvbt_tune_param | ||
952 | *tune_param) | ||
953 | { | ||
954 | int ret; | ||
955 | |||
956 | if (!tnr_dmd || !tune_param) | ||
957 | return -EINVAL; | ||
958 | |||
959 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
960 | return -EINVAL; | ||
961 | |||
962 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
963 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
964 | return -EINVAL; | ||
965 | |||
966 | atomic_set(&tnr_dmd->cancel, 0); | ||
967 | |||
968 | if (tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ && | ||
969 | tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ && | ||
970 | tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ && | ||
971 | tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ) { | ||
972 | return -ENOTTY; | ||
973 | } | ||
974 | |||
975 | ret = cxd2880_tnrdmd_dvbt_tune1(tnr_dmd, tune_param); | ||
976 | if (ret) | ||
977 | return ret; | ||
978 | |||
979 | usleep_range(CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000, | ||
980 | CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000 + 1000); | ||
981 | |||
982 | return cxd2880_tnrdmd_dvbt_tune2(tnr_dmd, tune_param); | ||
983 | } | ||
984 | |||
985 | static int cxd2880_dvbt2_tune(struct cxd2880_tnrdmd *tnr_dmd, | ||
986 | struct cxd2880_dvbt2_tune_param | ||
987 | *tune_param) | ||
988 | { | ||
989 | int ret; | ||
990 | |||
991 | if (!tnr_dmd || !tune_param) | ||
992 | return -EINVAL; | ||
993 | |||
994 | if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) | ||
995 | return -EINVAL; | ||
996 | |||
997 | if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && | ||
998 | tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) | ||
999 | return -EINVAL; | ||
1000 | |||
1001 | atomic_set(&tnr_dmd->cancel, 0); | ||
1002 | |||
1003 | if (tune_param->bandwidth != CXD2880_DTV_BW_1_7_MHZ && | ||
1004 | tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ && | ||
1005 | tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ && | ||
1006 | tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ && | ||
1007 | tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ) { | ||
1008 | return -ENOTTY; | ||
1009 | } | ||
1010 | |||
1011 | if (tune_param->profile != CXD2880_DVBT2_PROFILE_BASE && | ||
1012 | tune_param->profile != CXD2880_DVBT2_PROFILE_LITE) | ||
1013 | return -EINVAL; | ||
1014 | |||
1015 | ret = cxd2880_tnrdmd_dvbt2_tune1(tnr_dmd, tune_param); | ||
1016 | if (ret) | ||
1017 | return ret; | ||
1018 | |||
1019 | usleep_range(CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000, | ||
1020 | CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000 + 1000); | ||
1021 | |||
1022 | return cxd2880_tnrdmd_dvbt2_tune2(tnr_dmd, tune_param); | ||
1023 | } | ||
1024 | |||
1025 | static int cxd2880_set_frontend(struct dvb_frontend *fe) | ||
1026 | { | ||
1027 | int ret; | ||
1028 | struct dtv_frontend_properties *c; | ||
1029 | struct cxd2880_priv *priv; | ||
1030 | enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ; | ||
1031 | |||
1032 | if (!fe) { | ||
1033 | pr_err("invalid arg\n"); | ||
1034 | return -EINVAL; | ||
1035 | } | ||
1036 | |||
1037 | priv = fe->demodulator_priv; | ||
1038 | c = &fe->dtv_property_cache; | ||
1039 | |||
1040 | c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1041 | c->pre_bit_error.stat[0].uvalue = 0; | ||
1042 | c->pre_bit_error.len = 1; | ||
1043 | c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1044 | c->pre_bit_count.stat[0].uvalue = 0; | ||
1045 | c->pre_bit_count.len = 1; | ||
1046 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1047 | c->post_bit_error.stat[0].uvalue = 0; | ||
1048 | c->post_bit_error.len = 1; | ||
1049 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1050 | c->post_bit_count.stat[0].uvalue = 0; | ||
1051 | c->post_bit_count.len = 1; | ||
1052 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1053 | c->block_error.stat[0].uvalue = 0; | ||
1054 | c->block_error.len = 1; | ||
1055 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1056 | c->block_count.stat[0].uvalue = 0; | ||
1057 | c->block_count.len = 1; | ||
1058 | |||
1059 | switch (c->bandwidth_hz) { | ||
1060 | case 1712000: | ||
1061 | bw = CXD2880_DTV_BW_1_7_MHZ; | ||
1062 | break; | ||
1063 | case 5000000: | ||
1064 | bw = CXD2880_DTV_BW_5_MHZ; | ||
1065 | break; | ||
1066 | case 6000000: | ||
1067 | bw = CXD2880_DTV_BW_6_MHZ; | ||
1068 | break; | ||
1069 | case 7000000: | ||
1070 | bw = CXD2880_DTV_BW_7_MHZ; | ||
1071 | break; | ||
1072 | case 8000000: | ||
1073 | bw = CXD2880_DTV_BW_8_MHZ; | ||
1074 | break; | ||
1075 | default: | ||
1076 | return -EINVAL; | ||
1077 | } | ||
1078 | |||
1079 | priv->s = 0; | ||
1080 | |||
1081 | pr_info("sys:%d freq:%d bw:%d\n", | ||
1082 | c->delivery_system, c->frequency, bw); | ||
1083 | mutex_lock(priv->spi_mutex); | ||
1084 | if (c->delivery_system == SYS_DVBT) { | ||
1085 | priv->tnrdmd.sys = CXD2880_DTV_SYS_DVBT; | ||
1086 | priv->dvbt_tune_param.center_freq_khz = c->frequency / 1000; | ||
1087 | priv->dvbt_tune_param.bandwidth = bw; | ||
1088 | priv->dvbt_tune_param.profile = CXD2880_DVBT_PROFILE_HP; | ||
1089 | ret = cxd2880_dvbt_tune(&priv->tnrdmd, | ||
1090 | &priv->dvbt_tune_param); | ||
1091 | } else if (c->delivery_system == SYS_DVBT2) { | ||
1092 | priv->tnrdmd.sys = CXD2880_DTV_SYS_DVBT2; | ||
1093 | priv->dvbt2_tune_param.center_freq_khz = c->frequency / 1000; | ||
1094 | priv->dvbt2_tune_param.bandwidth = bw; | ||
1095 | priv->dvbt2_tune_param.data_plp_id = (u16)c->stream_id; | ||
1096 | priv->dvbt2_tune_param.profile = CXD2880_DVBT2_PROFILE_BASE; | ||
1097 | ret = cxd2880_dvbt2_tune(&priv->tnrdmd, | ||
1098 | &priv->dvbt2_tune_param); | ||
1099 | } else { | ||
1100 | pr_err("invalid system\n"); | ||
1101 | mutex_unlock(priv->spi_mutex); | ||
1102 | return -EINVAL; | ||
1103 | } | ||
1104 | mutex_unlock(priv->spi_mutex); | ||
1105 | |||
1106 | pr_info("tune result %d\n", ret); | ||
1107 | |||
1108 | return ret; | ||
1109 | } | ||
1110 | |||
1111 | static int cxd2880_get_stats(struct dvb_frontend *fe, | ||
1112 | enum fe_status status) | ||
1113 | { | ||
1114 | struct cxd2880_priv *priv = NULL; | ||
1115 | struct dtv_frontend_properties *c = NULL; | ||
1116 | u32 pre_bit_err = 0, pre_bit_count = 0; | ||
1117 | u32 post_bit_err = 0, post_bit_count = 0; | ||
1118 | u32 block_err = 0, block_count = 0; | ||
1119 | int ret; | ||
1120 | |||
1121 | if (!fe) { | ||
1122 | pr_err("invalid arg\n"); | ||
1123 | return -EINVAL; | ||
1124 | } | ||
1125 | |||
1126 | priv = fe->demodulator_priv; | ||
1127 | c = &fe->dtv_property_cache; | ||
1128 | |||
1129 | if (!(status & FE_HAS_LOCK)) { | ||
1130 | c->pre_bit_error.len = 1; | ||
1131 | c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1132 | c->pre_bit_count.len = 1; | ||
1133 | c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1134 | c->post_bit_error.len = 1; | ||
1135 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1136 | c->post_bit_count.len = 1; | ||
1137 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1138 | c->block_error.len = 1; | ||
1139 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1140 | c->block_count.len = 1; | ||
1141 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1142 | |||
1143 | return 0; | ||
1144 | } | ||
1145 | |||
1146 | if (time_after(jiffies, priv->pre_ber_update)) { | ||
1147 | priv->pre_ber_update = | ||
1148 | jiffies + msecs_to_jiffies(priv->pre_ber_interval); | ||
1149 | if (c->delivery_system == SYS_DVBT) { | ||
1150 | mutex_lock(priv->spi_mutex); | ||
1151 | ret = cxd2880_pre_bit_err_t(&priv->tnrdmd, | ||
1152 | &pre_bit_err, | ||
1153 | &pre_bit_count); | ||
1154 | mutex_unlock(priv->spi_mutex); | ||
1155 | } else if (c->delivery_system == SYS_DVBT2) { | ||
1156 | mutex_lock(priv->spi_mutex); | ||
1157 | ret = cxd2880_pre_bit_err_t2(&priv->tnrdmd, | ||
1158 | &pre_bit_err, | ||
1159 | &pre_bit_count); | ||
1160 | mutex_unlock(priv->spi_mutex); | ||
1161 | } else { | ||
1162 | return -EINVAL; | ||
1163 | } | ||
1164 | |||
1165 | if (!ret) { | ||
1166 | c->pre_bit_error.len = 1; | ||
1167 | c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||
1168 | c->pre_bit_error.stat[0].uvalue += pre_bit_err; | ||
1169 | c->pre_bit_count.len = 1; | ||
1170 | c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; | ||
1171 | c->pre_bit_count.stat[0].uvalue += pre_bit_count; | ||
1172 | } else { | ||
1173 | c->pre_bit_error.len = 1; | ||
1174 | c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1175 | c->pre_bit_count.len = 1; | ||
1176 | c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1177 | pr_debug("pre_bit_error_t failed %d\n", ret); | ||
1178 | } | ||
1179 | } | ||
1180 | |||
1181 | if (time_after(jiffies, priv->post_ber_update)) { | ||
1182 | priv->post_ber_update = | ||
1183 | jiffies + msecs_to_jiffies(priv->post_ber_interval); | ||
1184 | if (c->delivery_system == SYS_DVBT) { | ||
1185 | mutex_lock(priv->spi_mutex); | ||
1186 | ret = cxd2880_post_bit_err_t(&priv->tnrdmd, | ||
1187 | &post_bit_err, | ||
1188 | &post_bit_count); | ||
1189 | mutex_unlock(priv->spi_mutex); | ||
1190 | } else if (c->delivery_system == SYS_DVBT2) { | ||
1191 | mutex_lock(priv->spi_mutex); | ||
1192 | ret = cxd2880_post_bit_err_t2(&priv->tnrdmd, | ||
1193 | &post_bit_err, | ||
1194 | &post_bit_count); | ||
1195 | mutex_unlock(priv->spi_mutex); | ||
1196 | } else { | ||
1197 | return -EINVAL; | ||
1198 | } | ||
1199 | |||
1200 | if (!ret) { | ||
1201 | c->post_bit_error.len = 1; | ||
1202 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||
1203 | c->post_bit_error.stat[0].uvalue += post_bit_err; | ||
1204 | c->post_bit_count.len = 1; | ||
1205 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; | ||
1206 | c->post_bit_count.stat[0].uvalue += post_bit_count; | ||
1207 | } else { | ||
1208 | c->post_bit_error.len = 1; | ||
1209 | c->post_bit_error.stat[0].scale = | ||
1210 | FE_SCALE_NOT_AVAILABLE; | ||
1211 | c->post_bit_count.len = 1; | ||
1212 | c->post_bit_count.stat[0].scale = | ||
1213 | FE_SCALE_NOT_AVAILABLE; | ||
1214 | pr_debug("post_bit_err_t %d\n", ret); | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | if (time_after(jiffies, priv->ucblock_update)) { | ||
1219 | priv->ucblock_update = | ||
1220 | jiffies + msecs_to_jiffies(priv->ucblock_interval); | ||
1221 | if (c->delivery_system == SYS_DVBT) { | ||
1222 | mutex_lock(priv->spi_mutex); | ||
1223 | ret = cxd2880_read_block_err_t(&priv->tnrdmd, | ||
1224 | &block_err, | ||
1225 | &block_count); | ||
1226 | mutex_unlock(priv->spi_mutex); | ||
1227 | } else if (c->delivery_system == SYS_DVBT2) { | ||
1228 | mutex_lock(priv->spi_mutex); | ||
1229 | ret = cxd2880_read_block_err_t2(&priv->tnrdmd, | ||
1230 | &block_err, | ||
1231 | &block_count); | ||
1232 | mutex_unlock(priv->spi_mutex); | ||
1233 | } else { | ||
1234 | return -EINVAL; | ||
1235 | } | ||
1236 | if (!ret) { | ||
1237 | c->block_error.len = 1; | ||
1238 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; | ||
1239 | c->block_error.stat[0].uvalue += block_err; | ||
1240 | c->block_count.len = 1; | ||
1241 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; | ||
1242 | c->block_count.stat[0].uvalue += block_count; | ||
1243 | } else { | ||
1244 | c->block_error.len = 1; | ||
1245 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1246 | c->block_count.len = 1; | ||
1247 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1248 | pr_debug("read_block_err_t %d\n", ret); | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | return 0; | ||
1253 | } | ||
1254 | |||
1255 | static int cxd2880_check_l1post_plp(struct dvb_frontend *fe) | ||
1256 | { | ||
1257 | u8 valid = 0; | ||
1258 | u8 plp_not_found; | ||
1259 | int ret; | ||
1260 | struct cxd2880_priv *priv = NULL; | ||
1261 | |||
1262 | if (!fe) { | ||
1263 | pr_err("invalid arg\n"); | ||
1264 | return -EINVAL; | ||
1265 | } | ||
1266 | |||
1267 | priv = fe->demodulator_priv; | ||
1268 | |||
1269 | ret = cxd2880_tnrdmd_dvbt2_check_l1post_valid(&priv->tnrdmd, | ||
1270 | &valid); | ||
1271 | if (ret) | ||
1272 | return ret; | ||
1273 | |||
1274 | if (!valid) | ||
1275 | return -EAGAIN; | ||
1276 | |||
1277 | ret = cxd2880_tnrdmd_dvbt2_mon_data_plp_error(&priv->tnrdmd, | ||
1278 | &plp_not_found); | ||
1279 | if (ret) | ||
1280 | return ret; | ||
1281 | |||
1282 | if (plp_not_found) { | ||
1283 | priv->dvbt2_tune_param.tune_info = | ||
1284 | CXD2880_TNRDMD_DVBT2_TUNE_INFO_INVALID_PLP_ID; | ||
1285 | } else { | ||
1286 | priv->dvbt2_tune_param.tune_info = | ||
1287 | CXD2880_TNRDMD_DVBT2_TUNE_INFO_OK; | ||
1288 | } | ||
1289 | |||
1290 | return 0; | ||
1291 | } | ||
1292 | |||
1293 | static int cxd2880_read_status(struct dvb_frontend *fe, | ||
1294 | enum fe_status *status) | ||
1295 | { | ||
1296 | int ret; | ||
1297 | u8 sync = 0; | ||
1298 | u8 lock = 0; | ||
1299 | u8 unlock = 0; | ||
1300 | struct cxd2880_priv *priv = NULL; | ||
1301 | struct dtv_frontend_properties *c = NULL; | ||
1302 | |||
1303 | if (!fe || !status) { | ||
1304 | pr_err("invalid arg\n"); | ||
1305 | return -EINVAL; | ||
1306 | } | ||
1307 | |||
1308 | priv = fe->demodulator_priv; | ||
1309 | c = &fe->dtv_property_cache; | ||
1310 | *status = 0; | ||
1311 | |||
1312 | if (priv->tnrdmd.state == CXD2880_TNRDMD_STATE_ACTIVE) { | ||
1313 | mutex_lock(priv->spi_mutex); | ||
1314 | if (c->delivery_system == SYS_DVBT) { | ||
1315 | ret = cxd2880_tnrdmd_dvbt_mon_sync_stat(&priv->tnrdmd, | ||
1316 | &sync, | ||
1317 | &lock, | ||
1318 | &unlock); | ||
1319 | } else if (c->delivery_system == SYS_DVBT2) { | ||
1320 | ret = cxd2880_tnrdmd_dvbt2_mon_sync_stat(&priv->tnrdmd, | ||
1321 | &sync, | ||
1322 | &lock, | ||
1323 | &unlock); | ||
1324 | } else { | ||
1325 | pr_err("invalid system"); | ||
1326 | mutex_unlock(priv->spi_mutex); | ||
1327 | return -EINVAL; | ||
1328 | } | ||
1329 | |||
1330 | mutex_unlock(priv->spi_mutex); | ||
1331 | if (ret) { | ||
1332 | pr_err("failed. sys = %d\n", priv->tnrdmd.sys); | ||
1333 | return ret; | ||
1334 | } | ||
1335 | |||
1336 | if (sync == 6) { | ||
1337 | *status = FE_HAS_SIGNAL | | ||
1338 | FE_HAS_CARRIER; | ||
1339 | } | ||
1340 | if (lock) | ||
1341 | *status |= FE_HAS_VITERBI | | ||
1342 | FE_HAS_SYNC | | ||
1343 | FE_HAS_LOCK; | ||
1344 | } | ||
1345 | |||
1346 | pr_debug("status %d\n", *status); | ||
1347 | |||
1348 | if (priv->s == 0 && (*status & FE_HAS_LOCK)) { | ||
1349 | mutex_lock(priv->spi_mutex); | ||
1350 | if (c->delivery_system == SYS_DVBT) { | ||
1351 | ret = cxd2880_set_ber_per_period_t(fe); | ||
1352 | priv->s = *status; | ||
1353 | } else if (c->delivery_system == SYS_DVBT2) { | ||
1354 | ret = cxd2880_check_l1post_plp(fe); | ||
1355 | if (!ret) { | ||
1356 | ret = cxd2880_set_ber_per_period_t2(fe); | ||
1357 | priv->s = *status; | ||
1358 | } | ||
1359 | } else { | ||
1360 | pr_err("invalid system\n"); | ||
1361 | mutex_unlock(priv->spi_mutex); | ||
1362 | return -EINVAL; | ||
1363 | } | ||
1364 | mutex_unlock(priv->spi_mutex); | ||
1365 | } | ||
1366 | |||
1367 | cxd2880_get_stats(fe, *status); | ||
1368 | return 0; | ||
1369 | } | ||
1370 | |||
1371 | static int cxd2880_tune(struct dvb_frontend *fe, | ||
1372 | bool retune, | ||
1373 | unsigned int mode_flags, | ||
1374 | unsigned int *delay, | ||
1375 | enum fe_status *status) | ||
1376 | { | ||
1377 | int ret; | ||
1378 | |||
1379 | if (!fe || !delay || !status) { | ||
1380 | pr_err("invalid arg."); | ||
1381 | return -EINVAL; | ||
1382 | } | ||
1383 | |||
1384 | if (retune) { | ||
1385 | ret = cxd2880_set_frontend(fe); | ||
1386 | if (ret) { | ||
1387 | pr_err("cxd2880_set_frontend failed %d\n", ret); | ||
1388 | return ret; | ||
1389 | } | ||
1390 | } | ||
1391 | |||
1392 | *delay = HZ / 5; | ||
1393 | |||
1394 | return cxd2880_read_status(fe, status); | ||
1395 | } | ||
1396 | |||
1397 | static int cxd2880_get_frontend_t(struct dvb_frontend *fe, | ||
1398 | struct dtv_frontend_properties *c) | ||
1399 | { | ||
1400 | int ret; | ||
1401 | struct cxd2880_priv *priv = NULL; | ||
1402 | enum cxd2880_dvbt_mode mode = CXD2880_DVBT_MODE_2K; | ||
1403 | enum cxd2880_dvbt_guard guard = CXD2880_DVBT_GUARD_1_32; | ||
1404 | struct cxd2880_dvbt_tpsinfo tps; | ||
1405 | enum cxd2880_tnrdmd_spectrum_sense sense; | ||
1406 | u16 snr = 0; | ||
1407 | int strength = 0; | ||
1408 | |||
1409 | if (!fe || !c) { | ||
1410 | pr_err("invalid arg\n"); | ||
1411 | return -EINVAL; | ||
1412 | } | ||
1413 | |||
1414 | priv = fe->demodulator_priv; | ||
1415 | |||
1416 | mutex_lock(priv->spi_mutex); | ||
1417 | ret = cxd2880_tnrdmd_dvbt_mon_mode_guard(&priv->tnrdmd, | ||
1418 | &mode, &guard); | ||
1419 | mutex_unlock(priv->spi_mutex); | ||
1420 | if (!ret) { | ||
1421 | switch (mode) { | ||
1422 | case CXD2880_DVBT_MODE_2K: | ||
1423 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
1424 | break; | ||
1425 | case CXD2880_DVBT_MODE_8K: | ||
1426 | c->transmission_mode = TRANSMISSION_MODE_8K; | ||
1427 | break; | ||
1428 | default: | ||
1429 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
1430 | pr_debug("transmission mode is invalid %d\n", mode); | ||
1431 | break; | ||
1432 | } | ||
1433 | switch (guard) { | ||
1434 | case CXD2880_DVBT_GUARD_1_32: | ||
1435 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
1436 | break; | ||
1437 | case CXD2880_DVBT_GUARD_1_16: | ||
1438 | c->guard_interval = GUARD_INTERVAL_1_16; | ||
1439 | break; | ||
1440 | case CXD2880_DVBT_GUARD_1_8: | ||
1441 | c->guard_interval = GUARD_INTERVAL_1_8; | ||
1442 | break; | ||
1443 | case CXD2880_DVBT_GUARD_1_4: | ||
1444 | c->guard_interval = GUARD_INTERVAL_1_4; | ||
1445 | break; | ||
1446 | default: | ||
1447 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
1448 | pr_debug("guard interval is invalid %d\n", | ||
1449 | guard); | ||
1450 | break; | ||
1451 | } | ||
1452 | } else { | ||
1453 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
1454 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
1455 | pr_debug("ModeGuard err %d\n", ret); | ||
1456 | } | ||
1457 | |||
1458 | mutex_lock(priv->spi_mutex); | ||
1459 | ret = cxd2880_tnrdmd_dvbt_mon_tps_info(&priv->tnrdmd, &tps); | ||
1460 | mutex_unlock(priv->spi_mutex); | ||
1461 | if (!ret) { | ||
1462 | switch (tps.hierarchy) { | ||
1463 | case CXD2880_DVBT_HIERARCHY_NON: | ||
1464 | c->hierarchy = HIERARCHY_NONE; | ||
1465 | break; | ||
1466 | case CXD2880_DVBT_HIERARCHY_1: | ||
1467 | c->hierarchy = HIERARCHY_1; | ||
1468 | break; | ||
1469 | case CXD2880_DVBT_HIERARCHY_2: | ||
1470 | c->hierarchy = HIERARCHY_2; | ||
1471 | break; | ||
1472 | case CXD2880_DVBT_HIERARCHY_4: | ||
1473 | c->hierarchy = HIERARCHY_4; | ||
1474 | break; | ||
1475 | default: | ||
1476 | c->hierarchy = HIERARCHY_NONE; | ||
1477 | pr_debug("TPSInfo hierarchy is invalid %d\n", | ||
1478 | tps.hierarchy); | ||
1479 | break; | ||
1480 | } | ||
1481 | |||
1482 | switch (tps.rate_hp) { | ||
1483 | case CXD2880_DVBT_CODERATE_1_2: | ||
1484 | c->code_rate_HP = FEC_1_2; | ||
1485 | break; | ||
1486 | case CXD2880_DVBT_CODERATE_2_3: | ||
1487 | c->code_rate_HP = FEC_2_3; | ||
1488 | break; | ||
1489 | case CXD2880_DVBT_CODERATE_3_4: | ||
1490 | c->code_rate_HP = FEC_3_4; | ||
1491 | break; | ||
1492 | case CXD2880_DVBT_CODERATE_5_6: | ||
1493 | c->code_rate_HP = FEC_5_6; | ||
1494 | break; | ||
1495 | case CXD2880_DVBT_CODERATE_7_8: | ||
1496 | c->code_rate_HP = FEC_7_8; | ||
1497 | break; | ||
1498 | default: | ||
1499 | c->code_rate_HP = FEC_NONE; | ||
1500 | pr_debug("TPSInfo rateHP is invalid %d\n", | ||
1501 | tps.rate_hp); | ||
1502 | break; | ||
1503 | } | ||
1504 | switch (tps.rate_lp) { | ||
1505 | case CXD2880_DVBT_CODERATE_1_2: | ||
1506 | c->code_rate_LP = FEC_1_2; | ||
1507 | break; | ||
1508 | case CXD2880_DVBT_CODERATE_2_3: | ||
1509 | c->code_rate_LP = FEC_2_3; | ||
1510 | break; | ||
1511 | case CXD2880_DVBT_CODERATE_3_4: | ||
1512 | c->code_rate_LP = FEC_3_4; | ||
1513 | break; | ||
1514 | case CXD2880_DVBT_CODERATE_5_6: | ||
1515 | c->code_rate_LP = FEC_5_6; | ||
1516 | break; | ||
1517 | case CXD2880_DVBT_CODERATE_7_8: | ||
1518 | c->code_rate_LP = FEC_7_8; | ||
1519 | break; | ||
1520 | default: | ||
1521 | c->code_rate_LP = FEC_NONE; | ||
1522 | pr_debug("TPSInfo rateLP is invalid %d\n", | ||
1523 | tps.rate_lp); | ||
1524 | break; | ||
1525 | } | ||
1526 | switch (tps.constellation) { | ||
1527 | case CXD2880_DVBT_CONSTELLATION_QPSK: | ||
1528 | c->modulation = QPSK; | ||
1529 | break; | ||
1530 | case CXD2880_DVBT_CONSTELLATION_16QAM: | ||
1531 | c->modulation = QAM_16; | ||
1532 | break; | ||
1533 | case CXD2880_DVBT_CONSTELLATION_64QAM: | ||
1534 | c->modulation = QAM_64; | ||
1535 | break; | ||
1536 | default: | ||
1537 | c->modulation = QPSK; | ||
1538 | pr_debug("TPSInfo constellation is invalid %d\n", | ||
1539 | tps.constellation); | ||
1540 | break; | ||
1541 | } | ||
1542 | } else { | ||
1543 | c->hierarchy = HIERARCHY_NONE; | ||
1544 | c->code_rate_HP = FEC_NONE; | ||
1545 | c->code_rate_LP = FEC_NONE; | ||
1546 | c->modulation = QPSK; | ||
1547 | pr_debug("TPS info err %d\n", ret); | ||
1548 | } | ||
1549 | |||
1550 | mutex_lock(priv->spi_mutex); | ||
1551 | ret = cxd2880_tnrdmd_dvbt_mon_spectrum_sense(&priv->tnrdmd, &sense); | ||
1552 | mutex_unlock(priv->spi_mutex); | ||
1553 | if (!ret) { | ||
1554 | switch (sense) { | ||
1555 | case CXD2880_TNRDMD_SPECTRUM_NORMAL: | ||
1556 | c->inversion = INVERSION_OFF; | ||
1557 | break; | ||
1558 | case CXD2880_TNRDMD_SPECTRUM_INV: | ||
1559 | c->inversion = INVERSION_ON; | ||
1560 | break; | ||
1561 | default: | ||
1562 | c->inversion = INVERSION_OFF; | ||
1563 | pr_debug("spectrum sense is invalid %d\n", sense); | ||
1564 | break; | ||
1565 | } | ||
1566 | } else { | ||
1567 | c->inversion = INVERSION_OFF; | ||
1568 | pr_debug("spectrum_sense %d\n", ret); | ||
1569 | } | ||
1570 | |||
1571 | mutex_lock(priv->spi_mutex); | ||
1572 | ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &strength); | ||
1573 | mutex_unlock(priv->spi_mutex); | ||
1574 | if (!ret) { | ||
1575 | c->strength.len = 1; | ||
1576 | c->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||
1577 | c->strength.stat[0].svalue = strength; | ||
1578 | } else { | ||
1579 | c->strength.len = 1; | ||
1580 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1581 | pr_debug("mon_rf_lvl %d\n", ret); | ||
1582 | } | ||
1583 | |||
1584 | ret = cxd2880_read_snr(fe, &snr); | ||
1585 | if (!ret) { | ||
1586 | c->cnr.len = 1; | ||
1587 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
1588 | c->cnr.stat[0].svalue = snr; | ||
1589 | } else { | ||
1590 | c->cnr.len = 1; | ||
1591 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1592 | pr_debug("read_snr %d\n", ret); | ||
1593 | } | ||
1594 | |||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1598 | static int cxd2880_get_frontend_t2(struct dvb_frontend *fe, | ||
1599 | struct dtv_frontend_properties *c) | ||
1600 | { | ||
1601 | int ret; | ||
1602 | struct cxd2880_priv *priv = NULL; | ||
1603 | struct cxd2880_dvbt2_l1pre l1pre; | ||
1604 | enum cxd2880_dvbt2_plp_code_rate coderate; | ||
1605 | enum cxd2880_dvbt2_plp_constell qam; | ||
1606 | enum cxd2880_tnrdmd_spectrum_sense sense; | ||
1607 | u16 snr = 0; | ||
1608 | int strength = 0; | ||
1609 | |||
1610 | if (!fe || !c) { | ||
1611 | pr_err("invalid arg.\n"); | ||
1612 | return -EINVAL; | ||
1613 | } | ||
1614 | |||
1615 | priv = fe->demodulator_priv; | ||
1616 | |||
1617 | mutex_lock(priv->spi_mutex); | ||
1618 | ret = cxd2880_tnrdmd_dvbt2_mon_l1_pre(&priv->tnrdmd, &l1pre); | ||
1619 | mutex_unlock(priv->spi_mutex); | ||
1620 | if (!ret) { | ||
1621 | switch (l1pre.fft_mode) { | ||
1622 | case CXD2880_DVBT2_M2K: | ||
1623 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
1624 | break; | ||
1625 | case CXD2880_DVBT2_M8K: | ||
1626 | c->transmission_mode = TRANSMISSION_MODE_8K; | ||
1627 | break; | ||
1628 | case CXD2880_DVBT2_M4K: | ||
1629 | c->transmission_mode = TRANSMISSION_MODE_4K; | ||
1630 | break; | ||
1631 | case CXD2880_DVBT2_M1K: | ||
1632 | c->transmission_mode = TRANSMISSION_MODE_1K; | ||
1633 | break; | ||
1634 | case CXD2880_DVBT2_M16K: | ||
1635 | c->transmission_mode = TRANSMISSION_MODE_16K; | ||
1636 | break; | ||
1637 | case CXD2880_DVBT2_M32K: | ||
1638 | c->transmission_mode = TRANSMISSION_MODE_32K; | ||
1639 | break; | ||
1640 | default: | ||
1641 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
1642 | pr_debug("L1Pre fft_mode is invalid %d\n", | ||
1643 | l1pre.fft_mode); | ||
1644 | break; | ||
1645 | } | ||
1646 | switch (l1pre.gi) { | ||
1647 | case CXD2880_DVBT2_G1_32: | ||
1648 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
1649 | break; | ||
1650 | case CXD2880_DVBT2_G1_16: | ||
1651 | c->guard_interval = GUARD_INTERVAL_1_16; | ||
1652 | break; | ||
1653 | case CXD2880_DVBT2_G1_8: | ||
1654 | c->guard_interval = GUARD_INTERVAL_1_8; | ||
1655 | break; | ||
1656 | case CXD2880_DVBT2_G1_4: | ||
1657 | c->guard_interval = GUARD_INTERVAL_1_4; | ||
1658 | break; | ||
1659 | case CXD2880_DVBT2_G1_128: | ||
1660 | c->guard_interval = GUARD_INTERVAL_1_128; | ||
1661 | break; | ||
1662 | case CXD2880_DVBT2_G19_128: | ||
1663 | c->guard_interval = GUARD_INTERVAL_19_128; | ||
1664 | break; | ||
1665 | case CXD2880_DVBT2_G19_256: | ||
1666 | c->guard_interval = GUARD_INTERVAL_19_256; | ||
1667 | break; | ||
1668 | default: | ||
1669 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
1670 | pr_debug("L1Pre guard interval is invalid %d\n", | ||
1671 | l1pre.gi); | ||
1672 | break; | ||
1673 | } | ||
1674 | } else { | ||
1675 | c->transmission_mode = TRANSMISSION_MODE_2K; | ||
1676 | c->guard_interval = GUARD_INTERVAL_1_32; | ||
1677 | pr_debug("L1Pre err %d\n", ret); | ||
1678 | } | ||
1679 | |||
1680 | mutex_lock(priv->spi_mutex); | ||
1681 | ret = cxd2880_tnrdmd_dvbt2_mon_code_rate(&priv->tnrdmd, | ||
1682 | CXD2880_DVBT2_PLP_DATA, | ||
1683 | &coderate); | ||
1684 | mutex_unlock(priv->spi_mutex); | ||
1685 | if (!ret) { | ||
1686 | switch (coderate) { | ||
1687 | case CXD2880_DVBT2_R1_2: | ||
1688 | c->fec_inner = FEC_1_2; | ||
1689 | break; | ||
1690 | case CXD2880_DVBT2_R3_5: | ||
1691 | c->fec_inner = FEC_3_5; | ||
1692 | break; | ||
1693 | case CXD2880_DVBT2_R2_3: | ||
1694 | c->fec_inner = FEC_2_3; | ||
1695 | break; | ||
1696 | case CXD2880_DVBT2_R3_4: | ||
1697 | c->fec_inner = FEC_3_4; | ||
1698 | break; | ||
1699 | case CXD2880_DVBT2_R4_5: | ||
1700 | c->fec_inner = FEC_4_5; | ||
1701 | break; | ||
1702 | case CXD2880_DVBT2_R5_6: | ||
1703 | c->fec_inner = FEC_5_6; | ||
1704 | break; | ||
1705 | default: | ||
1706 | c->fec_inner = FEC_NONE; | ||
1707 | pr_debug("CodeRate is invalid %d\n", coderate); | ||
1708 | break; | ||
1709 | } | ||
1710 | } else { | ||
1711 | c->fec_inner = FEC_NONE; | ||
1712 | pr_debug("CodeRate %d\n", ret); | ||
1713 | } | ||
1714 | |||
1715 | mutex_lock(priv->spi_mutex); | ||
1716 | ret = cxd2880_tnrdmd_dvbt2_mon_qam(&priv->tnrdmd, | ||
1717 | CXD2880_DVBT2_PLP_DATA, | ||
1718 | &qam); | ||
1719 | mutex_unlock(priv->spi_mutex); | ||
1720 | if (!ret) { | ||
1721 | switch (qam) { | ||
1722 | case CXD2880_DVBT2_QPSK: | ||
1723 | c->modulation = QPSK; | ||
1724 | break; | ||
1725 | case CXD2880_DVBT2_QAM16: | ||
1726 | c->modulation = QAM_16; | ||
1727 | break; | ||
1728 | case CXD2880_DVBT2_QAM64: | ||
1729 | c->modulation = QAM_64; | ||
1730 | break; | ||
1731 | case CXD2880_DVBT2_QAM256: | ||
1732 | c->modulation = QAM_256; | ||
1733 | break; | ||
1734 | default: | ||
1735 | c->modulation = QPSK; | ||
1736 | pr_debug("QAM is invalid %d\n", qam); | ||
1737 | break; | ||
1738 | } | ||
1739 | } else { | ||
1740 | c->modulation = QPSK; | ||
1741 | pr_debug("QAM %d\n", ret); | ||
1742 | } | ||
1743 | |||
1744 | mutex_lock(priv->spi_mutex); | ||
1745 | ret = cxd2880_tnrdmd_dvbt2_mon_spectrum_sense(&priv->tnrdmd, &sense); | ||
1746 | mutex_unlock(priv->spi_mutex); | ||
1747 | if (!ret) { | ||
1748 | switch (sense) { | ||
1749 | case CXD2880_TNRDMD_SPECTRUM_NORMAL: | ||
1750 | c->inversion = INVERSION_OFF; | ||
1751 | break; | ||
1752 | case CXD2880_TNRDMD_SPECTRUM_INV: | ||
1753 | c->inversion = INVERSION_ON; | ||
1754 | break; | ||
1755 | default: | ||
1756 | c->inversion = INVERSION_OFF; | ||
1757 | pr_debug("spectrum sense is invalid %d\n", sense); | ||
1758 | break; | ||
1759 | } | ||
1760 | } else { | ||
1761 | c->inversion = INVERSION_OFF; | ||
1762 | pr_debug("SpectrumSense %d\n", ret); | ||
1763 | } | ||
1764 | |||
1765 | mutex_lock(priv->spi_mutex); | ||
1766 | ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &strength); | ||
1767 | mutex_unlock(priv->spi_mutex); | ||
1768 | if (!ret) { | ||
1769 | c->strength.len = 1; | ||
1770 | c->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||
1771 | c->strength.stat[0].svalue = strength; | ||
1772 | } else { | ||
1773 | c->strength.len = 1; | ||
1774 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1775 | pr_debug("mon_rf_lvl %d\n", ret); | ||
1776 | } | ||
1777 | |||
1778 | ret = cxd2880_read_snr(fe, &snr); | ||
1779 | if (!ret) { | ||
1780 | c->cnr.len = 1; | ||
1781 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
1782 | c->cnr.stat[0].svalue = snr; | ||
1783 | } else { | ||
1784 | c->cnr.len = 1; | ||
1785 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1786 | pr_debug("read_snr %d\n", ret); | ||
1787 | } | ||
1788 | |||
1789 | return 0; | ||
1790 | } | ||
1791 | |||
1792 | static int cxd2880_get_frontend(struct dvb_frontend *fe, | ||
1793 | struct dtv_frontend_properties *props) | ||
1794 | { | ||
1795 | int ret; | ||
1796 | |||
1797 | if (!fe || !props) { | ||
1798 | pr_err("invalid arg."); | ||
1799 | return -EINVAL; | ||
1800 | } | ||
1801 | |||
1802 | pr_debug("system=%d\n", fe->dtv_property_cache.delivery_system); | ||
1803 | switch (fe->dtv_property_cache.delivery_system) { | ||
1804 | case SYS_DVBT: | ||
1805 | ret = cxd2880_get_frontend_t(fe, props); | ||
1806 | break; | ||
1807 | case SYS_DVBT2: | ||
1808 | ret = cxd2880_get_frontend_t2(fe, props); | ||
1809 | break; | ||
1810 | default: | ||
1811 | ret = -EINVAL; | ||
1812 | break; | ||
1813 | } | ||
1814 | |||
1815 | return ret; | ||
1816 | } | ||
1817 | |||
1818 | static enum dvbfe_algo cxd2880_get_frontend_algo(struct dvb_frontend *fe) | ||
1819 | { | ||
1820 | return DVBFE_ALGO_HW; | ||
1821 | } | ||
1822 | |||
1823 | static struct dvb_frontend_ops cxd2880_dvbt_t2_ops = { | ||
1824 | .info = { | ||
1825 | .name = "Sony CXD2880", | ||
1826 | .frequency_min = 174000000, | ||
1827 | .frequency_max = 862000000, | ||
1828 | .frequency_stepsize = 1000, | ||
1829 | .caps = FE_CAN_INVERSION_AUTO | | ||
1830 | FE_CAN_FEC_1_2 | | ||
1831 | FE_CAN_FEC_2_3 | | ||
1832 | FE_CAN_FEC_3_4 | | ||
1833 | FE_CAN_FEC_4_5 | | ||
1834 | FE_CAN_FEC_5_6 | | ||
1835 | FE_CAN_FEC_7_8 | | ||
1836 | FE_CAN_FEC_AUTO | | ||
1837 | FE_CAN_QPSK | | ||
1838 | FE_CAN_QAM_16 | | ||
1839 | FE_CAN_QAM_32 | | ||
1840 | FE_CAN_QAM_64 | | ||
1841 | FE_CAN_QAM_128 | | ||
1842 | FE_CAN_QAM_256 | | ||
1843 | FE_CAN_QAM_AUTO | | ||
1844 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
1845 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
1846 | FE_CAN_2G_MODULATION | | ||
1847 | FE_CAN_RECOVER | | ||
1848 | FE_CAN_MUTE_TS, | ||
1849 | }, | ||
1850 | .delsys = { SYS_DVBT, SYS_DVBT2 }, | ||
1851 | |||
1852 | .release = cxd2880_release, | ||
1853 | .init = cxd2880_init, | ||
1854 | .sleep = cxd2880_sleep, | ||
1855 | .tune = cxd2880_tune, | ||
1856 | .set_frontend = cxd2880_set_frontend, | ||
1857 | .get_frontend = cxd2880_get_frontend, | ||
1858 | .read_status = cxd2880_read_status, | ||
1859 | .read_ber = cxd2880_read_ber, | ||
1860 | .read_signal_strength = cxd2880_read_signal_strength, | ||
1861 | .read_snr = cxd2880_read_snr, | ||
1862 | .read_ucblocks = cxd2880_read_ucblocks, | ||
1863 | .get_frontend_algo = cxd2880_get_frontend_algo, | ||
1864 | }; | ||
1865 | |||
1866 | struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe, | ||
1867 | struct cxd2880_config *cfg) | ||
1868 | { | ||
1869 | int ret; | ||
1870 | enum cxd2880_tnrdmd_chip_id chipid = | ||
1871 | CXD2880_TNRDMD_CHIP_ID_UNKNOWN; | ||
1872 | static struct cxd2880_priv *priv; | ||
1873 | u8 data = 0; | ||
1874 | |||
1875 | if (!fe) { | ||
1876 | pr_err("invalid arg.\n"); | ||
1877 | return NULL; | ||
1878 | } | ||
1879 | |||
1880 | priv = kzalloc(sizeof(struct cxd2880_priv), GFP_KERNEL); | ||
1881 | if (!priv) | ||
1882 | return NULL; | ||
1883 | |||
1884 | priv->spi = cfg->spi; | ||
1885 | priv->spi_mutex = cfg->spi_mutex; | ||
1886 | priv->spi_device.spi = cfg->spi; | ||
1887 | |||
1888 | memcpy(&fe->ops, &cxd2880_dvbt_t2_ops, | ||
1889 | sizeof(struct dvb_frontend_ops)); | ||
1890 | |||
1891 | ret = cxd2880_spi_device_initialize(&priv->spi_device, | ||
1892 | CXD2880_SPI_MODE_0, | ||
1893 | 55000000); | ||
1894 | if (ret) { | ||
1895 | pr_err("spi_device_initialize failed. %d\n", ret); | ||
1896 | kfree(priv); | ||
1897 | return NULL; | ||
1898 | } | ||
1899 | |||
1900 | ret = cxd2880_spi_device_create_spi(&priv->cxd2880_spi, | ||
1901 | &priv->spi_device); | ||
1902 | if (ret) { | ||
1903 | pr_err("spi_device_create_spi failed. %d\n", ret); | ||
1904 | kfree(priv); | ||
1905 | return NULL; | ||
1906 | } | ||
1907 | |||
1908 | ret = cxd2880_io_spi_create(&priv->regio, &priv->cxd2880_spi, 0); | ||
1909 | if (ret) { | ||
1910 | pr_err("io_spi_create failed. %d\n", ret); | ||
1911 | kfree(priv); | ||
1912 | return NULL; | ||
1913 | } | ||
1914 | ret = priv->regio.write_reg(&priv->regio, | ||
1915 | CXD2880_IO_TGT_SYS, 0x00, 0x00); | ||
1916 | if (ret) { | ||
1917 | pr_err("set bank to 0x00 failed.\n"); | ||
1918 | kfree(priv); | ||
1919 | return NULL; | ||
1920 | } | ||
1921 | ret = priv->regio.read_regs(&priv->regio, | ||
1922 | CXD2880_IO_TGT_SYS, 0xfd, &data, 1); | ||
1923 | if (ret) { | ||
1924 | pr_err("read chip id failed.\n"); | ||
1925 | kfree(priv); | ||
1926 | return NULL; | ||
1927 | } | ||
1928 | |||
1929 | chipid = (enum cxd2880_tnrdmd_chip_id)data; | ||
1930 | if (chipid != CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X && | ||
1931 | chipid != CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11) { | ||
1932 | pr_err("chip id invalid.\n"); | ||
1933 | kfree(priv); | ||
1934 | return NULL; | ||
1935 | } | ||
1936 | |||
1937 | fe->demodulator_priv = priv; | ||
1938 | pr_info("CXD2880 driver version: Ver %s\n", | ||
1939 | CXD2880_TNRDMD_DRIVER_VERSION); | ||
1940 | |||
1941 | return fe; | ||
1942 | } | ||
1943 | EXPORT_SYMBOL(cxd2880_attach); | ||
1944 | |||
1945 | MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver"); | ||
1946 | MODULE_AUTHOR("Sony Semiconductor Solutions Corporation"); | ||
1947 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 64f49c8eb1fb..ee7af34979ed 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c | |||
@@ -1285,7 +1285,7 @@ int dib0090_gain_control(struct dvb_frontend *fe) | |||
1285 | #endif | 1285 | #endif |
1286 | 1286 | ||
1287 | if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */ | 1287 | if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */ |
1288 | if (ABS(adc_error) < 50 || state->agc_step++ > 5) { | 1288 | if (abs(adc_error) < 50 || state->agc_step++ > 5) { |
1289 | 1289 | ||
1290 | #ifdef CONFIG_STANDARD_DAB | 1290 | #ifdef CONFIG_STANDARD_DAB |
1291 | if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) { | 1291 | if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) { |
@@ -1754,7 +1754,7 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front | |||
1754 | *tune_state = CT_TUNER_STEP_1; | 1754 | *tune_state = CT_TUNER_STEP_1; |
1755 | } else { | 1755 | } else { |
1756 | /* the minimum was what we have seen in the step before */ | 1756 | /* the minimum was what we have seen in the step before */ |
1757 | if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) { | 1757 | if (abs(state->adc_diff) > abs(state->min_adc_diff)) { |
1758 | dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff); | 1758 | dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff); |
1759 | state->step--; | 1759 | state->step--; |
1760 | } | 1760 | } |
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index 90ace707a80d..902af482448e 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c | |||
@@ -809,7 +809,7 @@ static int dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz) | |||
809 | { | 809 | { |
810 | u32 internal = dib7000p_get_internal_freq(state); | 810 | u32 internal = dib7000p_get_internal_freq(state); |
811 | s32 unit_khz_dds_val; | 811 | s32 unit_khz_dds_val; |
812 | u32 abs_offset_khz = ABS(offset_khz); | 812 | u32 abs_offset_khz = abs(offset_khz); |
813 | u32 dds = state->cfg.bw->ifreq & 0x1ffffff; | 813 | u32 dds = state->cfg.bw->ifreq & 0x1ffffff; |
814 | u8 invert = !!(state->cfg.bw->ifreq & (1 << 25)); | 814 | u8 invert = !!(state->cfg.bw->ifreq & (1 << 25)); |
815 | if (internal == 0) { | 815 | if (internal == 0) { |
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index e64014f338fb..6f35173d2968 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c | |||
@@ -2677,7 +2677,7 @@ static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff) | |||
2677 | static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz) | 2677 | static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz) |
2678 | { | 2678 | { |
2679 | s16 unit_khz_dds_val; | 2679 | s16 unit_khz_dds_val; |
2680 | u32 abs_offset_khz = ABS(offset_khz); | 2680 | u32 abs_offset_khz = abs(offset_khz); |
2681 | u32 dds = state->cfg.pll->ifreq & 0x1ffffff; | 2681 | u32 dds = state->cfg.pll->ifreq & 0x1ffffff; |
2682 | u8 invert = !!(state->cfg.pll->ifreq & (1 << 25)); | 2682 | u8 invert = !!(state->cfg.pll->ifreq & (1 << 25)); |
2683 | u8 ratio; | 2683 | u8 ratio; |
diff --git a/drivers/media/dvb-frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c index d981233e458f..70119c79ac2b 100644 --- a/drivers/media/dvb-frontends/dibx000_common.c +++ b/drivers/media/dvb-frontends/dibx000_common.c | |||
@@ -424,7 +424,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, | |||
424 | struct i2c_algorithm *algo, const char *name, | 424 | struct i2c_algorithm *algo, const char *name, |
425 | struct dibx000_i2c_master *mst) | 425 | struct dibx000_i2c_master *mst) |
426 | { | 426 | { |
427 | strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); | 427 | strlcpy(i2c_adap->name, name, sizeof(i2c_adap->name)); |
428 | i2c_adap->algo = algo; | 428 | i2c_adap->algo = algo; |
429 | i2c_adap->algo_data = NULL; | 429 | i2c_adap->algo_data = NULL; |
430 | i2c_set_adapdata(i2c_adap, mst); | 430 | i2c_set_adapdata(i2c_adap, mst); |
diff --git a/drivers/media/dvb-frontends/dibx000_common.h b/drivers/media/dvb-frontends/dibx000_common.h index 8784af962eba..12b58f5c677d 100644 --- a/drivers/media/dvb-frontends/dibx000_common.h +++ b/drivers/media/dvb-frontends/dibx000_common.h | |||
@@ -223,8 +223,6 @@ struct dvb_frontend_parametersContext { | |||
223 | 223 | ||
224 | #define FE_CALLBACK_TIME_NEVER 0xffffffff | 224 | #define FE_CALLBACK_TIME_NEVER 0xffffffff |
225 | 225 | ||
226 | #define ABS(x) ((x < 0) ? (-x) : (x)) | ||
227 | |||
228 | #define DATA_BUS_ACCESS_MODE_8BIT 0x01 | 226 | #define DATA_BUS_ACCESS_MODE_8BIT 0x01 |
229 | #define DATA_BUS_ACCESS_MODE_16BIT 0x02 | 227 | #define DATA_BUS_ACCESS_MODE_16BIT 0x02 |
230 | #define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10 | 228 | #define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10 |
diff --git a/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h b/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h deleted file mode 100644 index 2b3af247a1f1..000000000000 --- a/drivers/media/dvb-frontends/drx39xyj/bsp_i2c.h +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* | ||
2 | I2C API, implementation depends on board specifics | ||
3 | |||
4 | Copyright (c), 2004-2005,2007-2010 Trident Microsystems, Inc. | ||
5 | All rights reserved. | ||
6 | |||
7 | Redistribution and use in source and binary forms, with or without | ||
8 | modification, are permitted provided that the following conditions are met: | ||
9 | |||
10 | * Redistributions of source code must retain the above copyright notice, | ||
11 | this list of conditions and the following disclaimer. | ||
12 | * Redistributions in binary form must reproduce the above copyright notice, | ||
13 | this list of conditions and the following disclaimer in the documentation | ||
14 | and/or other materials provided with the distribution. | ||
15 | * Neither the name of Trident Microsystems nor Hauppauge Computer Works | ||
16 | nor the names of its contributors may be used to endorse or promote | ||
17 | products derived from this software without specific prior written | ||
18 | permission. | ||
19 | |||
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
30 | POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | This module encapsulates I2C access.In some applications several devices | ||
33 | share one I2C bus. If these devices have the same I2C address some kind | ||
34 | off "switch" must be implemented to ensure error free communication with | ||
35 | one device. In case such a "switch" is used, the device ID can be used | ||
36 | to implement control over this "switch". | ||
37 | */ | ||
38 | |||
39 | #ifndef __BSPI2C_H__ | ||
40 | #define __BSPI2C_H__ | ||
41 | |||
42 | #include "bsp_types.h" | ||
43 | |||
44 | /* | ||
45 | * This structure contains the I2C address, the device ID and a user_data pointer. | ||
46 | * The user_data pointer can be used for application specific purposes. | ||
47 | */ | ||
48 | struct i2c_device_addr { | ||
49 | u16 i2c_addr; /* The I2C address of the device. */ | ||
50 | u16 i2c_dev_id; /* The device identifier. */ | ||
51 | void *user_data; /* User data pointer */ | ||
52 | }; | ||
53 | |||
54 | |||
55 | /* | ||
56 | * \def IS_I2C_10BIT( addr ) | ||
57 | * \brief Determine if I2C address 'addr' is a 10 bits address or not. | ||
58 | * \param addr The I2C address. | ||
59 | * \return int. | ||
60 | * \retval 0 if address is not a 10 bits I2C address. | ||
61 | * \retval 1 if address is a 10 bits I2C address. | ||
62 | */ | ||
63 | #define IS_I2C_10BIT(addr) \ | ||
64 | (((addr) & 0xF8) == 0xF0) | ||
65 | |||
66 | /*------------------------------------------------------------------------------ | ||
67 | Exported FUNCTIONS | ||
68 | ------------------------------------------------------------------------------*/ | ||
69 | |||
70 | /* | ||
71 | * \fn drxbsp_i2c_init() | ||
72 | * \brief Initialize I2C communication module. | ||
73 | * \return drx_status_t Return status. | ||
74 | * \retval 0 Initialization successful. | ||
75 | * \retval -EIO Initialization failed. | ||
76 | */ | ||
77 | drx_status_t drxbsp_i2c_init(void); | ||
78 | |||
79 | /* | ||
80 | * \fn drxbsp_i2c_term() | ||
81 | * \brief Terminate I2C communication module. | ||
82 | * \return drx_status_t Return status. | ||
83 | * \retval 0 Termination successful. | ||
84 | * \retval -EIO Termination failed. | ||
85 | */ | ||
86 | drx_status_t drxbsp_i2c_term(void); | ||
87 | |||
88 | /* | ||
89 | * \fn drx_status_t drxbsp_i2c_write_read( struct i2c_device_addr *w_dev_addr, | ||
90 | * u16 w_count, | ||
91 | * u8 *wData, | ||
92 | * struct i2c_device_addr *r_dev_addr, | ||
93 | * u16 r_count, | ||
94 | * u8 *r_data) | ||
95 | * \brief Read and/or write count bytes from I2C bus, store them in data[]. | ||
96 | * \param w_dev_addr The device i2c address and the device ID to write to | ||
97 | * \param w_count The number of bytes to write | ||
98 | * \param wData The array to write the data to | ||
99 | * \param r_dev_addr The device i2c address and the device ID to read from | ||
100 | * \param r_count The number of bytes to read | ||
101 | * \param r_data The array to read the data from | ||
102 | * \return drx_status_t Return status. | ||
103 | * \retval 0 Succes. | ||
104 | * \retval -EIO Failure. | ||
105 | * \retval -EINVAL Parameter 'wcount' is not zero but parameter | ||
106 | * 'wdata' contains NULL. | ||
107 | * Idem for 'rcount' and 'rdata'. | ||
108 | * Both w_dev_addr and r_dev_addr are NULL. | ||
109 | * | ||
110 | * This function must implement an atomic write and/or read action on the I2C bus | ||
111 | * No other process may use the I2C bus when this function is executing. | ||
112 | * The critical section of this function runs from and including the I2C | ||
113 | * write, up to and including the I2C read action. | ||
114 | * | ||
115 | * The device ID can be useful if several devices share an I2C address. | ||
116 | * It can be used to control a "switch" on the I2C bus to the correct device. | ||
117 | */ | ||
118 | drx_status_t drxbsp_i2c_write_read(struct i2c_device_addr *w_dev_addr, | ||
119 | u16 w_count, | ||
120 | u8 *w_data, | ||
121 | struct i2c_device_addr *r_dev_addr, | ||
122 | u16 r_count, u8 *r_data); | ||
123 | |||
124 | /* | ||
125 | * \fn drxbsp_i2c_error_text() | ||
126 | * \brief Returns a human readable error. | ||
127 | * Counter part of numerical drx_i2c_error_g. | ||
128 | * | ||
129 | * \return char* Pointer to human readable error text. | ||
130 | */ | ||
131 | char *drxbsp_i2c_error_text(void); | ||
132 | |||
133 | /* | ||
134 | * \var drx_i2c_error_g; | ||
135 | * \brief I2C specific error codes, platform dependent. | ||
136 | */ | ||
137 | extern int drx_i2c_error_g; | ||
138 | |||
139 | #endif /* __BSPI2C_H__ */ | ||
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 6356815cf3e1..7eb4e1469d20 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c | |||
@@ -30,6 +30,17 @@ static int debug; | |||
30 | module_param(debug, int, 0644); | 30 | module_param(debug, int, 0644); |
31 | MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); | 31 | MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); |
32 | 32 | ||
33 | /* | ||
34 | * Older drivers treated QAM64 and QAM256 the same; that is the HW always | ||
35 | * used "Auto" mode during detection. Setting "forced_manual"=1 allows | ||
36 | * the user to treat these modes as separate. For backwards compatibility, | ||
37 | * it's off by default. QAM_AUTO can now be specified to achive that | ||
38 | * effect even if "forced_manual"=1 | ||
39 | */ | ||
40 | static int forced_manual; | ||
41 | module_param(forced_manual, int, 0644); | ||
42 | MODULE_PARM_DESC(forced_manual, "if set, QAM64 and QAM256 will only lock to modulation specified"); | ||
43 | |||
33 | #define DBG_INFO 1 | 44 | #define DBG_INFO 1 |
34 | #define DBG_REG 2 | 45 | #define DBG_REG 2 |
35 | #define DBG_DUMP 4 /* FGR - comment out to remove dump code */ | 46 | #define DBG_DUMP 4 /* FGR - comment out to remove dump code */ |
@@ -566,7 +577,12 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation) | |||
566 | /* 3. : 64QAM/256QAM detection(manual, auto) */ | 577 | /* 3. : 64QAM/256QAM detection(manual, auto) */ |
567 | ret = lgdt3306a_read_reg(state, 0x0009, &val); | 578 | ret = lgdt3306a_read_reg(state, 0x0009, &val); |
568 | val &= 0xfc; | 579 | val &= 0xfc; |
569 | val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */ | 580 | /* Check for forced Manual modulation modes; otherwise always "auto" */ |
581 | if(forced_manual && (modulation != QAM_AUTO)){ | ||
582 | val |= 0x01; /* STDOPDETCMODE[1:0]= 1=Manual */ | ||
583 | } else { | ||
584 | val |= 0x02; /* STDOPDETCMODE[1:0]= 2=Auto */ | ||
585 | } | ||
570 | ret = lgdt3306a_write_reg(state, 0x0009, val); | 586 | ret = lgdt3306a_write_reg(state, 0x0009, val); |
571 | if (lg_chkerr(ret)) | 587 | if (lg_chkerr(ret)) |
572 | goto fail; | 588 | goto fail; |
@@ -598,6 +614,28 @@ static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation) | |||
598 | if (lg_chkerr(ret)) | 614 | if (lg_chkerr(ret)) |
599 | goto fail; | 615 | goto fail; |
600 | 616 | ||
617 | /* 5.1 V0.36 SRDCHKALWAYS : For better QAM detection */ | ||
618 | ret = lgdt3306a_read_reg(state, 0x000a, &val); | ||
619 | val &= 0xfd; | ||
620 | val |= 0x02; | ||
621 | ret = lgdt3306a_write_reg(state, 0x000a, val); | ||
622 | if (lg_chkerr(ret)) | ||
623 | goto fail; | ||
624 | |||
625 | /* 5.2 V0.36 Control of "no signal" detector function */ | ||
626 | ret = lgdt3306a_read_reg(state, 0x2849, &val); | ||
627 | val &= 0xdf; | ||
628 | ret = lgdt3306a_write_reg(state, 0x2849, val); | ||
629 | if (lg_chkerr(ret)) | ||
630 | goto fail; | ||
631 | |||
632 | /* 5.3 Fix for Blonder Tongue HDE-2H-QAM and AQM modulators */ | ||
633 | ret = lgdt3306a_read_reg(state, 0x302b, &val); | ||
634 | val &= 0x7f; /* SELFSYNCFINDEN_CQS=0; disable auto reset */ | ||
635 | ret = lgdt3306a_write_reg(state, 0x302b, val); | ||
636 | if (lg_chkerr(ret)) | ||
637 | goto fail; | ||
638 | |||
601 | /* 6. Reset */ | 639 | /* 6. Reset */ |
602 | ret = lgdt3306a_soft_reset(state); | 640 | ret = lgdt3306a_soft_reset(state); |
603 | if (lg_chkerr(ret)) | 641 | if (lg_chkerr(ret)) |
@@ -620,10 +658,9 @@ static int lgdt3306a_set_modulation(struct lgdt3306a_state *state, | |||
620 | ret = lgdt3306a_set_vsb(state); | 658 | ret = lgdt3306a_set_vsb(state); |
621 | break; | 659 | break; |
622 | case QAM_64: | 660 | case QAM_64: |
623 | ret = lgdt3306a_set_qam(state, QAM_64); | ||
624 | break; | ||
625 | case QAM_256: | 661 | case QAM_256: |
626 | ret = lgdt3306a_set_qam(state, QAM_256); | 662 | case QAM_AUTO: |
663 | ret = lgdt3306a_set_qam(state, p->modulation); | ||
627 | break; | 664 | break; |
628 | default: | 665 | default: |
629 | return -EINVAL; | 666 | return -EINVAL; |
@@ -650,6 +687,7 @@ static int lgdt3306a_agc_setup(struct lgdt3306a_state *state, | |||
650 | break; | 687 | break; |
651 | case QAM_64: | 688 | case QAM_64: |
652 | case QAM_256: | 689 | case QAM_256: |
690 | case QAM_AUTO: | ||
653 | break; | 691 | break; |
654 | default: | 692 | default: |
655 | return -EINVAL; | 693 | return -EINVAL; |
@@ -704,6 +742,7 @@ static int lgdt3306a_spectral_inversion(struct lgdt3306a_state *state, | |||
704 | break; | 742 | break; |
705 | case QAM_64: | 743 | case QAM_64: |
706 | case QAM_256: | 744 | case QAM_256: |
745 | case QAM_AUTO: | ||
707 | /* Auto ok for QAM */ | 746 | /* Auto ok for QAM */ |
708 | ret = lgdt3306a_set_inversion_auto(state, 1); | 747 | ret = lgdt3306a_set_inversion_auto(state, 1); |
709 | break; | 748 | break; |
@@ -727,6 +766,7 @@ static int lgdt3306a_set_if(struct lgdt3306a_state *state, | |||
727 | break; | 766 | break; |
728 | case QAM_64: | 767 | case QAM_64: |
729 | case QAM_256: | 768 | case QAM_256: |
769 | case QAM_AUTO: | ||
730 | if_freq_khz = state->cfg->qam_if_khz; | 770 | if_freq_khz = state->cfg->qam_if_khz; |
731 | break; | 771 | break; |
732 | default: | 772 | default: |
@@ -1585,6 +1625,7 @@ static int lgdt3306a_read_status(struct dvb_frontend *fe, | |||
1585 | switch (state->current_modulation) { | 1625 | switch (state->current_modulation) { |
1586 | case QAM_256: | 1626 | case QAM_256: |
1587 | case QAM_64: | 1627 | case QAM_64: |
1628 | case QAM_AUTO: | ||
1588 | if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) { | 1629 | if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) { |
1589 | *status |= FE_HAS_VITERBI; | 1630 | *status |= FE_HAS_VITERBI; |
1590 | *status |= FE_HAS_SYNC; | 1631 | *status |= FE_HAS_SYNC; |
@@ -1628,6 +1669,7 @@ static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe, | |||
1628 | * Calculate some sort of "strength" from SNR | 1669 | * Calculate some sort of "strength" from SNR |
1629 | */ | 1670 | */ |
1630 | struct lgdt3306a_state *state = fe->demodulator_priv; | 1671 | struct lgdt3306a_state *state = fe->demodulator_priv; |
1672 | u8 val; | ||
1631 | u16 snr; /* snr_x10 */ | 1673 | u16 snr; /* snr_x10 */ |
1632 | int ret; | 1674 | int ret; |
1633 | u32 ref_snr; /* snr*100 */ | 1675 | u32 ref_snr; /* snr*100 */ |
@@ -1640,11 +1682,15 @@ static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe, | |||
1640 | ref_snr = 1600; /* 16dB */ | 1682 | ref_snr = 1600; /* 16dB */ |
1641 | break; | 1683 | break; |
1642 | case QAM_64: | 1684 | case QAM_64: |
1643 | ref_snr = 2200; /* 22dB */ | ||
1644 | break; | ||
1645 | case QAM_256: | 1685 | case QAM_256: |
1646 | ref_snr = 2800; /* 28dB */ | 1686 | case QAM_AUTO: |
1647 | break; | 1687 | /* need to know actual modulation to set proper SNR baseline */ |
1688 | lgdt3306a_read_reg(state, 0x00a6, &val); | ||
1689 | if(val & 0x04) | ||
1690 | ref_snr = 2800; /* QAM-256 28dB */ | ||
1691 | else | ||
1692 | ref_snr = 2200; /* QAM-64 22dB */ | ||
1693 | break; | ||
1648 | default: | 1694 | default: |
1649 | return -EINVAL; | 1695 | return -EINVAL; |
1650 | } | 1696 | } |
@@ -2114,7 +2160,7 @@ static const struct dvb_frontend_ops lgdt3306a_ops = { | |||
2114 | .frequency_min = 54000000, | 2160 | .frequency_min = 54000000, |
2115 | .frequency_max = 858000000, | 2161 | .frequency_max = 858000000, |
2116 | .frequency_stepsize = 62500, | 2162 | .frequency_stepsize = 62500, |
2117 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | 2163 | .caps = FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB |
2118 | }, | 2164 | }, |
2119 | .i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl, | 2165 | .i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl, |
2120 | .init = lgdt3306a_init, | 2166 | .init = lgdt3306a_init, |
@@ -2177,6 +2223,7 @@ static int lgdt3306a_probe(struct i2c_client *client, | |||
2177 | 2223 | ||
2178 | i2c_set_clientdata(client, fe->demodulator_priv); | 2224 | i2c_set_clientdata(client, fe->demodulator_priv); |
2179 | state = fe->demodulator_priv; | 2225 | state = fe->demodulator_priv; |
2226 | state->frontend.ops.release = NULL; | ||
2180 | 2227 | ||
2181 | /* create mux i2c adapter for tuner */ | 2228 | /* create mux i2c adapter for tuner */ |
2182 | state->muxc = i2c_mux_alloc(client->adapter, &client->dev, | 2229 | state->muxc = i2c_mux_alloc(client->adapter, &client->dev, |
@@ -2196,6 +2243,8 @@ static int lgdt3306a_probe(struct i2c_client *client, | |||
2196 | *config->i2c_adapter = state->muxc->adapter[0]; | 2243 | *config->i2c_adapter = state->muxc->adapter[0]; |
2197 | *config->fe = fe; | 2244 | *config->fe = fe; |
2198 | 2245 | ||
2246 | dev_info(&client->dev, "LG Electronics LGDT3306A successfully identified\n"); | ||
2247 | |||
2199 | return 0; | 2248 | return 0; |
2200 | 2249 | ||
2201 | err_kfree: | 2250 | err_kfree: |
@@ -2203,7 +2252,7 @@ err_kfree: | |||
2203 | err_fe: | 2252 | err_fe: |
2204 | kfree(config); | 2253 | kfree(config); |
2205 | fail: | 2254 | fail: |
2206 | dev_dbg(&client->dev, "failed=%d\n", ret); | 2255 | dev_warn(&client->dev, "probe failed = %d\n", ret); |
2207 | return ret; | 2256 | return ret; |
2208 | } | 2257 | } |
2209 | 2258 | ||
diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c index 2969ba6ed9e1..377cd984b069 100644 --- a/drivers/media/dvb-frontends/mb86a16.c +++ b/drivers/media/dvb-frontends/mb86a16.c | |||
@@ -31,8 +31,6 @@ | |||
31 | static unsigned int verbose = 5; | 31 | static unsigned int verbose = 5; |
32 | module_param(verbose, int, 0644); | 32 | module_param(verbose, int, 0644); |
33 | 33 | ||
34 | #define ABS(x) ((x) < 0 ? (-x) : (x)) | ||
35 | |||
36 | struct mb86a16_state { | 34 | struct mb86a16_state { |
37 | struct i2c_adapter *i2c_adap; | 35 | struct i2c_adapter *i2c_adap; |
38 | const struct mb86a16_config *config; | 36 | const struct mb86a16_config *config; |
@@ -1202,12 +1200,12 @@ static int mb86a16_set_fe(struct mb86a16_state *state) | |||
1202 | 1200 | ||
1203 | signal_dupl = 0; | 1201 | signal_dupl = 0; |
1204 | for (j = 0; j < prev_freq_num; j++) { | 1202 | for (j = 0; j < prev_freq_num; j++) { |
1205 | if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) { | 1203 | if ((abs(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) { |
1206 | signal_dupl = 1; | 1204 | signal_dupl = 1; |
1207 | dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j); | 1205 | dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j); |
1208 | } | 1206 | } |
1209 | } | 1207 | } |
1210 | if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) { | 1208 | if ((signal_dupl == 0) && (swp_freq > 0) && (abs(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) { |
1211 | dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate); | 1209 | dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate); |
1212 | prev_swp_freq[prev_freq_num] = swp_freq; | 1210 | prev_swp_freq[prev_freq_num] = swp_freq; |
1213 | prev_freq_num++; | 1211 | prev_freq_num++; |
@@ -1381,7 +1379,7 @@ static int mb86a16_set_fe(struct mb86a16_state *state) | |||
1381 | dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq); | 1379 | dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq); |
1382 | swp_freq += delta_freq; | 1380 | swp_freq += delta_freq; |
1383 | dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq); | 1381 | dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq); |
1384 | if (ABS(state->frequency * 1000 - swp_freq) > 3800) { | 1382 | if (abs(state->frequency * 1000 - swp_freq) > 3800) { |
1385 | dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL !"); | 1383 | dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL !"); |
1386 | } else { | 1384 | } else { |
1387 | 1385 | ||
diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c index e899821018a0..483ee7d6198e 100644 --- a/drivers/media/dvb-frontends/mxl5xx.c +++ b/drivers/media/dvb-frontends/mxl5xx.c | |||
@@ -380,6 +380,38 @@ static int get_algo(struct dvb_frontend *fe) | |||
380 | return DVBFE_ALGO_HW; | 380 | return DVBFE_ALGO_HW; |
381 | } | 381 | } |
382 | 382 | ||
383 | static u32 gold2root(u32 gold) | ||
384 | { | ||
385 | u32 x, g, tmp = gold; | ||
386 | |||
387 | if (tmp >= 0x3ffff) | ||
388 | tmp = 0; | ||
389 | for (g = 0, x = 1; g < tmp; g++) | ||
390 | x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1); | ||
391 | return x; | ||
392 | } | ||
393 | |||
394 | static int cfg_scrambler(struct mxl *state, u32 gold) | ||
395 | { | ||
396 | u32 root; | ||
397 | u8 buf[26] = { | ||
398 | MXL_HYDRA_PLID_CMD_WRITE, 24, | ||
399 | 0, MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD, 0, 0, | ||
400 | state->demod, 0, 0, 0, | ||
401 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
402 | 0, 0, 0, 0, 1, 0, 0, 0, | ||
403 | }; | ||
404 | |||
405 | root = gold2root(gold); | ||
406 | |||
407 | buf[25] = (root >> 24) & 0xff; | ||
408 | buf[24] = (root >> 16) & 0xff; | ||
409 | buf[23] = (root >> 8) & 0xff; | ||
410 | buf[22] = root & 0xff; | ||
411 | |||
412 | return send_command(state, sizeof(buf), buf); | ||
413 | } | ||
414 | |||
383 | static int cfg_demod_abort_tune(struct mxl *state) | 415 | static int cfg_demod_abort_tune(struct mxl *state) |
384 | { | 416 | { |
385 | struct MXL_HYDRA_DEMOD_ABORT_TUNE_T abort_tune_cmd; | 417 | struct MXL_HYDRA_DEMOD_ABORT_TUNE_T abort_tune_cmd; |
@@ -437,7 +469,7 @@ static int set_parameters(struct dvb_frontend *fe) | |||
437 | demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO; | 469 | demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO; |
438 | demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_AUTO; | 470 | demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_AUTO; |
439 | demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_AUTO; | 471 | demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_AUTO; |
440 | /* cfg_scrambler(state); */ | 472 | cfg_scrambler(state, p->scrambling_sequence_index); |
441 | break; | 473 | break; |
442 | default: | 474 | default: |
443 | return -EINVAL; | 475 | return -EINVAL; |
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 94bf5b7d6f3f..fa3b8169c1a5 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c | |||
@@ -498,7 +498,7 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) | |||
498 | * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22) | 498 | * RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22) |
499 | * / ConstWithBandwidthMode) | 499 | * / ConstWithBandwidthMode) |
500 | */ | 500 | */ |
501 | num = dev->pdata->clk * 7; | 501 | num = dev->pdata->clk * 7ULL; |
502 | num *= 0x400000; | 502 | num *= 0x400000; |
503 | num = div_u64(num, bw_mode); | 503 | num = div_u64(num, bw_mode); |
504 | resamp_ratio = num & 0x3ffffff; | 504 | resamp_ratio = num & 0x3ffffff; |
@@ -511,7 +511,7 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) | |||
511 | * / (CrystalFreqHz * 7)) | 511 | * / (CrystalFreqHz * 7)) |
512 | */ | 512 | */ |
513 | num = bw_mode << 20; | 513 | num = bw_mode << 20; |
514 | num2 = dev->pdata->clk * 7; | 514 | num2 = dev->pdata->clk * 7ULL; |
515 | num = div_u64(num, num2); | 515 | num = div_u64(num, num2); |
516 | num = -num; | 516 | num = -num; |
517 | cfreq_off_ratio = num & 0xfffff; | 517 | cfreq_off_ratio = num & 0xfffff; |
diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c index aced6a956ec5..a23ba8727218 100644 --- a/drivers/media/dvb-frontends/s5h1409.c +++ b/drivers/media/dvb-frontends/s5h1409.c | |||
@@ -682,17 +682,17 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) | |||
682 | 682 | ||
683 | val = s5h1409_readreg(state, 0xac) & 0xcfff; | 683 | val = s5h1409_readreg(state, 0xac) & 0xcfff; |
684 | switch (mode) { | 684 | switch (mode) { |
685 | case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: | 685 | case S5H1409_MPEGTIMING_CONTINUOUS_INVERTING_CLOCK: |
686 | val |= 0x0000; | 686 | val |= 0x0000; |
687 | break; | 687 | break; |
688 | case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: | 688 | case S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK: |
689 | dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); | 689 | dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); |
690 | val |= 0x1000; | 690 | val |= 0x1000; |
691 | break; | 691 | break; |
692 | case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: | 692 | case S5H1409_MPEGTIMING_NONCONTINUOUS_INVERTING_CLOCK: |
693 | val |= 0x2000; | 693 | val |= 0x2000; |
694 | break; | 694 | break; |
695 | case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: | 695 | case S5H1409_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK: |
696 | val |= 0x3000; | 696 | val |= 0x3000; |
697 | break; | 697 | break; |
698 | default: | 698 | default: |
diff --git a/drivers/media/dvb-frontends/s5h1409.h b/drivers/media/dvb-frontends/s5h1409.h index b38557c451b9..87de58ffc822 100644 --- a/drivers/media/dvb-frontends/s5h1409.h +++ b/drivers/media/dvb-frontends/s5h1409.h | |||
@@ -52,10 +52,10 @@ struct s5h1409_config { | |||
52 | u8 status_mode; | 52 | u8 status_mode; |
53 | 53 | ||
54 | /* MPEG signal timing */ | 54 | /* MPEG signal timing */ |
55 | #define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 | 55 | #define S5H1409_MPEGTIMING_CONTINUOUS_INVERTING_CLOCK 0 |
56 | #define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 | 56 | #define S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK 1 |
57 | #define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 | 57 | #define S5H1409_MPEGTIMING_NONCONTINUOUS_INVERTING_CLOCK 2 |
58 | #define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 | 58 | #define S5H1409_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK 3 |
59 | u16 mpeg_timing; | 59 | u16 mpeg_timing; |
60 | 60 | ||
61 | /* HVR-1600 optimizations (to better work with MXL5005s) | 61 | /* HVR-1600 optimizations (to better work with MXL5005s) |
diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c index c4b1e9725f3e..af5962807f2c 100644 --- a/drivers/media/dvb-frontends/s5h1411.c +++ b/drivers/media/dvb-frontends/s5h1411.c | |||
@@ -433,17 +433,17 @@ static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode) | |||
433 | 433 | ||
434 | val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff; | 434 | val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff; |
435 | switch (mode) { | 435 | switch (mode) { |
436 | case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: | 436 | case S5H1411_MPEGTIMING_CONTINUOUS_INVERTING_CLOCK: |
437 | val |= 0x0000; | 437 | val |= 0x0000; |
438 | break; | 438 | break; |
439 | case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: | 439 | case S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK: |
440 | dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); | 440 | dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); |
441 | val |= 0x1000; | 441 | val |= 0x1000; |
442 | break; | 442 | break; |
443 | case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: | 443 | case S5H1411_MPEGTIMING_NONCONTINUOUS_INVERTING_CLOCK: |
444 | val |= 0x2000; | 444 | val |= 0x2000; |
445 | break; | 445 | break; |
446 | case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: | 446 | case S5H1411_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK: |
447 | val |= 0x3000; | 447 | val |= 0x3000; |
448 | break; | 448 | break; |
449 | default: | 449 | default: |
diff --git a/drivers/media/dvb-frontends/s5h1411.h b/drivers/media/dvb-frontends/s5h1411.h index 791bab0e16e9..850ee713d64c 100644 --- a/drivers/media/dvb-frontends/s5h1411.h +++ b/drivers/media/dvb-frontends/s5h1411.h | |||
@@ -40,10 +40,10 @@ struct s5h1411_config { | |||
40 | u8 gpio; | 40 | u8 gpio; |
41 | 41 | ||
42 | /* MPEG signal timing */ | 42 | /* MPEG signal timing */ |
43 | #define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 | 43 | #define S5H1411_MPEGTIMING_CONTINUOUS_INVERTING_CLOCK 0 |
44 | #define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 | 44 | #define S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK 1 |
45 | #define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 | 45 | #define S5H1411_MPEGTIMING_NONCONTINUOUS_INVERTING_CLOCK 2 |
46 | #define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 | 46 | #define S5H1411_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK 3 |
47 | u16 mpeg_timing; | 47 | u16 mpeg_timing; |
48 | 48 | ||
49 | /* IF Freq for QAM and VSB in KHz */ | 49 | /* IF Freq for QAM and VSB in KHz */ |
diff --git a/drivers/media/dvb-frontends/s5h1432.h b/drivers/media/dvb-frontends/s5h1432.h index af3a157b5e77..646dda36262b 100644 --- a/drivers/media/dvb-frontends/s5h1432.h +++ b/drivers/media/dvb-frontends/s5h1432.h | |||
@@ -42,10 +42,10 @@ struct s5h1432_config { | |||
42 | u8 gpio; | 42 | u8 gpio; |
43 | 43 | ||
44 | /* MPEG signal timing */ | 44 | /* MPEG signal timing */ |
45 | #define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 | 45 | #define S5H1432_MPEGTIMING_CONTINUOUS_INVERTING_CLOCK 0 |
46 | #define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 | 46 | #define S5H1432_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK 1 |
47 | #define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 | 47 | #define S5H1432_MPEGTIMING_NONCONTINUOUS_INVERTING_CLOCK 2 |
48 | #define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 | 48 | #define S5H1432_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK 3 |
49 | u16 mpeg_timing; | 49 | u16 mpeg_timing; |
50 | 50 | ||
51 | /* IF Freq for QAM and VSB in KHz */ | 51 | /* IF Freq for QAM and VSB in KHz */ |
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 539399dac551..324493e05f9f 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c | |||
@@ -82,6 +82,30 @@ err_mutex_unlock: | |||
82 | return ret; | 82 | return ret; |
83 | } | 83 | } |
84 | 84 | ||
85 | static int si2168_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
86 | { | ||
87 | struct i2c_client *client = fe->demodulator_priv; | ||
88 | struct si2168_dev *dev = i2c_get_clientdata(client); | ||
89 | struct si2168_cmd cmd; | ||
90 | int ret = 0; | ||
91 | |||
92 | dev_dbg(&client->dev, "%s acquire: %d\n", __func__, acquire); | ||
93 | |||
94 | /* set TS_MODE property */ | ||
95 | memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); | ||
96 | if (acquire) | ||
97 | cmd.args[4] |= dev->ts_mode; | ||
98 | else | ||
99 | cmd.args[4] |= SI2168_TS_TRISTATE; | ||
100 | if (dev->ts_clock_gapped) | ||
101 | cmd.args[4] |= 0x40; | ||
102 | cmd.wlen = 6; | ||
103 | cmd.rlen = 4; | ||
104 | ret = si2168_cmd_execute(client, &cmd); | ||
105 | |||
106 | return ret; | ||
107 | } | ||
108 | |||
85 | static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) | 109 | static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) |
86 | { | 110 | { |
87 | struct i2c_client *client = fe->demodulator_priv; | 111 | struct i2c_client *client = fe->demodulator_priv; |
@@ -339,6 +363,8 @@ static int si2168_set_frontend(struct dvb_frontend *fe) | |||
339 | 363 | ||
340 | memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6); | 364 | memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6); |
341 | cmd.args[4] = delivery_system | bandwidth; | 365 | cmd.args[4] = delivery_system | bandwidth; |
366 | if (dev->spectral_inversion) | ||
367 | cmd.args[5] |= 1; | ||
342 | cmd.wlen = 6; | 368 | cmd.wlen = 6; |
343 | cmd.rlen = 4; | 369 | cmd.rlen = 4; |
344 | ret = si2168_cmd_execute(client, &cmd); | 370 | ret = si2168_cmd_execute(client, &cmd); |
@@ -403,6 +429,11 @@ static int si2168_set_frontend(struct dvb_frontend *fe) | |||
403 | 429 | ||
404 | dev->delivery_system = c->delivery_system; | 430 | dev->delivery_system = c->delivery_system; |
405 | 431 | ||
432 | /* enable ts bus */ | ||
433 | ret = si2168_ts_bus_ctrl(fe, 1); | ||
434 | if (ret) | ||
435 | goto err; | ||
436 | |||
406 | return 0; | 437 | return 0; |
407 | err: | 438 | err: |
408 | dev_dbg(&client->dev, "failed=%d\n", ret); | 439 | dev_dbg(&client->dev, "failed=%d\n", ret); |
@@ -541,13 +572,7 @@ static int si2168_init(struct dvb_frontend *fe) | |||
541 | dev->version >> 8 & 0xff, dev->version >> 0 & 0xff); | 572 | dev->version >> 8 & 0xff, dev->version >> 0 & 0xff); |
542 | 573 | ||
543 | /* set ts mode */ | 574 | /* set ts mode */ |
544 | memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6); | 575 | ret = si2168_ts_bus_ctrl(fe, 1); |
545 | cmd.args[4] |= dev->ts_mode; | ||
546 | if (dev->ts_clock_gapped) | ||
547 | cmd.args[4] |= 0x40; | ||
548 | cmd.wlen = 6; | ||
549 | cmd.rlen = 4; | ||
550 | ret = si2168_cmd_execute(client, &cmd); | ||
551 | if (ret) | 576 | if (ret) |
552 | goto err; | 577 | goto err; |
553 | 578 | ||
@@ -584,7 +609,12 @@ static int si2168_sleep(struct dvb_frontend *fe) | |||
584 | 609 | ||
585 | dev->active = false; | 610 | dev->active = false; |
586 | 611 | ||
587 | /* Firmware B 4.0-11 or later loses warm state during sleep */ | 612 | /* tri-state data bus */ |
613 | ret = si2168_ts_bus_ctrl(fe, 0); | ||
614 | if (ret) | ||
615 | goto err; | ||
616 | |||
617 | /* Firmware later than B 4.0-11 loses warm state during sleep */ | ||
588 | if (dev->version > ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0)) | 618 | if (dev->version > ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0)) |
589 | dev->warm = false; | 619 | dev->warm = false; |
590 | 620 | ||
@@ -776,6 +806,7 @@ static int si2168_probe(struct i2c_client *client, | |||
776 | dev->ts_mode = config->ts_mode; | 806 | dev->ts_mode = config->ts_mode; |
777 | dev->ts_clock_inv = config->ts_clock_inv; | 807 | dev->ts_clock_inv = config->ts_clock_inv; |
778 | dev->ts_clock_gapped = config->ts_clock_gapped; | 808 | dev->ts_clock_gapped = config->ts_clock_gapped; |
809 | dev->spectral_inversion = config->spectral_inversion; | ||
779 | 810 | ||
780 | dev_info(&client->dev, "Silicon Labs Si2168-%c%d%d successfully identified\n", | 811 | dev_info(&client->dev, "Silicon Labs Si2168-%c%d%d successfully identified\n", |
781 | dev->version >> 24 & 0xff, dev->version >> 16 & 0xff, | 812 | dev->version >> 24 & 0xff, dev->version >> 16 & 0xff, |
@@ -788,7 +819,7 @@ static int si2168_probe(struct i2c_client *client, | |||
788 | err_kfree: | 819 | err_kfree: |
789 | kfree(dev); | 820 | kfree(dev); |
790 | err: | 821 | err: |
791 | dev_dbg(&client->dev, "failed=%d\n", ret); | 822 | dev_warn(&client->dev, "probe failed = %d\n", ret); |
792 | return ret; | 823 | return ret; |
793 | } | 824 | } |
794 | 825 | ||
diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h index 3225d0cc93c7..d519edd26c21 100644 --- a/drivers/media/dvb-frontends/si2168.h +++ b/drivers/media/dvb-frontends/si2168.h | |||
@@ -38,6 +38,7 @@ struct si2168_config { | |||
38 | /* TS mode */ | 38 | /* TS mode */ |
39 | #define SI2168_TS_PARALLEL 0x06 | 39 | #define SI2168_TS_PARALLEL 0x06 |
40 | #define SI2168_TS_SERIAL 0x03 | 40 | #define SI2168_TS_SERIAL 0x03 |
41 | #define SI2168_TS_TRISTATE 0x00 | ||
41 | u8 ts_mode; | 42 | u8 ts_mode; |
42 | 43 | ||
43 | /* TS clock inverted */ | 44 | /* TS clock inverted */ |
@@ -45,6 +46,9 @@ struct si2168_config { | |||
45 | 46 | ||
46 | /* TS clock gapped */ | 47 | /* TS clock gapped */ |
47 | bool ts_clock_gapped; | 48 | bool ts_clock_gapped; |
49 | |||
50 | /* Inverted spectrum */ | ||
51 | bool spectral_inversion; | ||
48 | }; | 52 | }; |
49 | 53 | ||
50 | #endif | 54 | #endif |
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index 3c8746a20038..2d362e162ade 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h | |||
@@ -48,6 +48,7 @@ struct si2168_dev { | |||
48 | u8 ts_mode; | 48 | u8 ts_mode; |
49 | bool ts_clock_inv; | 49 | bool ts_clock_inv; |
50 | bool ts_clock_gapped; | 50 | bool ts_clock_gapped; |
51 | bool spectral_inversion; | ||
51 | }; | 52 | }; |
52 | 53 | ||
53 | /* firmware command struct */ | 54 | /* firmware command struct */ |
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c index 572a297811fe..f39d566d7d1d 100644 --- a/drivers/media/dvb-frontends/sp887x.c +++ b/drivers/media/dvb-frontends/sp887x.c | |||
@@ -136,7 +136,7 @@ static void sp887x_setup_agc (struct sp887x_state* state) | |||
136 | static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw) | 136 | static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw) |
137 | { | 137 | { |
138 | struct sp887x_state* state = fe->demodulator_priv; | 138 | struct sp887x_state* state = fe->demodulator_priv; |
139 | u8 buf [BLOCKSIZE+2]; | 139 | u8 buf [BLOCKSIZE + 2]; |
140 | int i; | 140 | int i; |
141 | int fw_size = fw->size; | 141 | int fw_size = fw->size; |
142 | const unsigned char *mem = fw->data; | 142 | const unsigned char *mem = fw->data; |
@@ -144,7 +144,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware | |||
144 | dprintk("%s\n", __func__); | 144 | dprintk("%s\n", __func__); |
145 | 145 | ||
146 | /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */ | 146 | /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */ |
147 | if (fw_size < FW_SIZE+10) | 147 | if (fw_size < FW_SIZE + 10) |
148 | return -ENODEV; | 148 | return -ENODEV; |
149 | 149 | ||
150 | mem = fw->data + 10; | 150 | mem = fw->data + 10; |
@@ -167,7 +167,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware | |||
167 | int c = BLOCKSIZE; | 167 | int c = BLOCKSIZE; |
168 | int err; | 168 | int err; |
169 | 169 | ||
170 | if (i+c > FW_SIZE) | 170 | if (c > FW_SIZE - i) |
171 | c = FW_SIZE - i; | 171 | c = FW_SIZE - i; |
172 | 172 | ||
173 | /* bit 0x8000 in address is set to enable 13bit mode */ | 173 | /* bit 0x8000 in address is set to enable 13bit mode */ |
diff --git a/drivers/media/dvb-frontends/stb0899_reg.h b/drivers/media/dvb-frontends/stb0899_reg.h index ba1ed56304a0..f564269249a6 100644 --- a/drivers/media/dvb-frontends/stb0899_reg.h +++ b/drivers/media/dvb-frontends/stb0899_reg.h | |||
@@ -374,22 +374,22 @@ | |||
374 | 374 | ||
375 | #define STB0899_OFF0_IF_AGC_GAIN 0xf30c | 375 | #define STB0899_OFF0_IF_AGC_GAIN 0xf30c |
376 | #define STB0899_BASE_IF_AGC_GAIN 0x00000000 | 376 | #define STB0899_BASE_IF_AGC_GAIN 0x00000000 |
377 | #define STB0899_IF_AGC_GAIN (0x3fff < 0) | 377 | #define STB0899_IF_AGC_GAIN (0x3fff << 0) |
378 | #define STB0899_OFFST_IF_AGC_GAIN 0 | 378 | #define STB0899_OFFST_IF_AGC_GAIN 0 |
379 | #define STB0899_WIDTH_IF_AGC_GAIN 14 | 379 | #define STB0899_WIDTH_IF_AGC_GAIN 14 |
380 | 380 | ||
381 | #define STB0899_OFF0_BB_AGC_GAIN 0xf310 | 381 | #define STB0899_OFF0_BB_AGC_GAIN 0xf310 |
382 | #define STB0899_BASE_BB_AGC_GAIN 0x00000000 | 382 | #define STB0899_BASE_BB_AGC_GAIN 0x00000000 |
383 | #define STB0899_BB_AGC_GAIN (0x3fff < 0) | 383 | #define STB0899_BB_AGC_GAIN (0x3fff << 0) |
384 | #define STB0899_OFFST_BB_AGC_GAIN 0 | 384 | #define STB0899_OFFST_BB_AGC_GAIN 0 |
385 | #define STB0899_WIDTH_BB_AGC_GAIN 14 | 385 | #define STB0899_WIDTH_BB_AGC_GAIN 14 |
386 | 386 | ||
387 | #define STB0899_OFF0_DC_OFFSET 0xf314 | 387 | #define STB0899_OFF0_DC_OFFSET 0xf314 |
388 | #define STB0899_BASE_DC_OFFSET 0x00000000 | 388 | #define STB0899_BASE_DC_OFFSET 0x00000000 |
389 | #define STB0899_I (0xff < 8) | 389 | #define STB0899_I (0xff << 8) |
390 | #define STB0899_OFFST_I 8 | 390 | #define STB0899_OFFST_I 8 |
391 | #define STB0899_WIDTH_I 8 | 391 | #define STB0899_WIDTH_I 8 |
392 | #define STB0899_Q (0xff < 0) | 392 | #define STB0899_Q (0xff << 0) |
393 | #define STB0899_OFFST_Q 8 | 393 | #define STB0899_OFFST_Q 8 |
394 | #define STB0899_WIDTH_Q 8 | 394 | #define STB0899_WIDTH_Q 8 |
395 | 395 | ||
diff --git a/drivers/media/dvb-frontends/stv0367_priv.h b/drivers/media/dvb-frontends/stv0367_priv.h index 8abc451dd524..460066a391b7 100644 --- a/drivers/media/dvb-frontends/stv0367_priv.h +++ b/drivers/media/dvb-frontends/stv0367_priv.h | |||
@@ -35,7 +35,6 @@ | |||
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | /* MACRO definitions */ | 37 | /* MACRO definitions */ |
38 | #define ABS(X) ((X) < 0 ? (-1 * (X)) : (X)) | ||
39 | #define MAX(X, Y) ((X) >= (Y) ? (X) : (Y)) | 38 | #define MAX(X, Y) ((X) >= (Y) ? (X) : (Y)) |
40 | #define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) | 39 | #define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) |
41 | #define INRANGE(X, Y, Z) \ | 40 | #define INRANGE(X, Y, Z) \ |
diff --git a/drivers/media/dvb-frontends/stv0900_priv.h b/drivers/media/dvb-frontends/stv0900_priv.h index d1fc06ff27d3..09a46477eae4 100644 --- a/drivers/media/dvb-frontends/stv0900_priv.h +++ b/drivers/media/dvb-frontends/stv0900_priv.h | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | 26 | ||
27 | #define ABS(X) ((X) < 0 ? (-1 * (X)) : (X)) | ||
28 | #define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \ | 27 | #define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \ |
29 | || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) | 28 | || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) |
30 | 29 | ||
diff --git a/drivers/media/dvb-frontends/stv0900_sw.c b/drivers/media/dvb-frontends/stv0900_sw.c index c97a39120ea5..d406c83e4744 100644 --- a/drivers/media/dvb-frontends/stv0900_sw.c +++ b/drivers/media/dvb-frontends/stv0900_sw.c | |||
@@ -1255,14 +1255,14 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) | |||
1255 | else | 1255 | else |
1256 | intp->freq[d] = stv0900_get_tuner_freq(fe); | 1256 | intp->freq[d] = stv0900_get_tuner_freq(fe); |
1257 | 1257 | ||
1258 | if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) | 1258 | if (abs(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) |
1259 | range = STV0900_RANGEOK; | 1259 | range = STV0900_RANGEOK; |
1260 | else if (ABS(offsetFreq) <= | 1260 | else if (abs(offsetFreq) <= |
1261 | (stv0900_carrier_width(result->symbol_rate, | 1261 | (stv0900_carrier_width(result->symbol_rate, |
1262 | result->rolloff) / 2000)) | 1262 | result->rolloff) / 2000)) |
1263 | range = STV0900_RANGEOK; | 1263 | range = STV0900_RANGEOK; |
1264 | 1264 | ||
1265 | } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) | 1265 | } else if (abs(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) |
1266 | range = STV0900_RANGEOK; | 1266 | range = STV0900_RANGEOK; |
1267 | 1267 | ||
1268 | dprintk("%s: range %d\n", __func__, range); | 1268 | dprintk("%s: range %d\n", __func__, range); |
diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index a2f7c0c1587f..52355c14fd64 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c | |||
@@ -1673,15 +1673,15 @@ static int send_master_cmd(struct dvb_frontend *fe, | |||
1673 | struct dvb_diseqc_master_cmd *cmd) | 1673 | struct dvb_diseqc_master_cmd *cmd) |
1674 | { | 1674 | { |
1675 | struct stv *state = fe->demodulator_priv; | 1675 | struct stv *state = fe->demodulator_priv; |
1676 | u16 offs = state->nr ? 0x40 : 0; | ||
1677 | int i; | 1676 | int i; |
1678 | 1677 | ||
1679 | write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E); | 1678 | SET_FIELD(DISEQC_MODE, 2); |
1679 | SET_FIELD(DIS_PRECHARGE, 1); | ||
1680 | for (i = 0; i < cmd->msg_len; i++) { | 1680 | for (i = 0; i < cmd->msg_len; i++) { |
1681 | wait_dis(state, 0x40, 0x00); | 1681 | wait_dis(state, 0x40, 0x00); |
1682 | write_reg(state, RSTV0910_P1_DISTXFIFO + offs, cmd->msg[i]); | 1682 | SET_REG(DISTXFIFO, cmd->msg[i]); |
1683 | } | 1683 | } |
1684 | write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); | 1684 | SET_FIELD(DIS_PRECHARGE, 0); |
1685 | wait_dis(state, 0x20, 0x20); | 1685 | wait_dis(state, 0x20, 0x20); |
1686 | return 0; | 1686 | return 0; |
1687 | } | 1687 | } |
@@ -1689,19 +1689,20 @@ static int send_master_cmd(struct dvb_frontend *fe, | |||
1689 | static int send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) | 1689 | static int send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst) |
1690 | { | 1690 | { |
1691 | struct stv *state = fe->demodulator_priv; | 1691 | struct stv *state = fe->demodulator_priv; |
1692 | u16 offs = state->nr ? 0x40 : 0; | ||
1693 | u8 value; | 1692 | u8 value; |
1694 | 1693 | ||
1695 | if (burst == SEC_MINI_A) { | 1694 | if (burst == SEC_MINI_A) { |
1696 | write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3F); | 1695 | SET_FIELD(DISEQC_MODE, 3); |
1697 | value = 0x00; | 1696 | value = 0x00; |
1698 | } else { | 1697 | } else { |
1699 | write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E); | 1698 | SET_FIELD(DISEQC_MODE, 2); |
1700 | value = 0xFF; | 1699 | value = 0xFF; |
1701 | } | 1700 | } |
1701 | |||
1702 | SET_FIELD(DIS_PRECHARGE, 1); | ||
1702 | wait_dis(state, 0x40, 0x00); | 1703 | wait_dis(state, 0x40, 0x00); |
1703 | write_reg(state, RSTV0910_P1_DISTXFIFO + offs, value); | 1704 | SET_REG(DISTXFIFO, value); |
1704 | write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A); | 1705 | SET_FIELD(DIS_PRECHARGE, 0); |
1705 | wait_dis(state, 0x20, 0x20); | 1706 | wait_dis(state, 0x20, 0x20); |
1706 | 1707 | ||
1707 | return 0; | 1708 | return 0; |
diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c index 1d8979289915..17600989f121 100644 --- a/drivers/media/dvb-frontends/ves1820.c +++ b/drivers/media/dvb-frontends/ves1820.c | |||
@@ -137,7 +137,7 @@ static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate) | |||
137 | NDEC = 3; | 137 | NDEC = 3; |
138 | 138 | ||
139 | /* yeuch! */ | 139 | /* yeuch! */ |
140 | fpxin = state->config->xin * 10; | 140 | fpxin = state->config->xin * 10ULL; |
141 | fptmp = fpxin; do_div(fptmp, 123); | 141 | fptmp = fpxin; do_div(fptmp, 123); |
142 | if (symbolrate < fptmp) | 142 | if (symbolrate < fptmp) |
143 | SFIL = 1; | 143 | SFIL = 1; |
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 9f18cd296841..541f0d28afd8 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig | |||
@@ -56,6 +56,17 @@ config VIDEO_TDA9840 | |||
56 | To compile this driver as a module, choose M here: the | 56 | To compile this driver as a module, choose M here: the |
57 | module will be called tda9840. | 57 | module will be called tda9840. |
58 | 58 | ||
59 | config VIDEO_TDA1997X | ||
60 | tristate "NXP TDA1997x HDMI receiver" | ||
61 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | ||
62 | depends on SND_SOC | ||
63 | select SND_PCM | ||
64 | ---help--- | ||
65 | V4L2 subdevice driver for the NXP TDA1997x HDMI receivers. | ||
66 | |||
67 | To compile this driver as a module, choose M here: the | ||
68 | module will be called tda1997x. | ||
69 | |||
59 | config VIDEO_TEA6415C | 70 | config VIDEO_TEA6415C |
60 | tristate "Philips TEA6415C audio processor" | 71 | tristate "Philips TEA6415C audio processor" |
61 | depends on I2C | 72 | depends on I2C |
@@ -423,6 +434,15 @@ config VIDEO_TW9906 | |||
423 | To compile this driver as a module, choose M here: the | 434 | To compile this driver as a module, choose M here: the |
424 | module will be called tw9906. | 435 | module will be called tw9906. |
425 | 436 | ||
437 | config VIDEO_TW9910 | ||
438 | tristate "Techwell TW9910 video decoder" | ||
439 | depends on VIDEO_V4L2 && I2C | ||
440 | ---help--- | ||
441 | Support for Techwell TW9910 NTSC/PAL/SECAM video decoder. | ||
442 | |||
443 | To compile this driver as a module, choose M here: the | ||
444 | module will be called tw9910. | ||
445 | |||
426 | config VIDEO_VPX3220 | 446 | config VIDEO_VPX3220 |
427 | tristate "vpx3220a, vpx3216b & vpx3214c video decoders" | 447 | tristate "vpx3220a, vpx3216b & vpx3214c video decoders" |
428 | depends on VIDEO_V4L2 && I2C | 448 | depends on VIDEO_V4L2 && I2C |
@@ -586,6 +606,18 @@ config VIDEO_OV2659 | |||
586 | To compile this driver as a module, choose M here: the | 606 | To compile this driver as a module, choose M here: the |
587 | module will be called ov2659. | 607 | module will be called ov2659. |
588 | 608 | ||
609 | config VIDEO_OV2685 | ||
610 | tristate "OmniVision OV2685 sensor support" | ||
611 | depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER | ||
612 | depends on MEDIA_CAMERA_SUPPORT | ||
613 | select V4L2_FWNODE | ||
614 | ---help--- | ||
615 | This is a Video4Linux2 sensor-level driver for the OmniVision | ||
616 | OV2685 camera. | ||
617 | |||
618 | To compile this driver as a module, choose M here: the | ||
619 | module will be called ov2685. | ||
620 | |||
589 | config VIDEO_OV5640 | 621 | config VIDEO_OV5640 |
590 | tristate "OmniVision OV5640 sensor support" | 622 | tristate "OmniVision OV5640 sensor support" |
591 | depends on OF | 623 | depends on OF |
@@ -645,6 +677,28 @@ config VIDEO_OV5670 | |||
645 | To compile this driver as a module, choose M here: the | 677 | To compile this driver as a module, choose M here: the |
646 | module will be called ov5670. | 678 | module will be called ov5670. |
647 | 679 | ||
680 | config VIDEO_OV5695 | ||
681 | tristate "OmniVision OV5695 sensor support" | ||
682 | depends on I2C && VIDEO_V4L2 | ||
683 | depends on MEDIA_CAMERA_SUPPORT | ||
684 | ---help--- | ||
685 | This is a Video4Linux2 sensor-level driver for the OmniVision | ||
686 | OV5695 camera. | ||
687 | |||
688 | To compile this driver as a module, choose M here: the | ||
689 | module will be called ov5695. | ||
690 | |||
691 | config VIDEO_OV772X | ||
692 | tristate "OmniVision OV772x sensor support" | ||
693 | depends on I2C && VIDEO_V4L2 | ||
694 | depends on MEDIA_CAMERA_SUPPORT | ||
695 | ---help--- | ||
696 | This is a Video4Linux2 sensor-level driver for the OmniVision | ||
697 | OV772x camera. | ||
698 | |||
699 | To compile this driver as a module, choose M here: the | ||
700 | module will be called ov772x. | ||
701 | |||
648 | config VIDEO_OV7640 | 702 | config VIDEO_OV7640 |
649 | tristate "OmniVision OV7640 sensor support" | 703 | tristate "OmniVision OV7640 sensor support" |
650 | depends on I2C && VIDEO_V4L2 | 704 | depends on I2C && VIDEO_V4L2 |
@@ -660,6 +714,7 @@ config VIDEO_OV7670 | |||
660 | tristate "OmniVision OV7670 sensor support" | 714 | tristate "OmniVision OV7670 sensor support" |
661 | depends on I2C && VIDEO_V4L2 | 715 | depends on I2C && VIDEO_V4L2 |
662 | depends on MEDIA_CAMERA_SUPPORT | 716 | depends on MEDIA_CAMERA_SUPPORT |
717 | select V4L2_FWNODE | ||
663 | ---help--- | 718 | ---help--- |
664 | This is a Video4Linux2 sensor-level driver for the OmniVision | 719 | This is a Video4Linux2 sensor-level driver for the OmniVision |
665 | OV7670 VGA camera. It currently only works with the M88ALP01 | 720 | OV7670 VGA camera. It currently only works with the M88ALP01 |
@@ -733,6 +788,17 @@ config VIDEO_MT9T001 | |||
733 | This is a Video4Linux2 sensor-level driver for the Aptina | 788 | This is a Video4Linux2 sensor-level driver for the Aptina |
734 | (Micron) mt0t001 3 Mpixel camera. | 789 | (Micron) mt0t001 3 Mpixel camera. |
735 | 790 | ||
791 | config VIDEO_MT9T112 | ||
792 | tristate "Aptina MT9T111/MT9T112 support" | ||
793 | depends on I2C && VIDEO_V4L2 | ||
794 | depends on MEDIA_CAMERA_SUPPORT | ||
795 | ---help--- | ||
796 | This is a Video4Linux2 sensor-level driver for the Aptina | ||
797 | (Micron) MT9T111 and MT9T112 3 Mpixel camera. | ||
798 | |||
799 | To compile this driver as a module, choose M here: the | ||
800 | module will be called mt9t112. | ||
801 | |||
736 | config VIDEO_MT9V011 | 802 | config VIDEO_MT9V011 |
737 | tristate "Micron mt9v011 sensor support" | 803 | tristate "Micron mt9v011 sensor support" |
738 | depends on I2C && VIDEO_V4L2 | 804 | depends on I2C && VIDEO_V4L2 |
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index c0f94cd8d56d..ea34aee1a85a 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o | |||
13 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o | 13 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o |
14 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o | 14 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o |
15 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o | 15 | obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o |
16 | obj-$(CONFIG_VIDEO_TDA1997X) += tda1997x.o | ||
16 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o | 17 | obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o |
17 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o | 18 | obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o |
18 | obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o | 19 | obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o |
@@ -48,6 +49,7 @@ obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o | |||
48 | obj-$(CONFIG_VIDEO_TW2804) += tw2804.o | 49 | obj-$(CONFIG_VIDEO_TW2804) += tw2804.o |
49 | obj-$(CONFIG_VIDEO_TW9903) += tw9903.o | 50 | obj-$(CONFIG_VIDEO_TW9903) += tw9903.o |
50 | obj-$(CONFIG_VIDEO_TW9906) += tw9906.o | 51 | obj-$(CONFIG_VIDEO_TW9906) += tw9906.o |
52 | obj-$(CONFIG_VIDEO_TW9910) += tw9910.o | ||
51 | obj-$(CONFIG_VIDEO_CS3308) += cs3308.o | 53 | obj-$(CONFIG_VIDEO_CS3308) += cs3308.o |
52 | obj-$(CONFIG_VIDEO_CS5345) += cs5345.o | 54 | obj-$(CONFIG_VIDEO_CS5345) += cs5345.o |
53 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o | 55 | obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o |
@@ -61,13 +63,16 @@ obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o | |||
61 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o | 63 | obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o |
62 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o | 64 | obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o |
63 | obj-$(CONFIG_VIDEO_OV2640) += ov2640.o | 65 | obj-$(CONFIG_VIDEO_OV2640) += ov2640.o |
66 | obj-$(CONFIG_VIDEO_OV2685) += ov2685.o | ||
64 | obj-$(CONFIG_VIDEO_OV5640) += ov5640.o | 67 | obj-$(CONFIG_VIDEO_OV5640) += ov5640.o |
65 | obj-$(CONFIG_VIDEO_OV5645) += ov5645.o | 68 | obj-$(CONFIG_VIDEO_OV5645) += ov5645.o |
66 | obj-$(CONFIG_VIDEO_OV5647) += ov5647.o | 69 | obj-$(CONFIG_VIDEO_OV5647) += ov5647.o |
67 | obj-$(CONFIG_VIDEO_OV5670) += ov5670.o | 70 | obj-$(CONFIG_VIDEO_OV5670) += ov5670.o |
71 | obj-$(CONFIG_VIDEO_OV5695) += ov5695.o | ||
68 | obj-$(CONFIG_VIDEO_OV6650) += ov6650.o | 72 | obj-$(CONFIG_VIDEO_OV6650) += ov6650.o |
69 | obj-$(CONFIG_VIDEO_OV7640) += ov7640.o | 73 | obj-$(CONFIG_VIDEO_OV7640) += ov7640.o |
70 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o | 74 | obj-$(CONFIG_VIDEO_OV7670) += ov7670.o |
75 | obj-$(CONFIG_VIDEO_OV772X) += ov772x.o | ||
71 | obj-$(CONFIG_VIDEO_OV7740) += ov7740.o | 76 | obj-$(CONFIG_VIDEO_OV7740) += ov7740.o |
72 | obj-$(CONFIG_VIDEO_OV9650) += ov9650.o | 77 | obj-$(CONFIG_VIDEO_OV9650) += ov9650.o |
73 | obj-$(CONFIG_VIDEO_OV13858) += ov13858.o | 78 | obj-$(CONFIG_VIDEO_OV13858) += ov13858.o |
@@ -75,6 +80,7 @@ obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o | |||
75 | obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o | 80 | obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o |
76 | obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o | 81 | obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o |
77 | obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o | 82 | obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o |
83 | obj-$(CONFIG_VIDEO_MT9T112) += mt9t112.o | ||
78 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o | 84 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o |
79 | obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o | 85 | obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o |
80 | obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o | 86 | obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o |
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c index a056d6cdaaaa..91ff06088572 100644 --- a/drivers/media/i2c/ad9389b.c +++ b/drivers/media/i2c/ad9389b.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Analog Devices AD9389B/AD9889B video encoder driver | 3 | * Analog Devices AD9389B/AD9889B video encoder driver |
3 | * | 4 | * |
4 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | /* | 8 | /* |
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c index fd92c9e4b519..6ca88daa0ecd 100644 --- a/drivers/media/i2c/adv748x/adv748x-core.c +++ b/drivers/media/i2c/adv748x/adv748x-core.c | |||
@@ -35,96 +35,28 @@ | |||
35 | * Register manipulation | 35 | * Register manipulation |
36 | */ | 36 | */ |
37 | 37 | ||
38 | static const struct regmap_config adv748x_regmap_cnf[] = { | 38 | #define ADV748X_REGMAP_CONF(n) \ |
39 | { | 39 | { \ |
40 | .name = "io", | 40 | .name = n, \ |
41 | .reg_bits = 8, | 41 | .reg_bits = 8, \ |
42 | .val_bits = 8, | 42 | .val_bits = 8, \ |
43 | 43 | .max_register = 0xff, \ | |
44 | .max_register = 0xff, | 44 | .cache_type = REGCACHE_NONE, \ |
45 | .cache_type = REGCACHE_NONE, | 45 | } |
46 | }, | ||
47 | { | ||
48 | .name = "dpll", | ||
49 | .reg_bits = 8, | ||
50 | .val_bits = 8, | ||
51 | |||
52 | .max_register = 0xff, | ||
53 | .cache_type = REGCACHE_NONE, | ||
54 | }, | ||
55 | { | ||
56 | .name = "cp", | ||
57 | .reg_bits = 8, | ||
58 | .val_bits = 8, | ||
59 | |||
60 | .max_register = 0xff, | ||
61 | .cache_type = REGCACHE_NONE, | ||
62 | }, | ||
63 | { | ||
64 | .name = "hdmi", | ||
65 | .reg_bits = 8, | ||
66 | .val_bits = 8, | ||
67 | |||
68 | .max_register = 0xff, | ||
69 | .cache_type = REGCACHE_NONE, | ||
70 | }, | ||
71 | { | ||
72 | .name = "edid", | ||
73 | .reg_bits = 8, | ||
74 | .val_bits = 8, | ||
75 | |||
76 | .max_register = 0xff, | ||
77 | .cache_type = REGCACHE_NONE, | ||
78 | }, | ||
79 | { | ||
80 | .name = "repeater", | ||
81 | .reg_bits = 8, | ||
82 | .val_bits = 8, | ||
83 | |||
84 | .max_register = 0xff, | ||
85 | .cache_type = REGCACHE_NONE, | ||
86 | }, | ||
87 | { | ||
88 | .name = "infoframe", | ||
89 | .reg_bits = 8, | ||
90 | .val_bits = 8, | ||
91 | |||
92 | .max_register = 0xff, | ||
93 | .cache_type = REGCACHE_NONE, | ||
94 | }, | ||
95 | { | ||
96 | .name = "cec", | ||
97 | .reg_bits = 8, | ||
98 | .val_bits = 8, | ||
99 | |||
100 | .max_register = 0xff, | ||
101 | .cache_type = REGCACHE_NONE, | ||
102 | }, | ||
103 | { | ||
104 | .name = "sdp", | ||
105 | .reg_bits = 8, | ||
106 | .val_bits = 8, | ||
107 | |||
108 | .max_register = 0xff, | ||
109 | .cache_type = REGCACHE_NONE, | ||
110 | }, | ||
111 | |||
112 | { | ||
113 | .name = "txb", | ||
114 | .reg_bits = 8, | ||
115 | .val_bits = 8, | ||
116 | |||
117 | .max_register = 0xff, | ||
118 | .cache_type = REGCACHE_NONE, | ||
119 | }, | ||
120 | { | ||
121 | .name = "txa", | ||
122 | .reg_bits = 8, | ||
123 | .val_bits = 8, | ||
124 | 46 | ||
125 | .max_register = 0xff, | 47 | static const struct regmap_config adv748x_regmap_cnf[] = { |
126 | .cache_type = REGCACHE_NONE, | 48 | ADV748X_REGMAP_CONF("io"), |
127 | }, | 49 | ADV748X_REGMAP_CONF("dpll"), |
50 | ADV748X_REGMAP_CONF("cp"), | ||
51 | ADV748X_REGMAP_CONF("hdmi"), | ||
52 | ADV748X_REGMAP_CONF("edid"), | ||
53 | ADV748X_REGMAP_CONF("repeater"), | ||
54 | ADV748X_REGMAP_CONF("infoframe"), | ||
55 | ADV748X_REGMAP_CONF("cbus"), | ||
56 | ADV748X_REGMAP_CONF("cec"), | ||
57 | ADV748X_REGMAP_CONF("sdp"), | ||
58 | ADV748X_REGMAP_CONF("txa"), | ||
59 | ADV748X_REGMAP_CONF("txb"), | ||
128 | }; | 60 | }; |
129 | 61 | ||
130 | static int adv748x_configure_regmap(struct adv748x_state *state, int region) | 62 | static int adv748x_configure_regmap(struct adv748x_state *state, int region) |
@@ -148,20 +80,24 @@ static int adv748x_configure_regmap(struct adv748x_state *state, int region) | |||
148 | 80 | ||
149 | return 0; | 81 | return 0; |
150 | } | 82 | } |
83 | struct adv748x_register_map { | ||
84 | const char *name; | ||
85 | u8 default_addr; | ||
86 | }; | ||
151 | 87 | ||
152 | /* Default addresses for the I2C pages */ | 88 | static const struct adv748x_register_map adv748x_default_addresses[] = { |
153 | static int adv748x_i2c_addresses[ADV748X_PAGE_MAX] = { | 89 | [ADV748X_PAGE_IO] = { "main", 0x70 }, |
154 | ADV748X_I2C_IO, | 90 | [ADV748X_PAGE_DPLL] = { "dpll", 0x26 }, |
155 | ADV748X_I2C_DPLL, | 91 | [ADV748X_PAGE_CP] = { "cp", 0x22 }, |
156 | ADV748X_I2C_CP, | 92 | [ADV748X_PAGE_HDMI] = { "hdmi", 0x34 }, |
157 | ADV748X_I2C_HDMI, | 93 | [ADV748X_PAGE_EDID] = { "edid", 0x36 }, |
158 | ADV748X_I2C_EDID, | 94 | [ADV748X_PAGE_REPEATER] = { "repeater", 0x32 }, |
159 | ADV748X_I2C_REPEATER, | 95 | [ADV748X_PAGE_INFOFRAME] = { "infoframe", 0x31 }, |
160 | ADV748X_I2C_INFOFRAME, | 96 | [ADV748X_PAGE_CBUS] = { "cbus", 0x30 }, |
161 | ADV748X_I2C_CEC, | 97 | [ADV748X_PAGE_CEC] = { "cec", 0x41 }, |
162 | ADV748X_I2C_SDP, | 98 | [ADV748X_PAGE_SDP] = { "sdp", 0x79 }, |
163 | ADV748X_I2C_TXB, | 99 | [ADV748X_PAGE_TXB] = { "txb", 0x48 }, |
164 | ADV748X_I2C_TXA, | 100 | [ADV748X_PAGE_TXA] = { "txa", 0x4a }, |
165 | }; | 101 | }; |
166 | 102 | ||
167 | static int adv748x_read_check(struct adv748x_state *state, | 103 | static int adv748x_read_check(struct adv748x_state *state, |
@@ -210,15 +146,20 @@ int adv748x_write_block(struct adv748x_state *state, int client_page, | |||
210 | return regmap_raw_write(regmap, init_reg, val, val_len); | 146 | return regmap_raw_write(regmap, init_reg, val, val_len); |
211 | } | 147 | } |
212 | 148 | ||
213 | static struct i2c_client *adv748x_dummy_client(struct adv748x_state *state, | 149 | static int adv748x_set_slave_addresses(struct adv748x_state *state) |
214 | u8 addr, u8 io_reg) | ||
215 | { | 150 | { |
216 | struct i2c_client *client = state->client; | 151 | struct i2c_client *client; |
152 | unsigned int i; | ||
153 | u8 io_reg; | ||
217 | 154 | ||
218 | if (addr) | 155 | for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { |
219 | io_write(state, io_reg, addr << 1); | 156 | io_reg = ADV748X_IO_SLAVE_ADDR_BASE + i; |
157 | client = state->i2c_clients[i]; | ||
158 | |||
159 | io_write(state, io_reg, client->addr << 1); | ||
160 | } | ||
220 | 161 | ||
221 | return i2c_new_dummy(client->adapter, io_read(state, io_reg) >> 1); | 162 | return 0; |
222 | } | 163 | } |
223 | 164 | ||
224 | static void adv748x_unregister_clients(struct adv748x_state *state) | 165 | static void adv748x_unregister_clients(struct adv748x_state *state) |
@@ -231,13 +172,15 @@ static void adv748x_unregister_clients(struct adv748x_state *state) | |||
231 | 172 | ||
232 | static int adv748x_initialise_clients(struct adv748x_state *state) | 173 | static int adv748x_initialise_clients(struct adv748x_state *state) |
233 | { | 174 | { |
234 | int i; | 175 | unsigned int i; |
235 | int ret; | 176 | int ret; |
236 | 177 | ||
237 | for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { | 178 | for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) { |
238 | state->i2c_clients[i] = | 179 | state->i2c_clients[i] = i2c_new_secondary_device( |
239 | adv748x_dummy_client(state, adv748x_i2c_addresses[i], | 180 | state->client, |
240 | ADV748X_IO_SLAVE_ADDR_BASE + i); | 181 | adv748x_default_addresses[i].name, |
182 | adv748x_default_addresses[i].default_addr); | ||
183 | |||
241 | if (state->i2c_clients[i] == NULL) { | 184 | if (state->i2c_clients[i] == NULL) { |
242 | adv_err(state, "failed to create i2c client %u\n", i); | 185 | adv_err(state, "failed to create i2c client %u\n", i); |
243 | return -ENOMEM; | 186 | return -ENOMEM; |
@@ -248,7 +191,7 @@ static int adv748x_initialise_clients(struct adv748x_state *state) | |||
248 | return ret; | 191 | return ret; |
249 | } | 192 | } |
250 | 193 | ||
251 | return 0; | 194 | return adv748x_set_slave_addresses(state); |
252 | } | 195 | } |
253 | 196 | ||
254 | /** | 197 | /** |
@@ -414,20 +357,6 @@ static const struct adv748x_reg_value adv748x_sw_reset[] = { | |||
414 | {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ | 357 | {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ |
415 | }; | 358 | }; |
416 | 359 | ||
417 | static const struct adv748x_reg_value adv748x_set_slave_address[] = { | ||
418 | {ADV748X_PAGE_IO, 0xf3, ADV748X_I2C_DPLL << 1}, | ||
419 | {ADV748X_PAGE_IO, 0xf4, ADV748X_I2C_CP << 1}, | ||
420 | {ADV748X_PAGE_IO, 0xf5, ADV748X_I2C_HDMI << 1}, | ||
421 | {ADV748X_PAGE_IO, 0xf6, ADV748X_I2C_EDID << 1}, | ||
422 | {ADV748X_PAGE_IO, 0xf7, ADV748X_I2C_REPEATER << 1}, | ||
423 | {ADV748X_PAGE_IO, 0xf8, ADV748X_I2C_INFOFRAME << 1}, | ||
424 | {ADV748X_PAGE_IO, 0xfa, ADV748X_I2C_CEC << 1}, | ||
425 | {ADV748X_PAGE_IO, 0xfb, ADV748X_I2C_SDP << 1}, | ||
426 | {ADV748X_PAGE_IO, 0xfc, ADV748X_I2C_TXB << 1}, | ||
427 | {ADV748X_PAGE_IO, 0xfd, ADV748X_I2C_TXA << 1}, | ||
428 | {ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */ | ||
429 | }; | ||
430 | |||
431 | /* Supported Formats For Script Below */ | 360 | /* Supported Formats For Script Below */ |
432 | /* - 01-29 HDMI to MIPI TxA CSI 4-Lane - RGB888: */ | 361 | /* - 01-29 HDMI to MIPI TxA CSI 4-Lane - RGB888: */ |
433 | static const struct adv748x_reg_value adv748x_init_txa_4lane[] = { | 362 | static const struct adv748x_reg_value adv748x_init_txa_4lane[] = { |
@@ -558,7 +487,7 @@ static int adv748x_reset(struct adv748x_state *state) | |||
558 | if (ret < 0) | 487 | if (ret < 0) |
559 | return ret; | 488 | return ret; |
560 | 489 | ||
561 | ret = adv748x_write_regs(state, adv748x_set_slave_address); | 490 | ret = adv748x_set_slave_addresses(state); |
562 | if (ret < 0) | 491 | if (ret < 0) |
563 | return ret; | 492 | return ret; |
564 | 493 | ||
@@ -715,7 +644,7 @@ static int adv748x_probe(struct i2c_client *client, | |||
715 | ret = adv748x_identify_chip(state); | 644 | ret = adv748x_identify_chip(state); |
716 | if (ret) { | 645 | if (ret) { |
717 | adv_err(state, "Failed to identify chip"); | 646 | adv_err(state, "Failed to identify chip"); |
718 | goto err_cleanup_clients; | 647 | goto err_cleanup_dt; |
719 | } | 648 | } |
720 | 649 | ||
721 | /* Configure remaining pages as I2C clients with regmap access */ | 650 | /* Configure remaining pages as I2C clients with regmap access */ |
diff --git a/drivers/media/i2c/adv748x/adv748x-hdmi.c b/drivers/media/i2c/adv748x/adv748x-hdmi.c index 4da4253553fc..10d229a4f088 100644 --- a/drivers/media/i2c/adv748x/adv748x-hdmi.c +++ b/drivers/media/i2c/adv748x/adv748x-hdmi.c | |||
@@ -105,6 +105,9 @@ static void adv748x_hdmi_fill_format(struct adv748x_hdmi *hdmi, | |||
105 | 105 | ||
106 | fmt->width = hdmi->timings.bt.width; | 106 | fmt->width = hdmi->timings.bt.width; |
107 | fmt->height = hdmi->timings.bt.height; | 107 | fmt->height = hdmi->timings.bt.height; |
108 | |||
109 | if (fmt->field == V4L2_FIELD_ALTERNATE) | ||
110 | fmt->height /= 2; | ||
108 | } | 111 | } |
109 | 112 | ||
110 | static void adv748x_fill_optional_dv_timings(struct v4l2_dv_timings *timings) | 113 | static void adv748x_fill_optional_dv_timings(struct v4l2_dv_timings *timings) |
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 6789e2f3bc8c..65f83741277e 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h | |||
@@ -27,19 +27,6 @@ | |||
27 | #ifndef _ADV748X_H_ | 27 | #ifndef _ADV748X_H_ |
28 | #define _ADV748X_H_ | 28 | #define _ADV748X_H_ |
29 | 29 | ||
30 | /* I2C slave addresses */ | ||
31 | #define ADV748X_I2C_IO 0x70 /* IO Map */ | ||
32 | #define ADV748X_I2C_DPLL 0x26 /* DPLL Map */ | ||
33 | #define ADV748X_I2C_CP 0x22 /* CP Map */ | ||
34 | #define ADV748X_I2C_HDMI 0x34 /* HDMI Map */ | ||
35 | #define ADV748X_I2C_EDID 0x36 /* EDID Map */ | ||
36 | #define ADV748X_I2C_REPEATER 0x32 /* HDMI RX Repeater Map */ | ||
37 | #define ADV748X_I2C_INFOFRAME 0x31 /* HDMI RX InfoFrame Map */ | ||
38 | #define ADV748X_I2C_CEC 0x41 /* CEC Map */ | ||
39 | #define ADV748X_I2C_SDP 0x79 /* SDP Map */ | ||
40 | #define ADV748X_I2C_TXB 0x48 /* CSI-TXB Map */ | ||
41 | #define ADV748X_I2C_TXA 0x4a /* CSI-TXA Map */ | ||
42 | |||
43 | enum adv748x_page { | 30 | enum adv748x_page { |
44 | ADV748X_PAGE_IO, | 31 | ADV748X_PAGE_IO, |
45 | ADV748X_PAGE_DPLL, | 32 | ADV748X_PAGE_DPLL, |
@@ -48,6 +35,7 @@ enum adv748x_page { | |||
48 | ADV748X_PAGE_EDID, | 35 | ADV748X_PAGE_EDID, |
49 | ADV748X_PAGE_REPEATER, | 36 | ADV748X_PAGE_REPEATER, |
50 | ADV748X_PAGE_INFOFRAME, | 37 | ADV748X_PAGE_INFOFRAME, |
38 | ADV748X_PAGE_CBUS, | ||
51 | ADV748X_PAGE_CEC, | 39 | ADV748X_PAGE_CEC, |
52 | ADV748X_PAGE_SDP, | 40 | ADV748X_PAGE_SDP, |
53 | ADV748X_PAGE_TXB, | 41 | ADV748X_PAGE_TXB, |
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index 2817bafc67bf..d23505a411ee 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Analog Devices ADV7511 HDMI Transmitter Device Driver | 3 | * Analog Devices ADV7511 HDMI Transmitter Device Driver |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | 8 | ||
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 1544920ec52d..cac2081e876e 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * adv7604 - Analog Devices ADV7604 video decoder driver | 3 | * adv7604 - Analog Devices ADV7604 video decoder driver |
3 | * | 4 | * |
4 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | 6 | * |
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | /* | 9 | /* |
@@ -2734,6 +2722,27 @@ static const struct v4l2_ctrl_config adv76xx_ctrl_free_run_color = { | |||
2734 | 2722 | ||
2735 | /* ----------------------------------------------------------------------- */ | 2723 | /* ----------------------------------------------------------------------- */ |
2736 | 2724 | ||
2725 | struct adv76xx_register_map { | ||
2726 | const char *name; | ||
2727 | u8 default_addr; | ||
2728 | }; | ||
2729 | |||
2730 | static const struct adv76xx_register_map adv76xx_default_addresses[] = { | ||
2731 | [ADV76XX_PAGE_IO] = { "main", 0x4c }, | ||
2732 | [ADV7604_PAGE_AVLINK] = { "avlink", 0x42 }, | ||
2733 | [ADV76XX_PAGE_CEC] = { "cec", 0x40 }, | ||
2734 | [ADV76XX_PAGE_INFOFRAME] = { "infoframe", 0x3e }, | ||
2735 | [ADV7604_PAGE_ESDP] = { "esdp", 0x38 }, | ||
2736 | [ADV7604_PAGE_DPP] = { "dpp", 0x3c }, | ||
2737 | [ADV76XX_PAGE_AFE] = { "afe", 0x26 }, | ||
2738 | [ADV76XX_PAGE_REP] = { "rep", 0x32 }, | ||
2739 | [ADV76XX_PAGE_EDID] = { "edid", 0x36 }, | ||
2740 | [ADV76XX_PAGE_HDMI] = { "hdmi", 0x34 }, | ||
2741 | [ADV76XX_PAGE_TEST] = { "test", 0x30 }, | ||
2742 | [ADV76XX_PAGE_CP] = { "cp", 0x22 }, | ||
2743 | [ADV7604_PAGE_VDP] = { "vdp", 0x24 }, | ||
2744 | }; | ||
2745 | |||
2737 | static int adv76xx_core_init(struct v4l2_subdev *sd) | 2746 | static int adv76xx_core_init(struct v4l2_subdev *sd) |
2738 | { | 2747 | { |
2739 | struct adv76xx_state *state = to_state(sd); | 2748 | struct adv76xx_state *state = to_state(sd); |
@@ -2834,13 +2843,26 @@ static void adv76xx_unregister_clients(struct adv76xx_state *state) | |||
2834 | } | 2843 | } |
2835 | 2844 | ||
2836 | static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd, | 2845 | static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd, |
2837 | u8 addr, u8 io_reg) | 2846 | unsigned int page) |
2838 | { | 2847 | { |
2839 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 2848 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
2849 | struct adv76xx_state *state = to_state(sd); | ||
2850 | struct adv76xx_platform_data *pdata = &state->pdata; | ||
2851 | unsigned int io_reg = 0xf2 + page; | ||
2852 | struct i2c_client *new_client; | ||
2853 | |||
2854 | if (pdata && pdata->i2c_addresses[page]) | ||
2855 | new_client = i2c_new_dummy(client->adapter, | ||
2856 | pdata->i2c_addresses[page]); | ||
2857 | else | ||
2858 | new_client = i2c_new_secondary_device(client, | ||
2859 | adv76xx_default_addresses[page].name, | ||
2860 | adv76xx_default_addresses[page].default_addr); | ||
2861 | |||
2862 | if (new_client) | ||
2863 | io_write(sd, io_reg, new_client->addr << 1); | ||
2840 | 2864 | ||
2841 | if (addr) | 2865 | return new_client; |
2842 | io_write(sd, io_reg, addr << 1); | ||
2843 | return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); | ||
2844 | } | 2866 | } |
2845 | 2867 | ||
2846 | static const struct adv76xx_reg_seq adv7604_recommended_settings_afe[] = { | 2868 | static const struct adv76xx_reg_seq adv7604_recommended_settings_afe[] = { |
@@ -3115,20 +3137,6 @@ static int adv76xx_parse_dt(struct adv76xx_state *state) | |||
3115 | /* Disable the interrupt for now as no DT-based board uses it. */ | 3137 | /* Disable the interrupt for now as no DT-based board uses it. */ |
3116 | state->pdata.int1_config = ADV76XX_INT1_CONFIG_DISABLED; | 3138 | state->pdata.int1_config = ADV76XX_INT1_CONFIG_DISABLED; |
3117 | 3139 | ||
3118 | /* Use the default I2C addresses. */ | ||
3119 | state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42; | ||
3120 | state->pdata.i2c_addresses[ADV76XX_PAGE_CEC] = 0x40; | ||
3121 | state->pdata.i2c_addresses[ADV76XX_PAGE_INFOFRAME] = 0x3e; | ||
3122 | state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38; | ||
3123 | state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c; | ||
3124 | state->pdata.i2c_addresses[ADV76XX_PAGE_AFE] = 0x26; | ||
3125 | state->pdata.i2c_addresses[ADV76XX_PAGE_REP] = 0x32; | ||
3126 | state->pdata.i2c_addresses[ADV76XX_PAGE_EDID] = 0x36; | ||
3127 | state->pdata.i2c_addresses[ADV76XX_PAGE_HDMI] = 0x34; | ||
3128 | state->pdata.i2c_addresses[ADV76XX_PAGE_TEST] = 0x30; | ||
3129 | state->pdata.i2c_addresses[ADV76XX_PAGE_CP] = 0x22; | ||
3130 | state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24; | ||
3131 | |||
3132 | /* Hardcode the remaining platform data fields. */ | 3140 | /* Hardcode the remaining platform data fields. */ |
3133 | state->pdata.disable_pwrdnb = 0; | 3141 | state->pdata.disable_pwrdnb = 0; |
3134 | state->pdata.disable_cable_det_rst = 0; | 3142 | state->pdata.disable_cable_det_rst = 0; |
@@ -3478,11 +3486,9 @@ static int adv76xx_probe(struct i2c_client *client, | |||
3478 | if (!(BIT(i) & state->info->page_mask)) | 3486 | if (!(BIT(i) & state->info->page_mask)) |
3479 | continue; | 3487 | continue; |
3480 | 3488 | ||
3481 | state->i2c_clients[i] = | 3489 | state->i2c_clients[i] = adv76xx_dummy_client(sd, i); |
3482 | adv76xx_dummy_client(sd, state->pdata.i2c_addresses[i], | ||
3483 | 0xf2 + i); | ||
3484 | if (!state->i2c_clients[i]) { | 3490 | if (!state->i2c_clients[i]) { |
3485 | err = -ENOMEM; | 3491 | err = -EINVAL; |
3486 | v4l2_err(sd, "failed to create i2c client %u\n", i); | 3492 | v4l2_err(sd, "failed to create i2c client %u\n", i); |
3487 | goto err_i2c; | 3493 | goto err_i2c; |
3488 | } | 3494 | } |
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 136aa80a834b..fddac32e5051 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c | |||
@@ -1,21 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * adv7842 - Analog Devices ADV7842 video decoder driver | 3 | * adv7842 - Analog Devices ADV7842 video decoder driver |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 6 | */ |
20 | 7 | ||
21 | /* | 8 | /* |
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 98be63ae8590..b168bf3635b6 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c | |||
@@ -463,8 +463,13 @@ static void cx23885_initialize(struct i2c_client *client) | |||
463 | { | 463 | { |
464 | DEFINE_WAIT(wait); | 464 | DEFINE_WAIT(wait); |
465 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); | 465 | struct cx25840_state *state = to_state(i2c_get_clientdata(client)); |
466 | u32 clk_freq = 0; | ||
466 | struct workqueue_struct *q; | 467 | struct workqueue_struct *q; |
467 | 468 | ||
469 | /* cx23885 sets hostdata to clk_freq pointer */ | ||
470 | if (v4l2_get_subdev_hostdata(&state->sd)) | ||
471 | clk_freq = *((u32 *)v4l2_get_subdev_hostdata(&state->sd)); | ||
472 | |||
468 | /* | 473 | /* |
469 | * Come out of digital power down | 474 | * Come out of digital power down |
470 | * The CX23888, at least, needs this, otherwise registers aside from | 475 | * The CX23888, at least, needs this, otherwise registers aside from |
@@ -500,8 +505,13 @@ static void cx23885_initialize(struct i2c_client *client) | |||
500 | * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz | 505 | * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz |
501 | * 572.73 MHz before post divide | 506 | * 572.73 MHz before post divide |
502 | */ | 507 | */ |
503 | /* HVR1850 or 50MHz xtal */ | 508 | if (clk_freq == 25000000) { |
504 | cx25840_write(client, 0x2, 0x71); | 509 | /* 888/ImpactVCBe or 25Mhz xtal */ |
510 | ; /* nothing to do */ | ||
511 | } else { | ||
512 | /* HVR1850 or 50MHz xtal */ | ||
513 | cx25840_write(client, 0x2, 0x71); | ||
514 | } | ||
505 | cx25840_write4(client, 0x11c, 0x01d1744c); | 515 | cx25840_write4(client, 0x11c, 0x01d1744c); |
506 | cx25840_write4(client, 0x118, 0x00000416); | 516 | cx25840_write4(client, 0x118, 0x00000416); |
507 | cx25840_write4(client, 0x404, 0x0010253e); | 517 | cx25840_write4(client, 0x404, 0x0010253e); |
@@ -544,9 +554,15 @@ static void cx23885_initialize(struct i2c_client *client) | |||
544 | /* HVR1850 */ | 554 | /* HVR1850 */ |
545 | switch (state->id) { | 555 | switch (state->id) { |
546 | case CX23888_AV: | 556 | case CX23888_AV: |
547 | /* 888/HVR1250 specific */ | 557 | if (clk_freq == 25000000) { |
548 | cx25840_write4(client, 0x10c, 0x13333333); | 558 | /* 888/ImpactVCBe or 25MHz xtal */ |
549 | cx25840_write4(client, 0x108, 0x00000515); | 559 | cx25840_write4(client, 0x10c, 0x01b6db7b); |
560 | cx25840_write4(client, 0x108, 0x00000512); | ||
561 | } else { | ||
562 | /* 888/HVR1250 or 50MHz xtal */ | ||
563 | cx25840_write4(client, 0x10c, 0x13333333); | ||
564 | cx25840_write4(client, 0x108, 0x00000515); | ||
565 | } | ||
550 | break; | 566 | break; |
551 | default: | 567 | default: |
552 | cx25840_write4(client, 0x10c, 0x002be2c9); | 568 | cx25840_write4(client, 0x10c, 0x002be2c9); |
@@ -576,7 +592,7 @@ static void cx23885_initialize(struct i2c_client *client) | |||
576 | * 368.64 MHz before post divide | 592 | * 368.64 MHz before post divide |
577 | * 122.88 MHz / 0xa = 12.288 MHz | 593 | * 122.88 MHz / 0xa = 12.288 MHz |
578 | */ | 594 | */ |
579 | /* HVR1850 or 50MHz xtal */ | 595 | /* HVR1850 or 50MHz xtal or 25MHz xtal */ |
580 | cx25840_write4(client, 0x114, 0x017dbf48); | 596 | cx25840_write4(client, 0x114, 0x017dbf48); |
581 | cx25840_write4(client, 0x110, 0x000a030e); | 597 | cx25840_write4(client, 0x110, 0x000a030e); |
582 | break; | 598 | break; |
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index 193020d64e51..a7e23bcf845c 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c | |||
@@ -168,11 +168,15 @@ static int get_key_haup_xvr(struct IR_i2c *ir, enum rc_proto *protocol, | |||
168 | static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol, | 168 | static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol, |
169 | u32 *scancode, u8 *toggle) | 169 | u32 *scancode, u8 *toggle) |
170 | { | 170 | { |
171 | int rc; | ||
171 | unsigned char b; | 172 | unsigned char b; |
172 | 173 | ||
173 | /* poll IR chip */ | 174 | /* poll IR chip */ |
174 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 175 | rc = i2c_master_recv(ir->c, &b, 1); |
176 | if (rc != 1) { | ||
175 | dev_dbg(&ir->rc->dev, "read error\n"); | 177 | dev_dbg(&ir->rc->dev, "read error\n"); |
178 | if (rc < 0) | ||
179 | return rc; | ||
176 | return -EIO; | 180 | return -EIO; |
177 | } | 181 | } |
178 | 182 | ||
@@ -185,11 +189,15 @@ static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol, | |||
185 | static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol, | 189 | static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol, |
186 | u32 *scancode, u8 *toggle) | 190 | u32 *scancode, u8 *toggle) |
187 | { | 191 | { |
192 | int rc; | ||
188 | unsigned char buf[4]; | 193 | unsigned char buf[4]; |
189 | 194 | ||
190 | /* poll IR chip */ | 195 | /* poll IR chip */ |
191 | if (4 != i2c_master_recv(ir->c, buf, 4)) { | 196 | rc = i2c_master_recv(ir->c, buf, 4); |
197 | if (rc != 4) { | ||
192 | dev_dbg(&ir->rc->dev, "read error\n"); | 198 | dev_dbg(&ir->rc->dev, "read error\n"); |
199 | if (rc < 0) | ||
200 | return rc; | ||
193 | return -EIO; | 201 | return -EIO; |
194 | } | 202 | } |
195 | 203 | ||
@@ -209,11 +217,15 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol, | |||
209 | static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol, | 217 | static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol, |
210 | u32 *scancode, u8 *toggle) | 218 | u32 *scancode, u8 *toggle) |
211 | { | 219 | { |
220 | int rc; | ||
212 | unsigned char b; | 221 | unsigned char b; |
213 | 222 | ||
214 | /* poll IR chip */ | 223 | /* poll IR chip */ |
215 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 224 | rc = i2c_master_recv(ir->c, &b, 1); |
225 | if (rc != 1) { | ||
216 | dev_dbg(&ir->rc->dev, "read error\n"); | 226 | dev_dbg(&ir->rc->dev, "read error\n"); |
227 | if (rc < 0) | ||
228 | return rc; | ||
217 | return -EIO; | 229 | return -EIO; |
218 | } | 230 | } |
219 | 231 | ||
@@ -571,7 +583,7 @@ static int zilog_ir_format(struct rc_dev *rcdev, unsigned int *txbuf, | |||
571 | /* first copy any leading non-repeating */ | 583 | /* first copy any leading non-repeating */ |
572 | int leading = c - rep * 3; | 584 | int leading = c - rep * 3; |
573 | 585 | ||
574 | if (leading + rep >= ARRAY_SIZE(code_block->codes) - 3) { | 586 | if (leading >= ARRAY_SIZE(code_block->codes) - 3 - rep) { |
575 | dev_warn(&rcdev->dev, "IR too long, cannot transmit\n"); | 587 | dev_warn(&rcdev->dev, "IR too long, cannot transmit\n"); |
576 | return -EINVAL; | 588 | return -EINVAL; |
577 | } | 589 | } |
diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c index 2f1966bdc473..87cba15b2977 100644 --- a/drivers/media/i2c/max2175.c +++ b/drivers/media/i2c/max2175.c | |||
@@ -643,7 +643,7 @@ static int max2175_set_nco_freq(struct max2175 *ctx, s32 nco_freq) | |||
643 | if (abs_nco_freq < clock_rate / 2) { | 643 | if (abs_nco_freq < clock_rate / 2) { |
644 | nco_val_desired = 2 * nco_freq; | 644 | nco_val_desired = 2 * nco_freq; |
645 | } else { | 645 | } else { |
646 | nco_val_desired = 2 * (clock_rate - abs_nco_freq); | 646 | nco_val_desired = 2LL * (clock_rate - abs_nco_freq); |
647 | if (nco_freq < 0) | 647 | if (nco_freq < 0) |
648 | nco_val_desired = -nco_val_desired; | 648 | nco_val_desired = -nco_val_desired; |
649 | } | 649 | } |
diff --git a/drivers/media/i2c/mt9t112.c b/drivers/media/i2c/mt9t112.c new file mode 100644 index 000000000000..af8cca984215 --- /dev/null +++ b/drivers/media/i2c/mt9t112.c | |||
@@ -0,0 +1,1140 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * mt9t112 Camera Driver | ||
4 | * | ||
5 | * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org> | ||
6 | * | ||
7 | * Copyright (C) 2009 Renesas Solutions Corp. | ||
8 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
9 | * | ||
10 | * Based on ov772x driver, mt9m111 driver, | ||
11 | * | ||
12 | * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
13 | * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr> | ||
14 | * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> | ||
15 | * Copyright (C) 2008 Magnus Damm | ||
16 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
17 | * | ||
18 | * TODO: This driver lacks support for frame rate control due to missing | ||
19 | * register level documentation and suitable hardware for testing. | ||
20 | * v4l-utils compliance tools will report errors. | ||
21 | */ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/gpio/consumer.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/v4l2-mediabus.h> | ||
31 | #include <linux/videodev2.h> | ||
32 | |||
33 | #include <media/i2c/mt9t112.h> | ||
34 | #include <media/v4l2-common.h> | ||
35 | #include <media/v4l2-image-sizes.h> | ||
36 | #include <media/v4l2-subdev.h> | ||
37 | |||
38 | /* you can check PLL/clock info */ | ||
39 | /* #define EXT_CLOCK 24000000 */ | ||
40 | |||
41 | /************************************************************************ | ||
42 | * macro | ||
43 | ***********************************************************************/ | ||
44 | /* | ||
45 | * frame size | ||
46 | */ | ||
47 | #define MAX_WIDTH 2048 | ||
48 | #define MAX_HEIGHT 1536 | ||
49 | |||
50 | /* | ||
51 | * macro of read/write | ||
52 | */ | ||
53 | #define ECHECKER(ret, x) \ | ||
54 | do { \ | ||
55 | (ret) = (x); \ | ||
56 | if ((ret) < 0) \ | ||
57 | return (ret); \ | ||
58 | } while (0) | ||
59 | |||
60 | #define mt9t112_reg_write(ret, client, a, b) \ | ||
61 | ECHECKER(ret, __mt9t112_reg_write(client, a, b)) | ||
62 | #define mt9t112_mcu_write(ret, client, a, b) \ | ||
63 | ECHECKER(ret, __mt9t112_mcu_write(client, a, b)) | ||
64 | |||
65 | #define mt9t112_reg_mask_set(ret, client, a, b, c) \ | ||
66 | ECHECKER(ret, __mt9t112_reg_mask_set(client, a, b, c)) | ||
67 | #define mt9t112_mcu_mask_set(ret, client, a, b, c) \ | ||
68 | ECHECKER(ret, __mt9t112_mcu_mask_set(client, a, b, c)) | ||
69 | |||
70 | #define mt9t112_reg_read(ret, client, a) \ | ||
71 | ECHECKER(ret, __mt9t112_reg_read(client, a)) | ||
72 | |||
73 | /* | ||
74 | * Logical address | ||
75 | */ | ||
76 | #define _VAR(id, offset, base) (base | (id & 0x1f) << 10 | (offset & 0x3ff)) | ||
77 | #define VAR(id, offset) _VAR(id, offset, 0x0000) | ||
78 | #define VAR8(id, offset) _VAR(id, offset, 0x8000) | ||
79 | |||
80 | /************************************************************************ | ||
81 | * struct | ||
82 | ***********************************************************************/ | ||
83 | struct mt9t112_format { | ||
84 | u32 code; | ||
85 | enum v4l2_colorspace colorspace; | ||
86 | u16 fmt; | ||
87 | u16 order; | ||
88 | }; | ||
89 | |||
90 | struct mt9t112_priv { | ||
91 | struct v4l2_subdev subdev; | ||
92 | struct mt9t112_platform_data *info; | ||
93 | struct i2c_client *client; | ||
94 | struct v4l2_rect frame; | ||
95 | struct clk *clk; | ||
96 | struct gpio_desc *standby_gpio; | ||
97 | const struct mt9t112_format *format; | ||
98 | int num_formats; | ||
99 | bool init_done; | ||
100 | }; | ||
101 | |||
102 | /************************************************************************ | ||
103 | * supported format | ||
104 | ***********************************************************************/ | ||
105 | |||
106 | static const struct mt9t112_format mt9t112_cfmts[] = { | ||
107 | { | ||
108 | .code = MEDIA_BUS_FMT_UYVY8_2X8, | ||
109 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
110 | .fmt = 1, | ||
111 | .order = 0, | ||
112 | }, { | ||
113 | .code = MEDIA_BUS_FMT_VYUY8_2X8, | ||
114 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
115 | .fmt = 1, | ||
116 | .order = 1, | ||
117 | }, { | ||
118 | .code = MEDIA_BUS_FMT_YUYV8_2X8, | ||
119 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
120 | .fmt = 1, | ||
121 | .order = 2, | ||
122 | }, { | ||
123 | .code = MEDIA_BUS_FMT_YVYU8_2X8, | ||
124 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
125 | .fmt = 1, | ||
126 | .order = 3, | ||
127 | }, { | ||
128 | .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, | ||
129 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
130 | .fmt = 8, | ||
131 | .order = 2, | ||
132 | }, { | ||
133 | .code = MEDIA_BUS_FMT_RGB565_2X8_LE, | ||
134 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
135 | .fmt = 4, | ||
136 | .order = 2, | ||
137 | }, | ||
138 | }; | ||
139 | |||
140 | /************************************************************************ | ||
141 | * general function | ||
142 | ***********************************************************************/ | ||
143 | static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) | ||
144 | { | ||
145 | return container_of(i2c_get_clientdata(client), | ||
146 | struct mt9t112_priv, | ||
147 | subdev); | ||
148 | } | ||
149 | |||
150 | static int __mt9t112_reg_read(const struct i2c_client *client, u16 command) | ||
151 | { | ||
152 | struct i2c_msg msg[2]; | ||
153 | u8 buf[2]; | ||
154 | int ret; | ||
155 | |||
156 | command = swab16(command); | ||
157 | |||
158 | msg[0].addr = client->addr; | ||
159 | msg[0].flags = 0; | ||
160 | msg[0].len = 2; | ||
161 | msg[0].buf = (u8 *)&command; | ||
162 | |||
163 | msg[1].addr = client->addr; | ||
164 | msg[1].flags = I2C_M_RD; | ||
165 | msg[1].len = 2; | ||
166 | msg[1].buf = buf; | ||
167 | |||
168 | /* | ||
169 | * If return value of this function is < 0, it means error, else, | ||
170 | * below 16bit is valid data. | ||
171 | */ | ||
172 | ret = i2c_transfer(client->adapter, msg, 2); | ||
173 | if (ret < 0) | ||
174 | return ret; | ||
175 | |||
176 | memcpy(&ret, buf, 2); | ||
177 | |||
178 | return swab16(ret); | ||
179 | } | ||
180 | |||
181 | static int __mt9t112_reg_write(const struct i2c_client *client, | ||
182 | u16 command, u16 data) | ||
183 | { | ||
184 | struct i2c_msg msg; | ||
185 | u8 buf[4]; | ||
186 | int ret; | ||
187 | |||
188 | command = swab16(command); | ||
189 | data = swab16(data); | ||
190 | |||
191 | memcpy(buf + 0, &command, 2); | ||
192 | memcpy(buf + 2, &data, 2); | ||
193 | |||
194 | msg.addr = client->addr; | ||
195 | msg.flags = 0; | ||
196 | msg.len = 4; | ||
197 | msg.buf = buf; | ||
198 | |||
199 | /* | ||
200 | * i2c_transfer return message length, but this function should | ||
201 | * return 0 if correct case. | ||
202 | */ | ||
203 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
204 | |||
205 | return ret >= 0 ? 0 : ret; | ||
206 | } | ||
207 | |||
208 | static int __mt9t112_reg_mask_set(const struct i2c_client *client, | ||
209 | u16 command, u16 mask, u16 set) | ||
210 | { | ||
211 | int val = __mt9t112_reg_read(client, command); | ||
212 | |||
213 | if (val < 0) | ||
214 | return val; | ||
215 | |||
216 | val &= ~mask; | ||
217 | val |= set & mask; | ||
218 | |||
219 | return __mt9t112_reg_write(client, command, val); | ||
220 | } | ||
221 | |||
222 | /* mcu access */ | ||
223 | static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command) | ||
224 | { | ||
225 | int ret; | ||
226 | |||
227 | ret = __mt9t112_reg_write(client, 0x098E, command); | ||
228 | if (ret < 0) | ||
229 | return ret; | ||
230 | |||
231 | return __mt9t112_reg_read(client, 0x0990); | ||
232 | } | ||
233 | |||
234 | static int __mt9t112_mcu_write(const struct i2c_client *client, | ||
235 | u16 command, u16 data) | ||
236 | { | ||
237 | int ret; | ||
238 | |||
239 | ret = __mt9t112_reg_write(client, 0x098E, command); | ||
240 | if (ret < 0) | ||
241 | return ret; | ||
242 | |||
243 | return __mt9t112_reg_write(client, 0x0990, data); | ||
244 | } | ||
245 | |||
246 | static int __mt9t112_mcu_mask_set(const struct i2c_client *client, | ||
247 | u16 command, u16 mask, u16 set) | ||
248 | { | ||
249 | int val = __mt9t112_mcu_read(client, command); | ||
250 | |||
251 | if (val < 0) | ||
252 | return val; | ||
253 | |||
254 | val &= ~mask; | ||
255 | val |= set & mask; | ||
256 | |||
257 | return __mt9t112_mcu_write(client, command, val); | ||
258 | } | ||
259 | |||
260 | static int mt9t112_reset(const struct i2c_client *client) | ||
261 | { | ||
262 | int ret; | ||
263 | |||
264 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001); | ||
265 | usleep_range(1000, 5000); | ||
266 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000); | ||
267 | |||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | #ifndef EXT_CLOCK | ||
272 | #define CLOCK_INFO(a, b) | ||
273 | #else | ||
274 | #define CLOCK_INFO(a, b) mt9t112_clock_info(a, b) | ||
275 | static int mt9t112_clock_info(const struct i2c_client *client, u32 ext) | ||
276 | { | ||
277 | int m, n, p1, p2, p3, p4, p5, p6, p7; | ||
278 | u32 vco, clk; | ||
279 | char *enable; | ||
280 | |||
281 | ext /= 1000; /* kbyte order */ | ||
282 | |||
283 | mt9t112_reg_read(n, client, 0x0012); | ||
284 | p1 = n & 0x000f; | ||
285 | n = n >> 4; | ||
286 | p2 = n & 0x000f; | ||
287 | n = n >> 4; | ||
288 | p3 = n & 0x000f; | ||
289 | |||
290 | mt9t112_reg_read(n, client, 0x002a); | ||
291 | p4 = n & 0x000f; | ||
292 | n = n >> 4; | ||
293 | p5 = n & 0x000f; | ||
294 | n = n >> 4; | ||
295 | p6 = n & 0x000f; | ||
296 | |||
297 | mt9t112_reg_read(n, client, 0x002c); | ||
298 | p7 = n & 0x000f; | ||
299 | |||
300 | mt9t112_reg_read(n, client, 0x0010); | ||
301 | m = n & 0x00ff; | ||
302 | n = (n >> 8) & 0x003f; | ||
303 | |||
304 | enable = ((ext < 6000) || (ext > 54000)) ? "X" : ""; | ||
305 | dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); | ||
306 | |||
307 | vco = 2 * m * ext / (n + 1); | ||
308 | enable = ((vco < 384000) || (vco > 768000)) ? "X" : ""; | ||
309 | dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable); | ||
310 | |||
311 | clk = vco / (p1 + 1) / (p2 + 1); | ||
312 | enable = (clk > 96000) ? "X" : ""; | ||
313 | dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); | ||
314 | |||
315 | clk = vco / (p3 + 1); | ||
316 | enable = (clk > 768000) ? "X" : ""; | ||
317 | dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); | ||
318 | |||
319 | clk = vco / (p6 + 1); | ||
320 | enable = (clk > 96000) ? "X" : ""; | ||
321 | dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); | ||
322 | |||
323 | clk = vco / (p5 + 1); | ||
324 | enable = (clk > 54000) ? "X" : ""; | ||
325 | dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); | ||
326 | |||
327 | clk = vco / (p4 + 1); | ||
328 | enable = (clk > 70000) ? "X" : ""; | ||
329 | dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); | ||
330 | |||
331 | clk = vco / (p7 + 1); | ||
332 | dev_dbg(&client->dev, "External sensor : %10u K\n", clk); | ||
333 | |||
334 | clk = ext / (n + 1); | ||
335 | enable = ((clk < 2000) || (clk > 24000)) ? "X" : ""; | ||
336 | dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | #endif | ||
341 | |||
342 | static int mt9t112_set_a_frame_size(const struct i2c_client *client, | ||
343 | u16 width, u16 height) | ||
344 | { | ||
345 | int ret; | ||
346 | u16 wstart = (MAX_WIDTH - width) / 2; | ||
347 | u16 hstart = (MAX_HEIGHT - height) / 2; | ||
348 | |||
349 | /* (Context A) Image Width/Height. */ | ||
350 | mt9t112_mcu_write(ret, client, VAR(26, 0), width); | ||
351 | mt9t112_mcu_write(ret, client, VAR(26, 2), height); | ||
352 | |||
353 | /* (Context A) Output Width/Height. */ | ||
354 | mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width); | ||
355 | mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height); | ||
356 | |||
357 | /* (Context A) Start Row/Column. */ | ||
358 | mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart); | ||
359 | mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart); | ||
360 | |||
361 | /* (Context A) End Row/Column. */ | ||
362 | mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart); | ||
363 | mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart); | ||
364 | |||
365 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | ||
366 | |||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | static int mt9t112_set_pll_dividers(const struct i2c_client *client, | ||
371 | u8 m, u8 n, u8 p1, u8 p2, u8 p3, u8 p4, | ||
372 | u8 p5, u8 p6, u8 p7) | ||
373 | { | ||
374 | int ret; | ||
375 | u16 val; | ||
376 | |||
377 | /* N/M */ | ||
378 | val = (n << 8) | (m << 0); | ||
379 | mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val); | ||
380 | |||
381 | /* P1/P2/P3 */ | ||
382 | val = ((p3 & 0x0F) << 8) | ((p2 & 0x0F) << 4) | ((p1 & 0x0F) << 0); | ||
383 | mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val); | ||
384 | |||
385 | /* P4/P5/P6 */ | ||
386 | val = (0x7 << 12) | ((p6 & 0x0F) << 8) | ((p5 & 0x0F) << 4) | | ||
387 | ((p4 & 0x0F) << 0); | ||
388 | mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val); | ||
389 | |||
390 | /* P7 */ | ||
391 | val = (0x1 << 12) | ((p7 & 0x0F) << 0); | ||
392 | mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val); | ||
393 | |||
394 | return ret; | ||
395 | } | ||
396 | |||
397 | static int mt9t112_init_pll(const struct i2c_client *client) | ||
398 | { | ||
399 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
400 | int data, i, ret; | ||
401 | |||
402 | mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001); | ||
403 | |||
404 | /* PLL control: BYPASS PLL = 8517. */ | ||
405 | mt9t112_reg_write(ret, client, 0x0014, 0x2145); | ||
406 | |||
407 | /* Replace these registers when new timing parameters are generated. */ | ||
408 | mt9t112_set_pll_dividers(client, | ||
409 | priv->info->divider.m, priv->info->divider.n, | ||
410 | priv->info->divider.p1, priv->info->divider.p2, | ||
411 | priv->info->divider.p3, priv->info->divider.p4, | ||
412 | priv->info->divider.p5, priv->info->divider.p6, | ||
413 | priv->info->divider.p7); | ||
414 | |||
415 | /* | ||
416 | * TEST_BYPASS on | ||
417 | * PLL_ENABLE on | ||
418 | * SEL_LOCK_DET on | ||
419 | * TEST_BYPASS off | ||
420 | */ | ||
421 | mt9t112_reg_write(ret, client, 0x0014, 0x2525); | ||
422 | mt9t112_reg_write(ret, client, 0x0014, 0x2527); | ||
423 | mt9t112_reg_write(ret, client, 0x0014, 0x3427); | ||
424 | mt9t112_reg_write(ret, client, 0x0014, 0x3027); | ||
425 | |||
426 | mdelay(10); | ||
427 | |||
428 | /* | ||
429 | * PLL_BYPASS off | ||
430 | * Reference clock count | ||
431 | * I2C Master Clock Divider | ||
432 | */ | ||
433 | mt9t112_reg_write(ret, client, 0x0014, 0x3046); | ||
434 | /* JPEG initialization workaround */ | ||
435 | mt9t112_reg_write(ret, client, 0x0016, 0x0400); | ||
436 | mt9t112_reg_write(ret, client, 0x0022, 0x0190); | ||
437 | mt9t112_reg_write(ret, client, 0x3B84, 0x0212); | ||
438 | |||
439 | /* External sensor clock is PLL bypass. */ | ||
440 | mt9t112_reg_write(ret, client, 0x002E, 0x0500); | ||
441 | |||
442 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002); | ||
443 | mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004); | ||
444 | |||
445 | /* MCU disabled. */ | ||
446 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004); | ||
447 | |||
448 | /* Out of standby. */ | ||
449 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0); | ||
450 | |||
451 | mdelay(50); | ||
452 | |||
453 | /* | ||
454 | * Standby Workaround | ||
455 | * Disable Secondary I2C Pads | ||
456 | */ | ||
457 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
458 | mdelay(1); | ||
459 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
460 | mdelay(1); | ||
461 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
462 | mdelay(1); | ||
463 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
464 | mdelay(1); | ||
465 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
466 | mdelay(1); | ||
467 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | ||
468 | mdelay(1); | ||
469 | |||
470 | /* Poll to verify out of standby. Must Poll this bit. */ | ||
471 | for (i = 0; i < 100; i++) { | ||
472 | mt9t112_reg_read(data, client, 0x0018); | ||
473 | if (!(data & 0x4000)) | ||
474 | break; | ||
475 | |||
476 | mdelay(10); | ||
477 | } | ||
478 | |||
479 | return ret; | ||
480 | } | ||
481 | |||
482 | static int mt9t112_init_setting(const struct i2c_client *client) | ||
483 | { | ||
484 | int ret; | ||
485 | |||
486 | /* Adaptive Output Clock (A) */ | ||
487 | mt9t112_mcu_mask_set(ret, client, VAR(26, 160), 0x0040, 0x0000); | ||
488 | |||
489 | /* Read Mode (A) */ | ||
490 | mt9t112_mcu_write(ret, client, VAR(18, 12), 0x0024); | ||
491 | |||
492 | /* Fine Correction (A) */ | ||
493 | mt9t112_mcu_write(ret, client, VAR(18, 15), 0x00CC); | ||
494 | |||
495 | /* Fine IT Min (A) */ | ||
496 | mt9t112_mcu_write(ret, client, VAR(18, 17), 0x01f1); | ||
497 | |||
498 | /* Fine IT Max Margin (A) */ | ||
499 | mt9t112_mcu_write(ret, client, VAR(18, 19), 0x00fF); | ||
500 | |||
501 | /* Base Frame Lines (A) */ | ||
502 | mt9t112_mcu_write(ret, client, VAR(18, 29), 0x032D); | ||
503 | |||
504 | /* Min Line Length (A) */ | ||
505 | mt9t112_mcu_write(ret, client, VAR(18, 31), 0x073a); | ||
506 | |||
507 | /* Line Length (A) */ | ||
508 | mt9t112_mcu_write(ret, client, VAR(18, 37), 0x07d0); | ||
509 | |||
510 | /* Adaptive Output Clock (B) */ | ||
511 | mt9t112_mcu_mask_set(ret, client, VAR(27, 160), 0x0040, 0x0000); | ||
512 | |||
513 | /* Row Start (B) */ | ||
514 | mt9t112_mcu_write(ret, client, VAR(18, 74), 0x004); | ||
515 | |||
516 | /* Column Start (B) */ | ||
517 | mt9t112_mcu_write(ret, client, VAR(18, 76), 0x004); | ||
518 | |||
519 | /* Row End (B) */ | ||
520 | mt9t112_mcu_write(ret, client, VAR(18, 78), 0x60B); | ||
521 | |||
522 | /* Column End (B) */ | ||
523 | mt9t112_mcu_write(ret, client, VAR(18, 80), 0x80B); | ||
524 | |||
525 | /* Fine Correction (B) */ | ||
526 | mt9t112_mcu_write(ret, client, VAR(18, 87), 0x008C); | ||
527 | |||
528 | /* Fine IT Min (B) */ | ||
529 | mt9t112_mcu_write(ret, client, VAR(18, 89), 0x01F1); | ||
530 | |||
531 | /* Fine IT Max Margin (B) */ | ||
532 | mt9t112_mcu_write(ret, client, VAR(18, 91), 0x00FF); | ||
533 | |||
534 | /* Base Frame Lines (B) */ | ||
535 | mt9t112_mcu_write(ret, client, VAR(18, 101), 0x0668); | ||
536 | |||
537 | /* Min Line Length (B) */ | ||
538 | mt9t112_mcu_write(ret, client, VAR(18, 103), 0x0AF0); | ||
539 | |||
540 | /* Line Length (B) */ | ||
541 | mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0); | ||
542 | |||
543 | /* | ||
544 | * Flicker Dectection registers. | ||
545 | * This section should be replaced whenever new timing file is | ||
546 | * generated. All the following registers need to be replaced. | ||
547 | * Following registers are generated from Register Wizard but user can | ||
548 | * modify them. For detail see auto flicker detection tuning. | ||
549 | */ | ||
550 | |||
551 | /* FD_FDPERIOD_SELECT */ | ||
552 | mt9t112_mcu_write(ret, client, VAR8(8, 5), 0x01); | ||
553 | |||
554 | /* PRI_B_CONFIG_FD_ALGO_RUN */ | ||
555 | mt9t112_mcu_write(ret, client, VAR(27, 17), 0x0003); | ||
556 | |||
557 | /* PRI_A_CONFIG_FD_ALGO_RUN */ | ||
558 | mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003); | ||
559 | |||
560 | /* | ||
561 | * AFD range detection tuning registers. | ||
562 | */ | ||
563 | |||
564 | /* Search_f1_50 */ | ||
565 | mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25); | ||
566 | |||
567 | /* Search_f2_50 */ | ||
568 | mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28); | ||
569 | |||
570 | /* Search_f1_60 */ | ||
571 | mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C); | ||
572 | |||
573 | /* Search_f2_60 */ | ||
574 | mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F); | ||
575 | |||
576 | /* Period_50Hz (A) */ | ||
577 | mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA); | ||
578 | |||
579 | /* Secret register by Aptina. */ | ||
580 | /* Period_50Hz (A MSB) */ | ||
581 | mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00); | ||
582 | |||
583 | /* Period_60Hz (A) */ | ||
584 | mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B); | ||
585 | |||
586 | /* Secret register by Aptina. */ | ||
587 | /* Period_60Hz (A MSB) */ | ||
588 | mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00); | ||
589 | |||
590 | /* Period_50Hz (B) */ | ||
591 | mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82); | ||
592 | |||
593 | /* Secret register by Aptina. */ | ||
594 | /* Period_50Hz (B) MSB */ | ||
595 | mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00); | ||
596 | |||
597 | /* Period_60Hz (B) */ | ||
598 | mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D); | ||
599 | |||
600 | /* Secret register by Aptina. */ | ||
601 | /* Period_60Hz (B) MSB */ | ||
602 | mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00); | ||
603 | |||
604 | /* FD Mode */ | ||
605 | mt9t112_mcu_write(ret, client, VAR8(8, 2), 0x10); | ||
606 | |||
607 | /* Stat_min */ | ||
608 | mt9t112_mcu_write(ret, client, VAR8(8, 9), 0x02); | ||
609 | |||
610 | /* Stat_max */ | ||
611 | mt9t112_mcu_write(ret, client, VAR8(8, 10), 0x03); | ||
612 | |||
613 | /* Min_amplitude */ | ||
614 | mt9t112_mcu_write(ret, client, VAR8(8, 12), 0x0A); | ||
615 | |||
616 | /* RX FIFO Watermark (A) */ | ||
617 | mt9t112_mcu_write(ret, client, VAR(18, 70), 0x0014); | ||
618 | |||
619 | /* RX FIFO Watermark (B) */ | ||
620 | mt9t112_mcu_write(ret, client, VAR(18, 142), 0x0014); | ||
621 | |||
622 | /* MCLK: 16MHz | ||
623 | * PCLK: 73MHz | ||
624 | * CorePixCLK: 36.5 MHz | ||
625 | */ | ||
626 | mt9t112_mcu_write(ret, client, VAR8(18, 0x0044), 133); | ||
627 | mt9t112_mcu_write(ret, client, VAR8(18, 0x0045), 110); | ||
628 | mt9t112_mcu_write(ret, client, VAR8(18, 0x008c), 130); | ||
629 | mt9t112_mcu_write(ret, client, VAR8(18, 0x008d), 108); | ||
630 | |||
631 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00A5), 27); | ||
632 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00a6), 30); | ||
633 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00a7), 32); | ||
634 | mt9t112_mcu_write(ret, client, VAR8(18, 0x00a8), 35); | ||
635 | |||
636 | return ret; | ||
637 | } | ||
638 | |||
639 | static int mt9t112_auto_focus_setting(const struct i2c_client *client) | ||
640 | { | ||
641 | int ret; | ||
642 | |||
643 | mt9t112_mcu_write(ret, client, VAR(12, 13), 0x000F); | ||
644 | mt9t112_mcu_write(ret, client, VAR(12, 23), 0x0F0F); | ||
645 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | ||
646 | |||
647 | mt9t112_reg_write(ret, client, 0x0614, 0x0000); | ||
648 | |||
649 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05); | ||
650 | mt9t112_mcu_write(ret, client, VAR8(12, 2), 0x02); | ||
651 | mt9t112_mcu_write(ret, client, VAR(12, 3), 0x0002); | ||
652 | mt9t112_mcu_write(ret, client, VAR(17, 3), 0x8001); | ||
653 | mt9t112_mcu_write(ret, client, VAR(17, 11), 0x0025); | ||
654 | mt9t112_mcu_write(ret, client, VAR(17, 13), 0x0193); | ||
655 | mt9t112_mcu_write(ret, client, VAR8(17, 33), 0x18); | ||
656 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x05); | ||
657 | |||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | static int mt9t112_auto_focus_trigger(const struct i2c_client *client) | ||
662 | { | ||
663 | int ret; | ||
664 | |||
665 | mt9t112_mcu_write(ret, client, VAR8(12, 25), 0x01); | ||
666 | |||
667 | return ret; | ||
668 | } | ||
669 | |||
670 | static int mt9t112_init_camera(const struct i2c_client *client) | ||
671 | { | ||
672 | int ret; | ||
673 | |||
674 | ECHECKER(ret, mt9t112_reset(client)); | ||
675 | ECHECKER(ret, mt9t112_init_pll(client)); | ||
676 | ECHECKER(ret, mt9t112_init_setting(client)); | ||
677 | ECHECKER(ret, mt9t112_auto_focus_setting(client)); | ||
678 | |||
679 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0); | ||
680 | |||
681 | /* Analog setting B.*/ | ||
682 | mt9t112_reg_write(ret, client, 0x3084, 0x2409); | ||
683 | mt9t112_reg_write(ret, client, 0x3092, 0x0A49); | ||
684 | mt9t112_reg_write(ret, client, 0x3094, 0x4949); | ||
685 | mt9t112_reg_write(ret, client, 0x3096, 0x4950); | ||
686 | |||
687 | /* | ||
688 | * Disable adaptive clock. | ||
689 | * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
690 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
691 | */ | ||
692 | mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E); | ||
693 | mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E); | ||
694 | |||
695 | /* | ||
696 | * Configure Status in Status_before_length Format and enable header. | ||
697 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
698 | */ | ||
699 | mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4); | ||
700 | |||
701 | /* | ||
702 | * Enable JPEG in context B. | ||
703 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
704 | */ | ||
705 | mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01); | ||
706 | |||
707 | /* Disable Dac_TXLO. */ | ||
708 | mt9t112_reg_write(ret, client, 0x316C, 0x350F); | ||
709 | |||
710 | /* Set max slew rates. */ | ||
711 | mt9t112_reg_write(ret, client, 0x1E, 0x777); | ||
712 | |||
713 | return ret; | ||
714 | } | ||
715 | |||
716 | /************************************************************************ | ||
717 | * v4l2_subdev_core_ops | ||
718 | ***********************************************************************/ | ||
719 | |||
720 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
721 | static int mt9t112_g_register(struct v4l2_subdev *sd, | ||
722 | struct v4l2_dbg_register *reg) | ||
723 | { | ||
724 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
725 | int ret; | ||
726 | |||
727 | reg->size = 2; | ||
728 | mt9t112_reg_read(ret, client, reg->reg); | ||
729 | |||
730 | reg->val = (__u64)ret; | ||
731 | |||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static int mt9t112_s_register(struct v4l2_subdev *sd, | ||
736 | const struct v4l2_dbg_register *reg) | ||
737 | { | ||
738 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
739 | int ret; | ||
740 | |||
741 | mt9t112_reg_write(ret, client, reg->reg, reg->val); | ||
742 | |||
743 | return ret; | ||
744 | } | ||
745 | #endif | ||
746 | |||
747 | static int mt9t112_power_on(struct mt9t112_priv *priv) | ||
748 | { | ||
749 | int ret; | ||
750 | |||
751 | ret = clk_prepare_enable(priv->clk); | ||
752 | if (ret) | ||
753 | return ret; | ||
754 | |||
755 | if (priv->standby_gpio) { | ||
756 | gpiod_set_value(priv->standby_gpio, 0); | ||
757 | msleep(100); | ||
758 | } | ||
759 | |||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | static int mt9t112_power_off(struct mt9t112_priv *priv) | ||
764 | { | ||
765 | clk_disable_unprepare(priv->clk); | ||
766 | if (priv->standby_gpio) { | ||
767 | gpiod_set_value(priv->standby_gpio, 1); | ||
768 | msleep(100); | ||
769 | } | ||
770 | |||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | static int mt9t112_s_power(struct v4l2_subdev *sd, int on) | ||
775 | { | ||
776 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
777 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
778 | |||
779 | return on ? mt9t112_power_on(priv) : | ||
780 | mt9t112_power_off(priv); | ||
781 | } | ||
782 | |||
783 | static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { | ||
784 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
785 | .g_register = mt9t112_g_register, | ||
786 | .s_register = mt9t112_s_register, | ||
787 | #endif | ||
788 | .s_power = mt9t112_s_power, | ||
789 | }; | ||
790 | |||
791 | /************************************************************************ | ||
792 | * v4l2_subdev_video_ops | ||
793 | **********************************************************************/ | ||
794 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | ||
795 | { | ||
796 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
797 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
798 | int ret = 0; | ||
799 | |||
800 | if (!enable) { | ||
801 | /* FIXME | ||
802 | * | ||
803 | * If user selected large output size, and used it long time, | ||
804 | * mt9t112 camera will be very warm. | ||
805 | * | ||
806 | * But current driver can not stop mt9t112 camera. | ||
807 | * So, set small size here to solve this problem. | ||
808 | */ | ||
809 | mt9t112_set_a_frame_size(client, VGA_WIDTH, VGA_HEIGHT); | ||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | if (!priv->init_done) { | ||
814 | u16 param = MT9T112_FLAG_PCLK_RISING_EDGE & priv->info->flags ? | ||
815 | 0x0001 : 0x0000; | ||
816 | |||
817 | ECHECKER(ret, mt9t112_init_camera(client)); | ||
818 | |||
819 | /* Invert PCLK (Data sampled on falling edge of pixclk). */ | ||
820 | mt9t112_reg_write(ret, client, 0x3C20, param); | ||
821 | |||
822 | mdelay(5); | ||
823 | |||
824 | priv->init_done = true; | ||
825 | } | ||
826 | |||
827 | mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt); | ||
828 | mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order); | ||
829 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | ||
830 | |||
831 | mt9t112_set_a_frame_size(client, priv->frame.width, priv->frame.height); | ||
832 | |||
833 | ECHECKER(ret, mt9t112_auto_focus_trigger(client)); | ||
834 | |||
835 | dev_dbg(&client->dev, "format : %d\n", priv->format->code); | ||
836 | dev_dbg(&client->dev, "size : %d x %d\n", | ||
837 | priv->frame.width, | ||
838 | priv->frame.height); | ||
839 | |||
840 | CLOCK_INFO(client, EXT_CLOCK); | ||
841 | |||
842 | return ret; | ||
843 | } | ||
844 | |||
845 | static int mt9t112_set_params(struct mt9t112_priv *priv, | ||
846 | const struct v4l2_rect *rect, | ||
847 | u32 code) | ||
848 | { | ||
849 | int i; | ||
850 | |||
851 | /* | ||
852 | * get color format | ||
853 | */ | ||
854 | for (i = 0; i < priv->num_formats; i++) | ||
855 | if (mt9t112_cfmts[i].code == code) | ||
856 | break; | ||
857 | |||
858 | if (i == priv->num_formats) | ||
859 | return -EINVAL; | ||
860 | |||
861 | priv->frame = *rect; | ||
862 | |||
863 | /* | ||
864 | * frame size check | ||
865 | */ | ||
866 | v4l_bound_align_image(&priv->frame.width, 0, MAX_WIDTH, 0, | ||
867 | &priv->frame.height, 0, MAX_HEIGHT, 0, 0); | ||
868 | |||
869 | priv->format = mt9t112_cfmts + i; | ||
870 | |||
871 | return 0; | ||
872 | } | ||
873 | |||
874 | static int mt9t112_get_selection(struct v4l2_subdev *sd, | ||
875 | struct v4l2_subdev_pad_config *cfg, | ||
876 | struct v4l2_subdev_selection *sel) | ||
877 | { | ||
878 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
879 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
880 | |||
881 | if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
882 | return -EINVAL; | ||
883 | |||
884 | switch (sel->target) { | ||
885 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
886 | sel->r.left = 0; | ||
887 | sel->r.top = 0; | ||
888 | sel->r.width = MAX_WIDTH; | ||
889 | sel->r.height = MAX_HEIGHT; | ||
890 | return 0; | ||
891 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
892 | sel->r.left = 0; | ||
893 | sel->r.top = 0; | ||
894 | sel->r.width = VGA_WIDTH; | ||
895 | sel->r.height = VGA_HEIGHT; | ||
896 | return 0; | ||
897 | case V4L2_SEL_TGT_CROP: | ||
898 | sel->r = priv->frame; | ||
899 | return 0; | ||
900 | default: | ||
901 | return -EINVAL; | ||
902 | } | ||
903 | } | ||
904 | |||
905 | static int mt9t112_set_selection(struct v4l2_subdev *sd, | ||
906 | struct v4l2_subdev_pad_config *cfg, | ||
907 | struct v4l2_subdev_selection *sel) | ||
908 | { | ||
909 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
910 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
911 | const struct v4l2_rect *rect = &sel->r; | ||
912 | |||
913 | if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || | ||
914 | sel->target != V4L2_SEL_TGT_CROP) | ||
915 | return -EINVAL; | ||
916 | |||
917 | return mt9t112_set_params(priv, rect, priv->format->code); | ||
918 | } | ||
919 | |||
920 | static int mt9t112_get_fmt(struct v4l2_subdev *sd, | ||
921 | struct v4l2_subdev_pad_config *cfg, | ||
922 | struct v4l2_subdev_format *format) | ||
923 | { | ||
924 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
925 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
926 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
927 | |||
928 | if (format->pad) | ||
929 | return -EINVAL; | ||
930 | |||
931 | mf->width = priv->frame.width; | ||
932 | mf->height = priv->frame.height; | ||
933 | mf->colorspace = priv->format->colorspace; | ||
934 | mf->code = priv->format->code; | ||
935 | mf->field = V4L2_FIELD_NONE; | ||
936 | |||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | static int mt9t112_s_fmt(struct v4l2_subdev *sd, | ||
941 | struct v4l2_mbus_framefmt *mf) | ||
942 | { | ||
943 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
944 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
945 | struct v4l2_rect rect = { | ||
946 | .width = mf->width, | ||
947 | .height = mf->height, | ||
948 | .left = priv->frame.left, | ||
949 | .top = priv->frame.top, | ||
950 | }; | ||
951 | int ret; | ||
952 | |||
953 | ret = mt9t112_set_params(priv, &rect, mf->code); | ||
954 | |||
955 | if (!ret) | ||
956 | mf->colorspace = priv->format->colorspace; | ||
957 | |||
958 | return ret; | ||
959 | } | ||
960 | |||
961 | static int mt9t112_set_fmt(struct v4l2_subdev *sd, | ||
962 | struct v4l2_subdev_pad_config *cfg, | ||
963 | struct v4l2_subdev_format *format) | ||
964 | { | ||
965 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
966 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
967 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
968 | int i; | ||
969 | |||
970 | if (format->pad) | ||
971 | return -EINVAL; | ||
972 | |||
973 | for (i = 0; i < priv->num_formats; i++) | ||
974 | if (mt9t112_cfmts[i].code == mf->code) | ||
975 | break; | ||
976 | |||
977 | if (i == priv->num_formats) { | ||
978 | mf->code = MEDIA_BUS_FMT_UYVY8_2X8; | ||
979 | mf->colorspace = V4L2_COLORSPACE_JPEG; | ||
980 | } else { | ||
981 | mf->colorspace = mt9t112_cfmts[i].colorspace; | ||
982 | } | ||
983 | |||
984 | v4l_bound_align_image(&mf->width, 0, MAX_WIDTH, 0, | ||
985 | &mf->height, 0, MAX_HEIGHT, 0, 0); | ||
986 | |||
987 | mf->field = V4L2_FIELD_NONE; | ||
988 | |||
989 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) | ||
990 | return mt9t112_s_fmt(sd, mf); | ||
991 | cfg->try_fmt = *mf; | ||
992 | |||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd, | ||
997 | struct v4l2_subdev_pad_config *cfg, | ||
998 | struct v4l2_subdev_mbus_code_enum *code) | ||
999 | { | ||
1000 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1001 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
1002 | |||
1003 | if (code->pad || code->index >= priv->num_formats) | ||
1004 | return -EINVAL; | ||
1005 | |||
1006 | code->code = mt9t112_cfmts[code->index].code; | ||
1007 | |||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { | ||
1012 | .s_stream = mt9t112_s_stream, | ||
1013 | }; | ||
1014 | |||
1015 | static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { | ||
1016 | .enum_mbus_code = mt9t112_enum_mbus_code, | ||
1017 | .get_selection = mt9t112_get_selection, | ||
1018 | .set_selection = mt9t112_set_selection, | ||
1019 | .get_fmt = mt9t112_get_fmt, | ||
1020 | .set_fmt = mt9t112_set_fmt, | ||
1021 | }; | ||
1022 | |||
1023 | /************************************************************************ | ||
1024 | * i2c driver | ||
1025 | ***********************************************************************/ | ||
1026 | static const struct v4l2_subdev_ops mt9t112_subdev_ops = { | ||
1027 | .core = &mt9t112_subdev_core_ops, | ||
1028 | .video = &mt9t112_subdev_video_ops, | ||
1029 | .pad = &mt9t112_subdev_pad_ops, | ||
1030 | }; | ||
1031 | |||
1032 | static int mt9t112_camera_probe(struct i2c_client *client) | ||
1033 | { | ||
1034 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
1035 | const char *devname; | ||
1036 | int chipid; | ||
1037 | int ret; | ||
1038 | |||
1039 | ret = mt9t112_s_power(&priv->subdev, 1); | ||
1040 | if (ret < 0) | ||
1041 | return ret; | ||
1042 | |||
1043 | /* Check and show chip ID. */ | ||
1044 | mt9t112_reg_read(chipid, client, 0x0000); | ||
1045 | |||
1046 | switch (chipid) { | ||
1047 | case 0x2680: | ||
1048 | devname = "mt9t111"; | ||
1049 | priv->num_formats = 1; | ||
1050 | break; | ||
1051 | case 0x2682: | ||
1052 | devname = "mt9t112"; | ||
1053 | priv->num_formats = ARRAY_SIZE(mt9t112_cfmts); | ||
1054 | break; | ||
1055 | default: | ||
1056 | dev_err(&client->dev, "Product ID error %04x\n", chipid); | ||
1057 | ret = -ENODEV; | ||
1058 | goto done; | ||
1059 | } | ||
1060 | |||
1061 | dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid); | ||
1062 | |||
1063 | done: | ||
1064 | mt9t112_s_power(&priv->subdev, 0); | ||
1065 | |||
1066 | return ret; | ||
1067 | } | ||
1068 | |||
1069 | static int mt9t112_probe(struct i2c_client *client, | ||
1070 | const struct i2c_device_id *did) | ||
1071 | { | ||
1072 | struct mt9t112_priv *priv; | ||
1073 | int ret; | ||
1074 | |||
1075 | if (!client->dev.platform_data) { | ||
1076 | dev_err(&client->dev, "mt9t112: missing platform data!\n"); | ||
1077 | return -EINVAL; | ||
1078 | } | ||
1079 | |||
1080 | priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); | ||
1081 | if (!priv) | ||
1082 | return -ENOMEM; | ||
1083 | |||
1084 | priv->info = client->dev.platform_data; | ||
1085 | priv->init_done = false; | ||
1086 | |||
1087 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); | ||
1088 | |||
1089 | priv->clk = devm_clk_get(&client->dev, "extclk"); | ||
1090 | if (PTR_ERR(priv->clk) == -ENOENT) { | ||
1091 | priv->clk = NULL; | ||
1092 | } else if (IS_ERR(priv->clk)) { | ||
1093 | dev_err(&client->dev, "Unable to get clock \"extclk\"\n"); | ||
1094 | return PTR_ERR(priv->clk); | ||
1095 | } | ||
1096 | |||
1097 | priv->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby", | ||
1098 | GPIOD_OUT_HIGH); | ||
1099 | if (IS_ERR(priv->standby_gpio)) { | ||
1100 | dev_err(&client->dev, "Unable to get gpio \"standby\"\n"); | ||
1101 | return PTR_ERR(priv->standby_gpio); | ||
1102 | } | ||
1103 | |||
1104 | ret = mt9t112_camera_probe(client); | ||
1105 | if (ret) | ||
1106 | return ret; | ||
1107 | |||
1108 | return v4l2_async_register_subdev(&priv->subdev); | ||
1109 | } | ||
1110 | |||
1111 | static int mt9t112_remove(struct i2c_client *client) | ||
1112 | { | ||
1113 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
1114 | |||
1115 | clk_disable_unprepare(priv->clk); | ||
1116 | v4l2_async_unregister_subdev(&priv->subdev); | ||
1117 | |||
1118 | return 0; | ||
1119 | } | ||
1120 | |||
1121 | static const struct i2c_device_id mt9t112_id[] = { | ||
1122 | { "mt9t112", 0 }, | ||
1123 | { } | ||
1124 | }; | ||
1125 | MODULE_DEVICE_TABLE(i2c, mt9t112_id); | ||
1126 | |||
1127 | static struct i2c_driver mt9t112_i2c_driver = { | ||
1128 | .driver = { | ||
1129 | .name = "mt9t112", | ||
1130 | }, | ||
1131 | .probe = mt9t112_probe, | ||
1132 | .remove = mt9t112_remove, | ||
1133 | .id_table = mt9t112_id, | ||
1134 | }; | ||
1135 | |||
1136 | module_i2c_driver(mt9t112_i2c_driver); | ||
1137 | |||
1138 | MODULE_DESCRIPTION("V4L2 driver for MT9T111/MT9T112 camera sensor"); | ||
1139 | MODULE_AUTHOR("Kuninori Morimoto"); | ||
1140 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index 5e29064fae91..46ef74a2ca36 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c | |||
@@ -364,33 +364,22 @@ static int mt9v011_set_fmt(struct v4l2_subdev *sd, | |||
364 | return 0; | 364 | return 0; |
365 | } | 365 | } |
366 | 366 | ||
367 | static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 367 | static int mt9v011_g_frame_interval(struct v4l2_subdev *sd, |
368 | struct v4l2_subdev_frame_interval *ival) | ||
368 | { | 369 | { |
369 | struct v4l2_captureparm *cp = &parms->parm.capture; | ||
370 | |||
371 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
372 | return -EINVAL; | ||
373 | |||
374 | memset(cp, 0, sizeof(struct v4l2_captureparm)); | ||
375 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
376 | calc_fps(sd, | 370 | calc_fps(sd, |
377 | &cp->timeperframe.numerator, | 371 | &ival->interval.numerator, |
378 | &cp->timeperframe.denominator); | 372 | &ival->interval.denominator); |
379 | 373 | ||
380 | return 0; | 374 | return 0; |
381 | } | 375 | } |
382 | 376 | ||
383 | static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 377 | static int mt9v011_s_frame_interval(struct v4l2_subdev *sd, |
378 | struct v4l2_subdev_frame_interval *ival) | ||
384 | { | 379 | { |
385 | struct v4l2_captureparm *cp = &parms->parm.capture; | 380 | struct v4l2_fract *tpf = &ival->interval; |
386 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
387 | u16 speed; | 381 | u16 speed; |
388 | 382 | ||
389 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
390 | return -EINVAL; | ||
391 | if (cp->extendedmode != 0) | ||
392 | return -EINVAL; | ||
393 | |||
394 | speed = calc_speed(sd, tpf->numerator, tpf->denominator); | 383 | speed = calc_speed(sd, tpf->numerator, tpf->denominator); |
395 | 384 | ||
396 | mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed); | 385 | mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed); |
@@ -469,8 +458,8 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { | |||
469 | }; | 458 | }; |
470 | 459 | ||
471 | static const struct v4l2_subdev_video_ops mt9v011_video_ops = { | 460 | static const struct v4l2_subdev_video_ops mt9v011_video_ops = { |
472 | .g_parm = mt9v011_g_parm, | 461 | .g_frame_interval = mt9v011_g_frame_interval, |
473 | .s_parm = mt9v011_s_parm, | 462 | .s_frame_interval = mt9v011_s_frame_interval, |
474 | }; | 463 | }; |
475 | 464 | ||
476 | static const struct v4l2_subdev_pad_ops mt9v011_pad_ops = { | 465 | static const struct v4l2_subdev_pad_ops mt9v011_pad_ops = { |
diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index bf7d06f3f21a..30ee9f71bf0d 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c | |||
@@ -194,6 +194,7 @@ static const struct ov13858_reg mode_4224x3136_regs[] = { | |||
194 | {0x3624, 0x1c}, | 194 | {0x3624, 0x1c}, |
195 | {0x3640, 0x10}, | 195 | {0x3640, 0x10}, |
196 | {0x3641, 0x70}, | 196 | {0x3641, 0x70}, |
197 | {0x3660, 0x04}, | ||
197 | {0x3661, 0x80}, | 198 | {0x3661, 0x80}, |
198 | {0x3662, 0x12}, | 199 | {0x3662, 0x12}, |
199 | {0x3664, 0x73}, | 200 | {0x3664, 0x73}, |
@@ -384,6 +385,7 @@ static const struct ov13858_reg mode_2112x1568_regs[] = { | |||
384 | {0x3624, 0x1c}, | 385 | {0x3624, 0x1c}, |
385 | {0x3640, 0x10}, | 386 | {0x3640, 0x10}, |
386 | {0x3641, 0x70}, | 387 | {0x3641, 0x70}, |
388 | {0x3660, 0x04}, | ||
387 | {0x3661, 0x80}, | 389 | {0x3661, 0x80}, |
388 | {0x3662, 0x10}, | 390 | {0x3662, 0x10}, |
389 | {0x3664, 0x73}, | 391 | {0x3664, 0x73}, |
@@ -574,6 +576,7 @@ static const struct ov13858_reg mode_2112x1188_regs[] = { | |||
574 | {0x3624, 0x1c}, | 576 | {0x3624, 0x1c}, |
575 | {0x3640, 0x10}, | 577 | {0x3640, 0x10}, |
576 | {0x3641, 0x70}, | 578 | {0x3641, 0x70}, |
579 | {0x3660, 0x04}, | ||
577 | {0x3661, 0x80}, | 580 | {0x3661, 0x80}, |
578 | {0x3662, 0x10}, | 581 | {0x3662, 0x10}, |
579 | {0x3664, 0x73}, | 582 | {0x3664, 0x73}, |
@@ -764,6 +767,7 @@ static const struct ov13858_reg mode_1056x784_regs[] = { | |||
764 | {0x3624, 0x1c}, | 767 | {0x3624, 0x1c}, |
765 | {0x3640, 0x10}, | 768 | {0x3640, 0x10}, |
766 | {0x3641, 0x70}, | 769 | {0x3641, 0x70}, |
770 | {0x3660, 0x04}, | ||
767 | {0x3661, 0x80}, | 771 | {0x3661, 0x80}, |
768 | {0x3662, 0x08}, | 772 | {0x3662, 0x08}, |
769 | {0x3664, 0x73}, | 773 | {0x3664, 0x73}, |
@@ -1057,14 +1061,15 @@ struct ov13858 { | |||
1057 | #define to_ov13858(_sd) container_of(_sd, struct ov13858, sd) | 1061 | #define to_ov13858(_sd) container_of(_sd, struct ov13858, sd) |
1058 | 1062 | ||
1059 | /* Read registers up to 4 at a time */ | 1063 | /* Read registers up to 4 at a time */ |
1060 | static int ov13858_read_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 *val) | 1064 | static int ov13858_read_reg(struct ov13858 *ov13858, u16 reg, u32 len, |
1065 | u32 *val) | ||
1061 | { | 1066 | { |
1062 | struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); | 1067 | struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); |
1063 | struct i2c_msg msgs[2]; | 1068 | struct i2c_msg msgs[2]; |
1064 | u8 *data_be_p; | 1069 | u8 *data_be_p; |
1065 | int ret; | 1070 | int ret; |
1066 | u32 data_be = 0; | 1071 | __be32 data_be = 0; |
1067 | u16 reg_addr_be = cpu_to_be16(reg); | 1072 | __be16 reg_addr_be = cpu_to_be16(reg); |
1068 | 1073 | ||
1069 | if (len > 4) | 1074 | if (len > 4) |
1070 | return -EINVAL; | 1075 | return -EINVAL; |
@@ -1092,11 +1097,13 @@ static int ov13858_read_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 *val) | |||
1092 | } | 1097 | } |
1093 | 1098 | ||
1094 | /* Write registers up to 4 at a time */ | 1099 | /* Write registers up to 4 at a time */ |
1095 | static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 val) | 1100 | static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len, |
1101 | u32 __val) | ||
1096 | { | 1102 | { |
1097 | struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); | 1103 | struct i2c_client *client = v4l2_get_subdevdata(&ov13858->sd); |
1098 | int buf_i, val_i; | 1104 | int buf_i, val_i; |
1099 | u8 buf[6], *val_p; | 1105 | u8 buf[6], *val_p; |
1106 | __be32 val; | ||
1100 | 1107 | ||
1101 | if (len > 4) | 1108 | if (len > 4) |
1102 | return -EINVAL; | 1109 | return -EINVAL; |
@@ -1104,7 +1111,7 @@ static int ov13858_write_reg(struct ov13858 *ov13858, u16 reg, u32 len, u32 val) | |||
1104 | buf[0] = reg >> 8; | 1111 | buf[0] = reg >> 8; |
1105 | buf[1] = reg & 0xff; | 1112 | buf[1] = reg & 0xff; |
1106 | 1113 | ||
1107 | val = cpu_to_be32(val); | 1114 | val = cpu_to_be32(__val); |
1108 | val_p = (u8 *)&val; | 1115 | val_p = (u8 *)&val; |
1109 | buf_i = 2; | 1116 | buf_i = 2; |
1110 | val_i = 4 - len; | 1117 | val_i = 4 - len; |
@@ -1348,39 +1355,6 @@ static int ov13858_get_pad_format(struct v4l2_subdev *sd, | |||
1348 | return ret; | 1355 | return ret; |
1349 | } | 1356 | } |
1350 | 1357 | ||
1351 | /* | ||
1352 | * Calculate resolution distance | ||
1353 | */ | ||
1354 | static int | ||
1355 | ov13858_get_resolution_dist(const struct ov13858_mode *mode, | ||
1356 | struct v4l2_mbus_framefmt *framefmt) | ||
1357 | { | ||
1358 | return abs(mode->width - framefmt->width) + | ||
1359 | abs(mode->height - framefmt->height); | ||
1360 | } | ||
1361 | |||
1362 | /* | ||
1363 | * Find the closest supported resolution to the requested resolution | ||
1364 | */ | ||
1365 | static const struct ov13858_mode * | ||
1366 | ov13858_find_best_fit(struct ov13858 *ov13858, | ||
1367 | struct v4l2_subdev_format *fmt) | ||
1368 | { | ||
1369 | int i, dist, cur_best_fit = 0, cur_best_fit_dist = -1; | ||
1370 | struct v4l2_mbus_framefmt *framefmt = &fmt->format; | ||
1371 | |||
1372 | for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { | ||
1373 | dist = ov13858_get_resolution_dist(&supported_modes[i], | ||
1374 | framefmt); | ||
1375 | if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { | ||
1376 | cur_best_fit_dist = dist; | ||
1377 | cur_best_fit = i; | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | return &supported_modes[cur_best_fit]; | ||
1382 | } | ||
1383 | |||
1384 | static int | 1358 | static int |
1385 | ov13858_set_pad_format(struct v4l2_subdev *sd, | 1359 | ov13858_set_pad_format(struct v4l2_subdev *sd, |
1386 | struct v4l2_subdev_pad_config *cfg, | 1360 | struct v4l2_subdev_pad_config *cfg, |
@@ -1401,7 +1375,8 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, | |||
1401 | if (fmt->format.code != MEDIA_BUS_FMT_SGRBG10_1X10) | 1375 | if (fmt->format.code != MEDIA_BUS_FMT_SGRBG10_1X10) |
1402 | fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; | 1376 | fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
1403 | 1377 | ||
1404 | mode = ov13858_find_best_fit(ov13858, fmt); | 1378 | mode = v4l2_find_nearest_size(supported_modes, width, height, |
1379 | fmt->format.width, fmt->format.height); | ||
1405 | ov13858_update_pad_format(mode, fmt); | 1380 | ov13858_update_pad_format(mode, fmt); |
1406 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 1381 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1407 | framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); | 1382 | framefmt = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
@@ -1565,7 +1540,7 @@ static int __maybe_unused ov13858_resume(struct device *dev) | |||
1565 | 1540 | ||
1566 | error: | 1541 | error: |
1567 | ov13858_stop_streaming(ov13858); | 1542 | ov13858_stop_streaming(ov13858); |
1568 | ov13858->streaming = 0; | 1543 | ov13858->streaming = false; |
1569 | return ret; | 1544 | return ret; |
1570 | } | 1545 | } |
1571 | 1546 | ||
diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c new file mode 100644 index 000000000000..83c55e8288e7 --- /dev/null +++ b/drivers/media/i2c/ov2685.c | |||
@@ -0,0 +1,846 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * ov2685 driver | ||
4 | * | ||
5 | * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk.h> | ||
9 | #include <linux/device.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/gpio/consumer.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/pm_runtime.h> | ||
15 | #include <linux/regulator/consumer.h> | ||
16 | #include <linux/sysfs.h> | ||
17 | #include <media/media-entity.h> | ||
18 | #include <media/v4l2-async.h> | ||
19 | #include <media/v4l2-ctrls.h> | ||
20 | #include <media/v4l2-subdev.h> | ||
21 | |||
22 | #define CHIP_ID 0x2685 | ||
23 | #define OV2685_REG_CHIP_ID 0x300a | ||
24 | |||
25 | #define OV2685_XVCLK_FREQ 24000000 | ||
26 | |||
27 | #define REG_SC_CTRL_MODE 0x0100 | ||
28 | #define SC_CTRL_MODE_STANDBY 0x0 | ||
29 | #define SC_CTRL_MODE_STREAMING BIT(0) | ||
30 | |||
31 | #define OV2685_REG_EXPOSURE 0x3500 | ||
32 | #define OV2685_EXPOSURE_MIN 4 | ||
33 | #define OV2685_EXPOSURE_STEP 1 | ||
34 | |||
35 | #define OV2685_REG_VTS 0x380e | ||
36 | #define OV2685_VTS_MAX 0x7fff | ||
37 | |||
38 | #define OV2685_REG_GAIN 0x350a | ||
39 | #define OV2685_GAIN_MIN 0 | ||
40 | #define OV2685_GAIN_MAX 0x07ff | ||
41 | #define OV2685_GAIN_STEP 0x1 | ||
42 | #define OV2685_GAIN_DEFAULT 0x0036 | ||
43 | |||
44 | #define OV2685_REG_TEST_PATTERN 0x5080 | ||
45 | #define OV2685_TEST_PATTERN_DISABLED 0x00 | ||
46 | #define OV2685_TEST_PATTERN_COLOR_BAR 0x80 | ||
47 | #define OV2685_TEST_PATTERN_RANDOM 0x81 | ||
48 | #define OV2685_TEST_PATTERN_COLOR_BAR_FADE 0x88 | ||
49 | #define OV2685_TEST_PATTERN_BW_SQUARE 0x92 | ||
50 | #define OV2685_TEST_PATTERN_COLOR_SQUARE 0x82 | ||
51 | |||
52 | #define REG_NULL 0xFFFF | ||
53 | |||
54 | #define OV2685_REG_VALUE_08BIT 1 | ||
55 | #define OV2685_REG_VALUE_16BIT 2 | ||
56 | #define OV2685_REG_VALUE_24BIT 3 | ||
57 | |||
58 | #define OV2685_LANES 1 | ||
59 | #define OV2685_BITS_PER_SAMPLE 10 | ||
60 | |||
61 | static const char * const ov2685_supply_names[] = { | ||
62 | "avdd", /* Analog power */ | ||
63 | "dovdd", /* Digital I/O power */ | ||
64 | "dvdd", /* Digital core power */ | ||
65 | }; | ||
66 | |||
67 | #define OV2685_NUM_SUPPLIES ARRAY_SIZE(ov2685_supply_names) | ||
68 | |||
69 | struct regval { | ||
70 | u16 addr; | ||
71 | u8 val; | ||
72 | }; | ||
73 | |||
74 | struct ov2685_mode { | ||
75 | u32 width; | ||
76 | u32 height; | ||
77 | u32 exp_def; | ||
78 | u32 hts_def; | ||
79 | u32 vts_def; | ||
80 | const struct regval *reg_list; | ||
81 | }; | ||
82 | |||
83 | struct ov2685 { | ||
84 | struct i2c_client *client; | ||
85 | struct clk *xvclk; | ||
86 | struct gpio_desc *reset_gpio; | ||
87 | struct regulator_bulk_data supplies[OV2685_NUM_SUPPLIES]; | ||
88 | |||
89 | bool streaming; | ||
90 | struct mutex mutex; | ||
91 | struct v4l2_subdev subdev; | ||
92 | struct media_pad pad; | ||
93 | struct v4l2_ctrl *anal_gain; | ||
94 | struct v4l2_ctrl *exposure; | ||
95 | struct v4l2_ctrl *hblank; | ||
96 | struct v4l2_ctrl *vblank; | ||
97 | struct v4l2_ctrl *test_pattern; | ||
98 | struct v4l2_ctrl_handler ctrl_handler; | ||
99 | |||
100 | const struct ov2685_mode *cur_mode; | ||
101 | }; | ||
102 | |||
103 | #define to_ov2685(sd) container_of(sd, struct ov2685, subdev) | ||
104 | |||
105 | /* PLL settings bases on 24M xvclk */ | ||
106 | static struct regval ov2685_1600x1200_regs[] = { | ||
107 | {0x0103, 0x01}, | ||
108 | {0x0100, 0x00}, | ||
109 | {0x3002, 0x00}, | ||
110 | {0x3016, 0x1c}, | ||
111 | {0x3018, 0x44}, | ||
112 | {0x301d, 0xf0}, | ||
113 | {0x3020, 0x00}, | ||
114 | {0x3082, 0x37}, | ||
115 | {0x3083, 0x03}, | ||
116 | {0x3084, 0x09}, | ||
117 | {0x3085, 0x04}, | ||
118 | {0x3086, 0x00}, | ||
119 | {0x3087, 0x00}, | ||
120 | {0x3501, 0x4e}, | ||
121 | {0x3502, 0xe0}, | ||
122 | {0x3503, 0x27}, | ||
123 | {0x350b, 0x36}, | ||
124 | {0x3600, 0xb4}, | ||
125 | {0x3603, 0x35}, | ||
126 | {0x3604, 0x24}, | ||
127 | {0x3605, 0x00}, | ||
128 | {0x3620, 0x24}, | ||
129 | {0x3621, 0x34}, | ||
130 | {0x3622, 0x03}, | ||
131 | {0x3628, 0x10}, | ||
132 | {0x3705, 0x3c}, | ||
133 | {0x370a, 0x21}, | ||
134 | {0x370c, 0x50}, | ||
135 | {0x370d, 0xc0}, | ||
136 | {0x3717, 0x58}, | ||
137 | {0x3718, 0x80}, | ||
138 | {0x3720, 0x00}, | ||
139 | {0x3721, 0x09}, | ||
140 | {0x3722, 0x06}, | ||
141 | {0x3723, 0x59}, | ||
142 | {0x3738, 0x99}, | ||
143 | {0x3781, 0x80}, | ||
144 | {0x3784, 0x0c}, | ||
145 | {0x3789, 0x60}, | ||
146 | {0x3800, 0x00}, | ||
147 | {0x3801, 0x00}, | ||
148 | {0x3802, 0x00}, | ||
149 | {0x3803, 0x00}, | ||
150 | {0x3804, 0x06}, | ||
151 | {0x3805, 0x4f}, | ||
152 | {0x3806, 0x04}, | ||
153 | {0x3807, 0xbf}, | ||
154 | {0x3808, 0x06}, | ||
155 | {0x3809, 0x40}, | ||
156 | {0x380a, 0x04}, | ||
157 | {0x380b, 0xb0}, | ||
158 | {0x380c, 0x06}, | ||
159 | {0x380d, 0xa4}, | ||
160 | {0x380e, 0x05}, | ||
161 | {0x380f, 0x0e}, | ||
162 | {0x3810, 0x00}, | ||
163 | {0x3811, 0x08}, | ||
164 | {0x3812, 0x00}, | ||
165 | {0x3813, 0x08}, | ||
166 | {0x3814, 0x11}, | ||
167 | {0x3815, 0x11}, | ||
168 | {0x3819, 0x04}, | ||
169 | {0x3820, 0xc0}, | ||
170 | {0x3821, 0x00}, | ||
171 | {0x3a06, 0x01}, | ||
172 | {0x3a07, 0x84}, | ||
173 | {0x3a08, 0x01}, | ||
174 | {0x3a09, 0x43}, | ||
175 | {0x3a0a, 0x24}, | ||
176 | {0x3a0b, 0x60}, | ||
177 | {0x3a0c, 0x28}, | ||
178 | {0x3a0d, 0x60}, | ||
179 | {0x3a0e, 0x04}, | ||
180 | {0x3a0f, 0x8c}, | ||
181 | {0x3a10, 0x05}, | ||
182 | {0x3a11, 0x0c}, | ||
183 | {0x4000, 0x81}, | ||
184 | {0x4001, 0x40}, | ||
185 | {0x4008, 0x02}, | ||
186 | {0x4009, 0x09}, | ||
187 | {0x4300, 0x00}, | ||
188 | {0x430e, 0x00}, | ||
189 | {0x4602, 0x02}, | ||
190 | {0x481b, 0x40}, | ||
191 | {0x481f, 0x40}, | ||
192 | {0x4837, 0x18}, | ||
193 | {0x5000, 0x1f}, | ||
194 | {0x5001, 0x05}, | ||
195 | {0x5002, 0x30}, | ||
196 | {0x5003, 0x04}, | ||
197 | {0x5004, 0x00}, | ||
198 | {0x5005, 0x0c}, | ||
199 | {0x5280, 0x15}, | ||
200 | {0x5281, 0x06}, | ||
201 | {0x5282, 0x06}, | ||
202 | {0x5283, 0x08}, | ||
203 | {0x5284, 0x1c}, | ||
204 | {0x5285, 0x1c}, | ||
205 | {0x5286, 0x20}, | ||
206 | {0x5287, 0x10}, | ||
207 | {REG_NULL, 0x00} | ||
208 | }; | ||
209 | |||
210 | #define OV2685_LINK_FREQ_330MHZ 330000000 | ||
211 | static const s64 link_freq_menu_items[] = { | ||
212 | OV2685_LINK_FREQ_330MHZ | ||
213 | }; | ||
214 | |||
215 | static const char * const ov2685_test_pattern_menu[] = { | ||
216 | "Disabled", | ||
217 | "Color Bar", | ||
218 | "Color Bar FADE", | ||
219 | "Random Data", | ||
220 | "Black White Square", | ||
221 | "Color Square" | ||
222 | }; | ||
223 | |||
224 | static const int ov2685_test_pattern_val[] = { | ||
225 | OV2685_TEST_PATTERN_DISABLED, | ||
226 | OV2685_TEST_PATTERN_COLOR_BAR, | ||
227 | OV2685_TEST_PATTERN_COLOR_BAR_FADE, | ||
228 | OV2685_TEST_PATTERN_RANDOM, | ||
229 | OV2685_TEST_PATTERN_BW_SQUARE, | ||
230 | OV2685_TEST_PATTERN_COLOR_SQUARE, | ||
231 | }; | ||
232 | |||
233 | static const struct ov2685_mode supported_modes[] = { | ||
234 | { | ||
235 | .width = 1600, | ||
236 | .height = 1200, | ||
237 | .exp_def = 0x04ee, | ||
238 | .hts_def = 0x06a4, | ||
239 | .vts_def = 0x050e, | ||
240 | .reg_list = ov2685_1600x1200_regs, | ||
241 | }, | ||
242 | }; | ||
243 | |||
244 | /* Write registers up to 4 at a time */ | ||
245 | static int ov2685_write_reg(struct i2c_client *client, u16 reg, | ||
246 | u32 len, u32 val) | ||
247 | { | ||
248 | u32 val_i, buf_i; | ||
249 | u8 buf[6]; | ||
250 | u8 *val_p; | ||
251 | __be32 val_be; | ||
252 | |||
253 | if (len > 4) | ||
254 | return -EINVAL; | ||
255 | |||
256 | buf[0] = reg >> 8; | ||
257 | buf[1] = reg & 0xff; | ||
258 | |||
259 | val_be = cpu_to_be32(val); | ||
260 | val_p = (u8 *)&val_be; | ||
261 | buf_i = 2; | ||
262 | val_i = 4 - len; | ||
263 | |||
264 | while (val_i < 4) | ||
265 | buf[buf_i++] = val_p[val_i++]; | ||
266 | |||
267 | if (i2c_master_send(client, buf, len + 2) != len + 2) | ||
268 | return -EIO; | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int ov2685_write_array(struct i2c_client *client, | ||
274 | const struct regval *regs) | ||
275 | { | ||
276 | int ret = 0; | ||
277 | u32 i; | ||
278 | |||
279 | for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) | ||
280 | ret = ov2685_write_reg(client, regs[i].addr, | ||
281 | OV2685_REG_VALUE_08BIT, regs[i].val); | ||
282 | |||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | /* Read registers up to 4 at a time */ | ||
287 | static int ov2685_read_reg(struct i2c_client *client, u16 reg, | ||
288 | u32 len, u32 *val) | ||
289 | { | ||
290 | struct i2c_msg msgs[2]; | ||
291 | u8 *data_be_p; | ||
292 | __be32 data_be = 0; | ||
293 | __be16 reg_addr_be = cpu_to_be16(reg); | ||
294 | int ret; | ||
295 | |||
296 | if (len > 4) | ||
297 | return -EINVAL; | ||
298 | |||
299 | data_be_p = (u8 *)&data_be; | ||
300 | /* Write register address */ | ||
301 | msgs[0].addr = client->addr; | ||
302 | msgs[0].flags = 0; | ||
303 | msgs[0].len = 2; | ||
304 | msgs[0].buf = (u8 *)®_addr_be; | ||
305 | |||
306 | /* Read data from register */ | ||
307 | msgs[1].addr = client->addr; | ||
308 | msgs[1].flags = I2C_M_RD; | ||
309 | msgs[1].len = len; | ||
310 | msgs[1].buf = &data_be_p[4 - len]; | ||
311 | |||
312 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
313 | if (ret != ARRAY_SIZE(msgs)) | ||
314 | return -EIO; | ||
315 | |||
316 | *val = be32_to_cpu(data_be); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static void ov2685_fill_fmt(const struct ov2685_mode *mode, | ||
322 | struct v4l2_mbus_framefmt *fmt) | ||
323 | { | ||
324 | fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
325 | fmt->width = mode->width; | ||
326 | fmt->height = mode->height; | ||
327 | fmt->field = V4L2_FIELD_NONE; | ||
328 | } | ||
329 | |||
330 | static int ov2685_set_fmt(struct v4l2_subdev *sd, | ||
331 | struct v4l2_subdev_pad_config *cfg, | ||
332 | struct v4l2_subdev_format *fmt) | ||
333 | { | ||
334 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
335 | struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; | ||
336 | |||
337 | /* only one mode supported for now */ | ||
338 | ov2685_fill_fmt(ov2685->cur_mode, mbus_fmt); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int ov2685_get_fmt(struct v4l2_subdev *sd, | ||
344 | struct v4l2_subdev_pad_config *cfg, | ||
345 | struct v4l2_subdev_format *fmt) | ||
346 | { | ||
347 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
348 | struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; | ||
349 | |||
350 | ov2685_fill_fmt(ov2685->cur_mode, mbus_fmt); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int ov2685_enum_mbus_code(struct v4l2_subdev *sd, | ||
356 | struct v4l2_subdev_pad_config *cfg, | ||
357 | struct v4l2_subdev_mbus_code_enum *code) | ||
358 | { | ||
359 | if (code->index >= ARRAY_SIZE(supported_modes)) | ||
360 | return -EINVAL; | ||
361 | |||
362 | code->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int ov2685_enum_frame_sizes(struct v4l2_subdev *sd, | ||
368 | struct v4l2_subdev_pad_config *cfg, | ||
369 | struct v4l2_subdev_frame_size_enum *fse) | ||
370 | { | ||
371 | int index = fse->index; | ||
372 | |||
373 | if (index >= ARRAY_SIZE(supported_modes)) | ||
374 | return -EINVAL; | ||
375 | |||
376 | fse->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
377 | |||
378 | fse->min_width = supported_modes[index].width; | ||
379 | fse->max_width = supported_modes[index].width; | ||
380 | fse->max_height = supported_modes[index].height; | ||
381 | fse->min_height = supported_modes[index].height; | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | /* Calculate the delay in us by clock rate and clock cycles */ | ||
387 | static inline u32 ov2685_cal_delay(u32 cycles) | ||
388 | { | ||
389 | return DIV_ROUND_UP(cycles, OV2685_XVCLK_FREQ / 1000 / 1000); | ||
390 | } | ||
391 | |||
392 | static int __ov2685_power_on(struct ov2685 *ov2685) | ||
393 | { | ||
394 | int ret; | ||
395 | u32 delay_us; | ||
396 | struct device *dev = &ov2685->client->dev; | ||
397 | |||
398 | ret = clk_prepare_enable(ov2685->xvclk); | ||
399 | if (ret < 0) { | ||
400 | dev_err(dev, "Failed to enable xvclk\n"); | ||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | gpiod_set_value_cansleep(ov2685->reset_gpio, 1); | ||
405 | |||
406 | ret = regulator_bulk_enable(OV2685_NUM_SUPPLIES, ov2685->supplies); | ||
407 | if (ret < 0) { | ||
408 | dev_err(dev, "Failed to enable regulators\n"); | ||
409 | goto disable_clk; | ||
410 | } | ||
411 | |||
412 | /* The minimum delay between power supplies and reset rising can be 0 */ | ||
413 | gpiod_set_value_cansleep(ov2685->reset_gpio, 0); | ||
414 | /* 8192 xvclk cycles prior to the first SCCB transaction */ | ||
415 | delay_us = ov2685_cal_delay(8192); | ||
416 | usleep_range(delay_us, delay_us * 2); | ||
417 | |||
418 | /* HACK: ov2685 would output messy data after reset(R0103), | ||
419 | * writing register before .s_stream() as a workaround | ||
420 | */ | ||
421 | ret = ov2685_write_array(ov2685->client, ov2685->cur_mode->reg_list); | ||
422 | if (ret) | ||
423 | goto disable_supplies; | ||
424 | |||
425 | return 0; | ||
426 | |||
427 | disable_supplies: | ||
428 | regulator_bulk_disable(OV2685_NUM_SUPPLIES, ov2685->supplies); | ||
429 | disable_clk: | ||
430 | clk_disable_unprepare(ov2685->xvclk); | ||
431 | |||
432 | return ret; | ||
433 | } | ||
434 | |||
435 | static void __ov2685_power_off(struct ov2685 *ov2685) | ||
436 | { | ||
437 | /* 512 xvclk cycles after the last SCCB transaction or MIPI frame end */ | ||
438 | u32 delay_us = ov2685_cal_delay(512); | ||
439 | |||
440 | usleep_range(delay_us, delay_us * 2); | ||
441 | clk_disable_unprepare(ov2685->xvclk); | ||
442 | gpiod_set_value_cansleep(ov2685->reset_gpio, 1); | ||
443 | regulator_bulk_disable(OV2685_NUM_SUPPLIES, ov2685->supplies); | ||
444 | } | ||
445 | |||
446 | static int ov2685_s_stream(struct v4l2_subdev *sd, int on) | ||
447 | { | ||
448 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
449 | struct i2c_client *client = ov2685->client; | ||
450 | int ret = 0; | ||
451 | |||
452 | mutex_lock(&ov2685->mutex); | ||
453 | |||
454 | on = !!on; | ||
455 | if (on == ov2685->streaming) | ||
456 | goto unlock_and_return; | ||
457 | |||
458 | if (on) { | ||
459 | ret = pm_runtime_get_sync(&ov2685->client->dev); | ||
460 | if (ret < 0) { | ||
461 | pm_runtime_put_noidle(&client->dev); | ||
462 | goto unlock_and_return; | ||
463 | } | ||
464 | ret = __v4l2_ctrl_handler_setup(&ov2685->ctrl_handler); | ||
465 | if (ret) { | ||
466 | pm_runtime_put(&client->dev); | ||
467 | goto unlock_and_return; | ||
468 | } | ||
469 | ret = ov2685_write_reg(client, REG_SC_CTRL_MODE, | ||
470 | OV2685_REG_VALUE_08BIT, SC_CTRL_MODE_STREAMING); | ||
471 | if (ret) { | ||
472 | pm_runtime_put(&client->dev); | ||
473 | goto unlock_and_return; | ||
474 | } | ||
475 | } else { | ||
476 | ov2685_write_reg(client, REG_SC_CTRL_MODE, | ||
477 | OV2685_REG_VALUE_08BIT, SC_CTRL_MODE_STANDBY); | ||
478 | pm_runtime_put(&ov2685->client->dev); | ||
479 | } | ||
480 | |||
481 | ov2685->streaming = on; | ||
482 | |||
483 | unlock_and_return: | ||
484 | mutex_unlock(&ov2685->mutex); | ||
485 | |||
486 | return ret; | ||
487 | } | ||
488 | |||
489 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
490 | static int ov2685_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
491 | { | ||
492 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
493 | struct v4l2_mbus_framefmt *try_fmt; | ||
494 | |||
495 | mutex_lock(&ov2685->mutex); | ||
496 | |||
497 | try_fmt = v4l2_subdev_get_try_format(sd, fh->pad, 0); | ||
498 | /* Initialize try_fmt */ | ||
499 | ov2685_fill_fmt(&supported_modes[0], try_fmt); | ||
500 | |||
501 | mutex_unlock(&ov2685->mutex); | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | #endif | ||
506 | |||
507 | static int __maybe_unused ov2685_runtime_resume(struct device *dev) | ||
508 | { | ||
509 | struct i2c_client *client = to_i2c_client(dev); | ||
510 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
511 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
512 | |||
513 | return __ov2685_power_on(ov2685); | ||
514 | } | ||
515 | |||
516 | static int __maybe_unused ov2685_runtime_suspend(struct device *dev) | ||
517 | { | ||
518 | struct i2c_client *client = to_i2c_client(dev); | ||
519 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
520 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
521 | |||
522 | __ov2685_power_off(ov2685); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static const struct dev_pm_ops ov2685_pm_ops = { | ||
528 | SET_RUNTIME_PM_OPS(ov2685_runtime_suspend, | ||
529 | ov2685_runtime_resume, NULL) | ||
530 | }; | ||
531 | |||
532 | static int ov2685_set_ctrl(struct v4l2_ctrl *ctrl) | ||
533 | { | ||
534 | struct ov2685 *ov2685 = container_of(ctrl->handler, | ||
535 | struct ov2685, ctrl_handler); | ||
536 | struct i2c_client *client = ov2685->client; | ||
537 | s64 max_expo; | ||
538 | int ret; | ||
539 | |||
540 | /* Propagate change of current control to all related controls */ | ||
541 | switch (ctrl->id) { | ||
542 | case V4L2_CID_VBLANK: | ||
543 | /* Update max exposure while meeting expected vblanking */ | ||
544 | max_expo = ov2685->cur_mode->height + ctrl->val - 4; | ||
545 | __v4l2_ctrl_modify_range(ov2685->exposure, | ||
546 | ov2685->exposure->minimum, max_expo, | ||
547 | ov2685->exposure->step, | ||
548 | ov2685->exposure->default_value); | ||
549 | break; | ||
550 | } | ||
551 | |||
552 | if (pm_runtime_get_if_in_use(&client->dev) <= 0) | ||
553 | return 0; | ||
554 | |||
555 | switch (ctrl->id) { | ||
556 | case V4L2_CID_EXPOSURE: | ||
557 | ret = ov2685_write_reg(ov2685->client, OV2685_REG_EXPOSURE, | ||
558 | OV2685_REG_VALUE_24BIT, ctrl->val << 4); | ||
559 | break; | ||
560 | case V4L2_CID_ANALOGUE_GAIN: | ||
561 | ret = ov2685_write_reg(ov2685->client, OV2685_REG_GAIN, | ||
562 | OV2685_REG_VALUE_16BIT, ctrl->val); | ||
563 | break; | ||
564 | case V4L2_CID_VBLANK: | ||
565 | ret = ov2685_write_reg(ov2685->client, OV2685_REG_VTS, | ||
566 | OV2685_REG_VALUE_16BIT, | ||
567 | ctrl->val + ov2685->cur_mode->height); | ||
568 | break; | ||
569 | case V4L2_CID_TEST_PATTERN: | ||
570 | ret = ov2685_write_reg(ov2685->client, OV2685_REG_TEST_PATTERN, | ||
571 | OV2685_REG_VALUE_08BIT, | ||
572 | ov2685_test_pattern_val[ctrl->val]); | ||
573 | break; | ||
574 | default: | ||
575 | dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", | ||
576 | __func__, ctrl->id, ctrl->val); | ||
577 | ret = -EINVAL; | ||
578 | break; | ||
579 | }; | ||
580 | |||
581 | pm_runtime_put(&client->dev); | ||
582 | |||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | static const struct v4l2_subdev_video_ops ov2685_video_ops = { | ||
587 | .s_stream = ov2685_s_stream, | ||
588 | }; | ||
589 | |||
590 | static const struct v4l2_subdev_pad_ops ov2685_pad_ops = { | ||
591 | .enum_mbus_code = ov2685_enum_mbus_code, | ||
592 | .enum_frame_size = ov2685_enum_frame_sizes, | ||
593 | .get_fmt = ov2685_get_fmt, | ||
594 | .set_fmt = ov2685_set_fmt, | ||
595 | }; | ||
596 | |||
597 | static const struct v4l2_subdev_ops ov2685_subdev_ops = { | ||
598 | .video = &ov2685_video_ops, | ||
599 | .pad = &ov2685_pad_ops, | ||
600 | }; | ||
601 | |||
602 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
603 | static const struct v4l2_subdev_internal_ops ov2685_internal_ops = { | ||
604 | .open = ov2685_open, | ||
605 | }; | ||
606 | #endif | ||
607 | |||
608 | static const struct v4l2_ctrl_ops ov2685_ctrl_ops = { | ||
609 | .s_ctrl = ov2685_set_ctrl, | ||
610 | }; | ||
611 | |||
612 | static int ov2685_initialize_controls(struct ov2685 *ov2685) | ||
613 | { | ||
614 | const struct ov2685_mode *mode; | ||
615 | struct v4l2_ctrl_handler *handler; | ||
616 | struct v4l2_ctrl *ctrl; | ||
617 | u64 exposure_max; | ||
618 | u32 pixel_rate, h_blank; | ||
619 | int ret; | ||
620 | |||
621 | handler = &ov2685->ctrl_handler; | ||
622 | mode = ov2685->cur_mode; | ||
623 | ret = v4l2_ctrl_handler_init(handler, 8); | ||
624 | if (ret) | ||
625 | return ret; | ||
626 | handler->lock = &ov2685->mutex; | ||
627 | |||
628 | ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, | ||
629 | 0, 0, link_freq_menu_items); | ||
630 | if (ctrl) | ||
631 | ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
632 | |||
633 | pixel_rate = (link_freq_menu_items[0] * 2 * OV2685_LANES) / | ||
634 | OV2685_BITS_PER_SAMPLE; | ||
635 | v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, | ||
636 | 0, pixel_rate, 1, pixel_rate); | ||
637 | |||
638 | h_blank = mode->hts_def - mode->width; | ||
639 | ov2685->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, | ||
640 | h_blank, h_blank, 1, h_blank); | ||
641 | if (ov2685->hblank) | ||
642 | ov2685->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
643 | |||
644 | ov2685->vblank = v4l2_ctrl_new_std(handler, &ov2685_ctrl_ops, | ||
645 | V4L2_CID_VBLANK, mode->vts_def - mode->height, | ||
646 | OV2685_VTS_MAX - mode->height, 1, | ||
647 | mode->vts_def - mode->height); | ||
648 | |||
649 | exposure_max = mode->vts_def - 4; | ||
650 | ov2685->exposure = v4l2_ctrl_new_std(handler, &ov2685_ctrl_ops, | ||
651 | V4L2_CID_EXPOSURE, OV2685_EXPOSURE_MIN, | ||
652 | exposure_max, OV2685_EXPOSURE_STEP, | ||
653 | mode->exp_def); | ||
654 | |||
655 | ov2685->anal_gain = v4l2_ctrl_new_std(handler, &ov2685_ctrl_ops, | ||
656 | V4L2_CID_ANALOGUE_GAIN, OV2685_GAIN_MIN, | ||
657 | OV2685_GAIN_MAX, OV2685_GAIN_STEP, | ||
658 | OV2685_GAIN_DEFAULT); | ||
659 | |||
660 | ov2685->test_pattern = v4l2_ctrl_new_std_menu_items(handler, | ||
661 | &ov2685_ctrl_ops, V4L2_CID_TEST_PATTERN, | ||
662 | ARRAY_SIZE(ov2685_test_pattern_menu) - 1, | ||
663 | 0, 0, ov2685_test_pattern_menu); | ||
664 | |||
665 | if (handler->error) { | ||
666 | ret = handler->error; | ||
667 | dev_err(&ov2685->client->dev, | ||
668 | "Failed to init controls(%d)\n", ret); | ||
669 | goto err_free_handler; | ||
670 | } | ||
671 | |||
672 | ov2685->subdev.ctrl_handler = handler; | ||
673 | |||
674 | return 0; | ||
675 | |||
676 | err_free_handler: | ||
677 | v4l2_ctrl_handler_free(handler); | ||
678 | |||
679 | return ret; | ||
680 | } | ||
681 | |||
682 | static int ov2685_check_sensor_id(struct ov2685 *ov2685, | ||
683 | struct i2c_client *client) | ||
684 | { | ||
685 | struct device *dev = &ov2685->client->dev; | ||
686 | int ret; | ||
687 | u32 id = 0; | ||
688 | |||
689 | ret = ov2685_read_reg(client, OV2685_REG_CHIP_ID, | ||
690 | OV2685_REG_VALUE_16BIT, &id); | ||
691 | if (id != CHIP_ID) { | ||
692 | dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret); | ||
693 | return ret; | ||
694 | } | ||
695 | |||
696 | dev_info(dev, "Detected OV%04x sensor\n", CHIP_ID); | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static int ov2685_configure_regulators(struct ov2685 *ov2685) | ||
702 | { | ||
703 | int i; | ||
704 | |||
705 | for (i = 0; i < OV2685_NUM_SUPPLIES; i++) | ||
706 | ov2685->supplies[i].supply = ov2685_supply_names[i]; | ||
707 | |||
708 | return devm_regulator_bulk_get(&ov2685->client->dev, | ||
709 | OV2685_NUM_SUPPLIES, | ||
710 | ov2685->supplies); | ||
711 | } | ||
712 | |||
713 | static int ov2685_probe(struct i2c_client *client, | ||
714 | const struct i2c_device_id *id) | ||
715 | { | ||
716 | struct device *dev = &client->dev; | ||
717 | struct ov2685 *ov2685; | ||
718 | int ret; | ||
719 | |||
720 | ov2685 = devm_kzalloc(dev, sizeof(*ov2685), GFP_KERNEL); | ||
721 | if (!ov2685) | ||
722 | return -ENOMEM; | ||
723 | |||
724 | ov2685->client = client; | ||
725 | ov2685->cur_mode = &supported_modes[0]; | ||
726 | |||
727 | ov2685->xvclk = devm_clk_get(dev, "xvclk"); | ||
728 | if (IS_ERR(ov2685->xvclk)) { | ||
729 | dev_err(dev, "Failed to get xvclk\n"); | ||
730 | return -EINVAL; | ||
731 | } | ||
732 | ret = clk_set_rate(ov2685->xvclk, OV2685_XVCLK_FREQ); | ||
733 | if (ret < 0) { | ||
734 | dev_err(dev, "Failed to set xvclk rate (24MHz)\n"); | ||
735 | return ret; | ||
736 | } | ||
737 | if (clk_get_rate(ov2685->xvclk) != OV2685_XVCLK_FREQ) | ||
738 | dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); | ||
739 | |||
740 | ov2685->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); | ||
741 | if (IS_ERR(ov2685->reset_gpio)) { | ||
742 | dev_err(dev, "Failed to get reset-gpios\n"); | ||
743 | return -EINVAL; | ||
744 | } | ||
745 | |||
746 | ret = ov2685_configure_regulators(ov2685); | ||
747 | if (ret) { | ||
748 | dev_err(dev, "Failed to get power regulators\n"); | ||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | mutex_init(&ov2685->mutex); | ||
753 | v4l2_i2c_subdev_init(&ov2685->subdev, client, &ov2685_subdev_ops); | ||
754 | ret = ov2685_initialize_controls(ov2685); | ||
755 | if (ret) | ||
756 | goto err_destroy_mutex; | ||
757 | |||
758 | ret = __ov2685_power_on(ov2685); | ||
759 | if (ret) | ||
760 | goto err_free_handler; | ||
761 | |||
762 | ret = ov2685_check_sensor_id(ov2685, client); | ||
763 | if (ret) | ||
764 | goto err_power_off; | ||
765 | |||
766 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
767 | ov2685->subdev.internal_ops = &ov2685_internal_ops; | ||
768 | ov2685->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
769 | #endif | ||
770 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
771 | ov2685->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
772 | ov2685->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; | ||
773 | ret = media_entity_pads_init(&ov2685->subdev.entity, 1, &ov2685->pad); | ||
774 | if (ret < 0) | ||
775 | goto err_power_off; | ||
776 | #endif | ||
777 | |||
778 | ret = v4l2_async_register_subdev(&ov2685->subdev); | ||
779 | if (ret) { | ||
780 | dev_err(dev, "v4l2 async register subdev failed\n"); | ||
781 | goto err_clean_entity; | ||
782 | } | ||
783 | |||
784 | pm_runtime_set_active(dev); | ||
785 | pm_runtime_enable(dev); | ||
786 | pm_runtime_idle(dev); | ||
787 | |||
788 | return 0; | ||
789 | |||
790 | err_clean_entity: | ||
791 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
792 | media_entity_cleanup(&ov2685->subdev.entity); | ||
793 | #endif | ||
794 | err_power_off: | ||
795 | __ov2685_power_off(ov2685); | ||
796 | err_free_handler: | ||
797 | v4l2_ctrl_handler_free(&ov2685->ctrl_handler); | ||
798 | err_destroy_mutex: | ||
799 | mutex_destroy(&ov2685->mutex); | ||
800 | |||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | static int ov2685_remove(struct i2c_client *client) | ||
805 | { | ||
806 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
807 | struct ov2685 *ov2685 = to_ov2685(sd); | ||
808 | |||
809 | v4l2_async_unregister_subdev(sd); | ||
810 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
811 | media_entity_cleanup(&sd->entity); | ||
812 | #endif | ||
813 | v4l2_ctrl_handler_free(&ov2685->ctrl_handler); | ||
814 | mutex_destroy(&ov2685->mutex); | ||
815 | |||
816 | pm_runtime_disable(&client->dev); | ||
817 | if (!pm_runtime_status_suspended(&client->dev)) | ||
818 | __ov2685_power_off(ov2685); | ||
819 | pm_runtime_set_suspended(&client->dev); | ||
820 | |||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | #if IS_ENABLED(CONFIG_OF) | ||
825 | static const struct of_device_id ov2685_of_match[] = { | ||
826 | { .compatible = "ovti,ov2685" }, | ||
827 | {}, | ||
828 | }; | ||
829 | MODULE_DEVICE_TABLE(of, ov2685_of_match); | ||
830 | #endif | ||
831 | |||
832 | static struct i2c_driver ov2685_i2c_driver = { | ||
833 | .driver = { | ||
834 | .name = "ov2685", | ||
835 | .owner = THIS_MODULE, | ||
836 | .pm = &ov2685_pm_ops, | ||
837 | .of_match_table = of_match_ptr(ov2685_of_match), | ||
838 | }, | ||
839 | .probe = &ov2685_probe, | ||
840 | .remove = &ov2685_remove, | ||
841 | }; | ||
842 | |||
843 | module_i2c_driver(ov2685_i2c_driver); | ||
844 | |||
845 | MODULE_DESCRIPTION("OmniVision ov2685 sensor driver"); | ||
846 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index e2dd352224c7..03940f0cdfa6 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c | |||
@@ -14,14 +14,14 @@ | |||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/gpio/consumer.h> | ||
17 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
20 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/regulator/consumer.h> | ||
21 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
22 | #include <linux/types.h> | 24 | #include <linux/types.h> |
23 | #include <linux/gpio/consumer.h> | ||
24 | #include <linux/regulator/consumer.h> | ||
25 | #include <media/v4l2-async.h> | 25 | #include <media/v4l2-async.h> |
26 | #include <media/v4l2-ctrls.h> | 26 | #include <media/v4l2-ctrls.h> |
27 | #include <media/v4l2-device.h> | 27 | #include <media/v4l2-device.h> |
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #define OV5640_DEFAULT_SLAVE_ID 0x3c | 35 | #define OV5640_DEFAULT_SLAVE_ID 0x3c |
36 | 36 | ||
37 | #define OV5640_REG_SYS_RESET02 0x3002 | ||
38 | #define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006 | ||
37 | #define OV5640_REG_SYS_CTRL0 0x3008 | 39 | #define OV5640_REG_SYS_CTRL0 0x3008 |
38 | #define OV5640_REG_CHIP_ID 0x300a | 40 | #define OV5640_REG_CHIP_ID 0x300a |
39 | #define OV5640_REG_IO_MIPI_CTRL00 0x300e | 41 | #define OV5640_REG_IO_MIPI_CTRL00 0x300e |
@@ -114,6 +116,7 @@ struct ov5640_pixfmt { | |||
114 | }; | 116 | }; |
115 | 117 | ||
116 | static const struct ov5640_pixfmt ov5640_formats[] = { | 118 | static const struct ov5640_pixfmt ov5640_formats[] = { |
119 | { MEDIA_BUS_FMT_JPEG_1X8, V4L2_COLORSPACE_JPEG, }, | ||
117 | { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, }, | 120 | { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, }, |
118 | { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, }, | 121 | { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, }, |
119 | { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, }, | 122 | { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, }, |
@@ -125,7 +128,7 @@ static const struct ov5640_pixfmt ov5640_formats[] = { | |||
125 | * to set the MIPI CSI-2 virtual channel. | 128 | * to set the MIPI CSI-2 virtual channel. |
126 | */ | 129 | */ |
127 | static unsigned int virtual_channel; | 130 | static unsigned int virtual_channel; |
128 | module_param(virtual_channel, int, 0); | 131 | module_param(virtual_channel, uint, 0444); |
129 | MODULE_PARM_DESC(virtual_channel, | 132 | MODULE_PARM_DESC(virtual_channel, |
130 | "MIPI CSI-2 virtual channel (0..3), default 0"); | 133 | "MIPI CSI-2 virtual channel (0..3), default 0"); |
131 | 134 | ||
@@ -136,7 +139,7 @@ static const int ov5640_framerates[] = { | |||
136 | 139 | ||
137 | /* regulator supplies */ | 140 | /* regulator supplies */ |
138 | static const char * const ov5640_supply_name[] = { | 141 | static const char * const ov5640_supply_name[] = { |
139 | "DOVDD", /* Digital I/O (1.8V) suppply */ | 142 | "DOVDD", /* Digital I/O (1.8V) supply */ |
140 | "DVDD", /* Digital Core (1.5V) supply */ | 143 | "DVDD", /* Digital Core (1.5V) supply */ |
141 | "AVDD", /* Analog (2.8V) supply */ | 144 | "AVDD", /* Analog (2.8V) supply */ |
142 | }; | 145 | }; |
@@ -242,7 +245,6 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) | |||
242 | */ | 245 | */ |
243 | 246 | ||
244 | static const struct reg_value ov5640_init_setting_30fps_VGA[] = { | 247 | static const struct reg_value ov5640_init_setting_30fps_VGA[] = { |
245 | |||
246 | {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, | 248 | {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, |
247 | {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, | 249 | {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, |
248 | {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, | 250 | {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, |
@@ -331,7 +333,6 @@ static const struct reg_value ov5640_init_setting_30fps_VGA[] = { | |||
331 | }; | 333 | }; |
332 | 334 | ||
333 | static const struct reg_value ov5640_setting_30fps_VGA_640_480[] = { | 335 | static const struct reg_value ov5640_setting_30fps_VGA_640_480[] = { |
334 | |||
335 | {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, | 336 | {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, |
336 | {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, | 337 | {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, |
337 | {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, | 338 | {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, |
@@ -374,7 +375,6 @@ static const struct reg_value ov5640_setting_15fps_VGA_640_480[] = { | |||
374 | }; | 375 | }; |
375 | 376 | ||
376 | static const struct reg_value ov5640_setting_30fps_XGA_1024_768[] = { | 377 | static const struct reg_value ov5640_setting_30fps_XGA_1024_768[] = { |
377 | |||
378 | {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, | 378 | {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, |
379 | {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, | 379 | {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, |
380 | {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, | 380 | {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, |
@@ -481,6 +481,7 @@ static const struct reg_value ov5640_setting_30fps_QCIF_176_144[] = { | |||
481 | {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, | 481 | {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, |
482 | {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, | 482 | {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, |
483 | }; | 483 | }; |
484 | |||
484 | static const struct reg_value ov5640_setting_15fps_QCIF_176_144[] = { | 485 | static const struct reg_value ov5640_setting_15fps_QCIF_176_144[] = { |
485 | {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, | 486 | {0x3035, 0x22, 0, 0}, {0x3036, 0x38, 0, 0}, {0x3c07, 0x08, 0, 0}, |
486 | {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, | 487 | {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, |
@@ -836,7 +837,7 @@ static int ov5640_write_reg(struct ov5640_dev *sensor, u16 reg, u8 val) | |||
836 | 837 | ||
837 | ret = i2c_transfer(client->adapter, &msg, 1); | 838 | ret = i2c_transfer(client->adapter, &msg, 1); |
838 | if (ret < 0) { | 839 | if (ret < 0) { |
839 | v4l2_err(&sensor->sd, "%s: error: reg=%x, val=%x\n", | 840 | dev_err(&client->dev, "%s: error: reg=%x, val=%x\n", |
840 | __func__, reg, val); | 841 | __func__, reg, val); |
841 | return ret; | 842 | return ret; |
842 | } | 843 | } |
@@ -865,8 +866,11 @@ static int ov5640_read_reg(struct ov5640_dev *sensor, u16 reg, u8 *val) | |||
865 | msg[1].len = 1; | 866 | msg[1].len = 1; |
866 | 867 | ||
867 | ret = i2c_transfer(client->adapter, msg, 2); | 868 | ret = i2c_transfer(client->adapter, msg, 2); |
868 | if (ret < 0) | 869 | if (ret < 0) { |
870 | dev_err(&client->dev, "%s: error: reg=%x\n", | ||
871 | __func__, reg); | ||
869 | return ret; | 872 | return ret; |
873 | } | ||
870 | 874 | ||
871 | *val = buf[0]; | 875 | *val = buf[0]; |
872 | return 0; | 876 | return 0; |
@@ -880,7 +884,7 @@ static int ov5640_read_reg16(struct ov5640_dev *sensor, u16 reg, u16 *val) | |||
880 | ret = ov5640_read_reg(sensor, reg, &hi); | 884 | ret = ov5640_read_reg(sensor, reg, &hi); |
881 | if (ret) | 885 | if (ret) |
882 | return ret; | 886 | return ret; |
883 | ret = ov5640_read_reg(sensor, reg+1, &lo); | 887 | ret = ov5640_read_reg(sensor, reg + 1, &lo); |
884 | if (ret) | 888 | if (ret) |
885 | return ret; | 889 | return ret; |
886 | 890 | ||
@@ -941,7 +945,7 @@ static int ov5640_load_regs(struct ov5640_dev *sensor, | |||
941 | break; | 945 | break; |
942 | 946 | ||
943 | if (delay_ms) | 947 | if (delay_ms) |
944 | usleep_range(1000*delay_ms, 1000*delay_ms+100); | 948 | usleep_range(1000 * delay_ms, 1000 * delay_ms + 100); |
945 | } | 949 | } |
946 | 950 | ||
947 | return ret; | 951 | return ret; |
@@ -1283,7 +1287,6 @@ static int ov5640_set_bandingfilter(struct ov5640_dev *sensor) | |||
1283 | return ret; | 1287 | return ret; |
1284 | prev_vts = ret; | 1288 | prev_vts = ret; |
1285 | 1289 | ||
1286 | |||
1287 | /* calculate banding filter */ | 1290 | /* calculate banding filter */ |
1288 | /* 60Hz */ | 1291 | /* 60Hz */ |
1289 | band_step60 = sensor->prev_sysclk * 100 / sensor->prev_hts * 100 / 120; | 1292 | band_step60 = sensor->prev_sysclk * 100 / sensor->prev_hts * 100 / 120; |
@@ -1355,11 +1358,16 @@ static int ov5640_binning_on(struct ov5640_dev *sensor) | |||
1355 | 1358 | ||
1356 | static int ov5640_set_virtual_channel(struct ov5640_dev *sensor) | 1359 | static int ov5640_set_virtual_channel(struct ov5640_dev *sensor) |
1357 | { | 1360 | { |
1361 | struct i2c_client *client = sensor->i2c_client; | ||
1358 | u8 temp, channel = virtual_channel; | 1362 | u8 temp, channel = virtual_channel; |
1359 | int ret; | 1363 | int ret; |
1360 | 1364 | ||
1361 | if (channel > 3) | 1365 | if (channel > 3) { |
1366 | dev_err(&client->dev, | ||
1367 | "%s: wrong virtual_channel parameter, expected (0..3), got %d\n", | ||
1368 | __func__, channel); | ||
1362 | return -EINVAL; | 1369 | return -EINVAL; |
1370 | } | ||
1363 | 1371 | ||
1364 | ret = ov5640_read_reg(sensor, OV5640_REG_DEBUG_MODE, &temp); | 1372 | ret = ov5640_read_reg(sensor, OV5640_REG_DEBUG_MODE, &temp); |
1365 | if (ret) | 1373 | if (ret) |
@@ -1399,8 +1407,8 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr, | |||
1399 | * sensor changes between scaling and subsampling, go through | 1407 | * sensor changes between scaling and subsampling, go through |
1400 | * exposure calculation | 1408 | * exposure calculation |
1401 | */ | 1409 | */ |
1402 | static int ov5640_set_mode_exposure_calc( | 1410 | static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor, |
1403 | struct ov5640_dev *sensor, const struct ov5640_mode_info *mode) | 1411 | const struct ov5640_mode_info *mode) |
1404 | { | 1412 | { |
1405 | u32 prev_shutter, prev_gain16; | 1413 | u32 prev_shutter, prev_gain16; |
1406 | u32 cap_shutter, cap_gain16; | 1414 | u32 cap_shutter, cap_gain16; |
@@ -1410,7 +1418,7 @@ static int ov5640_set_mode_exposure_calc( | |||
1410 | u8 average; | 1418 | u8 average; |
1411 | int ret; | 1419 | int ret; |
1412 | 1420 | ||
1413 | if (mode->reg_data == NULL) | 1421 | if (!mode->reg_data) |
1414 | return -EINVAL; | 1422 | return -EINVAL; |
1415 | 1423 | ||
1416 | /* read preview shutter */ | 1424 | /* read preview shutter */ |
@@ -1564,7 +1572,7 @@ static int ov5640_set_mode_direct(struct ov5640_dev *sensor, | |||
1564 | { | 1572 | { |
1565 | int ret; | 1573 | int ret; |
1566 | 1574 | ||
1567 | if (mode->reg_data == NULL) | 1575 | if (!mode->reg_data) |
1568 | return -EINVAL; | 1576 | return -EINVAL; |
1569 | 1577 | ||
1570 | /* Write capture setting */ | 1578 | /* Write capture setting */ |
@@ -1915,6 +1923,7 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor, | |||
1915 | { | 1923 | { |
1916 | int ret = 0; | 1924 | int ret = 0; |
1917 | bool is_rgb = false; | 1925 | bool is_rgb = false; |
1926 | bool is_jpeg = false; | ||
1918 | u8 val; | 1927 | u8 val; |
1919 | 1928 | ||
1920 | switch (format->code) { | 1929 | switch (format->code) { |
@@ -1936,6 +1945,11 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor, | |||
1936 | val = 0x61; | 1945 | val = 0x61; |
1937 | is_rgb = true; | 1946 | is_rgb = true; |
1938 | break; | 1947 | break; |
1948 | case MEDIA_BUS_FMT_JPEG_1X8: | ||
1949 | /* YUV422, YUYV */ | ||
1950 | val = 0x30; | ||
1951 | is_jpeg = true; | ||
1952 | break; | ||
1939 | default: | 1953 | default: |
1940 | return -EINVAL; | 1954 | return -EINVAL; |
1941 | } | 1955 | } |
@@ -1946,8 +1960,40 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor, | |||
1946 | return ret; | 1960 | return ret; |
1947 | 1961 | ||
1948 | /* FORMAT MUX CONTROL: ISP YUV or RGB */ | 1962 | /* FORMAT MUX CONTROL: ISP YUV or RGB */ |
1949 | return ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL, | 1963 | ret = ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL, |
1950 | is_rgb ? 0x01 : 0x00); | 1964 | is_rgb ? 0x01 : 0x00); |
1965 | if (ret) | ||
1966 | return ret; | ||
1967 | |||
1968 | /* | ||
1969 | * TIMING TC REG21: | ||
1970 | * - [5]: JPEG enable | ||
1971 | */ | ||
1972 | ret = ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21, | ||
1973 | BIT(5), is_jpeg ? BIT(5) : 0); | ||
1974 | if (ret) | ||
1975 | return ret; | ||
1976 | |||
1977 | /* | ||
1978 | * SYSTEM RESET02: | ||
1979 | * - [4]: Reset JFIFO | ||
1980 | * - [3]: Reset SFIFO | ||
1981 | * - [2]: Reset JPEG | ||
1982 | */ | ||
1983 | ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_RESET02, | ||
1984 | BIT(4) | BIT(3) | BIT(2), | ||
1985 | is_jpeg ? 0 : (BIT(4) | BIT(3) | BIT(2))); | ||
1986 | if (ret) | ||
1987 | return ret; | ||
1988 | |||
1989 | /* | ||
1990 | * CLOCK ENABLE02: | ||
1991 | * - [5]: Enable JPEG 2x clock | ||
1992 | * - [3]: Enable JPEG clock | ||
1993 | */ | ||
1994 | return ov5640_mod_reg(sensor, OV5640_REG_SYS_CLOCK_ENABLE02, | ||
1995 | BIT(5) | BIT(3), | ||
1996 | is_jpeg ? (BIT(5) | BIT(3)) : 0); | ||
1951 | } | 1997 | } |
1952 | 1998 | ||
1953 | /* | 1999 | /* |
@@ -2073,7 +2119,8 @@ static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, int auto_gain) | |||
2073 | 2119 | ||
2074 | if (ctrls->auto_gain->is_new) { | 2120 | if (ctrls->auto_gain->is_new) { |
2075 | ret = ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL, | 2121 | ret = ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL, |
2076 | BIT(1), ctrls->auto_gain->val ? 0 : BIT(1)); | 2122 | BIT(1), |
2123 | ctrls->auto_gain->val ? 0 : BIT(1)); | ||
2077 | if (ret) | 2124 | if (ret) |
2078 | return ret; | 2125 | return ret; |
2079 | } | 2126 | } |
@@ -2253,10 +2300,12 @@ static int ov5640_enum_frame_size(struct v4l2_subdev *sd, | |||
2253 | if (fse->index >= OV5640_NUM_MODES) | 2300 | if (fse->index >= OV5640_NUM_MODES) |
2254 | return -EINVAL; | 2301 | return -EINVAL; |
2255 | 2302 | ||
2256 | fse->min_width = fse->max_width = | 2303 | fse->min_width = |
2257 | ov5640_mode_data[0][fse->index].width; | 2304 | ov5640_mode_data[0][fse->index].width; |
2258 | fse->min_height = fse->max_height = | 2305 | fse->max_width = fse->min_width; |
2306 | fse->min_height = | ||
2259 | ov5640_mode_data[0][fse->index].height; | 2307 | ov5640_mode_data[0][fse->index].height; |
2308 | fse->max_height = fse->min_height; | ||
2260 | 2309 | ||
2261 | return 0; | 2310 | return 0; |
2262 | } | 2311 | } |
@@ -2325,6 +2374,8 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd, | |||
2325 | 2374 | ||
2326 | sensor->current_fr = frame_rate; | 2375 | sensor->current_fr = frame_rate; |
2327 | sensor->frame_interval = fi->interval; | 2376 | sensor->frame_interval = fi->interval; |
2377 | sensor->current_mode = ov5640_find_mode(sensor, frame_rate, mode->width, | ||
2378 | mode->height, true); | ||
2328 | sensor->pending_mode_change = true; | 2379 | sensor->pending_mode_change = true; |
2329 | out: | 2380 | out: |
2330 | mutex_unlock(&sensor->lock); | 2381 | mutex_unlock(&sensor->lock); |
@@ -2332,8 +2383,8 @@ out: | |||
2332 | } | 2383 | } |
2333 | 2384 | ||
2334 | static int ov5640_enum_mbus_code(struct v4l2_subdev *sd, | 2385 | static int ov5640_enum_mbus_code(struct v4l2_subdev *sd, |
2335 | struct v4l2_subdev_pad_config *cfg, | 2386 | struct v4l2_subdev_pad_config *cfg, |
2336 | struct v4l2_subdev_mbus_code_enum *code) | 2387 | struct v4l2_subdev_mbus_code_enum *code) |
2337 | { | 2388 | { |
2338 | if (code->pad != 0) | 2389 | if (code->pad != 0) |
2339 | return -EINVAL; | 2390 | return -EINVAL; |
diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 9f9196568eb8..d2db480da1b9 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c | |||
@@ -1853,8 +1853,8 @@ static int ov5670_read_reg(struct ov5670 *ov5670, u16 reg, unsigned int len, | |||
1853 | struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); | 1853 | struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); |
1854 | struct i2c_msg msgs[2]; | 1854 | struct i2c_msg msgs[2]; |
1855 | u8 *data_be_p; | 1855 | u8 *data_be_p; |
1856 | u32 data_be = 0; | 1856 | __be32 data_be = 0; |
1857 | u16 reg_addr_be = cpu_to_be16(reg); | 1857 | __be16 reg_addr_be = cpu_to_be16(reg); |
1858 | int ret; | 1858 | int ret; |
1859 | 1859 | ||
1860 | if (len > 4) | 1860 | if (len > 4) |
@@ -1891,6 +1891,7 @@ static int ov5670_write_reg(struct ov5670 *ov5670, u16 reg, unsigned int len, | |||
1891 | int val_i; | 1891 | int val_i; |
1892 | u8 buf[6]; | 1892 | u8 buf[6]; |
1893 | u8 *val_p; | 1893 | u8 *val_p; |
1894 | __be32 tmp; | ||
1894 | 1895 | ||
1895 | if (len > 4) | 1896 | if (len > 4) |
1896 | return -EINVAL; | 1897 | return -EINVAL; |
@@ -1898,8 +1899,8 @@ static int ov5670_write_reg(struct ov5670 *ov5670, u16 reg, unsigned int len, | |||
1898 | buf[0] = reg >> 8; | 1899 | buf[0] = reg >> 8; |
1899 | buf[1] = reg & 0xff; | 1900 | buf[1] = reg & 0xff; |
1900 | 1901 | ||
1901 | val = cpu_to_be32(val); | 1902 | tmp = cpu_to_be32(val); |
1902 | val_p = (u8 *)&val; | 1903 | val_p = (u8 *)&tmp; |
1903 | buf_i = 2; | 1904 | buf_i = 2; |
1904 | val_i = 4 - len; | 1905 | val_i = 4 - len; |
1905 | 1906 | ||
@@ -2180,36 +2181,6 @@ static int ov5670_enum_frame_size(struct v4l2_subdev *sd, | |||
2180 | return 0; | 2181 | return 0; |
2181 | } | 2182 | } |
2182 | 2183 | ||
2183 | /* Calculate resolution distance */ | ||
2184 | static int ov5670_get_reso_dist(const struct ov5670_mode *mode, | ||
2185 | struct v4l2_mbus_framefmt *framefmt) | ||
2186 | { | ||
2187 | return abs(mode->width - framefmt->width) + | ||
2188 | abs(mode->height - framefmt->height); | ||
2189 | } | ||
2190 | |||
2191 | /* Find the closest supported resolution to the requested resolution */ | ||
2192 | static const struct ov5670_mode *ov5670_find_best_fit( | ||
2193 | struct ov5670 *ov5670, | ||
2194 | struct v4l2_subdev_format *fmt) | ||
2195 | { | ||
2196 | struct v4l2_mbus_framefmt *framefmt = &fmt->format; | ||
2197 | int dist; | ||
2198 | int cur_best_fit = 0; | ||
2199 | int cur_best_fit_dist = -1; | ||
2200 | int i; | ||
2201 | |||
2202 | for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { | ||
2203 | dist = ov5670_get_reso_dist(&supported_modes[i], framefmt); | ||
2204 | if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { | ||
2205 | cur_best_fit_dist = dist; | ||
2206 | cur_best_fit = i; | ||
2207 | } | ||
2208 | } | ||
2209 | |||
2210 | return &supported_modes[cur_best_fit]; | ||
2211 | } | ||
2212 | |||
2213 | static void ov5670_update_pad_format(const struct ov5670_mode *mode, | 2184 | static void ov5670_update_pad_format(const struct ov5670_mode *mode, |
2214 | struct v4l2_subdev_format *fmt) | 2185 | struct v4l2_subdev_format *fmt) |
2215 | { | 2186 | { |
@@ -2259,7 +2230,8 @@ static int ov5670_set_pad_format(struct v4l2_subdev *sd, | |||
2259 | 2230 | ||
2260 | fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; | 2231 | fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
2261 | 2232 | ||
2262 | mode = ov5670_find_best_fit(ov5670, fmt); | 2233 | mode = v4l2_find_nearest_size(supported_modes, width, height, |
2234 | fmt->format.width, fmt->format.height); | ||
2263 | ov5670_update_pad_format(mode, fmt); | 2235 | ov5670_update_pad_format(mode, fmt); |
2264 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | 2236 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
2265 | *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; | 2237 | *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; |
diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c new file mode 100644 index 000000000000..9be38a0a2046 --- /dev/null +++ b/drivers/media/i2c/ov5695.c | |||
@@ -0,0 +1,1399 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * ov5695 driver | ||
4 | * | ||
5 | * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk.h> | ||
9 | #include <linux/device.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/gpio/consumer.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/pm_runtime.h> | ||
15 | #include <linux/regulator/consumer.h> | ||
16 | #include <linux/sysfs.h> | ||
17 | #include <media/media-entity.h> | ||
18 | #include <media/v4l2-async.h> | ||
19 | #include <media/v4l2-ctrls.h> | ||
20 | #include <media/v4l2-subdev.h> | ||
21 | |||
22 | #ifndef V4L2_CID_DIGITAL_GAIN | ||
23 | #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN | ||
24 | #endif | ||
25 | |||
26 | /* 45Mhz * 4 Binning */ | ||
27 | #define OV5695_PIXEL_RATE (45 * 1000 * 1000 * 4) | ||
28 | #define OV5695_XVCLK_FREQ 24000000 | ||
29 | |||
30 | #define CHIP_ID 0x005695 | ||
31 | #define OV5695_REG_CHIP_ID 0x300a | ||
32 | |||
33 | #define OV5695_REG_CTRL_MODE 0x0100 | ||
34 | #define OV5695_MODE_SW_STANDBY 0x0 | ||
35 | #define OV5695_MODE_STREAMING BIT(0) | ||
36 | |||
37 | #define OV5695_REG_EXPOSURE 0x3500 | ||
38 | #define OV5695_EXPOSURE_MIN 4 | ||
39 | #define OV5695_EXPOSURE_STEP 1 | ||
40 | #define OV5695_VTS_MAX 0x7fff | ||
41 | |||
42 | #define OV5695_REG_ANALOG_GAIN 0x3509 | ||
43 | #define ANALOG_GAIN_MIN 0x10 | ||
44 | #define ANALOG_GAIN_MAX 0xf8 | ||
45 | #define ANALOG_GAIN_STEP 1 | ||
46 | #define ANALOG_GAIN_DEFAULT 0xf8 | ||
47 | |||
48 | #define OV5695_REG_DIGI_GAIN_H 0x350a | ||
49 | #define OV5695_REG_DIGI_GAIN_L 0x350b | ||
50 | #define OV5695_DIGI_GAIN_L_MASK 0x3f | ||
51 | #define OV5695_DIGI_GAIN_H_SHIFT 6 | ||
52 | #define OV5695_DIGI_GAIN_MIN 0 | ||
53 | #define OV5695_DIGI_GAIN_MAX (0x4000 - 1) | ||
54 | #define OV5695_DIGI_GAIN_STEP 1 | ||
55 | #define OV5695_DIGI_GAIN_DEFAULT 1024 | ||
56 | |||
57 | #define OV5695_REG_TEST_PATTERN 0x4503 | ||
58 | #define OV5695_TEST_PATTERN_ENABLE 0x80 | ||
59 | #define OV5695_TEST_PATTERN_DISABLE 0x0 | ||
60 | |||
61 | #define OV5695_REG_VTS 0x380e | ||
62 | |||
63 | #define REG_NULL 0xFFFF | ||
64 | |||
65 | #define OV5695_REG_VALUE_08BIT 1 | ||
66 | #define OV5695_REG_VALUE_16BIT 2 | ||
67 | #define OV5695_REG_VALUE_24BIT 3 | ||
68 | |||
69 | #define OV5695_LANES 2 | ||
70 | #define OV5695_BITS_PER_SAMPLE 10 | ||
71 | |||
72 | static const char * const ov5695_supply_names[] = { | ||
73 | "avdd", /* Analog power */ | ||
74 | "dovdd", /* Digital I/O power */ | ||
75 | "dvdd", /* Digital core power */ | ||
76 | }; | ||
77 | |||
78 | #define OV5695_NUM_SUPPLIES ARRAY_SIZE(ov5695_supply_names) | ||
79 | |||
80 | struct regval { | ||
81 | u16 addr; | ||
82 | u8 val; | ||
83 | }; | ||
84 | |||
85 | struct ov5695_mode { | ||
86 | u32 width; | ||
87 | u32 height; | ||
88 | u32 max_fps; | ||
89 | u32 hts_def; | ||
90 | u32 vts_def; | ||
91 | u32 exp_def; | ||
92 | const struct regval *reg_list; | ||
93 | }; | ||
94 | |||
95 | struct ov5695 { | ||
96 | struct i2c_client *client; | ||
97 | struct clk *xvclk; | ||
98 | struct gpio_desc *reset_gpio; | ||
99 | struct regulator_bulk_data supplies[OV5695_NUM_SUPPLIES]; | ||
100 | |||
101 | struct v4l2_subdev subdev; | ||
102 | struct media_pad pad; | ||
103 | struct v4l2_ctrl_handler ctrl_handler; | ||
104 | struct v4l2_ctrl *exposure; | ||
105 | struct v4l2_ctrl *anal_gain; | ||
106 | struct v4l2_ctrl *digi_gain; | ||
107 | struct v4l2_ctrl *hblank; | ||
108 | struct v4l2_ctrl *vblank; | ||
109 | struct v4l2_ctrl *test_pattern; | ||
110 | struct mutex mutex; | ||
111 | bool streaming; | ||
112 | const struct ov5695_mode *cur_mode; | ||
113 | }; | ||
114 | |||
115 | #define to_ov5695(sd) container_of(sd, struct ov5695, subdev) | ||
116 | |||
117 | /* | ||
118 | * Xclk 24Mhz | ||
119 | * Pclk 45Mhz | ||
120 | * linelength 672(0x2a0) | ||
121 | * framelength 2232(0x8b8) | ||
122 | * grabwindow_width 1296 | ||
123 | * grabwindow_height 972 | ||
124 | * max_framerate 30fps | ||
125 | * mipi_datarate per lane 840Mbps | ||
126 | */ | ||
127 | static const struct regval ov5695_global_regs[] = { | ||
128 | {0x0103, 0x01}, | ||
129 | {0x0100, 0x00}, | ||
130 | {0x0300, 0x04}, | ||
131 | {0x0301, 0x00}, | ||
132 | {0x0302, 0x69}, | ||
133 | {0x0303, 0x00}, | ||
134 | {0x0304, 0x00}, | ||
135 | {0x0305, 0x01}, | ||
136 | {0x0307, 0x00}, | ||
137 | {0x030b, 0x00}, | ||
138 | {0x030c, 0x00}, | ||
139 | {0x030d, 0x1e}, | ||
140 | {0x030e, 0x04}, | ||
141 | {0x030f, 0x03}, | ||
142 | {0x0312, 0x01}, | ||
143 | {0x3000, 0x00}, | ||
144 | {0x3002, 0xa1}, | ||
145 | {0x3008, 0x00}, | ||
146 | {0x3010, 0x00}, | ||
147 | {0x3022, 0x51}, | ||
148 | {0x3106, 0x15}, | ||
149 | {0x3107, 0x01}, | ||
150 | {0x3108, 0x05}, | ||
151 | {0x3500, 0x00}, | ||
152 | {0x3501, 0x45}, | ||
153 | {0x3502, 0x00}, | ||
154 | {0x3503, 0x08}, | ||
155 | {0x3504, 0x03}, | ||
156 | {0x3505, 0x8c}, | ||
157 | {0x3507, 0x03}, | ||
158 | {0x3508, 0x00}, | ||
159 | {0x3509, 0x10}, | ||
160 | {0x350c, 0x00}, | ||
161 | {0x350d, 0x80}, | ||
162 | {0x3510, 0x00}, | ||
163 | {0x3511, 0x02}, | ||
164 | {0x3512, 0x00}, | ||
165 | {0x3601, 0x55}, | ||
166 | {0x3602, 0x58}, | ||
167 | {0x3614, 0x30}, | ||
168 | {0x3615, 0x77}, | ||
169 | {0x3621, 0x08}, | ||
170 | {0x3624, 0x40}, | ||
171 | {0x3633, 0x0c}, | ||
172 | {0x3634, 0x0c}, | ||
173 | {0x3635, 0x0c}, | ||
174 | {0x3636, 0x0c}, | ||
175 | {0x3638, 0x00}, | ||
176 | {0x3639, 0x00}, | ||
177 | {0x363a, 0x00}, | ||
178 | {0x363b, 0x00}, | ||
179 | {0x363c, 0xff}, | ||
180 | {0x363d, 0xfa}, | ||
181 | {0x3650, 0x44}, | ||
182 | {0x3651, 0x44}, | ||
183 | {0x3652, 0x44}, | ||
184 | {0x3653, 0x44}, | ||
185 | {0x3654, 0x44}, | ||
186 | {0x3655, 0x44}, | ||
187 | {0x3656, 0x44}, | ||
188 | {0x3657, 0x44}, | ||
189 | {0x3660, 0x00}, | ||
190 | {0x3661, 0x00}, | ||
191 | {0x3662, 0x00}, | ||
192 | {0x366a, 0x00}, | ||
193 | {0x366e, 0x0c}, | ||
194 | {0x3673, 0x04}, | ||
195 | {0x3700, 0x14}, | ||
196 | {0x3703, 0x0c}, | ||
197 | {0x3715, 0x01}, | ||
198 | {0x3733, 0x10}, | ||
199 | {0x3734, 0x40}, | ||
200 | {0x373f, 0xa0}, | ||
201 | {0x3765, 0x20}, | ||
202 | {0x37a1, 0x1d}, | ||
203 | {0x37a8, 0x26}, | ||
204 | {0x37ab, 0x14}, | ||
205 | {0x37c2, 0x04}, | ||
206 | {0x37cb, 0x09}, | ||
207 | {0x37cc, 0x13}, | ||
208 | {0x37cd, 0x1f}, | ||
209 | {0x37ce, 0x1f}, | ||
210 | {0x3800, 0x00}, | ||
211 | {0x3801, 0x00}, | ||
212 | {0x3802, 0x00}, | ||
213 | {0x3803, 0x00}, | ||
214 | {0x3804, 0x0a}, | ||
215 | {0x3805, 0x3f}, | ||
216 | {0x3806, 0x07}, | ||
217 | {0x3807, 0xaf}, | ||
218 | {0x3808, 0x05}, | ||
219 | {0x3809, 0x10}, | ||
220 | {0x380a, 0x03}, | ||
221 | {0x380b, 0xcc}, | ||
222 | {0x380c, 0x02}, | ||
223 | {0x380d, 0xa0}, | ||
224 | {0x380e, 0x08}, | ||
225 | {0x380f, 0xb8}, | ||
226 | {0x3810, 0x00}, | ||
227 | {0x3811, 0x06}, | ||
228 | {0x3812, 0x00}, | ||
229 | {0x3813, 0x06}, | ||
230 | {0x3814, 0x03}, | ||
231 | {0x3815, 0x01}, | ||
232 | {0x3816, 0x03}, | ||
233 | {0x3817, 0x01}, | ||
234 | {0x3818, 0x00}, | ||
235 | {0x3819, 0x00}, | ||
236 | {0x381a, 0x00}, | ||
237 | {0x381b, 0x01}, | ||
238 | {0x3820, 0x8b}, | ||
239 | {0x3821, 0x01}, | ||
240 | {0x3c80, 0x08}, | ||
241 | {0x3c82, 0x00}, | ||
242 | {0x3c83, 0x00}, | ||
243 | {0x3c88, 0x00}, | ||
244 | {0x3d85, 0x14}, | ||
245 | {0x3f02, 0x08}, | ||
246 | {0x3f03, 0x10}, | ||
247 | {0x4008, 0x02}, | ||
248 | {0x4009, 0x09}, | ||
249 | {0x404e, 0x20}, | ||
250 | {0x4501, 0x00}, | ||
251 | {0x4502, 0x10}, | ||
252 | {0x4800, 0x00}, | ||
253 | {0x481f, 0x2a}, | ||
254 | {0x4837, 0x13}, | ||
255 | {0x5000, 0x17}, | ||
256 | {0x5780, 0x3e}, | ||
257 | {0x5781, 0x0f}, | ||
258 | {0x5782, 0x44}, | ||
259 | {0x5783, 0x02}, | ||
260 | {0x5784, 0x01}, | ||
261 | {0x5785, 0x01}, | ||
262 | {0x5786, 0x00}, | ||
263 | {0x5787, 0x04}, | ||
264 | {0x5788, 0x02}, | ||
265 | {0x5789, 0x0f}, | ||
266 | {0x578a, 0xfd}, | ||
267 | {0x578b, 0xf5}, | ||
268 | {0x578c, 0xf5}, | ||
269 | {0x578d, 0x03}, | ||
270 | {0x578e, 0x08}, | ||
271 | {0x578f, 0x0c}, | ||
272 | {0x5790, 0x08}, | ||
273 | {0x5791, 0x06}, | ||
274 | {0x5792, 0x00}, | ||
275 | {0x5793, 0x52}, | ||
276 | {0x5794, 0xa3}, | ||
277 | {0x5b00, 0x00}, | ||
278 | {0x5b01, 0x1c}, | ||
279 | {0x5b02, 0x00}, | ||
280 | {0x5b03, 0x7f}, | ||
281 | {0x5b05, 0x6c}, | ||
282 | {0x5e10, 0xfc}, | ||
283 | {0x4010, 0xf1}, | ||
284 | {0x3503, 0x08}, | ||
285 | {0x3505, 0x8c}, | ||
286 | {0x3507, 0x03}, | ||
287 | {0x3508, 0x00}, | ||
288 | {0x3509, 0xf8}, | ||
289 | {REG_NULL, 0x00}, | ||
290 | }; | ||
291 | |||
292 | /* | ||
293 | * Xclk 24Mhz | ||
294 | * Pclk 45Mhz | ||
295 | * linelength 740(0x2e4) | ||
296 | * framelength 2024(0x7e8) | ||
297 | * grabwindow_width 2592 | ||
298 | * grabwindow_height 1944 | ||
299 | * max_framerate 30fps | ||
300 | * mipi_datarate per lane 840Mbps | ||
301 | */ | ||
302 | static const struct regval ov5695_2592x1944_regs[] = { | ||
303 | {0x3501, 0x7e}, | ||
304 | {0x366e, 0x18}, | ||
305 | {0x3800, 0x00}, | ||
306 | {0x3801, 0x00}, | ||
307 | {0x3802, 0x00}, | ||
308 | {0x3803, 0x04}, | ||
309 | {0x3804, 0x0a}, | ||
310 | {0x3805, 0x3f}, | ||
311 | {0x3806, 0x07}, | ||
312 | {0x3807, 0xab}, | ||
313 | {0x3808, 0x0a}, | ||
314 | {0x3809, 0x20}, | ||
315 | {0x380a, 0x07}, | ||
316 | {0x380b, 0x98}, | ||
317 | {0x380c, 0x02}, | ||
318 | {0x380d, 0xe4}, | ||
319 | {0x380e, 0x07}, | ||
320 | {0x380f, 0xe8}, | ||
321 | {0x3811, 0x06}, | ||
322 | {0x3813, 0x08}, | ||
323 | {0x3814, 0x01}, | ||
324 | {0x3816, 0x01}, | ||
325 | {0x3817, 0x01}, | ||
326 | {0x3820, 0x88}, | ||
327 | {0x3821, 0x00}, | ||
328 | {0x4501, 0x00}, | ||
329 | {0x4008, 0x04}, | ||
330 | {0x4009, 0x13}, | ||
331 | {REG_NULL, 0x00}, | ||
332 | }; | ||
333 | |||
334 | /* | ||
335 | * Xclk 24Mhz | ||
336 | * Pclk 45Mhz | ||
337 | * linelength 672(0x2a0) | ||
338 | * framelength 2232(0x8b8) | ||
339 | * grabwindow_width 1920 | ||
340 | * grabwindow_height 1080 | ||
341 | * max_framerate 30fps | ||
342 | * mipi_datarate per lane 840Mbps | ||
343 | */ | ||
344 | static const struct regval ov5695_1920x1080_regs[] = { | ||
345 | {0x3501, 0x45}, | ||
346 | {0x366e, 0x18}, | ||
347 | {0x3800, 0x01}, | ||
348 | {0x3801, 0x50}, | ||
349 | {0x3802, 0x01}, | ||
350 | {0x3803, 0xb8}, | ||
351 | {0x3804, 0x08}, | ||
352 | {0x3805, 0xef}, | ||
353 | {0x3806, 0x05}, | ||
354 | {0x3807, 0xf7}, | ||
355 | {0x3808, 0x07}, | ||
356 | {0x3809, 0x80}, | ||
357 | {0x380a, 0x04}, | ||
358 | {0x380b, 0x38}, | ||
359 | {0x380c, 0x02}, | ||
360 | {0x380d, 0xa0}, | ||
361 | {0x380e, 0x08}, | ||
362 | {0x380f, 0xb8}, | ||
363 | {0x3811, 0x06}, | ||
364 | {0x3813, 0x04}, | ||
365 | {0x3814, 0x01}, | ||
366 | {0x3816, 0x01}, | ||
367 | {0x3817, 0x01}, | ||
368 | {0x3820, 0x88}, | ||
369 | {0x3821, 0x00}, | ||
370 | {0x4501, 0x00}, | ||
371 | {0x4008, 0x04}, | ||
372 | {0x4009, 0x13}, | ||
373 | {REG_NULL, 0x00} | ||
374 | }; | ||
375 | |||
376 | /* | ||
377 | * Xclk 24Mhz | ||
378 | * Pclk 45Mhz | ||
379 | * linelength 740(0x02e4) | ||
380 | * framelength 1012(0x03f4) | ||
381 | * grabwindow_width 1296 | ||
382 | * grabwindow_height 972 | ||
383 | * max_framerate 60fps | ||
384 | * mipi_datarate per lane 840Mbps | ||
385 | */ | ||
386 | static const struct regval ov5695_1296x972_regs[] = { | ||
387 | {0x0103, 0x01}, | ||
388 | {0x0100, 0x00}, | ||
389 | {0x0300, 0x04}, | ||
390 | {0x0301, 0x00}, | ||
391 | {0x0302, 0x69}, | ||
392 | {0x0303, 0x00}, | ||
393 | {0x0304, 0x00}, | ||
394 | {0x0305, 0x01}, | ||
395 | {0x0307, 0x00}, | ||
396 | {0x030b, 0x00}, | ||
397 | {0x030c, 0x00}, | ||
398 | {0x030d, 0x1e}, | ||
399 | {0x030e, 0x04}, | ||
400 | {0x030f, 0x03}, | ||
401 | {0x0312, 0x01}, | ||
402 | {0x3000, 0x00}, | ||
403 | {0x3002, 0xa1}, | ||
404 | {0x3008, 0x00}, | ||
405 | {0x3010, 0x00}, | ||
406 | {0x3016, 0x32}, | ||
407 | {0x3022, 0x51}, | ||
408 | {0x3106, 0x15}, | ||
409 | {0x3107, 0x01}, | ||
410 | {0x3108, 0x05}, | ||
411 | {0x3500, 0x00}, | ||
412 | {0x3501, 0x3e}, | ||
413 | {0x3502, 0x00}, | ||
414 | {0x3503, 0x08}, | ||
415 | {0x3504, 0x03}, | ||
416 | {0x3505, 0x8c}, | ||
417 | {0x3507, 0x03}, | ||
418 | {0x3508, 0x00}, | ||
419 | {0x3509, 0x10}, | ||
420 | {0x350c, 0x00}, | ||
421 | {0x350d, 0x80}, | ||
422 | {0x3510, 0x00}, | ||
423 | {0x3511, 0x02}, | ||
424 | {0x3512, 0x00}, | ||
425 | {0x3601, 0x55}, | ||
426 | {0x3602, 0x58}, | ||
427 | {0x3611, 0x58}, | ||
428 | {0x3614, 0x30}, | ||
429 | {0x3615, 0x77}, | ||
430 | {0x3621, 0x08}, | ||
431 | {0x3624, 0x40}, | ||
432 | {0x3633, 0x0c}, | ||
433 | {0x3634, 0x0c}, | ||
434 | {0x3635, 0x0c}, | ||
435 | {0x3636, 0x0c}, | ||
436 | {0x3638, 0x00}, | ||
437 | {0x3639, 0x00}, | ||
438 | {0x363a, 0x00}, | ||
439 | {0x363b, 0x00}, | ||
440 | {0x363c, 0xff}, | ||
441 | {0x363d, 0xfa}, | ||
442 | {0x3650, 0x44}, | ||
443 | {0x3651, 0x44}, | ||
444 | {0x3652, 0x44}, | ||
445 | {0x3653, 0x44}, | ||
446 | {0x3654, 0x44}, | ||
447 | {0x3655, 0x44}, | ||
448 | {0x3656, 0x44}, | ||
449 | {0x3657, 0x44}, | ||
450 | {0x3660, 0x00}, | ||
451 | {0x3661, 0x00}, | ||
452 | {0x3662, 0x00}, | ||
453 | {0x366a, 0x00}, | ||
454 | {0x366e, 0x0c}, | ||
455 | {0x3673, 0x04}, | ||
456 | {0x3700, 0x14}, | ||
457 | {0x3703, 0x0c}, | ||
458 | {0x3706, 0x24}, | ||
459 | {0x3714, 0x27}, | ||
460 | {0x3715, 0x01}, | ||
461 | {0x3716, 0x00}, | ||
462 | {0x3717, 0x02}, | ||
463 | {0x3733, 0x10}, | ||
464 | {0x3734, 0x40}, | ||
465 | {0x373f, 0xa0}, | ||
466 | {0x3765, 0x20}, | ||
467 | {0x37a1, 0x1d}, | ||
468 | {0x37a8, 0x26}, | ||
469 | {0x37ab, 0x14}, | ||
470 | {0x37c2, 0x04}, | ||
471 | {0x37c3, 0xf0}, | ||
472 | {0x37cb, 0x09}, | ||
473 | {0x37cc, 0x13}, | ||
474 | {0x37cd, 0x1f}, | ||
475 | {0x37ce, 0x1f}, | ||
476 | {0x3800, 0x00}, | ||
477 | {0x3801, 0x00}, | ||
478 | {0x3802, 0x00}, | ||
479 | {0x3803, 0x00}, | ||
480 | {0x3804, 0x0a}, | ||
481 | {0x3805, 0x3f}, | ||
482 | {0x3806, 0x07}, | ||
483 | {0x3807, 0xaf}, | ||
484 | {0x3808, 0x05}, | ||
485 | {0x3809, 0x10}, | ||
486 | {0x380a, 0x03}, | ||
487 | {0x380b, 0xcc}, | ||
488 | {0x380c, 0x02}, | ||
489 | {0x380d, 0xe4}, | ||
490 | {0x380e, 0x03}, | ||
491 | {0x380f, 0xf4}, | ||
492 | {0x3810, 0x00}, | ||
493 | {0x3811, 0x00}, | ||
494 | {0x3812, 0x00}, | ||
495 | {0x3813, 0x06}, | ||
496 | {0x3814, 0x03}, | ||
497 | {0x3815, 0x01}, | ||
498 | {0x3816, 0x03}, | ||
499 | {0x3817, 0x01}, | ||
500 | {0x3818, 0x00}, | ||
501 | {0x3819, 0x00}, | ||
502 | {0x381a, 0x00}, | ||
503 | {0x381b, 0x01}, | ||
504 | {0x3820, 0x8b}, | ||
505 | {0x3821, 0x01}, | ||
506 | {0x3c80, 0x08}, | ||
507 | {0x3c82, 0x00}, | ||
508 | {0x3c83, 0x00}, | ||
509 | {0x3c88, 0x00}, | ||
510 | {0x3d85, 0x14}, | ||
511 | {0x3f02, 0x08}, | ||
512 | {0x3f03, 0x10}, | ||
513 | {0x4008, 0x02}, | ||
514 | {0x4009, 0x09}, | ||
515 | {0x404e, 0x20}, | ||
516 | {0x4501, 0x00}, | ||
517 | {0x4502, 0x10}, | ||
518 | {0x4800, 0x00}, | ||
519 | {0x481f, 0x2a}, | ||
520 | {0x4837, 0x13}, | ||
521 | {0x5000, 0x13}, | ||
522 | {0x5780, 0x3e}, | ||
523 | {0x5781, 0x0f}, | ||
524 | {0x5782, 0x44}, | ||
525 | {0x5783, 0x02}, | ||
526 | {0x5784, 0x01}, | ||
527 | {0x5785, 0x01}, | ||
528 | {0x5786, 0x00}, | ||
529 | {0x5787, 0x04}, | ||
530 | {0x5788, 0x02}, | ||
531 | {0x5789, 0x0f}, | ||
532 | {0x578a, 0xfd}, | ||
533 | {0x578b, 0xf5}, | ||
534 | {0x578c, 0xf5}, | ||
535 | {0x578d, 0x03}, | ||
536 | {0x578e, 0x08}, | ||
537 | {0x578f, 0x0c}, | ||
538 | {0x5790, 0x08}, | ||
539 | {0x5791, 0x06}, | ||
540 | {0x5792, 0x00}, | ||
541 | {0x5793, 0x52}, | ||
542 | {0x5794, 0xa3}, | ||
543 | {0x5b00, 0x00}, | ||
544 | {0x5b01, 0x1c}, | ||
545 | {0x5b02, 0x00}, | ||
546 | {0x5b03, 0x7f}, | ||
547 | {0x5b05, 0x6c}, | ||
548 | {0x5e10, 0xfc}, | ||
549 | {0x4010, 0xf1}, | ||
550 | {0x3503, 0x08}, | ||
551 | {0x3505, 0x8c}, | ||
552 | {0x3507, 0x03}, | ||
553 | {0x3508, 0x00}, | ||
554 | {0x3509, 0xf8}, | ||
555 | {0x0100, 0x01}, | ||
556 | {REG_NULL, 0x00} | ||
557 | }; | ||
558 | |||
559 | /* | ||
560 | * Xclk 24Mhz | ||
561 | * Pclk 45Mhz | ||
562 | * linelength 672(0x2a0) | ||
563 | * framelength 2232(0x8b8) | ||
564 | * grabwindow_width 1280 | ||
565 | * grabwindow_height 720 | ||
566 | * max_framerate 30fps | ||
567 | * mipi_datarate per lane 840Mbps | ||
568 | */ | ||
569 | static const struct regval ov5695_1280x720_regs[] = { | ||
570 | {0x3501, 0x45}, | ||
571 | {0x366e, 0x0c}, | ||
572 | {0x3800, 0x00}, | ||
573 | {0x3801, 0x00}, | ||
574 | {0x3802, 0x01}, | ||
575 | {0x3803, 0x00}, | ||
576 | {0x3804, 0x0a}, | ||
577 | {0x3805, 0x3f}, | ||
578 | {0x3806, 0x06}, | ||
579 | {0x3807, 0xaf}, | ||
580 | {0x3808, 0x05}, | ||
581 | {0x3809, 0x00}, | ||
582 | {0x380a, 0x02}, | ||
583 | {0x380b, 0xd0}, | ||
584 | {0x380c, 0x02}, | ||
585 | {0x380d, 0xa0}, | ||
586 | {0x380e, 0x08}, | ||
587 | {0x380f, 0xb8}, | ||
588 | {0x3811, 0x06}, | ||
589 | {0x3813, 0x02}, | ||
590 | {0x3814, 0x03}, | ||
591 | {0x3816, 0x03}, | ||
592 | {0x3817, 0x01}, | ||
593 | {0x3820, 0x8b}, | ||
594 | {0x3821, 0x01}, | ||
595 | {0x4501, 0x00}, | ||
596 | {0x4008, 0x02}, | ||
597 | {0x4009, 0x09}, | ||
598 | {REG_NULL, 0x00} | ||
599 | }; | ||
600 | |||
601 | /* | ||
602 | * Xclk 24Mhz | ||
603 | * Pclk 45Mhz | ||
604 | * linelength 672(0x2a0) | ||
605 | * framelength 558(0x22e) | ||
606 | * grabwindow_width 640 | ||
607 | * grabwindow_height 480 | ||
608 | * max_framerate 120fps | ||
609 | * mipi_datarate per lane 840Mbps | ||
610 | */ | ||
611 | static const struct regval ov5695_640x480_regs[] = { | ||
612 | {0x3501, 0x22}, | ||
613 | {0x366e, 0x0c}, | ||
614 | {0x3800, 0x00}, | ||
615 | {0x3801, 0x00}, | ||
616 | {0x3802, 0x00}, | ||
617 | {0x3803, 0x08}, | ||
618 | {0x3804, 0x0a}, | ||
619 | {0x3805, 0x3f}, | ||
620 | {0x3806, 0x07}, | ||
621 | {0x3807, 0xa7}, | ||
622 | {0x3808, 0x02}, | ||
623 | {0x3809, 0x80}, | ||
624 | {0x380a, 0x01}, | ||
625 | {0x380b, 0xe0}, | ||
626 | {0x380c, 0x02}, | ||
627 | {0x380d, 0xa0}, | ||
628 | {0x380e, 0x02}, | ||
629 | {0x380f, 0x2e}, | ||
630 | {0x3811, 0x06}, | ||
631 | {0x3813, 0x04}, | ||
632 | {0x3814, 0x07}, | ||
633 | {0x3816, 0x05}, | ||
634 | {0x3817, 0x03}, | ||
635 | {0x3820, 0x8d}, | ||
636 | {0x3821, 0x01}, | ||
637 | {0x4501, 0x00}, | ||
638 | {0x4008, 0x02}, | ||
639 | {0x4009, 0x09}, | ||
640 | {REG_NULL, 0x00} | ||
641 | }; | ||
642 | |||
643 | static const struct ov5695_mode supported_modes[] = { | ||
644 | { | ||
645 | .width = 2592, | ||
646 | .height = 1944, | ||
647 | .max_fps = 30, | ||
648 | .exp_def = 0x0450, | ||
649 | .hts_def = 0x02e4 * 4, | ||
650 | .vts_def = 0x07e8, | ||
651 | .reg_list = ov5695_2592x1944_regs, | ||
652 | }, | ||
653 | { | ||
654 | .width = 1920, | ||
655 | .height = 1080, | ||
656 | .max_fps = 30, | ||
657 | .exp_def = 0x0450, | ||
658 | .hts_def = 0x02a0 * 4, | ||
659 | .vts_def = 0x08b8, | ||
660 | .reg_list = ov5695_1920x1080_regs, | ||
661 | }, | ||
662 | { | ||
663 | .width = 1296, | ||
664 | .height = 972, | ||
665 | .max_fps = 60, | ||
666 | .exp_def = 0x03e0, | ||
667 | .hts_def = 0x02e4 * 4, | ||
668 | .vts_def = 0x03f4, | ||
669 | .reg_list = ov5695_1296x972_regs, | ||
670 | }, | ||
671 | { | ||
672 | .width = 1280, | ||
673 | .height = 720, | ||
674 | .max_fps = 30, | ||
675 | .exp_def = 0x0450, | ||
676 | .hts_def = 0x02a0 * 4, | ||
677 | .vts_def = 0x08b8, | ||
678 | .reg_list = ov5695_1280x720_regs, | ||
679 | }, | ||
680 | { | ||
681 | .width = 640, | ||
682 | .height = 480, | ||
683 | .max_fps = 120, | ||
684 | .exp_def = 0x0450, | ||
685 | .hts_def = 0x02a0 * 4, | ||
686 | .vts_def = 0x022e, | ||
687 | .reg_list = ov5695_640x480_regs, | ||
688 | }, | ||
689 | }; | ||
690 | |||
691 | #define OV5695_LINK_FREQ_420MHZ 420000000 | ||
692 | static const s64 link_freq_menu_items[] = { | ||
693 | OV5695_LINK_FREQ_420MHZ | ||
694 | }; | ||
695 | |||
696 | static const char * const ov5695_test_pattern_menu[] = { | ||
697 | "Disabled", | ||
698 | "Vertical Color Bar Type 1", | ||
699 | "Vertical Color Bar Type 2", | ||
700 | "Vertical Color Bar Type 3", | ||
701 | "Vertical Color Bar Type 4" | ||
702 | }; | ||
703 | |||
704 | /* Write registers up to 4 at a time */ | ||
705 | static int ov5695_write_reg(struct i2c_client *client, u16 reg, | ||
706 | u32 len, u32 val) | ||
707 | { | ||
708 | u32 buf_i, val_i; | ||
709 | u8 buf[6]; | ||
710 | u8 *val_p; | ||
711 | __be32 val_be; | ||
712 | |||
713 | if (len > 4) | ||
714 | return -EINVAL; | ||
715 | |||
716 | buf[0] = reg >> 8; | ||
717 | buf[1] = reg & 0xff; | ||
718 | |||
719 | val_be = cpu_to_be32(val); | ||
720 | val_p = (u8 *)&val_be; | ||
721 | buf_i = 2; | ||
722 | val_i = 4 - len; | ||
723 | |||
724 | while (val_i < 4) | ||
725 | buf[buf_i++] = val_p[val_i++]; | ||
726 | |||
727 | if (i2c_master_send(client, buf, len + 2) != len + 2) | ||
728 | return -EIO; | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | static int ov5695_write_array(struct i2c_client *client, | ||
734 | const struct regval *regs) | ||
735 | { | ||
736 | u32 i; | ||
737 | int ret = 0; | ||
738 | |||
739 | for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) | ||
740 | ret = ov5695_write_reg(client, regs[i].addr, | ||
741 | OV5695_REG_VALUE_08BIT, regs[i].val); | ||
742 | |||
743 | return ret; | ||
744 | } | ||
745 | |||
746 | /* Read registers up to 4 at a time */ | ||
747 | static int ov5695_read_reg(struct i2c_client *client, u16 reg, unsigned int len, | ||
748 | u32 *val) | ||
749 | { | ||
750 | struct i2c_msg msgs[2]; | ||
751 | u8 *data_be_p; | ||
752 | __be32 data_be = 0; | ||
753 | __be16 reg_addr_be = cpu_to_be16(reg); | ||
754 | int ret; | ||
755 | |||
756 | if (len > 4) | ||
757 | return -EINVAL; | ||
758 | |||
759 | data_be_p = (u8 *)&data_be; | ||
760 | /* Write register address */ | ||
761 | msgs[0].addr = client->addr; | ||
762 | msgs[0].flags = 0; | ||
763 | msgs[0].len = 2; | ||
764 | msgs[0].buf = (u8 *)®_addr_be; | ||
765 | |||
766 | /* Read data from register */ | ||
767 | msgs[1].addr = client->addr; | ||
768 | msgs[1].flags = I2C_M_RD; | ||
769 | msgs[1].len = len; | ||
770 | msgs[1].buf = &data_be_p[4 - len]; | ||
771 | |||
772 | ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); | ||
773 | if (ret != ARRAY_SIZE(msgs)) | ||
774 | return -EIO; | ||
775 | |||
776 | *val = be32_to_cpu(data_be); | ||
777 | |||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | static int ov5695_get_reso_dist(const struct ov5695_mode *mode, | ||
782 | struct v4l2_mbus_framefmt *framefmt) | ||
783 | { | ||
784 | return abs(mode->width - framefmt->width) + | ||
785 | abs(mode->height - framefmt->height); | ||
786 | } | ||
787 | |||
788 | static const struct ov5695_mode * | ||
789 | ov5695_find_best_fit(struct v4l2_subdev_format *fmt) | ||
790 | { | ||
791 | struct v4l2_mbus_framefmt *framefmt = &fmt->format; | ||
792 | int dist; | ||
793 | int cur_best_fit = 0; | ||
794 | int cur_best_fit_dist = -1; | ||
795 | int i; | ||
796 | |||
797 | for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { | ||
798 | dist = ov5695_get_reso_dist(&supported_modes[i], framefmt); | ||
799 | if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { | ||
800 | cur_best_fit_dist = dist; | ||
801 | cur_best_fit = i; | ||
802 | } | ||
803 | } | ||
804 | |||
805 | return &supported_modes[cur_best_fit]; | ||
806 | } | ||
807 | |||
808 | static int ov5695_set_fmt(struct v4l2_subdev *sd, | ||
809 | struct v4l2_subdev_pad_config *cfg, | ||
810 | struct v4l2_subdev_format *fmt) | ||
811 | { | ||
812 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
813 | const struct ov5695_mode *mode; | ||
814 | s64 h_blank, vblank_def; | ||
815 | |||
816 | mutex_lock(&ov5695->mutex); | ||
817 | |||
818 | mode = ov5695_find_best_fit(fmt); | ||
819 | fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
820 | fmt->format.width = mode->width; | ||
821 | fmt->format.height = mode->height; | ||
822 | fmt->format.field = V4L2_FIELD_NONE; | ||
823 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
824 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
825 | *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; | ||
826 | #else | ||
827 | mutex_unlock(&ov5695->mutex); | ||
828 | return -ENOTTY; | ||
829 | #endif | ||
830 | } else { | ||
831 | ov5695->cur_mode = mode; | ||
832 | h_blank = mode->hts_def - mode->width; | ||
833 | __v4l2_ctrl_modify_range(ov5695->hblank, h_blank, | ||
834 | h_blank, 1, h_blank); | ||
835 | vblank_def = mode->vts_def - mode->height; | ||
836 | __v4l2_ctrl_modify_range(ov5695->vblank, vblank_def, | ||
837 | OV5695_VTS_MAX - mode->height, | ||
838 | 1, vblank_def); | ||
839 | } | ||
840 | |||
841 | mutex_unlock(&ov5695->mutex); | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | static int ov5695_get_fmt(struct v4l2_subdev *sd, | ||
847 | struct v4l2_subdev_pad_config *cfg, | ||
848 | struct v4l2_subdev_format *fmt) | ||
849 | { | ||
850 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
851 | const struct ov5695_mode *mode = ov5695->cur_mode; | ||
852 | |||
853 | mutex_lock(&ov5695->mutex); | ||
854 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
855 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
856 | fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); | ||
857 | #else | ||
858 | mutex_unlock(&ov5695->mutex); | ||
859 | return -ENOTTY; | ||
860 | #endif | ||
861 | } else { | ||
862 | fmt->format.width = mode->width; | ||
863 | fmt->format.height = mode->height; | ||
864 | fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
865 | fmt->format.field = V4L2_FIELD_NONE; | ||
866 | } | ||
867 | mutex_unlock(&ov5695->mutex); | ||
868 | |||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | static int ov5695_enum_mbus_code(struct v4l2_subdev *sd, | ||
873 | struct v4l2_subdev_pad_config *cfg, | ||
874 | struct v4l2_subdev_mbus_code_enum *code) | ||
875 | { | ||
876 | if (code->index != 0) | ||
877 | return -EINVAL; | ||
878 | code->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
879 | |||
880 | return 0; | ||
881 | } | ||
882 | |||
883 | static int ov5695_enum_frame_sizes(struct v4l2_subdev *sd, | ||
884 | struct v4l2_subdev_pad_config *cfg, | ||
885 | struct v4l2_subdev_frame_size_enum *fse) | ||
886 | { | ||
887 | if (fse->index >= ARRAY_SIZE(supported_modes)) | ||
888 | return -EINVAL; | ||
889 | |||
890 | if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10) | ||
891 | return -EINVAL; | ||
892 | |||
893 | fse->min_width = supported_modes[fse->index].width; | ||
894 | fse->max_width = supported_modes[fse->index].width; | ||
895 | fse->max_height = supported_modes[fse->index].height; | ||
896 | fse->min_height = supported_modes[fse->index].height; | ||
897 | |||
898 | return 0; | ||
899 | } | ||
900 | |||
901 | static int ov5695_enable_test_pattern(struct ov5695 *ov5695, u32 pattern) | ||
902 | { | ||
903 | u32 val; | ||
904 | |||
905 | if (pattern) | ||
906 | val = (pattern - 1) | OV5695_TEST_PATTERN_ENABLE; | ||
907 | else | ||
908 | val = OV5695_TEST_PATTERN_DISABLE; | ||
909 | |||
910 | return ov5695_write_reg(ov5695->client, OV5695_REG_TEST_PATTERN, | ||
911 | OV5695_REG_VALUE_08BIT, val); | ||
912 | } | ||
913 | |||
914 | static int __ov5695_start_stream(struct ov5695 *ov5695) | ||
915 | { | ||
916 | int ret; | ||
917 | |||
918 | ret = ov5695_write_array(ov5695->client, ov5695_global_regs); | ||
919 | if (ret) | ||
920 | return ret; | ||
921 | ret = ov5695_write_array(ov5695->client, ov5695->cur_mode->reg_list); | ||
922 | if (ret) | ||
923 | return ret; | ||
924 | |||
925 | /* In case these controls are set before streaming */ | ||
926 | ret = __v4l2_ctrl_handler_setup(&ov5695->ctrl_handler); | ||
927 | if (ret) | ||
928 | return ret; | ||
929 | |||
930 | return ov5695_write_reg(ov5695->client, OV5695_REG_CTRL_MODE, | ||
931 | OV5695_REG_VALUE_08BIT, OV5695_MODE_STREAMING); | ||
932 | } | ||
933 | |||
934 | static int __ov5695_stop_stream(struct ov5695 *ov5695) | ||
935 | { | ||
936 | return ov5695_write_reg(ov5695->client, OV5695_REG_CTRL_MODE, | ||
937 | OV5695_REG_VALUE_08BIT, OV5695_MODE_SW_STANDBY); | ||
938 | } | ||
939 | |||
940 | static int ov5695_s_stream(struct v4l2_subdev *sd, int on) | ||
941 | { | ||
942 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
943 | struct i2c_client *client = ov5695->client; | ||
944 | int ret = 0; | ||
945 | |||
946 | mutex_lock(&ov5695->mutex); | ||
947 | on = !!on; | ||
948 | if (on == ov5695->streaming) | ||
949 | goto unlock_and_return; | ||
950 | |||
951 | if (on) { | ||
952 | ret = pm_runtime_get_sync(&client->dev); | ||
953 | if (ret < 0) { | ||
954 | pm_runtime_put_noidle(&client->dev); | ||
955 | goto unlock_and_return; | ||
956 | } | ||
957 | |||
958 | ret = __ov5695_start_stream(ov5695); | ||
959 | if (ret) { | ||
960 | v4l2_err(sd, "start stream failed while write regs\n"); | ||
961 | pm_runtime_put(&client->dev); | ||
962 | goto unlock_and_return; | ||
963 | } | ||
964 | } else { | ||
965 | __ov5695_stop_stream(ov5695); | ||
966 | pm_runtime_put(&client->dev); | ||
967 | } | ||
968 | |||
969 | ov5695->streaming = on; | ||
970 | |||
971 | unlock_and_return: | ||
972 | mutex_unlock(&ov5695->mutex); | ||
973 | |||
974 | return ret; | ||
975 | } | ||
976 | |||
977 | /* Calculate the delay in us by clock rate and clock cycles */ | ||
978 | static inline u32 ov5695_cal_delay(u32 cycles) | ||
979 | { | ||
980 | return DIV_ROUND_UP(cycles, OV5695_XVCLK_FREQ / 1000 / 1000); | ||
981 | } | ||
982 | |||
983 | static int __ov5695_power_on(struct ov5695 *ov5695) | ||
984 | { | ||
985 | int ret; | ||
986 | u32 delay_us; | ||
987 | struct device *dev = &ov5695->client->dev; | ||
988 | |||
989 | ret = clk_prepare_enable(ov5695->xvclk); | ||
990 | if (ret < 0) { | ||
991 | dev_err(dev, "Failed to enable xvclk\n"); | ||
992 | return ret; | ||
993 | } | ||
994 | |||
995 | gpiod_set_value_cansleep(ov5695->reset_gpio, 1); | ||
996 | |||
997 | ret = regulator_bulk_enable(OV5695_NUM_SUPPLIES, ov5695->supplies); | ||
998 | if (ret < 0) { | ||
999 | dev_err(dev, "Failed to enable regulators\n"); | ||
1000 | goto disable_clk; | ||
1001 | } | ||
1002 | |||
1003 | gpiod_set_value_cansleep(ov5695->reset_gpio, 0); | ||
1004 | |||
1005 | /* 8192 cycles prior to first SCCB transaction */ | ||
1006 | delay_us = ov5695_cal_delay(8192); | ||
1007 | usleep_range(delay_us, delay_us * 2); | ||
1008 | |||
1009 | return 0; | ||
1010 | |||
1011 | disable_clk: | ||
1012 | clk_disable_unprepare(ov5695->xvclk); | ||
1013 | |||
1014 | return ret; | ||
1015 | } | ||
1016 | |||
1017 | static void __ov5695_power_off(struct ov5695 *ov5695) | ||
1018 | { | ||
1019 | clk_disable_unprepare(ov5695->xvclk); | ||
1020 | gpiod_set_value_cansleep(ov5695->reset_gpio, 1); | ||
1021 | regulator_bulk_disable(OV5695_NUM_SUPPLIES, ov5695->supplies); | ||
1022 | } | ||
1023 | |||
1024 | static int __maybe_unused ov5695_runtime_resume(struct device *dev) | ||
1025 | { | ||
1026 | struct i2c_client *client = to_i2c_client(dev); | ||
1027 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
1028 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
1029 | |||
1030 | return __ov5695_power_on(ov5695); | ||
1031 | } | ||
1032 | |||
1033 | static int __maybe_unused ov5695_runtime_suspend(struct device *dev) | ||
1034 | { | ||
1035 | struct i2c_client *client = to_i2c_client(dev); | ||
1036 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
1037 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
1038 | |||
1039 | __ov5695_power_off(ov5695); | ||
1040 | |||
1041 | return 0; | ||
1042 | } | ||
1043 | |||
1044 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
1045 | static int ov5695_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
1046 | { | ||
1047 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
1048 | struct v4l2_mbus_framefmt *try_fmt = | ||
1049 | v4l2_subdev_get_try_format(sd, fh->pad, 0); | ||
1050 | const struct ov5695_mode *def_mode = &supported_modes[0]; | ||
1051 | |||
1052 | mutex_lock(&ov5695->mutex); | ||
1053 | /* Initialize try_fmt */ | ||
1054 | try_fmt->width = def_mode->width; | ||
1055 | try_fmt->height = def_mode->height; | ||
1056 | try_fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
1057 | try_fmt->field = V4L2_FIELD_NONE; | ||
1058 | |||
1059 | mutex_unlock(&ov5695->mutex); | ||
1060 | /* No crop or compose */ | ||
1061 | |||
1062 | return 0; | ||
1063 | } | ||
1064 | #endif | ||
1065 | |||
1066 | static const struct dev_pm_ops ov5695_pm_ops = { | ||
1067 | SET_RUNTIME_PM_OPS(ov5695_runtime_suspend, | ||
1068 | ov5695_runtime_resume, NULL) | ||
1069 | }; | ||
1070 | |||
1071 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
1072 | static const struct v4l2_subdev_internal_ops ov5695_internal_ops = { | ||
1073 | .open = ov5695_open, | ||
1074 | }; | ||
1075 | #endif | ||
1076 | |||
1077 | static const struct v4l2_subdev_video_ops ov5695_video_ops = { | ||
1078 | .s_stream = ov5695_s_stream, | ||
1079 | }; | ||
1080 | |||
1081 | static const struct v4l2_subdev_pad_ops ov5695_pad_ops = { | ||
1082 | .enum_mbus_code = ov5695_enum_mbus_code, | ||
1083 | .enum_frame_size = ov5695_enum_frame_sizes, | ||
1084 | .get_fmt = ov5695_get_fmt, | ||
1085 | .set_fmt = ov5695_set_fmt, | ||
1086 | }; | ||
1087 | |||
1088 | static const struct v4l2_subdev_ops ov5695_subdev_ops = { | ||
1089 | .video = &ov5695_video_ops, | ||
1090 | .pad = &ov5695_pad_ops, | ||
1091 | }; | ||
1092 | |||
1093 | static int ov5695_set_ctrl(struct v4l2_ctrl *ctrl) | ||
1094 | { | ||
1095 | struct ov5695 *ov5695 = container_of(ctrl->handler, | ||
1096 | struct ov5695, ctrl_handler); | ||
1097 | struct i2c_client *client = ov5695->client; | ||
1098 | s64 max; | ||
1099 | int ret = 0; | ||
1100 | |||
1101 | /* Propagate change of current control to all related controls */ | ||
1102 | switch (ctrl->id) { | ||
1103 | case V4L2_CID_VBLANK: | ||
1104 | /* Update max exposure while meeting expected vblanking */ | ||
1105 | max = ov5695->cur_mode->height + ctrl->val - 4; | ||
1106 | __v4l2_ctrl_modify_range(ov5695->exposure, | ||
1107 | ov5695->exposure->minimum, max, | ||
1108 | ov5695->exposure->step, | ||
1109 | ov5695->exposure->default_value); | ||
1110 | break; | ||
1111 | } | ||
1112 | |||
1113 | if (pm_runtime_get_if_in_use(&client->dev) <= 0) | ||
1114 | return 0; | ||
1115 | |||
1116 | switch (ctrl->id) { | ||
1117 | case V4L2_CID_EXPOSURE: | ||
1118 | /* 4 least significant bits of expsoure are fractional part */ | ||
1119 | ret = ov5695_write_reg(ov5695->client, OV5695_REG_EXPOSURE, | ||
1120 | OV5695_REG_VALUE_24BIT, ctrl->val << 4); | ||
1121 | break; | ||
1122 | case V4L2_CID_ANALOGUE_GAIN: | ||
1123 | ret = ov5695_write_reg(ov5695->client, OV5695_REG_ANALOG_GAIN, | ||
1124 | OV5695_REG_VALUE_08BIT, ctrl->val); | ||
1125 | break; | ||
1126 | case V4L2_CID_DIGITAL_GAIN: | ||
1127 | ret = ov5695_write_reg(ov5695->client, OV5695_REG_DIGI_GAIN_L, | ||
1128 | OV5695_REG_VALUE_08BIT, | ||
1129 | ctrl->val & OV5695_DIGI_GAIN_L_MASK); | ||
1130 | ret = ov5695_write_reg(ov5695->client, OV5695_REG_DIGI_GAIN_H, | ||
1131 | OV5695_REG_VALUE_08BIT, | ||
1132 | ctrl->val >> OV5695_DIGI_GAIN_H_SHIFT); | ||
1133 | break; | ||
1134 | case V4L2_CID_VBLANK: | ||
1135 | ret = ov5695_write_reg(ov5695->client, OV5695_REG_VTS, | ||
1136 | OV5695_REG_VALUE_16BIT, | ||
1137 | ctrl->val + ov5695->cur_mode->height); | ||
1138 | break; | ||
1139 | case V4L2_CID_TEST_PATTERN: | ||
1140 | ret = ov5695_enable_test_pattern(ov5695, ctrl->val); | ||
1141 | break; | ||
1142 | default: | ||
1143 | dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", | ||
1144 | __func__, ctrl->id, ctrl->val); | ||
1145 | break; | ||
1146 | }; | ||
1147 | |||
1148 | pm_runtime_put(&client->dev); | ||
1149 | |||
1150 | return ret; | ||
1151 | } | ||
1152 | |||
1153 | static const struct v4l2_ctrl_ops ov5695_ctrl_ops = { | ||
1154 | .s_ctrl = ov5695_set_ctrl, | ||
1155 | }; | ||
1156 | |||
1157 | static int ov5695_initialize_controls(struct ov5695 *ov5695) | ||
1158 | { | ||
1159 | const struct ov5695_mode *mode; | ||
1160 | struct v4l2_ctrl_handler *handler; | ||
1161 | struct v4l2_ctrl *ctrl; | ||
1162 | s64 exposure_max, vblank_def; | ||
1163 | u32 h_blank; | ||
1164 | int ret; | ||
1165 | |||
1166 | handler = &ov5695->ctrl_handler; | ||
1167 | mode = ov5695->cur_mode; | ||
1168 | ret = v4l2_ctrl_handler_init(handler, 8); | ||
1169 | if (ret) | ||
1170 | return ret; | ||
1171 | handler->lock = &ov5695->mutex; | ||
1172 | |||
1173 | ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, | ||
1174 | 0, 0, link_freq_menu_items); | ||
1175 | if (ctrl) | ||
1176 | ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
1177 | |||
1178 | v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, | ||
1179 | 0, OV5695_PIXEL_RATE, 1, OV5695_PIXEL_RATE); | ||
1180 | |||
1181 | h_blank = mode->hts_def - mode->width; | ||
1182 | ov5695->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, | ||
1183 | h_blank, h_blank, 1, h_blank); | ||
1184 | if (ov5695->hblank) | ||
1185 | ov5695->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||
1186 | |||
1187 | vblank_def = mode->vts_def - mode->height; | ||
1188 | ov5695->vblank = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops, | ||
1189 | V4L2_CID_VBLANK, vblank_def, | ||
1190 | OV5695_VTS_MAX - mode->height, | ||
1191 | 1, vblank_def); | ||
1192 | |||
1193 | exposure_max = mode->vts_def - 4; | ||
1194 | ov5695->exposure = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops, | ||
1195 | V4L2_CID_EXPOSURE, OV5695_EXPOSURE_MIN, | ||
1196 | exposure_max, OV5695_EXPOSURE_STEP, | ||
1197 | mode->exp_def); | ||
1198 | |||
1199 | ov5695->anal_gain = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops, | ||
1200 | V4L2_CID_ANALOGUE_GAIN, ANALOG_GAIN_MIN, | ||
1201 | ANALOG_GAIN_MAX, ANALOG_GAIN_STEP, | ||
1202 | ANALOG_GAIN_DEFAULT); | ||
1203 | |||
1204 | /* Digital gain */ | ||
1205 | ov5695->digi_gain = v4l2_ctrl_new_std(handler, &ov5695_ctrl_ops, | ||
1206 | V4L2_CID_DIGITAL_GAIN, OV5695_DIGI_GAIN_MIN, | ||
1207 | OV5695_DIGI_GAIN_MAX, OV5695_DIGI_GAIN_STEP, | ||
1208 | OV5695_DIGI_GAIN_DEFAULT); | ||
1209 | |||
1210 | ov5695->test_pattern = v4l2_ctrl_new_std_menu_items(handler, | ||
1211 | &ov5695_ctrl_ops, V4L2_CID_TEST_PATTERN, | ||
1212 | ARRAY_SIZE(ov5695_test_pattern_menu) - 1, | ||
1213 | 0, 0, ov5695_test_pattern_menu); | ||
1214 | |||
1215 | if (handler->error) { | ||
1216 | ret = handler->error; | ||
1217 | dev_err(&ov5695->client->dev, | ||
1218 | "Failed to init controls(%d)\n", ret); | ||
1219 | goto err_free_handler; | ||
1220 | } | ||
1221 | |||
1222 | ov5695->subdev.ctrl_handler = handler; | ||
1223 | |||
1224 | return 0; | ||
1225 | |||
1226 | err_free_handler: | ||
1227 | v4l2_ctrl_handler_free(handler); | ||
1228 | |||
1229 | return ret; | ||
1230 | } | ||
1231 | |||
1232 | static int ov5695_check_sensor_id(struct ov5695 *ov5695, | ||
1233 | struct i2c_client *client) | ||
1234 | { | ||
1235 | struct device *dev = &ov5695->client->dev; | ||
1236 | u32 id = 0; | ||
1237 | int ret; | ||
1238 | |||
1239 | ret = ov5695_read_reg(client, OV5695_REG_CHIP_ID, | ||
1240 | OV5695_REG_VALUE_24BIT, &id); | ||
1241 | if (id != CHIP_ID) { | ||
1242 | dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); | ||
1243 | return ret; | ||
1244 | } | ||
1245 | |||
1246 | dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID); | ||
1247 | |||
1248 | return 0; | ||
1249 | } | ||
1250 | |||
1251 | static int ov5695_configure_regulators(struct ov5695 *ov5695) | ||
1252 | { | ||
1253 | int i; | ||
1254 | |||
1255 | for (i = 0; i < OV5695_NUM_SUPPLIES; i++) | ||
1256 | ov5695->supplies[i].supply = ov5695_supply_names[i]; | ||
1257 | |||
1258 | return devm_regulator_bulk_get(&ov5695->client->dev, | ||
1259 | OV5695_NUM_SUPPLIES, | ||
1260 | ov5695->supplies); | ||
1261 | } | ||
1262 | |||
1263 | static int ov5695_probe(struct i2c_client *client, | ||
1264 | const struct i2c_device_id *id) | ||
1265 | { | ||
1266 | struct device *dev = &client->dev; | ||
1267 | struct ov5695 *ov5695; | ||
1268 | struct v4l2_subdev *sd; | ||
1269 | int ret; | ||
1270 | |||
1271 | ov5695 = devm_kzalloc(dev, sizeof(*ov5695), GFP_KERNEL); | ||
1272 | if (!ov5695) | ||
1273 | return -ENOMEM; | ||
1274 | |||
1275 | ov5695->client = client; | ||
1276 | ov5695->cur_mode = &supported_modes[0]; | ||
1277 | |||
1278 | ov5695->xvclk = devm_clk_get(dev, "xvclk"); | ||
1279 | if (IS_ERR(ov5695->xvclk)) { | ||
1280 | dev_err(dev, "Failed to get xvclk\n"); | ||
1281 | return -EINVAL; | ||
1282 | } | ||
1283 | ret = clk_set_rate(ov5695->xvclk, OV5695_XVCLK_FREQ); | ||
1284 | if (ret < 0) { | ||
1285 | dev_err(dev, "Failed to set xvclk rate (24MHz)\n"); | ||
1286 | return ret; | ||
1287 | } | ||
1288 | if (clk_get_rate(ov5695->xvclk) != OV5695_XVCLK_FREQ) | ||
1289 | dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); | ||
1290 | |||
1291 | ov5695->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); | ||
1292 | if (IS_ERR(ov5695->reset_gpio)) { | ||
1293 | dev_err(dev, "Failed to get reset-gpios\n"); | ||
1294 | return -EINVAL; | ||
1295 | } | ||
1296 | |||
1297 | ret = ov5695_configure_regulators(ov5695); | ||
1298 | if (ret) { | ||
1299 | dev_err(dev, "Failed to get power regulators\n"); | ||
1300 | return ret; | ||
1301 | } | ||
1302 | |||
1303 | mutex_init(&ov5695->mutex); | ||
1304 | |||
1305 | sd = &ov5695->subdev; | ||
1306 | v4l2_i2c_subdev_init(sd, client, &ov5695_subdev_ops); | ||
1307 | ret = ov5695_initialize_controls(ov5695); | ||
1308 | if (ret) | ||
1309 | goto err_destroy_mutex; | ||
1310 | |||
1311 | ret = __ov5695_power_on(ov5695); | ||
1312 | if (ret) | ||
1313 | goto err_free_handler; | ||
1314 | |||
1315 | ret = ov5695_check_sensor_id(ov5695, client); | ||
1316 | if (ret) | ||
1317 | goto err_power_off; | ||
1318 | |||
1319 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | ||
1320 | sd->internal_ops = &ov5695_internal_ops; | ||
1321 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
1322 | #endif | ||
1323 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1324 | ov5695->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
1325 | sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; | ||
1326 | ret = media_entity_pads_init(&sd->entity, 1, &ov5695->pad); | ||
1327 | if (ret < 0) | ||
1328 | goto err_power_off; | ||
1329 | #endif | ||
1330 | |||
1331 | ret = v4l2_async_register_subdev(sd); | ||
1332 | if (ret) { | ||
1333 | dev_err(dev, "v4l2 async register subdev failed\n"); | ||
1334 | goto err_clean_entity; | ||
1335 | } | ||
1336 | |||
1337 | pm_runtime_set_active(dev); | ||
1338 | pm_runtime_enable(dev); | ||
1339 | pm_runtime_idle(dev); | ||
1340 | |||
1341 | return 0; | ||
1342 | |||
1343 | err_clean_entity: | ||
1344 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1345 | media_entity_cleanup(&sd->entity); | ||
1346 | #endif | ||
1347 | err_power_off: | ||
1348 | __ov5695_power_off(ov5695); | ||
1349 | err_free_handler: | ||
1350 | v4l2_ctrl_handler_free(&ov5695->ctrl_handler); | ||
1351 | err_destroy_mutex: | ||
1352 | mutex_destroy(&ov5695->mutex); | ||
1353 | |||
1354 | return ret; | ||
1355 | } | ||
1356 | |||
1357 | static int ov5695_remove(struct i2c_client *client) | ||
1358 | { | ||
1359 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
1360 | struct ov5695 *ov5695 = to_ov5695(sd); | ||
1361 | |||
1362 | v4l2_async_unregister_subdev(sd); | ||
1363 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1364 | media_entity_cleanup(&sd->entity); | ||
1365 | #endif | ||
1366 | v4l2_ctrl_handler_free(&ov5695->ctrl_handler); | ||
1367 | mutex_destroy(&ov5695->mutex); | ||
1368 | |||
1369 | pm_runtime_disable(&client->dev); | ||
1370 | if (!pm_runtime_status_suspended(&client->dev)) | ||
1371 | __ov5695_power_off(ov5695); | ||
1372 | pm_runtime_set_suspended(&client->dev); | ||
1373 | |||
1374 | return 0; | ||
1375 | } | ||
1376 | |||
1377 | #if IS_ENABLED(CONFIG_OF) | ||
1378 | static const struct of_device_id ov5695_of_match[] = { | ||
1379 | { .compatible = "ovti,ov5695" }, | ||
1380 | {}, | ||
1381 | }; | ||
1382 | MODULE_DEVICE_TABLE(of, ov5695_of_match); | ||
1383 | #endif | ||
1384 | |||
1385 | static struct i2c_driver ov5695_i2c_driver = { | ||
1386 | .driver = { | ||
1387 | .name = "ov5695", | ||
1388 | .owner = THIS_MODULE, | ||
1389 | .pm = &ov5695_pm_ops, | ||
1390 | .of_match_table = of_match_ptr(ov5695_of_match), | ||
1391 | }, | ||
1392 | .probe = &ov5695_probe, | ||
1393 | .remove = &ov5695_remove, | ||
1394 | }; | ||
1395 | |||
1396 | module_i2c_driver(ov5695_i2c_driver); | ||
1397 | |||
1398 | MODULE_DESCRIPTION("OmniVision ov5695 sensor driver"); | ||
1399 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c index 8975d16b2b24..17a34b4a819d 100644 --- a/drivers/media/i2c/ov6650.c +++ b/drivers/media/i2c/ov6650.c | |||
@@ -201,7 +201,7 @@ struct ov6650 { | |||
201 | struct v4l2_rect rect; /* sensor cropping window */ | 201 | struct v4l2_rect rect; /* sensor cropping window */ |
202 | unsigned long pclk_limit; /* from host */ | 202 | unsigned long pclk_limit; /* from host */ |
203 | unsigned long pclk_max; /* from resolution and format */ | 203 | unsigned long pclk_max; /* from resolution and format */ |
204 | struct v4l2_fract tpf; /* as requested with s_parm */ | 204 | struct v4l2_fract tpf; /* as requested with s_frame_interval */ |
205 | u32 code; | 205 | u32 code; |
206 | enum v4l2_colorspace colorspace; | 206 | enum v4l2_colorspace colorspace; |
207 | }; | 207 | }; |
@@ -723,42 +723,31 @@ static int ov6650_enum_mbus_code(struct v4l2_subdev *sd, | |||
723 | return 0; | 723 | return 0; |
724 | } | 724 | } |
725 | 725 | ||
726 | static int ov6650_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 726 | static int ov6650_g_frame_interval(struct v4l2_subdev *sd, |
727 | struct v4l2_subdev_frame_interval *ival) | ||
727 | { | 728 | { |
728 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 729 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
729 | struct ov6650 *priv = to_ov6650(client); | 730 | struct ov6650 *priv = to_ov6650(client); |
730 | struct v4l2_captureparm *cp = &parms->parm.capture; | ||
731 | 731 | ||
732 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 732 | ival->interval.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf, |
733 | return -EINVAL; | ||
734 | |||
735 | memset(cp, 0, sizeof(*cp)); | ||
736 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
737 | cp->timeperframe.numerator = GET_CLKRC_DIV(to_clkrc(&priv->tpf, | ||
738 | priv->pclk_limit, priv->pclk_max)); | 733 | priv->pclk_limit, priv->pclk_max)); |
739 | cp->timeperframe.denominator = FRAME_RATE_MAX; | 734 | ival->interval.denominator = FRAME_RATE_MAX; |
740 | 735 | ||
741 | dev_dbg(&client->dev, "Frame interval: %u/%u s\n", | 736 | dev_dbg(&client->dev, "Frame interval: %u/%u s\n", |
742 | cp->timeperframe.numerator, cp->timeperframe.denominator); | 737 | ival->interval.numerator, ival->interval.denominator); |
743 | 738 | ||
744 | return 0; | 739 | return 0; |
745 | } | 740 | } |
746 | 741 | ||
747 | static int ov6650_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 742 | static int ov6650_s_frame_interval(struct v4l2_subdev *sd, |
743 | struct v4l2_subdev_frame_interval *ival) | ||
748 | { | 744 | { |
749 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 745 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
750 | struct ov6650 *priv = to_ov6650(client); | 746 | struct ov6650 *priv = to_ov6650(client); |
751 | struct v4l2_captureparm *cp = &parms->parm.capture; | 747 | struct v4l2_fract *tpf = &ival->interval; |
752 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
753 | int div, ret; | 748 | int div, ret; |
754 | u8 clkrc; | 749 | u8 clkrc; |
755 | 750 | ||
756 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
757 | return -EINVAL; | ||
758 | |||
759 | if (cp->extendedmode != 0) | ||
760 | return -EINVAL; | ||
761 | |||
762 | if (tpf->numerator == 0 || tpf->denominator == 0) | 751 | if (tpf->numerator == 0 || tpf->denominator == 0) |
763 | div = 1; /* Reset to full rate */ | 752 | div = 1; /* Reset to full rate */ |
764 | else | 753 | else |
@@ -921,8 +910,8 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd, | |||
921 | 910 | ||
922 | static const struct v4l2_subdev_video_ops ov6650_video_ops = { | 911 | static const struct v4l2_subdev_video_ops ov6650_video_ops = { |
923 | .s_stream = ov6650_s_stream, | 912 | .s_stream = ov6650_s_stream, |
924 | .g_parm = ov6650_g_parm, | 913 | .g_frame_interval = ov6650_g_frame_interval, |
925 | .s_parm = ov6650_s_parm, | 914 | .s_frame_interval = ov6650_s_frame_interval, |
926 | .g_mbus_config = ov6650_g_mbus_config, | 915 | .g_mbus_config = ov6650_g_mbus_config, |
927 | .s_mbus_config = ov6650_s_mbus_config, | 916 | .s_mbus_config = ov6650_s_mbus_config, |
928 | }; | 917 | }; |
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 28571de1c2f6..3474ef832c1e 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/gpio/consumer.h> | 21 | #include <linux/gpio/consumer.h> |
22 | #include <media/v4l2-device.h> | 22 | #include <media/v4l2-device.h> |
23 | #include <media/v4l2-ctrls.h> | 23 | #include <media/v4l2-ctrls.h> |
24 | #include <media/v4l2-fwnode.h> | ||
24 | #include <media/v4l2-mediabus.h> | 25 | #include <media/v4l2-mediabus.h> |
25 | #include <media/v4l2-image-sizes.h> | 26 | #include <media/v4l2-image-sizes.h> |
26 | #include <media/i2c/ov7670.h> | 27 | #include <media/i2c/ov7670.h> |
@@ -242,6 +243,7 @@ struct ov7670_info { | |||
242 | struct clk *clk; | 243 | struct clk *clk; |
243 | struct gpio_desc *resetb_gpio; | 244 | struct gpio_desc *resetb_gpio; |
244 | struct gpio_desc *pwdn_gpio; | 245 | struct gpio_desc *pwdn_gpio; |
246 | unsigned int mbus_config; /* Media bus configuration flags */ | ||
245 | int min_width; /* Filter out smaller sizes */ | 247 | int min_width; /* Filter out smaller sizes */ |
246 | int min_height; /* Filter out smaller sizes */ | 248 | int min_height; /* Filter out smaller sizes */ |
247 | int clock_speed; /* External clock speed (MHz) */ | 249 | int clock_speed; /* External clock speed (MHz) */ |
@@ -1014,7 +1016,7 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, | |||
1014 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API | 1016 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API |
1015 | struct v4l2_mbus_framefmt *mbus_fmt; | 1017 | struct v4l2_mbus_framefmt *mbus_fmt; |
1016 | #endif | 1018 | #endif |
1017 | unsigned char com7; | 1019 | unsigned char com7, com10 = 0; |
1018 | int ret; | 1020 | int ret; |
1019 | 1021 | ||
1020 | if (format->pad) | 1022 | if (format->pad) |
@@ -1034,7 +1036,6 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, | |||
1034 | } | 1036 | } |
1035 | 1037 | ||
1036 | ret = ov7670_try_fmt_internal(sd, &format->format, &ovfmt, &wsize); | 1038 | ret = ov7670_try_fmt_internal(sd, &format->format, &ovfmt, &wsize); |
1037 | |||
1038 | if (ret) | 1039 | if (ret) |
1039 | return ret; | 1040 | return ret; |
1040 | /* | 1041 | /* |
@@ -1045,16 +1046,41 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, | |||
1045 | */ | 1046 | */ |
1046 | com7 = ovfmt->regs[0].value; | 1047 | com7 = ovfmt->regs[0].value; |
1047 | com7 |= wsize->com7_bit; | 1048 | com7 |= wsize->com7_bit; |
1048 | ov7670_write(sd, REG_COM7, com7); | 1049 | ret = ov7670_write(sd, REG_COM7, com7); |
1050 | if (ret) | ||
1051 | return ret; | ||
1052 | |||
1053 | /* | ||
1054 | * Configure the media bus through COM10 register | ||
1055 | */ | ||
1056 | if (info->mbus_config & V4L2_MBUS_VSYNC_ACTIVE_LOW) | ||
1057 | com10 |= COM10_VS_NEG; | ||
1058 | if (info->mbus_config & V4L2_MBUS_HSYNC_ACTIVE_LOW) | ||
1059 | com10 |= COM10_HREF_REV; | ||
1060 | if (info->pclk_hb_disable) | ||
1061 | com10 |= COM10_PCLK_HB; | ||
1062 | ret = ov7670_write(sd, REG_COM10, com10); | ||
1063 | if (ret) | ||
1064 | return ret; | ||
1065 | |||
1049 | /* | 1066 | /* |
1050 | * Now write the rest of the array. Also store start/stops | 1067 | * Now write the rest of the array. Also store start/stops |
1051 | */ | 1068 | */ |
1052 | ov7670_write_array(sd, ovfmt->regs + 1); | 1069 | ret = ov7670_write_array(sd, ovfmt->regs + 1); |
1053 | ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart, | 1070 | if (ret) |
1054 | wsize->vstop); | 1071 | return ret; |
1055 | ret = 0; | 1072 | |
1056 | if (wsize->regs) | 1073 | ret = ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart, |
1074 | wsize->vstop); | ||
1075 | if (ret) | ||
1076 | return ret; | ||
1077 | |||
1078 | if (wsize->regs) { | ||
1057 | ret = ov7670_write_array(sd, wsize->regs); | 1079 | ret = ov7670_write_array(sd, wsize->regs); |
1080 | if (ret) | ||
1081 | return ret; | ||
1082 | } | ||
1083 | |||
1058 | info->fmt = ovfmt; | 1084 | info->fmt = ovfmt; |
1059 | 1085 | ||
1060 | /* | 1086 | /* |
@@ -1067,8 +1093,10 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, | |||
1067 | * to write it unconditionally, and that will make the frame | 1093 | * to write it unconditionally, and that will make the frame |
1068 | * rate persistent too. | 1094 | * rate persistent too. |
1069 | */ | 1095 | */ |
1070 | if (ret == 0) | 1096 | ret = ov7670_write(sd, REG_CLKRC, info->clkrc); |
1071 | ret = ov7670_write(sd, REG_CLKRC, info->clkrc); | 1097 | if (ret) |
1098 | return ret; | ||
1099 | |||
1072 | return 0; | 1100 | return 0; |
1073 | } | 1101 | } |
1074 | 1102 | ||
@@ -1100,30 +1128,24 @@ static int ov7670_get_fmt(struct v4l2_subdev *sd, | |||
1100 | * Implement G/S_PARM. There is a "high quality" mode we could try | 1128 | * Implement G/S_PARM. There is a "high quality" mode we could try |
1101 | * to do someday; for now, we just do the frame rate tweak. | 1129 | * to do someday; for now, we just do the frame rate tweak. |
1102 | */ | 1130 | */ |
1103 | static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 1131 | static int ov7670_g_frame_interval(struct v4l2_subdev *sd, |
1132 | struct v4l2_subdev_frame_interval *ival) | ||
1104 | { | 1133 | { |
1105 | struct v4l2_captureparm *cp = &parms->parm.capture; | ||
1106 | struct ov7670_info *info = to_state(sd); | 1134 | struct ov7670_info *info = to_state(sd); |
1107 | 1135 | ||
1108 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1109 | return -EINVAL; | ||
1110 | 1136 | ||
1111 | cp->capability = V4L2_CAP_TIMEPERFRAME; | 1137 | info->devtype->get_framerate(sd, &ival->interval); |
1112 | info->devtype->get_framerate(sd, &cp->timeperframe); | ||
1113 | 1138 | ||
1114 | return 0; | 1139 | return 0; |
1115 | } | 1140 | } |
1116 | 1141 | ||
1117 | static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 1142 | static int ov7670_s_frame_interval(struct v4l2_subdev *sd, |
1143 | struct v4l2_subdev_frame_interval *ival) | ||
1118 | { | 1144 | { |
1119 | struct v4l2_captureparm *cp = &parms->parm.capture; | 1145 | struct v4l2_fract *tpf = &ival->interval; |
1120 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
1121 | struct ov7670_info *info = to_state(sd); | 1146 | struct ov7670_info *info = to_state(sd); |
1122 | 1147 | ||
1123 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1124 | return -EINVAL; | ||
1125 | 1148 | ||
1126 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
1127 | return info->devtype->set_framerate(sd, tpf); | 1149 | return info->devtype->set_framerate(sd, tpf); |
1128 | } | 1150 | } |
1129 | 1151 | ||
@@ -1636,8 +1658,8 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { | |||
1636 | }; | 1658 | }; |
1637 | 1659 | ||
1638 | static const struct v4l2_subdev_video_ops ov7670_video_ops = { | 1660 | static const struct v4l2_subdev_video_ops ov7670_video_ops = { |
1639 | .s_parm = ov7670_s_parm, | 1661 | .s_frame_interval = ov7670_s_frame_interval, |
1640 | .g_parm = ov7670_g_parm, | 1662 | .g_frame_interval = ov7670_g_frame_interval, |
1641 | }; | 1663 | }; |
1642 | 1664 | ||
1643 | static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { | 1665 | static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { |
@@ -1698,6 +1720,45 @@ static int ov7670_init_gpio(struct i2c_client *client, struct ov7670_info *info) | |||
1698 | return 0; | 1720 | return 0; |
1699 | } | 1721 | } |
1700 | 1722 | ||
1723 | /* | ||
1724 | * ov7670_parse_dt() - Parse device tree to collect mbus configuration | ||
1725 | * properties | ||
1726 | */ | ||
1727 | static int ov7670_parse_dt(struct device *dev, | ||
1728 | struct ov7670_info *info) | ||
1729 | { | ||
1730 | struct fwnode_handle *fwnode = dev_fwnode(dev); | ||
1731 | struct v4l2_fwnode_endpoint bus_cfg; | ||
1732 | struct fwnode_handle *ep; | ||
1733 | int ret; | ||
1734 | |||
1735 | if (!fwnode) | ||
1736 | return -EINVAL; | ||
1737 | |||
1738 | info->pclk_hb_disable = false; | ||
1739 | if (fwnode_property_present(fwnode, "ov7670,pclk-hb-disable")) | ||
1740 | info->pclk_hb_disable = true; | ||
1741 | |||
1742 | ep = fwnode_graph_get_next_endpoint(fwnode, NULL); | ||
1743 | if (!ep) | ||
1744 | return -EINVAL; | ||
1745 | |||
1746 | ret = v4l2_fwnode_endpoint_parse(ep, &bus_cfg); | ||
1747 | if (ret) { | ||
1748 | fwnode_handle_put(ep); | ||
1749 | return ret; | ||
1750 | } | ||
1751 | |||
1752 | if (bus_cfg.bus_type != V4L2_MBUS_PARALLEL) { | ||
1753 | dev_err(dev, "Unsupported media bus type\n"); | ||
1754 | fwnode_handle_put(ep); | ||
1755 | return ret; | ||
1756 | } | ||
1757 | info->mbus_config = bus_cfg.bus.parallel.flags; | ||
1758 | |||
1759 | return 0; | ||
1760 | } | ||
1761 | |||
1701 | static int ov7670_probe(struct i2c_client *client, | 1762 | static int ov7670_probe(struct i2c_client *client, |
1702 | const struct i2c_device_id *id) | 1763 | const struct i2c_device_id *id) |
1703 | { | 1764 | { |
@@ -1718,7 +1779,13 @@ static int ov7670_probe(struct i2c_client *client, | |||
1718 | #endif | 1779 | #endif |
1719 | 1780 | ||
1720 | info->clock_speed = 30; /* default: a guess */ | 1781 | info->clock_speed = 30; /* default: a guess */ |
1721 | if (client->dev.platform_data) { | 1782 | |
1783 | if (dev_fwnode(&client->dev)) { | ||
1784 | ret = ov7670_parse_dt(&client->dev, info); | ||
1785 | if (ret) | ||
1786 | return ret; | ||
1787 | |||
1788 | } else if (client->dev.platform_data) { | ||
1722 | struct ov7670_config *config = client->dev.platform_data; | 1789 | struct ov7670_config *config = client->dev.platform_data; |
1723 | 1790 | ||
1724 | /* | 1791 | /* |
@@ -1785,9 +1852,6 @@ static int ov7670_probe(struct i2c_client *client, | |||
1785 | tpf.denominator = 30; | 1852 | tpf.denominator = 30; |
1786 | info->devtype->set_framerate(sd, &tpf); | 1853 | info->devtype->set_framerate(sd, &tpf); |
1787 | 1854 | ||
1788 | if (info->pclk_hb_disable) | ||
1789 | ov7670_write(sd, REG_COM10, COM10_PCLK_HB); | ||
1790 | |||
1791 | v4l2_ctrl_handler_init(&info->hdl, 10); | 1855 | v4l2_ctrl_handler_init(&info->hdl, 10); |
1792 | v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, | 1856 | v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops, |
1793 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); | 1857 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); |
diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c new file mode 100644 index 000000000000..b62860c89439 --- /dev/null +++ b/drivers/media/i2c/ov772x.c | |||
@@ -0,0 +1,1356 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * ov772x Camera Driver | ||
4 | * | ||
5 | * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org> | ||
6 | * | ||
7 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
8 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
9 | * | ||
10 | * Based on ov7670 and soc_camera_platform driver, | ||
11 | * | ||
12 | * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> | ||
13 | * Copyright (C) 2008 Magnus Damm | ||
14 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/gpio/consumer.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/v4l2-mediabus.h> | ||
26 | #include <linux/videodev2.h> | ||
27 | |||
28 | #include <media/i2c/ov772x.h> | ||
29 | |||
30 | #include <media/v4l2-ctrls.h> | ||
31 | #include <media/v4l2-device.h> | ||
32 | #include <media/v4l2-image-sizes.h> | ||
33 | #include <media/v4l2-subdev.h> | ||
34 | |||
35 | /* | ||
36 | * register offset | ||
37 | */ | ||
38 | #define GAIN 0x00 /* AGC - Gain control gain setting */ | ||
39 | #define BLUE 0x01 /* AWB - Blue channel gain setting */ | ||
40 | #define RED 0x02 /* AWB - Red channel gain setting */ | ||
41 | #define GREEN 0x03 /* AWB - Green channel gain setting */ | ||
42 | #define COM1 0x04 /* Common control 1 */ | ||
43 | #define BAVG 0x05 /* U/B Average Level */ | ||
44 | #define GAVG 0x06 /* Y/Gb Average Level */ | ||
45 | #define RAVG 0x07 /* V/R Average Level */ | ||
46 | #define AECH 0x08 /* Exposure Value - AEC MSBs */ | ||
47 | #define COM2 0x09 /* Common control 2 */ | ||
48 | #define PID 0x0A /* Product ID Number MSB */ | ||
49 | #define VER 0x0B /* Product ID Number LSB */ | ||
50 | #define COM3 0x0C /* Common control 3 */ | ||
51 | #define COM4 0x0D /* Common control 4 */ | ||
52 | #define COM5 0x0E /* Common control 5 */ | ||
53 | #define COM6 0x0F /* Common control 6 */ | ||
54 | #define AEC 0x10 /* Exposure Value */ | ||
55 | #define CLKRC 0x11 /* Internal clock */ | ||
56 | #define COM7 0x12 /* Common control 7 */ | ||
57 | #define COM8 0x13 /* Common control 8 */ | ||
58 | #define COM9 0x14 /* Common control 9 */ | ||
59 | #define COM10 0x15 /* Common control 10 */ | ||
60 | #define REG16 0x16 /* Register 16 */ | ||
61 | #define HSTART 0x17 /* Horizontal sensor size */ | ||
62 | #define HSIZE 0x18 /* Horizontal frame (HREF column) end high 8-bit */ | ||
63 | #define VSTART 0x19 /* Vertical frame (row) start high 8-bit */ | ||
64 | #define VSIZE 0x1A /* Vertical sensor size */ | ||
65 | #define PSHFT 0x1B /* Data format - pixel delay select */ | ||
66 | #define MIDH 0x1C /* Manufacturer ID byte - high */ | ||
67 | #define MIDL 0x1D /* Manufacturer ID byte - low */ | ||
68 | #define LAEC 0x1F /* Fine AEC value */ | ||
69 | #define COM11 0x20 /* Common control 11 */ | ||
70 | #define BDBASE 0x22 /* Banding filter Minimum AEC value */ | ||
71 | #define DBSTEP 0x23 /* Banding filter Maximum Setp */ | ||
72 | #define AEW 0x24 /* AGC/AEC - Stable operating region (upper limit) */ | ||
73 | #define AEB 0x25 /* AGC/AEC - Stable operating region (lower limit) */ | ||
74 | #define VPT 0x26 /* AGC/AEC Fast mode operating region */ | ||
75 | #define REG28 0x28 /* Register 28 */ | ||
76 | #define HOUTSIZE 0x29 /* Horizontal data output size MSBs */ | ||
77 | #define EXHCH 0x2A /* Dummy pixel insert MSB */ | ||
78 | #define EXHCL 0x2B /* Dummy pixel insert LSB */ | ||
79 | #define VOUTSIZE 0x2C /* Vertical data output size MSBs */ | ||
80 | #define ADVFL 0x2D /* LSB of insert dummy lines in Vertical direction */ | ||
81 | #define ADVFH 0x2E /* MSG of insert dummy lines in Vertical direction */ | ||
82 | #define YAVE 0x2F /* Y/G Channel Average value */ | ||
83 | #define LUMHTH 0x30 /* Histogram AEC/AGC Luminance high level threshold */ | ||
84 | #define LUMLTH 0x31 /* Histogram AEC/AGC Luminance low level threshold */ | ||
85 | #define HREF 0x32 /* Image start and size control */ | ||
86 | #define DM_LNL 0x33 /* Dummy line low 8 bits */ | ||
87 | #define DM_LNH 0x34 /* Dummy line high 8 bits */ | ||
88 | #define ADOFF_B 0x35 /* AD offset compensation value for B channel */ | ||
89 | #define ADOFF_R 0x36 /* AD offset compensation value for R channel */ | ||
90 | #define ADOFF_GB 0x37 /* AD offset compensation value for Gb channel */ | ||
91 | #define ADOFF_GR 0x38 /* AD offset compensation value for Gr channel */ | ||
92 | #define OFF_B 0x39 /* Analog process B channel offset value */ | ||
93 | #define OFF_R 0x3A /* Analog process R channel offset value */ | ||
94 | #define OFF_GB 0x3B /* Analog process Gb channel offset value */ | ||
95 | #define OFF_GR 0x3C /* Analog process Gr channel offset value */ | ||
96 | #define COM12 0x3D /* Common control 12 */ | ||
97 | #define COM13 0x3E /* Common control 13 */ | ||
98 | #define COM14 0x3F /* Common control 14 */ | ||
99 | #define COM15 0x40 /* Common control 15*/ | ||
100 | #define COM16 0x41 /* Common control 16 */ | ||
101 | #define TGT_B 0x42 /* BLC blue channel target value */ | ||
102 | #define TGT_R 0x43 /* BLC red channel target value */ | ||
103 | #define TGT_GB 0x44 /* BLC Gb channel target value */ | ||
104 | #define TGT_GR 0x45 /* BLC Gr channel target value */ | ||
105 | /* for ov7720 */ | ||
106 | #define LCC0 0x46 /* Lens correction control 0 */ | ||
107 | #define LCC1 0x47 /* Lens correction option 1 - X coordinate */ | ||
108 | #define LCC2 0x48 /* Lens correction option 2 - Y coordinate */ | ||
109 | #define LCC3 0x49 /* Lens correction option 3 */ | ||
110 | #define LCC4 0x4A /* Lens correction option 4 - radius of the circular */ | ||
111 | #define LCC5 0x4B /* Lens correction option 5 */ | ||
112 | #define LCC6 0x4C /* Lens correction option 6 */ | ||
113 | /* for ov7725 */ | ||
114 | #define LC_CTR 0x46 /* Lens correction control */ | ||
115 | #define LC_XC 0x47 /* X coordinate of lens correction center relative */ | ||
116 | #define LC_YC 0x48 /* Y coordinate of lens correction center relative */ | ||
117 | #define LC_COEF 0x49 /* Lens correction coefficient */ | ||
118 | #define LC_RADI 0x4A /* Lens correction radius */ | ||
119 | #define LC_COEFB 0x4B /* Lens B channel compensation coefficient */ | ||
120 | #define LC_COEFR 0x4C /* Lens R channel compensation coefficient */ | ||
121 | |||
122 | #define FIXGAIN 0x4D /* Analog fix gain amplifer */ | ||
123 | #define AREF0 0x4E /* Sensor reference control */ | ||
124 | #define AREF1 0x4F /* Sensor reference current control */ | ||
125 | #define AREF2 0x50 /* Analog reference control */ | ||
126 | #define AREF3 0x51 /* ADC reference control */ | ||
127 | #define AREF4 0x52 /* ADC reference control */ | ||
128 | #define AREF5 0x53 /* ADC reference control */ | ||
129 | #define AREF6 0x54 /* Analog reference control */ | ||
130 | #define AREF7 0x55 /* Analog reference control */ | ||
131 | #define UFIX 0x60 /* U channel fixed value output */ | ||
132 | #define VFIX 0x61 /* V channel fixed value output */ | ||
133 | #define AWBB_BLK 0x62 /* AWB option for advanced AWB */ | ||
134 | #define AWB_CTRL0 0x63 /* AWB control byte 0 */ | ||
135 | #define DSP_CTRL1 0x64 /* DSP control byte 1 */ | ||
136 | #define DSP_CTRL2 0x65 /* DSP control byte 2 */ | ||
137 | #define DSP_CTRL3 0x66 /* DSP control byte 3 */ | ||
138 | #define DSP_CTRL4 0x67 /* DSP control byte 4 */ | ||
139 | #define AWB_BIAS 0x68 /* AWB BLC level clip */ | ||
140 | #define AWB_CTRL1 0x69 /* AWB control 1 */ | ||
141 | #define AWB_CTRL2 0x6A /* AWB control 2 */ | ||
142 | #define AWB_CTRL3 0x6B /* AWB control 3 */ | ||
143 | #define AWB_CTRL4 0x6C /* AWB control 4 */ | ||
144 | #define AWB_CTRL5 0x6D /* AWB control 5 */ | ||
145 | #define AWB_CTRL6 0x6E /* AWB control 6 */ | ||
146 | #define AWB_CTRL7 0x6F /* AWB control 7 */ | ||
147 | #define AWB_CTRL8 0x70 /* AWB control 8 */ | ||
148 | #define AWB_CTRL9 0x71 /* AWB control 9 */ | ||
149 | #define AWB_CTRL10 0x72 /* AWB control 10 */ | ||
150 | #define AWB_CTRL11 0x73 /* AWB control 11 */ | ||
151 | #define AWB_CTRL12 0x74 /* AWB control 12 */ | ||
152 | #define AWB_CTRL13 0x75 /* AWB control 13 */ | ||
153 | #define AWB_CTRL14 0x76 /* AWB control 14 */ | ||
154 | #define AWB_CTRL15 0x77 /* AWB control 15 */ | ||
155 | #define AWB_CTRL16 0x78 /* AWB control 16 */ | ||
156 | #define AWB_CTRL17 0x79 /* AWB control 17 */ | ||
157 | #define AWB_CTRL18 0x7A /* AWB control 18 */ | ||
158 | #define AWB_CTRL19 0x7B /* AWB control 19 */ | ||
159 | #define AWB_CTRL20 0x7C /* AWB control 20 */ | ||
160 | #define AWB_CTRL21 0x7D /* AWB control 21 */ | ||
161 | #define GAM1 0x7E /* Gamma Curve 1st segment input end point */ | ||
162 | #define GAM2 0x7F /* Gamma Curve 2nd segment input end point */ | ||
163 | #define GAM3 0x80 /* Gamma Curve 3rd segment input end point */ | ||
164 | #define GAM4 0x81 /* Gamma Curve 4th segment input end point */ | ||
165 | #define GAM5 0x82 /* Gamma Curve 5th segment input end point */ | ||
166 | #define GAM6 0x83 /* Gamma Curve 6th segment input end point */ | ||
167 | #define GAM7 0x84 /* Gamma Curve 7th segment input end point */ | ||
168 | #define GAM8 0x85 /* Gamma Curve 8th segment input end point */ | ||
169 | #define GAM9 0x86 /* Gamma Curve 9th segment input end point */ | ||
170 | #define GAM10 0x87 /* Gamma Curve 10th segment input end point */ | ||
171 | #define GAM11 0x88 /* Gamma Curve 11th segment input end point */ | ||
172 | #define GAM12 0x89 /* Gamma Curve 12th segment input end point */ | ||
173 | #define GAM13 0x8A /* Gamma Curve 13th segment input end point */ | ||
174 | #define GAM14 0x8B /* Gamma Curve 14th segment input end point */ | ||
175 | #define GAM15 0x8C /* Gamma Curve 15th segment input end point */ | ||
176 | #define SLOP 0x8D /* Gamma curve highest segment slope */ | ||
177 | #define DNSTH 0x8E /* De-noise threshold */ | ||
178 | #define EDGE_STRNGT 0x8F /* Edge strength control when manual mode */ | ||
179 | #define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */ | ||
180 | #define DNSOFF 0x91 /* Auto De-noise threshold control */ | ||
181 | #define EDGE_UPPER 0x92 /* Edge strength upper limit when Auto mode */ | ||
182 | #define EDGE_LOWER 0x93 /* Edge strength lower limit when Auto mode */ | ||
183 | #define MTX1 0x94 /* Matrix coefficient 1 */ | ||
184 | #define MTX2 0x95 /* Matrix coefficient 2 */ | ||
185 | #define MTX3 0x96 /* Matrix coefficient 3 */ | ||
186 | #define MTX4 0x97 /* Matrix coefficient 4 */ | ||
187 | #define MTX5 0x98 /* Matrix coefficient 5 */ | ||
188 | #define MTX6 0x99 /* Matrix coefficient 6 */ | ||
189 | #define MTX_CTRL 0x9A /* Matrix control */ | ||
190 | #define BRIGHT 0x9B /* Brightness control */ | ||
191 | #define CNTRST 0x9C /* Contrast contrast */ | ||
192 | #define CNTRST_CTRL 0x9D /* Contrast contrast center */ | ||
193 | #define UVAD_J0 0x9E /* Auto UV adjust contrast 0 */ | ||
194 | #define UVAD_J1 0x9F /* Auto UV adjust contrast 1 */ | ||
195 | #define SCAL0 0xA0 /* Scaling control 0 */ | ||
196 | #define SCAL1 0xA1 /* Scaling control 1 */ | ||
197 | #define SCAL2 0xA2 /* Scaling control 2 */ | ||
198 | #define FIFODLYM 0xA3 /* FIFO manual mode delay control */ | ||
199 | #define FIFODLYA 0xA4 /* FIFO auto mode delay control */ | ||
200 | #define SDE 0xA6 /* Special digital effect control */ | ||
201 | #define USAT 0xA7 /* U component saturation control */ | ||
202 | #define VSAT 0xA8 /* V component saturation control */ | ||
203 | /* for ov7720 */ | ||
204 | #define HUE0 0xA9 /* Hue control 0 */ | ||
205 | #define HUE1 0xAA /* Hue control 1 */ | ||
206 | /* for ov7725 */ | ||
207 | #define HUECOS 0xA9 /* Cosine value */ | ||
208 | #define HUESIN 0xAA /* Sine value */ | ||
209 | |||
210 | #define SIGN 0xAB /* Sign bit for Hue and contrast */ | ||
211 | #define DSPAUTO 0xAC /* DSP auto function ON/OFF control */ | ||
212 | |||
213 | /* | ||
214 | * register detail | ||
215 | */ | ||
216 | |||
217 | /* COM2 */ | ||
218 | #define SOFT_SLEEP_MODE 0x10 /* Soft sleep mode */ | ||
219 | /* Output drive capability */ | ||
220 | #define OCAP_1x 0x00 /* 1x */ | ||
221 | #define OCAP_2x 0x01 /* 2x */ | ||
222 | #define OCAP_3x 0x02 /* 3x */ | ||
223 | #define OCAP_4x 0x03 /* 4x */ | ||
224 | |||
225 | /* COM3 */ | ||
226 | #define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML) | ||
227 | #define IMG_MASK (VFLIP_IMG | HFLIP_IMG) | ||
228 | |||
229 | #define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */ | ||
230 | #define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */ | ||
231 | #define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */ | ||
232 | #define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */ | ||
233 | #define SWAP_ML 0x08 /* Swap output MSB/LSB */ | ||
234 | /* Tri-state option for output clock */ | ||
235 | #define NOTRI_CLOCK 0x04 /* 0: Tri-state at this period */ | ||
236 | /* 1: No tri-state at this period */ | ||
237 | /* Tri-state option for output data */ | ||
238 | #define NOTRI_DATA 0x02 /* 0: Tri-state at this period */ | ||
239 | /* 1: No tri-state at this period */ | ||
240 | #define SCOLOR_TEST 0x01 /* Sensor color bar test pattern */ | ||
241 | |||
242 | /* COM4 */ | ||
243 | /* PLL frequency control */ | ||
244 | #define PLL_BYPASS 0x00 /* 00: Bypass PLL */ | ||
245 | #define PLL_4x 0x40 /* 01: PLL 4x */ | ||
246 | #define PLL_6x 0x80 /* 10: PLL 6x */ | ||
247 | #define PLL_8x 0xc0 /* 11: PLL 8x */ | ||
248 | /* AEC evaluate window */ | ||
249 | #define AEC_FULL 0x00 /* 00: Full window */ | ||
250 | #define AEC_1p2 0x10 /* 01: 1/2 window */ | ||
251 | #define AEC_1p4 0x20 /* 10: 1/4 window */ | ||
252 | #define AEC_2p3 0x30 /* 11: Low 2/3 window */ | ||
253 | #define COM4_RESERVED 0x01 /* Reserved bit */ | ||
254 | |||
255 | /* COM5 */ | ||
256 | #define AFR_ON_OFF 0x80 /* Auto frame rate control ON/OFF selection */ | ||
257 | #define AFR_SPPED 0x40 /* Auto frame rate control speed selection */ | ||
258 | /* Auto frame rate max rate control */ | ||
259 | #define AFR_NO_RATE 0x00 /* No reduction of frame rate */ | ||
260 | #define AFR_1p2 0x10 /* Max reduction to 1/2 frame rate */ | ||
261 | #define AFR_1p4 0x20 /* Max reduction to 1/4 frame rate */ | ||
262 | #define AFR_1p8 0x30 /* Max reduction to 1/8 frame rate */ | ||
263 | /* Auto frame rate active point control */ | ||
264 | #define AF_2x 0x00 /* Add frame when AGC reaches 2x gain */ | ||
265 | #define AF_4x 0x04 /* Add frame when AGC reaches 4x gain */ | ||
266 | #define AF_8x 0x08 /* Add frame when AGC reaches 8x gain */ | ||
267 | #define AF_16x 0x0c /* Add frame when AGC reaches 16x gain */ | ||
268 | /* AEC max step control */ | ||
269 | #define AEC_NO_LIMIT 0x01 /* 0 : AEC incease step has limit */ | ||
270 | /* 1 : No limit to AEC increase step */ | ||
271 | /* CLKRC */ | ||
272 | /* Input clock divider register */ | ||
273 | #define CLKRC_RESERVED 0x80 /* Reserved bit */ | ||
274 | #define CLKRC_DIV(n) ((n) - 1) | ||
275 | |||
276 | /* COM7 */ | ||
277 | /* SCCB Register Reset */ | ||
278 | #define SCCB_RESET 0x80 /* 0 : No change */ | ||
279 | /* 1 : Resets all registers to default */ | ||
280 | /* Resolution selection */ | ||
281 | #define SLCT_MASK 0x40 /* Mask of VGA or QVGA */ | ||
282 | #define SLCT_VGA 0x00 /* 0 : VGA */ | ||
283 | #define SLCT_QVGA 0x40 /* 1 : QVGA */ | ||
284 | #define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */ | ||
285 | #define SENSOR_RAW 0x10 /* Sensor RAW */ | ||
286 | /* RGB output format control */ | ||
287 | #define FMT_MASK 0x0c /* Mask of color format */ | ||
288 | #define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */ | ||
289 | #define FMT_RGB565 0x04 /* 01 : RGB 565 */ | ||
290 | #define FMT_RGB555 0x08 /* 10 : RGB 555 */ | ||
291 | #define FMT_RGB444 0x0c /* 11 : RGB 444 */ | ||
292 | /* Output format control */ | ||
293 | #define OFMT_MASK 0x03 /* Mask of output format */ | ||
294 | #define OFMT_YUV 0x00 /* 00 : YUV */ | ||
295 | #define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */ | ||
296 | #define OFMT_RGB 0x02 /* 10 : RGB */ | ||
297 | #define OFMT_BRAW 0x03 /* 11 : Bayer RAW */ | ||
298 | |||
299 | /* COM8 */ | ||
300 | #define FAST_ALGO 0x80 /* Enable fast AGC/AEC algorithm */ | ||
301 | /* AEC Setp size limit */ | ||
302 | #define UNLMT_STEP 0x40 /* 0 : Step size is limited */ | ||
303 | /* 1 : Unlimited step size */ | ||
304 | #define BNDF_ON_OFF 0x20 /* Banding filter ON/OFF */ | ||
305 | #define AEC_BND 0x10 /* Enable AEC below banding value */ | ||
306 | #define AEC_ON_OFF 0x08 /* Fine AEC ON/OFF control */ | ||
307 | #define AGC_ON 0x04 /* AGC Enable */ | ||
308 | #define AWB_ON 0x02 /* AWB Enable */ | ||
309 | #define AEC_ON 0x01 /* AEC Enable */ | ||
310 | |||
311 | /* COM9 */ | ||
312 | #define BASE_AECAGC 0x80 /* Histogram or average based AEC/AGC */ | ||
313 | /* Automatic gain ceiling - maximum AGC value */ | ||
314 | #define GAIN_2x 0x00 /* 000 : 2x */ | ||
315 | #define GAIN_4x 0x10 /* 001 : 4x */ | ||
316 | #define GAIN_8x 0x20 /* 010 : 8x */ | ||
317 | #define GAIN_16x 0x30 /* 011 : 16x */ | ||
318 | #define GAIN_32x 0x40 /* 100 : 32x */ | ||
319 | #define GAIN_64x 0x50 /* 101 : 64x */ | ||
320 | #define GAIN_128x 0x60 /* 110 : 128x */ | ||
321 | #define DROP_VSYNC 0x04 /* Drop VSYNC output of corrupt frame */ | ||
322 | #define DROP_HREF 0x02 /* Drop HREF output of corrupt frame */ | ||
323 | |||
324 | /* COM11 */ | ||
325 | #define SGLF_ON_OFF 0x02 /* Single frame ON/OFF selection */ | ||
326 | #define SGLF_TRIG 0x01 /* Single frame transfer trigger */ | ||
327 | |||
328 | /* HREF */ | ||
329 | #define HREF_VSTART_SHIFT 6 /* VSTART LSB */ | ||
330 | #define HREF_HSTART_SHIFT 4 /* HSTART 2 LSBs */ | ||
331 | #define HREF_VSIZE_SHIFT 2 /* VSIZE LSB */ | ||
332 | #define HREF_HSIZE_SHIFT 0 /* HSIZE 2 LSBs */ | ||
333 | |||
334 | /* EXHCH */ | ||
335 | #define EXHCH_VSIZE_SHIFT 2 /* VOUTSIZE LSB */ | ||
336 | #define EXHCH_HSIZE_SHIFT 0 /* HOUTSIZE 2 LSBs */ | ||
337 | |||
338 | /* DSP_CTRL1 */ | ||
339 | #define FIFO_ON 0x80 /* FIFO enable/disable selection */ | ||
340 | #define UV_ON_OFF 0x40 /* UV adjust function ON/OFF selection */ | ||
341 | #define YUV444_2_422 0x20 /* YUV444 to 422 UV channel option selection */ | ||
342 | #define CLR_MTRX_ON_OFF 0x10 /* Color matrix ON/OFF selection */ | ||
343 | #define INTPLT_ON_OFF 0x08 /* Interpolation ON/OFF selection */ | ||
344 | #define GMM_ON_OFF 0x04 /* Gamma function ON/OFF selection */ | ||
345 | #define AUTO_BLK_ON_OFF 0x02 /* Black defect auto correction ON/OFF */ | ||
346 | #define AUTO_WHT_ON_OFF 0x01 /* White define auto correction ON/OFF */ | ||
347 | |||
348 | /* DSP_CTRL3 */ | ||
349 | #define UV_MASK 0x80 /* UV output sequence option */ | ||
350 | #define UV_ON 0x80 /* ON */ | ||
351 | #define UV_OFF 0x00 /* OFF */ | ||
352 | #define CBAR_MASK 0x20 /* DSP Color bar mask */ | ||
353 | #define CBAR_ON 0x20 /* ON */ | ||
354 | #define CBAR_OFF 0x00 /* OFF */ | ||
355 | |||
356 | /* DSP_CTRL4 */ | ||
357 | #define DSP_OFMT_YUV 0x00 | ||
358 | #define DSP_OFMT_RGB 0x00 | ||
359 | #define DSP_OFMT_RAW8 0x02 | ||
360 | #define DSP_OFMT_RAW10 0x03 | ||
361 | |||
362 | /* DSPAUTO (DSP Auto Function ON/OFF Control) */ | ||
363 | #define AWB_ACTRL 0x80 /* AWB auto threshold control */ | ||
364 | #define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */ | ||
365 | #define EDGE_ACTRL 0x20 /* Edge enhancement auto strength control */ | ||
366 | #define UV_ACTRL 0x10 /* UV adjust auto slope control */ | ||
367 | #define SCAL0_ACTRL 0x08 /* Auto scaling factor control */ | ||
368 | #define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */ | ||
369 | |||
370 | #define OV772X_MAX_WIDTH VGA_WIDTH | ||
371 | #define OV772X_MAX_HEIGHT VGA_HEIGHT | ||
372 | |||
373 | /* | ||
374 | * ID | ||
375 | */ | ||
376 | #define OV7720 0x7720 | ||
377 | #define OV7725 0x7721 | ||
378 | #define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF)) | ||
379 | |||
380 | /* | ||
381 | * PLL multipliers | ||
382 | */ | ||
383 | static struct { | ||
384 | unsigned int mult; | ||
385 | u8 com4; | ||
386 | } ov772x_pll[] = { | ||
387 | { 1, PLL_BYPASS, }, | ||
388 | { 4, PLL_4x, }, | ||
389 | { 6, PLL_6x, }, | ||
390 | { 8, PLL_8x, }, | ||
391 | }; | ||
392 | |||
393 | /* | ||
394 | * struct | ||
395 | */ | ||
396 | |||
397 | struct ov772x_color_format { | ||
398 | u32 code; | ||
399 | enum v4l2_colorspace colorspace; | ||
400 | u8 dsp3; | ||
401 | u8 dsp4; | ||
402 | u8 com3; | ||
403 | u8 com7; | ||
404 | }; | ||
405 | |||
406 | struct ov772x_win_size { | ||
407 | char *name; | ||
408 | unsigned char com7_bit; | ||
409 | unsigned int sizeimage; | ||
410 | struct v4l2_rect rect; | ||
411 | }; | ||
412 | |||
413 | struct ov772x_priv { | ||
414 | struct v4l2_subdev subdev; | ||
415 | struct v4l2_ctrl_handler hdl; | ||
416 | struct clk *clk; | ||
417 | struct ov772x_camera_info *info; | ||
418 | struct gpio_desc *pwdn_gpio; | ||
419 | struct gpio_desc *rstb_gpio; | ||
420 | const struct ov772x_color_format *cfmt; | ||
421 | const struct ov772x_win_size *win; | ||
422 | unsigned short flag_vflip:1; | ||
423 | unsigned short flag_hflip:1; | ||
424 | /* band_filter = COM8[5] ? 256 - BDBASE : 0 */ | ||
425 | unsigned short band_filter; | ||
426 | unsigned int fps; | ||
427 | }; | ||
428 | |||
429 | /* | ||
430 | * supported color format list | ||
431 | */ | ||
432 | static const struct ov772x_color_format ov772x_cfmts[] = { | ||
433 | { | ||
434 | .code = MEDIA_BUS_FMT_YUYV8_2X8, | ||
435 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
436 | .dsp3 = 0x0, | ||
437 | .dsp4 = DSP_OFMT_YUV, | ||
438 | .com3 = SWAP_YUV, | ||
439 | .com7 = OFMT_YUV, | ||
440 | }, | ||
441 | { | ||
442 | .code = MEDIA_BUS_FMT_YVYU8_2X8, | ||
443 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
444 | .dsp3 = UV_ON, | ||
445 | .dsp4 = DSP_OFMT_YUV, | ||
446 | .com3 = SWAP_YUV, | ||
447 | .com7 = OFMT_YUV, | ||
448 | }, | ||
449 | { | ||
450 | .code = MEDIA_BUS_FMT_UYVY8_2X8, | ||
451 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
452 | .dsp3 = 0x0, | ||
453 | .dsp4 = DSP_OFMT_YUV, | ||
454 | .com3 = 0x0, | ||
455 | .com7 = OFMT_YUV, | ||
456 | }, | ||
457 | { | ||
458 | .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, | ||
459 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
460 | .dsp3 = 0x0, | ||
461 | .dsp4 = DSP_OFMT_YUV, | ||
462 | .com3 = SWAP_RGB, | ||
463 | .com7 = FMT_RGB555 | OFMT_RGB, | ||
464 | }, | ||
465 | { | ||
466 | .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, | ||
467 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
468 | .dsp3 = 0x0, | ||
469 | .dsp4 = DSP_OFMT_YUV, | ||
470 | .com3 = 0x0, | ||
471 | .com7 = FMT_RGB555 | OFMT_RGB, | ||
472 | }, | ||
473 | { | ||
474 | .code = MEDIA_BUS_FMT_RGB565_2X8_LE, | ||
475 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
476 | .dsp3 = 0x0, | ||
477 | .dsp4 = DSP_OFMT_YUV, | ||
478 | .com3 = SWAP_RGB, | ||
479 | .com7 = FMT_RGB565 | OFMT_RGB, | ||
480 | }, | ||
481 | { | ||
482 | .code = MEDIA_BUS_FMT_RGB565_2X8_BE, | ||
483 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
484 | .dsp3 = 0x0, | ||
485 | .dsp4 = DSP_OFMT_YUV, | ||
486 | .com3 = 0x0, | ||
487 | .com7 = FMT_RGB565 | OFMT_RGB, | ||
488 | }, | ||
489 | { | ||
490 | /* Setting DSP4 to DSP_OFMT_RAW8 still gives 10-bit output, | ||
491 | * regardless of the COM7 value. We can thus only support 10-bit | ||
492 | * Bayer until someone figures it out. | ||
493 | */ | ||
494 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, | ||
495 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
496 | .dsp3 = 0x0, | ||
497 | .dsp4 = DSP_OFMT_RAW10, | ||
498 | .com3 = 0x0, | ||
499 | .com7 = SENSOR_RAW | OFMT_BRAW, | ||
500 | }, | ||
501 | }; | ||
502 | |||
503 | /* | ||
504 | * window size list | ||
505 | */ | ||
506 | |||
507 | static const struct ov772x_win_size ov772x_win_sizes[] = { | ||
508 | { | ||
509 | .name = "VGA", | ||
510 | .com7_bit = SLCT_VGA, | ||
511 | .sizeimage = 510 * 748, | ||
512 | .rect = { | ||
513 | .left = 140, | ||
514 | .top = 14, | ||
515 | .width = VGA_WIDTH, | ||
516 | .height = VGA_HEIGHT, | ||
517 | }, | ||
518 | }, { | ||
519 | .name = "QVGA", | ||
520 | .com7_bit = SLCT_QVGA, | ||
521 | .sizeimage = 278 * 576, | ||
522 | .rect = { | ||
523 | .left = 252, | ||
524 | .top = 6, | ||
525 | .width = QVGA_WIDTH, | ||
526 | .height = QVGA_HEIGHT, | ||
527 | }, | ||
528 | }, | ||
529 | }; | ||
530 | |||
531 | /* | ||
532 | * frame rate settings lists | ||
533 | */ | ||
534 | static const unsigned int ov772x_frame_intervals[] = { 5, 10, 15, 20, 30, 60 }; | ||
535 | |||
536 | /* | ||
537 | * general function | ||
538 | */ | ||
539 | |||
540 | static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd) | ||
541 | { | ||
542 | return container_of(sd, struct ov772x_priv, subdev); | ||
543 | } | ||
544 | |||
545 | static inline int ov772x_read(struct i2c_client *client, u8 addr) | ||
546 | { | ||
547 | return i2c_smbus_read_byte_data(client, addr); | ||
548 | } | ||
549 | |||
550 | static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value) | ||
551 | { | ||
552 | return i2c_smbus_write_byte_data(client, addr, value); | ||
553 | } | ||
554 | |||
555 | static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask, | ||
556 | u8 set) | ||
557 | { | ||
558 | s32 val = ov772x_read(client, command); | ||
559 | |||
560 | if (val < 0) | ||
561 | return val; | ||
562 | |||
563 | val &= ~mask; | ||
564 | val |= set & mask; | ||
565 | |||
566 | return ov772x_write(client, command, val); | ||
567 | } | ||
568 | |||
569 | static int ov772x_reset(struct i2c_client *client) | ||
570 | { | ||
571 | int ret; | ||
572 | |||
573 | ret = ov772x_write(client, COM7, SCCB_RESET); | ||
574 | if (ret < 0) | ||
575 | return ret; | ||
576 | |||
577 | usleep_range(1000, 5000); | ||
578 | |||
579 | return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); | ||
580 | } | ||
581 | |||
582 | /* | ||
583 | * subdev ops | ||
584 | */ | ||
585 | |||
586 | static int ov772x_s_stream(struct v4l2_subdev *sd, int enable) | ||
587 | { | ||
588 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
589 | struct ov772x_priv *priv = to_ov772x(sd); | ||
590 | |||
591 | if (!enable) { | ||
592 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); | ||
597 | |||
598 | dev_dbg(&client->dev, "format %d, win %s\n", | ||
599 | priv->cfmt->code, priv->win->name); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int ov772x_set_frame_rate(struct ov772x_priv *priv, | ||
605 | struct v4l2_fract *tpf, | ||
606 | const struct ov772x_color_format *cfmt, | ||
607 | const struct ov772x_win_size *win) | ||
608 | { | ||
609 | struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); | ||
610 | unsigned long fin = clk_get_rate(priv->clk); | ||
611 | unsigned int fps = tpf->numerator ? | ||
612 | tpf->denominator / tpf->numerator : | ||
613 | tpf->denominator; | ||
614 | unsigned int best_diff; | ||
615 | unsigned int fsize; | ||
616 | unsigned int pclk; | ||
617 | unsigned int diff; | ||
618 | unsigned int idx; | ||
619 | unsigned int i; | ||
620 | u8 clkrc = 0; | ||
621 | u8 com4 = 0; | ||
622 | int ret; | ||
623 | |||
624 | /* Approximate to the closest supported frame interval. */ | ||
625 | best_diff = ~0L; | ||
626 | for (i = 0, idx = 0; i < ARRAY_SIZE(ov772x_frame_intervals); i++) { | ||
627 | diff = abs(fps - ov772x_frame_intervals[i]); | ||
628 | if (diff < best_diff) { | ||
629 | idx = i; | ||
630 | best_diff = diff; | ||
631 | } | ||
632 | } | ||
633 | fps = ov772x_frame_intervals[idx]; | ||
634 | |||
635 | /* Use image size (with blankings) to calculate desired pixel clock. */ | ||
636 | switch (cfmt->com7 & OFMT_MASK) { | ||
637 | case OFMT_BRAW: | ||
638 | fsize = win->sizeimage; | ||
639 | break; | ||
640 | case OFMT_RGB: | ||
641 | case OFMT_YUV: | ||
642 | default: | ||
643 | fsize = win->sizeimage * 2; | ||
644 | break; | ||
645 | } | ||
646 | |||
647 | pclk = fps * fsize; | ||
648 | |||
649 | /* | ||
650 | * Pixel clock generation circuit is pretty simple: | ||
651 | * | ||
652 | * Fin -> [ / CLKRC_div] -> [ * PLL_mult] -> pclk | ||
653 | * | ||
654 | * Try to approximate the desired pixel clock testing all available | ||
655 | * PLL multipliers (1x, 4x, 6x, 8x) and calculate corresponding | ||
656 | * divisor with: | ||
657 | * | ||
658 | * div = PLL_mult * Fin / pclk | ||
659 | * | ||
660 | * and re-calculate the pixel clock using it: | ||
661 | * | ||
662 | * pclk = Fin * PLL_mult / CLKRC_div | ||
663 | * | ||
664 | * Choose the PLL_mult and CLKRC_div pair that gives a pixel clock | ||
665 | * closer to the desired one. | ||
666 | * | ||
667 | * The desired pixel clock is calculated using a known frame size | ||
668 | * (blanking included) and FPS. | ||
669 | */ | ||
670 | best_diff = ~0L; | ||
671 | for (i = 0; i < ARRAY_SIZE(ov772x_pll); i++) { | ||
672 | unsigned int pll_mult = ov772x_pll[i].mult; | ||
673 | unsigned int pll_out = pll_mult * fin; | ||
674 | unsigned int t_pclk; | ||
675 | unsigned int div; | ||
676 | |||
677 | if (pll_out < pclk) | ||
678 | continue; | ||
679 | |||
680 | div = DIV_ROUND_CLOSEST(pll_out, pclk); | ||
681 | t_pclk = DIV_ROUND_CLOSEST(fin * pll_mult, div); | ||
682 | diff = abs(pclk - t_pclk); | ||
683 | if (diff < best_diff) { | ||
684 | best_diff = diff; | ||
685 | clkrc = CLKRC_DIV(div); | ||
686 | com4 = ov772x_pll[i].com4; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | ret = ov772x_write(client, COM4, com4 | COM4_RESERVED); | ||
691 | if (ret < 0) | ||
692 | return ret; | ||
693 | |||
694 | ret = ov772x_write(client, CLKRC, clkrc | CLKRC_RESERVED); | ||
695 | if (ret < 0) | ||
696 | return ret; | ||
697 | |||
698 | tpf->numerator = 1; | ||
699 | tpf->denominator = fps; | ||
700 | priv->fps = tpf->denominator; | ||
701 | |||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static int ov772x_g_frame_interval(struct v4l2_subdev *sd, | ||
706 | struct v4l2_subdev_frame_interval *ival) | ||
707 | { | ||
708 | struct ov772x_priv *priv = to_ov772x(sd); | ||
709 | struct v4l2_fract *tpf = &ival->interval; | ||
710 | |||
711 | tpf->numerator = 1; | ||
712 | tpf->denominator = priv->fps; | ||
713 | |||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | static int ov772x_s_frame_interval(struct v4l2_subdev *sd, | ||
718 | struct v4l2_subdev_frame_interval *ival) | ||
719 | { | ||
720 | struct ov772x_priv *priv = to_ov772x(sd); | ||
721 | struct v4l2_fract *tpf = &ival->interval; | ||
722 | |||
723 | return ov772x_set_frame_rate(priv, tpf, priv->cfmt, priv->win); | ||
724 | } | ||
725 | |||
726 | static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl) | ||
727 | { | ||
728 | struct ov772x_priv *priv = container_of(ctrl->handler, | ||
729 | struct ov772x_priv, hdl); | ||
730 | struct v4l2_subdev *sd = &priv->subdev; | ||
731 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
732 | int ret = 0; | ||
733 | u8 val; | ||
734 | |||
735 | switch (ctrl->id) { | ||
736 | case V4L2_CID_VFLIP: | ||
737 | val = ctrl->val ? VFLIP_IMG : 0x00; | ||
738 | priv->flag_vflip = ctrl->val; | ||
739 | if (priv->info->flags & OV772X_FLAG_VFLIP) | ||
740 | val ^= VFLIP_IMG; | ||
741 | return ov772x_mask_set(client, COM3, VFLIP_IMG, val); | ||
742 | case V4L2_CID_HFLIP: | ||
743 | val = ctrl->val ? HFLIP_IMG : 0x00; | ||
744 | priv->flag_hflip = ctrl->val; | ||
745 | if (priv->info->flags & OV772X_FLAG_HFLIP) | ||
746 | val ^= HFLIP_IMG; | ||
747 | return ov772x_mask_set(client, COM3, HFLIP_IMG, val); | ||
748 | case V4L2_CID_BAND_STOP_FILTER: | ||
749 | if (!ctrl->val) { | ||
750 | /* Switch the filter off, it is on now */ | ||
751 | ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff); | ||
752 | if (!ret) | ||
753 | ret = ov772x_mask_set(client, COM8, | ||
754 | BNDF_ON_OFF, 0); | ||
755 | } else { | ||
756 | /* Switch the filter on, set AEC low limit */ | ||
757 | val = 256 - ctrl->val; | ||
758 | ret = ov772x_mask_set(client, COM8, | ||
759 | BNDF_ON_OFF, BNDF_ON_OFF); | ||
760 | if (!ret) | ||
761 | ret = ov772x_mask_set(client, BDBASE, | ||
762 | 0xff, val); | ||
763 | } | ||
764 | if (!ret) | ||
765 | priv->band_filter = ctrl->val; | ||
766 | return ret; | ||
767 | } | ||
768 | |||
769 | return -EINVAL; | ||
770 | } | ||
771 | |||
772 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
773 | static int ov772x_g_register(struct v4l2_subdev *sd, | ||
774 | struct v4l2_dbg_register *reg) | ||
775 | { | ||
776 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
777 | int ret; | ||
778 | |||
779 | reg->size = 1; | ||
780 | if (reg->reg > 0xff) | ||
781 | return -EINVAL; | ||
782 | |||
783 | ret = ov772x_read(client, reg->reg); | ||
784 | if (ret < 0) | ||
785 | return ret; | ||
786 | |||
787 | reg->val = (__u64)ret; | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static int ov772x_s_register(struct v4l2_subdev *sd, | ||
793 | const struct v4l2_dbg_register *reg) | ||
794 | { | ||
795 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
796 | |||
797 | if (reg->reg > 0xff || | ||
798 | reg->val > 0xff) | ||
799 | return -EINVAL; | ||
800 | |||
801 | return ov772x_write(client, reg->reg, reg->val); | ||
802 | } | ||
803 | #endif | ||
804 | |||
805 | static int ov772x_power_on(struct ov772x_priv *priv) | ||
806 | { | ||
807 | struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); | ||
808 | int ret; | ||
809 | |||
810 | if (priv->clk) { | ||
811 | ret = clk_prepare_enable(priv->clk); | ||
812 | if (ret) | ||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | if (priv->pwdn_gpio) { | ||
817 | gpiod_set_value(priv->pwdn_gpio, 1); | ||
818 | usleep_range(500, 1000); | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * FIXME: The reset signal is connected to a shared GPIO on some | ||
823 | * platforms (namely the SuperH Migo-R). Until a framework becomes | ||
824 | * available to handle this cleanly, request the GPIO temporarily | ||
825 | * to avoid conflicts. | ||
826 | */ | ||
827 | priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb", | ||
828 | GPIOD_OUT_LOW); | ||
829 | if (IS_ERR(priv->rstb_gpio)) { | ||
830 | dev_info(&client->dev, "Unable to get GPIO \"rstb\""); | ||
831 | return PTR_ERR(priv->rstb_gpio); | ||
832 | } | ||
833 | |||
834 | if (priv->rstb_gpio) { | ||
835 | gpiod_set_value(priv->rstb_gpio, 1); | ||
836 | usleep_range(500, 1000); | ||
837 | gpiod_set_value(priv->rstb_gpio, 0); | ||
838 | usleep_range(500, 1000); | ||
839 | |||
840 | gpiod_put(priv->rstb_gpio); | ||
841 | } | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | static int ov772x_power_off(struct ov772x_priv *priv) | ||
847 | { | ||
848 | clk_disable_unprepare(priv->clk); | ||
849 | |||
850 | if (priv->pwdn_gpio) { | ||
851 | gpiod_set_value(priv->pwdn_gpio, 0); | ||
852 | usleep_range(500, 1000); | ||
853 | } | ||
854 | |||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | static int ov772x_s_power(struct v4l2_subdev *sd, int on) | ||
859 | { | ||
860 | struct ov772x_priv *priv = to_ov772x(sd); | ||
861 | |||
862 | return on ? ov772x_power_on(priv) : | ||
863 | ov772x_power_off(priv); | ||
864 | } | ||
865 | |||
866 | static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) | ||
867 | { | ||
868 | const struct ov772x_win_size *win = &ov772x_win_sizes[0]; | ||
869 | u32 best_diff = UINT_MAX; | ||
870 | unsigned int i; | ||
871 | |||
872 | for (i = 0; i < ARRAY_SIZE(ov772x_win_sizes); ++i) { | ||
873 | u32 diff = abs(width - ov772x_win_sizes[i].rect.width) | ||
874 | + abs(height - ov772x_win_sizes[i].rect.height); | ||
875 | if (diff < best_diff) { | ||
876 | best_diff = diff; | ||
877 | win = &ov772x_win_sizes[i]; | ||
878 | } | ||
879 | } | ||
880 | |||
881 | return win; | ||
882 | } | ||
883 | |||
884 | static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf, | ||
885 | const struct ov772x_color_format **cfmt, | ||
886 | const struct ov772x_win_size **win) | ||
887 | { | ||
888 | unsigned int i; | ||
889 | |||
890 | /* Select a format. */ | ||
891 | *cfmt = &ov772x_cfmts[0]; | ||
892 | |||
893 | for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { | ||
894 | if (mf->code == ov772x_cfmts[i].code) { | ||
895 | *cfmt = &ov772x_cfmts[i]; | ||
896 | break; | ||
897 | } | ||
898 | } | ||
899 | |||
900 | /* Select a window size. */ | ||
901 | *win = ov772x_select_win(mf->width, mf->height); | ||
902 | } | ||
903 | |||
904 | static int ov772x_set_params(struct ov772x_priv *priv, | ||
905 | const struct ov772x_color_format *cfmt, | ||
906 | const struct ov772x_win_size *win) | ||
907 | { | ||
908 | struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); | ||
909 | struct v4l2_fract tpf; | ||
910 | int ret; | ||
911 | u8 val; | ||
912 | |||
913 | /* Reset hardware. */ | ||
914 | ov772x_reset(client); | ||
915 | |||
916 | /* Edge Ctrl. */ | ||
917 | if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) { | ||
918 | /* | ||
919 | * Manual Edge Control Mode. | ||
920 | * | ||
921 | * Edge auto strength bit is set by default. | ||
922 | * Remove it when manual mode. | ||
923 | */ | ||
924 | |||
925 | ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00); | ||
926 | if (ret < 0) | ||
927 | goto ov772x_set_fmt_error; | ||
928 | |||
929 | ret = ov772x_mask_set(client, | ||
930 | EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK, | ||
931 | priv->info->edgectrl.threshold); | ||
932 | if (ret < 0) | ||
933 | goto ov772x_set_fmt_error; | ||
934 | |||
935 | ret = ov772x_mask_set(client, | ||
936 | EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK, | ||
937 | priv->info->edgectrl.strength); | ||
938 | if (ret < 0) | ||
939 | goto ov772x_set_fmt_error; | ||
940 | |||
941 | } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) { | ||
942 | /* | ||
943 | * Auto Edge Control Mode. | ||
944 | * | ||
945 | * Set upper and lower limit. | ||
946 | */ | ||
947 | ret = ov772x_mask_set(client, | ||
948 | EDGE_UPPER, OV772X_EDGE_UPPER_MASK, | ||
949 | priv->info->edgectrl.upper); | ||
950 | if (ret < 0) | ||
951 | goto ov772x_set_fmt_error; | ||
952 | |||
953 | ret = ov772x_mask_set(client, | ||
954 | EDGE_LOWER, OV772X_EDGE_LOWER_MASK, | ||
955 | priv->info->edgectrl.lower); | ||
956 | if (ret < 0) | ||
957 | goto ov772x_set_fmt_error; | ||
958 | } | ||
959 | |||
960 | /* Format and window size. */ | ||
961 | ret = ov772x_write(client, HSTART, win->rect.left >> 2); | ||
962 | if (ret < 0) | ||
963 | goto ov772x_set_fmt_error; | ||
964 | ret = ov772x_write(client, HSIZE, win->rect.width >> 2); | ||
965 | if (ret < 0) | ||
966 | goto ov772x_set_fmt_error; | ||
967 | ret = ov772x_write(client, VSTART, win->rect.top >> 1); | ||
968 | if (ret < 0) | ||
969 | goto ov772x_set_fmt_error; | ||
970 | ret = ov772x_write(client, VSIZE, win->rect.height >> 1); | ||
971 | if (ret < 0) | ||
972 | goto ov772x_set_fmt_error; | ||
973 | ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2); | ||
974 | if (ret < 0) | ||
975 | goto ov772x_set_fmt_error; | ||
976 | ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1); | ||
977 | if (ret < 0) | ||
978 | goto ov772x_set_fmt_error; | ||
979 | ret = ov772x_write(client, HREF, | ||
980 | ((win->rect.top & 1) << HREF_VSTART_SHIFT) | | ||
981 | ((win->rect.left & 3) << HREF_HSTART_SHIFT) | | ||
982 | ((win->rect.height & 1) << HREF_VSIZE_SHIFT) | | ||
983 | ((win->rect.width & 3) << HREF_HSIZE_SHIFT)); | ||
984 | if (ret < 0) | ||
985 | goto ov772x_set_fmt_error; | ||
986 | ret = ov772x_write(client, EXHCH, | ||
987 | ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) | | ||
988 | ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT)); | ||
989 | if (ret < 0) | ||
990 | goto ov772x_set_fmt_error; | ||
991 | |||
992 | /* Set DSP_CTRL3. */ | ||
993 | val = cfmt->dsp3; | ||
994 | if (val) { | ||
995 | ret = ov772x_mask_set(client, | ||
996 | DSP_CTRL3, UV_MASK, val); | ||
997 | if (ret < 0) | ||
998 | goto ov772x_set_fmt_error; | ||
999 | } | ||
1000 | |||
1001 | /* DSP_CTRL4: AEC reference point and DSP output format. */ | ||
1002 | if (cfmt->dsp4) { | ||
1003 | ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4); | ||
1004 | if (ret < 0) | ||
1005 | goto ov772x_set_fmt_error; | ||
1006 | } | ||
1007 | |||
1008 | /* Set COM3. */ | ||
1009 | val = cfmt->com3; | ||
1010 | if (priv->info->flags & OV772X_FLAG_VFLIP) | ||
1011 | val |= VFLIP_IMG; | ||
1012 | if (priv->info->flags & OV772X_FLAG_HFLIP) | ||
1013 | val |= HFLIP_IMG; | ||
1014 | if (priv->flag_vflip) | ||
1015 | val ^= VFLIP_IMG; | ||
1016 | if (priv->flag_hflip) | ||
1017 | val ^= HFLIP_IMG; | ||
1018 | |||
1019 | ret = ov772x_mask_set(client, | ||
1020 | COM3, SWAP_MASK | IMG_MASK, val); | ||
1021 | if (ret < 0) | ||
1022 | goto ov772x_set_fmt_error; | ||
1023 | |||
1024 | /* COM7: Sensor resolution and output format control. */ | ||
1025 | ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7); | ||
1026 | if (ret < 0) | ||
1027 | goto ov772x_set_fmt_error; | ||
1028 | |||
1029 | /* COM4, CLKRC: Set pixel clock and framerate. */ | ||
1030 | tpf.numerator = 1; | ||
1031 | tpf.denominator = priv->fps; | ||
1032 | ret = ov772x_set_frame_rate(priv, &tpf, cfmt, win); | ||
1033 | if (ret < 0) | ||
1034 | goto ov772x_set_fmt_error; | ||
1035 | |||
1036 | /* Set COM8. */ | ||
1037 | if (priv->band_filter) { | ||
1038 | ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1); | ||
1039 | if (!ret) | ||
1040 | ret = ov772x_mask_set(client, BDBASE, | ||
1041 | 0xff, 256 - priv->band_filter); | ||
1042 | if (ret < 0) | ||
1043 | goto ov772x_set_fmt_error; | ||
1044 | } | ||
1045 | |||
1046 | return ret; | ||
1047 | |||
1048 | ov772x_set_fmt_error: | ||
1049 | |||
1050 | ov772x_reset(client); | ||
1051 | |||
1052 | return ret; | ||
1053 | } | ||
1054 | |||
1055 | static int ov772x_get_selection(struct v4l2_subdev *sd, | ||
1056 | struct v4l2_subdev_pad_config *cfg, | ||
1057 | struct v4l2_subdev_selection *sel) | ||
1058 | { | ||
1059 | struct ov772x_priv *priv = to_ov772x(sd); | ||
1060 | |||
1061 | if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
1062 | return -EINVAL; | ||
1063 | |||
1064 | sel->r.left = 0; | ||
1065 | sel->r.top = 0; | ||
1066 | switch (sel->target) { | ||
1067 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
1068 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
1069 | case V4L2_SEL_TGT_CROP: | ||
1070 | sel->r.width = priv->win->rect.width; | ||
1071 | sel->r.height = priv->win->rect.height; | ||
1072 | return 0; | ||
1073 | default: | ||
1074 | return -EINVAL; | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1078 | static int ov772x_get_fmt(struct v4l2_subdev *sd, | ||
1079 | struct v4l2_subdev_pad_config *cfg, | ||
1080 | struct v4l2_subdev_format *format) | ||
1081 | { | ||
1082 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
1083 | struct ov772x_priv *priv = to_ov772x(sd); | ||
1084 | |||
1085 | if (format->pad) | ||
1086 | return -EINVAL; | ||
1087 | |||
1088 | mf->width = priv->win->rect.width; | ||
1089 | mf->height = priv->win->rect.height; | ||
1090 | mf->code = priv->cfmt->code; | ||
1091 | mf->colorspace = priv->cfmt->colorspace; | ||
1092 | mf->field = V4L2_FIELD_NONE; | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | static int ov772x_set_fmt(struct v4l2_subdev *sd, | ||
1098 | struct v4l2_subdev_pad_config *cfg, | ||
1099 | struct v4l2_subdev_format *format) | ||
1100 | { | ||
1101 | struct ov772x_priv *priv = to_ov772x(sd); | ||
1102 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
1103 | const struct ov772x_color_format *cfmt; | ||
1104 | const struct ov772x_win_size *win; | ||
1105 | int ret; | ||
1106 | |||
1107 | if (format->pad) | ||
1108 | return -EINVAL; | ||
1109 | |||
1110 | ov772x_select_params(mf, &cfmt, &win); | ||
1111 | |||
1112 | mf->code = cfmt->code; | ||
1113 | mf->width = win->rect.width; | ||
1114 | mf->height = win->rect.height; | ||
1115 | mf->field = V4L2_FIELD_NONE; | ||
1116 | mf->colorspace = cfmt->colorspace; | ||
1117 | mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; | ||
1118 | mf->quantization = V4L2_QUANTIZATION_DEFAULT; | ||
1119 | mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; | ||
1120 | |||
1121 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1122 | cfg->try_fmt = *mf; | ||
1123 | return 0; | ||
1124 | } | ||
1125 | |||
1126 | ret = ov772x_set_params(priv, cfmt, win); | ||
1127 | if (ret < 0) | ||
1128 | return ret; | ||
1129 | |||
1130 | priv->win = win; | ||
1131 | priv->cfmt = cfmt; | ||
1132 | |||
1133 | return 0; | ||
1134 | } | ||
1135 | |||
1136 | static int ov772x_video_probe(struct ov772x_priv *priv) | ||
1137 | { | ||
1138 | struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); | ||
1139 | u8 pid, ver; | ||
1140 | const char *devname; | ||
1141 | int ret; | ||
1142 | |||
1143 | ret = ov772x_s_power(&priv->subdev, 1); | ||
1144 | if (ret < 0) | ||
1145 | return ret; | ||
1146 | |||
1147 | /* Check and show product ID and manufacturer ID. */ | ||
1148 | pid = ov772x_read(client, PID); | ||
1149 | ver = ov772x_read(client, VER); | ||
1150 | |||
1151 | switch (VERSION(pid, ver)) { | ||
1152 | case OV7720: | ||
1153 | devname = "ov7720"; | ||
1154 | break; | ||
1155 | case OV7725: | ||
1156 | devname = "ov7725"; | ||
1157 | break; | ||
1158 | default: | ||
1159 | dev_err(&client->dev, | ||
1160 | "Product ID error %x:%x\n", pid, ver); | ||
1161 | ret = -ENODEV; | ||
1162 | goto done; | ||
1163 | } | ||
1164 | |||
1165 | dev_info(&client->dev, | ||
1166 | "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", | ||
1167 | devname, | ||
1168 | pid, | ||
1169 | ver, | ||
1170 | ov772x_read(client, MIDH), | ||
1171 | ov772x_read(client, MIDL)); | ||
1172 | ret = v4l2_ctrl_handler_setup(&priv->hdl); | ||
1173 | |||
1174 | done: | ||
1175 | ov772x_s_power(&priv->subdev, 0); | ||
1176 | |||
1177 | return ret; | ||
1178 | } | ||
1179 | |||
1180 | static const struct v4l2_ctrl_ops ov772x_ctrl_ops = { | ||
1181 | .s_ctrl = ov772x_s_ctrl, | ||
1182 | }; | ||
1183 | |||
1184 | static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { | ||
1185 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1186 | .g_register = ov772x_g_register, | ||
1187 | .s_register = ov772x_s_register, | ||
1188 | #endif | ||
1189 | .s_power = ov772x_s_power, | ||
1190 | }; | ||
1191 | |||
1192 | static int ov772x_enum_frame_interval(struct v4l2_subdev *sd, | ||
1193 | struct v4l2_subdev_pad_config *cfg, | ||
1194 | struct v4l2_subdev_frame_interval_enum *fie) | ||
1195 | { | ||
1196 | if (fie->pad || fie->index >= ARRAY_SIZE(ov772x_frame_intervals)) | ||
1197 | return -EINVAL; | ||
1198 | |||
1199 | if (fie->width != VGA_WIDTH && fie->width != QVGA_WIDTH) | ||
1200 | return -EINVAL; | ||
1201 | if (fie->height != VGA_HEIGHT && fie->height != QVGA_HEIGHT) | ||
1202 | return -EINVAL; | ||
1203 | |||
1204 | fie->interval.numerator = 1; | ||
1205 | fie->interval.denominator = ov772x_frame_intervals[fie->index]; | ||
1206 | |||
1207 | return 0; | ||
1208 | } | ||
1209 | |||
1210 | static int ov772x_enum_mbus_code(struct v4l2_subdev *sd, | ||
1211 | struct v4l2_subdev_pad_config *cfg, | ||
1212 | struct v4l2_subdev_mbus_code_enum *code) | ||
1213 | { | ||
1214 | if (code->pad || code->index >= ARRAY_SIZE(ov772x_cfmts)) | ||
1215 | return -EINVAL; | ||
1216 | |||
1217 | code->code = ov772x_cfmts[code->index].code; | ||
1218 | |||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1222 | static const struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { | ||
1223 | .s_stream = ov772x_s_stream, | ||
1224 | .s_frame_interval = ov772x_s_frame_interval, | ||
1225 | .g_frame_interval = ov772x_g_frame_interval, | ||
1226 | }; | ||
1227 | |||
1228 | static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { | ||
1229 | .enum_frame_interval = ov772x_enum_frame_interval, | ||
1230 | .enum_mbus_code = ov772x_enum_mbus_code, | ||
1231 | .get_selection = ov772x_get_selection, | ||
1232 | .get_fmt = ov772x_get_fmt, | ||
1233 | .set_fmt = ov772x_set_fmt, | ||
1234 | }; | ||
1235 | |||
1236 | static const struct v4l2_subdev_ops ov772x_subdev_ops = { | ||
1237 | .core = &ov772x_subdev_core_ops, | ||
1238 | .video = &ov772x_subdev_video_ops, | ||
1239 | .pad = &ov772x_subdev_pad_ops, | ||
1240 | }; | ||
1241 | |||
1242 | /* | ||
1243 | * i2c_driver function | ||
1244 | */ | ||
1245 | |||
1246 | static int ov772x_probe(struct i2c_client *client, | ||
1247 | const struct i2c_device_id *did) | ||
1248 | { | ||
1249 | struct ov772x_priv *priv; | ||
1250 | struct i2c_adapter *adapter = client->adapter; | ||
1251 | int ret; | ||
1252 | |||
1253 | if (!client->dev.platform_data) { | ||
1254 | dev_err(&client->dev, "Missing ov772x platform data\n"); | ||
1255 | return -EINVAL; | ||
1256 | } | ||
1257 | |||
1258 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
1259 | I2C_FUNC_PROTOCOL_MANGLING)) { | ||
1260 | dev_err(&adapter->dev, | ||
1261 | "I2C-Adapter doesn't support SMBUS_BYTE_DATA or PROTOCOL_MANGLING\n"); | ||
1262 | return -EIO; | ||
1263 | } | ||
1264 | client->flags |= I2C_CLIENT_SCCB; | ||
1265 | |||
1266 | priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); | ||
1267 | if (!priv) | ||
1268 | return -ENOMEM; | ||
1269 | |||
1270 | priv->info = client->dev.platform_data; | ||
1271 | |||
1272 | v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); | ||
1273 | v4l2_ctrl_handler_init(&priv->hdl, 3); | ||
1274 | v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, | ||
1275 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
1276 | v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, | ||
1277 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
1278 | v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, | ||
1279 | V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0); | ||
1280 | priv->subdev.ctrl_handler = &priv->hdl; | ||
1281 | if (priv->hdl.error) | ||
1282 | return priv->hdl.error; | ||
1283 | |||
1284 | priv->clk = clk_get(&client->dev, "xclk"); | ||
1285 | if (IS_ERR(priv->clk)) { | ||
1286 | dev_err(&client->dev, "Unable to get xclk clock\n"); | ||
1287 | ret = PTR_ERR(priv->clk); | ||
1288 | goto error_ctrl_free; | ||
1289 | } | ||
1290 | |||
1291 | priv->pwdn_gpio = gpiod_get_optional(&client->dev, "pwdn", | ||
1292 | GPIOD_OUT_LOW); | ||
1293 | if (IS_ERR(priv->pwdn_gpio)) { | ||
1294 | dev_info(&client->dev, "Unable to get GPIO \"pwdn\""); | ||
1295 | ret = PTR_ERR(priv->pwdn_gpio); | ||
1296 | goto error_clk_put; | ||
1297 | } | ||
1298 | |||
1299 | ret = ov772x_video_probe(priv); | ||
1300 | if (ret < 0) | ||
1301 | goto error_gpio_put; | ||
1302 | |||
1303 | priv->cfmt = &ov772x_cfmts[0]; | ||
1304 | priv->win = &ov772x_win_sizes[0]; | ||
1305 | priv->fps = 15; | ||
1306 | |||
1307 | ret = v4l2_async_register_subdev(&priv->subdev); | ||
1308 | if (ret) | ||
1309 | goto error_gpio_put; | ||
1310 | |||
1311 | return 0; | ||
1312 | |||
1313 | error_gpio_put: | ||
1314 | if (priv->pwdn_gpio) | ||
1315 | gpiod_put(priv->pwdn_gpio); | ||
1316 | error_clk_put: | ||
1317 | clk_put(priv->clk); | ||
1318 | error_ctrl_free: | ||
1319 | v4l2_ctrl_handler_free(&priv->hdl); | ||
1320 | |||
1321 | return ret; | ||
1322 | } | ||
1323 | |||
1324 | static int ov772x_remove(struct i2c_client *client) | ||
1325 | { | ||
1326 | struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client)); | ||
1327 | |||
1328 | clk_put(priv->clk); | ||
1329 | if (priv->pwdn_gpio) | ||
1330 | gpiod_put(priv->pwdn_gpio); | ||
1331 | v4l2_async_unregister_subdev(&priv->subdev); | ||
1332 | v4l2_ctrl_handler_free(&priv->hdl); | ||
1333 | |||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | static const struct i2c_device_id ov772x_id[] = { | ||
1338 | { "ov772x", 0 }, | ||
1339 | { } | ||
1340 | }; | ||
1341 | MODULE_DEVICE_TABLE(i2c, ov772x_id); | ||
1342 | |||
1343 | static struct i2c_driver ov772x_i2c_driver = { | ||
1344 | .driver = { | ||
1345 | .name = "ov772x", | ||
1346 | }, | ||
1347 | .probe = ov772x_probe, | ||
1348 | .remove = ov772x_remove, | ||
1349 | .id_table = ov772x_id, | ||
1350 | }; | ||
1351 | |||
1352 | module_i2c_driver(ov772x_i2c_driver); | ||
1353 | |||
1354 | MODULE_DESCRIPTION("V4L2 driver for OV772x image sensor"); | ||
1355 | MODULE_AUTHOR("Kuninori Morimoto"); | ||
1356 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index fc9dbbcae56e..01f578785e79 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c | |||
@@ -279,7 +279,7 @@ static int ov7740_get_register(struct v4l2_subdev *sd, | |||
279 | reg->val = val; | 279 | reg->val = val; |
280 | reg->size = 1; | 280 | reg->size = 1; |
281 | 281 | ||
282 | return 0; | 282 | return ret; |
283 | } | 283 | } |
284 | 284 | ||
285 | static int ov7740_set_register(struct v4l2_subdev *sd, | 285 | static int ov7740_set_register(struct v4l2_subdev *sd, |
@@ -624,17 +624,11 @@ err_unlock: | |||
624 | return ret; | 624 | return ret; |
625 | } | 625 | } |
626 | 626 | ||
627 | static int ov7740_get_parm(struct v4l2_subdev *sd, | 627 | static int ov7740_g_frame_interval(struct v4l2_subdev *sd, |
628 | struct v4l2_streamparm *parms) | 628 | struct v4l2_subdev_frame_interval *ival) |
629 | { | 629 | { |
630 | struct v4l2_captureparm *cp = &parms->parm.capture; | 630 | struct v4l2_fract *tpf = &ival->interval; |
631 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
632 | |||
633 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
634 | return -EINVAL; | ||
635 | 631 | ||
636 | memset(cp, 0, sizeof(struct v4l2_captureparm)); | ||
637 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
638 | 632 | ||
639 | tpf->numerator = 1; | 633 | tpf->numerator = 1; |
640 | tpf->denominator = 60; | 634 | tpf->denominator = 60; |
@@ -642,18 +636,11 @@ static int ov7740_get_parm(struct v4l2_subdev *sd, | |||
642 | return 0; | 636 | return 0; |
643 | } | 637 | } |
644 | 638 | ||
645 | static int ov7740_set_parm(struct v4l2_subdev *sd, | 639 | static int ov7740_s_frame_interval(struct v4l2_subdev *sd, |
646 | struct v4l2_streamparm *parms) | 640 | struct v4l2_subdev_frame_interval *ival) |
647 | { | 641 | { |
648 | struct v4l2_captureparm *cp = &parms->parm.capture; | 642 | struct v4l2_fract *tpf = &ival->interval; |
649 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
650 | |||
651 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
652 | return -EINVAL; | ||
653 | if (cp->extendedmode != 0) | ||
654 | return -EINVAL; | ||
655 | 643 | ||
656 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
657 | 644 | ||
658 | tpf->numerator = 1; | 645 | tpf->numerator = 1; |
659 | tpf->denominator = 60; | 646 | tpf->denominator = 60; |
@@ -663,8 +650,8 @@ static int ov7740_set_parm(struct v4l2_subdev *sd, | |||
663 | 650 | ||
664 | static struct v4l2_subdev_video_ops ov7740_subdev_video_ops = { | 651 | static struct v4l2_subdev_video_ops ov7740_subdev_video_ops = { |
665 | .s_stream = ov7740_set_stream, | 652 | .s_stream = ov7740_set_stream, |
666 | .s_parm = ov7740_set_parm, | 653 | .s_frame_interval = ov7740_s_frame_interval, |
667 | .g_parm = ov7740_get_parm, | 654 | .g_frame_interval = ov7740_g_frame_interval, |
668 | }; | 655 | }; |
669 | 656 | ||
670 | static const struct reg_sequence ov7740_format_yuyv[] = { | 657 | static const struct reg_sequence ov7740_format_yuyv[] = { |
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index e519f278d5f9..5bea31cd41aa 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c | |||
@@ -11,8 +11,10 @@ | |||
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | ||
14 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
15 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/gpio/consumer.h> | ||
16 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
17 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
18 | #include <linux/media.h> | 20 | #include <linux/media.h> |
@@ -249,9 +251,10 @@ struct ov965x { | |||
249 | struct v4l2_subdev sd; | 251 | struct v4l2_subdev sd; |
250 | struct media_pad pad; | 252 | struct media_pad pad; |
251 | enum v4l2_mbus_type bus_type; | 253 | enum v4l2_mbus_type bus_type; |
252 | int gpios[NUM_GPIOS]; | 254 | struct gpio_desc *gpios[NUM_GPIOS]; |
253 | /* External master clock frequency */ | 255 | /* External master clock frequency */ |
254 | unsigned long mclk_frequency; | 256 | unsigned long mclk_frequency; |
257 | struct clk *clk; | ||
255 | 258 | ||
256 | /* Protects the struct fields below */ | 259 | /* Protects the struct fields below */ |
257 | struct mutex lock; | 260 | struct mutex lock; |
@@ -513,24 +516,27 @@ static int ov965x_set_color_matrix(struct ov965x *ov965x) | |||
513 | return 0; | 516 | return 0; |
514 | } | 517 | } |
515 | 518 | ||
516 | static void ov965x_gpio_set(int gpio, int val) | 519 | static int __ov965x_set_power(struct ov965x *ov965x, int on) |
517 | { | ||
518 | if (gpio_is_valid(gpio)) | ||
519 | gpio_set_value(gpio, val); | ||
520 | } | ||
521 | |||
522 | static void __ov965x_set_power(struct ov965x *ov965x, int on) | ||
523 | { | 520 | { |
524 | if (on) { | 521 | if (on) { |
525 | ov965x_gpio_set(ov965x->gpios[GPIO_PWDN], 0); | 522 | int ret = clk_prepare_enable(ov965x->clk); |
526 | ov965x_gpio_set(ov965x->gpios[GPIO_RST], 0); | 523 | |
524 | if (ret) | ||
525 | return ret; | ||
526 | |||
527 | gpiod_set_value_cansleep(ov965x->gpios[GPIO_PWDN], 0); | ||
528 | gpiod_set_value_cansleep(ov965x->gpios[GPIO_RST], 0); | ||
527 | msleep(25); | 529 | msleep(25); |
528 | } else { | 530 | } else { |
529 | ov965x_gpio_set(ov965x->gpios[GPIO_RST], 1); | 531 | gpiod_set_value_cansleep(ov965x->gpios[GPIO_RST], 1); |
530 | ov965x_gpio_set(ov965x->gpios[GPIO_PWDN], 1); | 532 | gpiod_set_value_cansleep(ov965x->gpios[GPIO_PWDN], 1); |
533 | |||
534 | clk_disable_unprepare(ov965x->clk); | ||
531 | } | 535 | } |
532 | 536 | ||
533 | ov965x->streaming = 0; | 537 | ov965x->streaming = 0; |
538 | |||
539 | return 0; | ||
534 | } | 540 | } |
535 | 541 | ||
536 | static int ov965x_s_power(struct v4l2_subdev *sd, int on) | 542 | static int ov965x_s_power(struct v4l2_subdev *sd, int on) |
@@ -543,8 +549,8 @@ static int ov965x_s_power(struct v4l2_subdev *sd, int on) | |||
543 | 549 | ||
544 | mutex_lock(&ov965x->lock); | 550 | mutex_lock(&ov965x->lock); |
545 | if (ov965x->power == !on) { | 551 | if (ov965x->power == !on) { |
546 | __ov965x_set_power(ov965x, on); | 552 | ret = __ov965x_set_power(ov965x, on); |
547 | if (on) { | 553 | if (!ret && on) { |
548 | ret = ov965x_write_array(client, | 554 | ret = ov965x_write_array(client, |
549 | ov965x_init_regs); | 555 | ov965x_init_regs); |
550 | ov965x->apply_frame_fmt = 1; | 556 | ov965x->apply_frame_fmt = 1; |
@@ -1130,8 +1136,8 @@ static int __ov965x_set_frame_interval(struct ov965x *ov965x, | |||
1130 | if (fi->interval.denominator == 0) | 1136 | if (fi->interval.denominator == 0) |
1131 | return -EINVAL; | 1137 | return -EINVAL; |
1132 | 1138 | ||
1133 | req_int = (u64)(fi->interval.numerator * 10000) / | 1139 | req_int = (u64)fi->interval.numerator * 10000; |
1134 | fi->interval.denominator; | 1140 | do_div(req_int, fi->interval.denominator); |
1135 | 1141 | ||
1136 | for (i = 0; i < ARRAY_SIZE(ov965x_intervals); i++) { | 1142 | for (i = 0; i < ARRAY_SIZE(ov965x_intervals); i++) { |
1137 | const struct ov965x_interval *iv = &ov965x_intervals[i]; | 1143 | const struct ov965x_interval *iv = &ov965x_intervals[i]; |
@@ -1410,16 +1416,17 @@ static const struct v4l2_subdev_ops ov965x_subdev_ops = { | |||
1410 | /* | 1416 | /* |
1411 | * Reset and power down GPIOs configuration | 1417 | * Reset and power down GPIOs configuration |
1412 | */ | 1418 | */ |
1413 | static int ov965x_configure_gpios(struct ov965x *ov965x, | 1419 | static int ov965x_configure_gpios_pdata(struct ov965x *ov965x, |
1414 | const struct ov9650_platform_data *pdata) | 1420 | const struct ov9650_platform_data *pdata) |
1415 | { | 1421 | { |
1416 | int ret, i; | 1422 | int ret, i; |
1423 | int gpios[NUM_GPIOS]; | ||
1417 | 1424 | ||
1418 | ov965x->gpios[GPIO_PWDN] = pdata->gpio_pwdn; | 1425 | gpios[GPIO_PWDN] = pdata->gpio_pwdn; |
1419 | ov965x->gpios[GPIO_RST] = pdata->gpio_reset; | 1426 | gpios[GPIO_RST] = pdata->gpio_reset; |
1420 | 1427 | ||
1421 | for (i = 0; i < ARRAY_SIZE(ov965x->gpios); i++) { | 1428 | for (i = 0; i < ARRAY_SIZE(ov965x->gpios); i++) { |
1422 | int gpio = ov965x->gpios[i]; | 1429 | int gpio = gpios[i]; |
1423 | 1430 | ||
1424 | if (!gpio_is_valid(gpio)) | 1431 | if (!gpio_is_valid(gpio)) |
1425 | continue; | 1432 | continue; |
@@ -1429,9 +1436,30 @@ static int ov965x_configure_gpios(struct ov965x *ov965x, | |||
1429 | return ret; | 1436 | return ret; |
1430 | v4l2_dbg(1, debug, &ov965x->sd, "set gpio %d to 1\n", gpio); | 1437 | v4l2_dbg(1, debug, &ov965x->sd, "set gpio %d to 1\n", gpio); |
1431 | 1438 | ||
1432 | gpio_set_value(gpio, 1); | 1439 | gpio_set_value_cansleep(gpio, 1); |
1433 | gpio_export(gpio, 0); | 1440 | gpio_export(gpio, 0); |
1434 | ov965x->gpios[i] = gpio; | 1441 | ov965x->gpios[i] = gpio_to_desc(gpio); |
1442 | } | ||
1443 | |||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1447 | static int ov965x_configure_gpios(struct ov965x *ov965x) | ||
1448 | { | ||
1449 | struct device *dev = &ov965x->client->dev; | ||
1450 | |||
1451 | ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown", | ||
1452 | GPIOD_OUT_HIGH); | ||
1453 | if (IS_ERR(ov965x->gpios[GPIO_PWDN])) { | ||
1454 | dev_info(dev, "can't get %s GPIO\n", "powerdown"); | ||
1455 | return PTR_ERR(ov965x->gpios[GPIO_PWDN]); | ||
1456 | } | ||
1457 | |||
1458 | ov965x->gpios[GPIO_RST] = devm_gpiod_get_optional(dev, "reset", | ||
1459 | GPIOD_OUT_HIGH); | ||
1460 | if (IS_ERR(ov965x->gpios[GPIO_RST])) { | ||
1461 | dev_info(dev, "can't get %s GPIO\n", "reset"); | ||
1462 | return PTR_ERR(ov965x->gpios[GPIO_RST]); | ||
1435 | } | 1463 | } |
1436 | 1464 | ||
1437 | return 0; | 1465 | return 0; |
@@ -1445,7 +1473,10 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd) | |||
1445 | int ret; | 1473 | int ret; |
1446 | 1474 | ||
1447 | mutex_lock(&ov965x->lock); | 1475 | mutex_lock(&ov965x->lock); |
1448 | __ov965x_set_power(ov965x, 1); | 1476 | ret = __ov965x_set_power(ov965x, 1); |
1477 | if (ret) | ||
1478 | goto out; | ||
1479 | |||
1449 | msleep(25); | 1480 | msleep(25); |
1450 | 1481 | ||
1451 | /* Check sensor revision */ | 1482 | /* Check sensor revision */ |
@@ -1465,6 +1496,7 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd) | |||
1465 | ret = -ENODEV; | 1496 | ret = -ENODEV; |
1466 | } | 1497 | } |
1467 | } | 1498 | } |
1499 | out: | ||
1468 | mutex_unlock(&ov965x->lock); | 1500 | mutex_unlock(&ov965x->lock); |
1469 | 1501 | ||
1470 | return ret; | 1502 | return ret; |
@@ -1478,23 +1510,39 @@ static int ov965x_probe(struct i2c_client *client, | |||
1478 | struct ov965x *ov965x; | 1510 | struct ov965x *ov965x; |
1479 | int ret; | 1511 | int ret; |
1480 | 1512 | ||
1481 | if (!pdata) { | ||
1482 | dev_err(&client->dev, "platform data not specified\n"); | ||
1483 | return -EINVAL; | ||
1484 | } | ||
1485 | |||
1486 | if (pdata->mclk_frequency == 0) { | ||
1487 | dev_err(&client->dev, "MCLK frequency not specified\n"); | ||
1488 | return -EINVAL; | ||
1489 | } | ||
1490 | |||
1491 | ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL); | 1513 | ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL); |
1492 | if (!ov965x) | 1514 | if (!ov965x) |
1493 | return -ENOMEM; | 1515 | return -ENOMEM; |
1494 | 1516 | ||
1495 | mutex_init(&ov965x->lock); | ||
1496 | ov965x->client = client; | 1517 | ov965x->client = client; |
1497 | ov965x->mclk_frequency = pdata->mclk_frequency; | 1518 | |
1519 | if (pdata) { | ||
1520 | if (pdata->mclk_frequency == 0) { | ||
1521 | dev_err(&client->dev, "MCLK frequency not specified\n"); | ||
1522 | return -EINVAL; | ||
1523 | } | ||
1524 | ov965x->mclk_frequency = pdata->mclk_frequency; | ||
1525 | |||
1526 | ret = ov965x_configure_gpios_pdata(ov965x, pdata); | ||
1527 | if (ret < 0) | ||
1528 | return ret; | ||
1529 | } else if (dev_fwnode(&client->dev)) { | ||
1530 | ov965x->clk = devm_clk_get(&ov965x->client->dev, NULL); | ||
1531 | if (IS_ERR(ov965x->clk)) | ||
1532 | return PTR_ERR(ov965x->clk); | ||
1533 | ov965x->mclk_frequency = clk_get_rate(ov965x->clk); | ||
1534 | |||
1535 | ret = ov965x_configure_gpios(ov965x); | ||
1536 | if (ret < 0) | ||
1537 | return ret; | ||
1538 | } else { | ||
1539 | dev_err(&client->dev, | ||
1540 | "Neither platform data nor device property specified\n"); | ||
1541 | |||
1542 | return -EINVAL; | ||
1543 | } | ||
1544 | |||
1545 | mutex_init(&ov965x->lock); | ||
1498 | 1546 | ||
1499 | sd = &ov965x->sd; | 1547 | sd = &ov965x->sd; |
1500 | v4l2_i2c_subdev_init(sd, client, &ov965x_subdev_ops); | 1548 | v4l2_i2c_subdev_init(sd, client, &ov965x_subdev_ops); |
@@ -1504,10 +1552,6 @@ static int ov965x_probe(struct i2c_client *client, | |||
1504 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | | 1552 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | |
1505 | V4L2_SUBDEV_FL_HAS_EVENTS; | 1553 | V4L2_SUBDEV_FL_HAS_EVENTS; |
1506 | 1554 | ||
1507 | ret = ov965x_configure_gpios(ov965x, pdata); | ||
1508 | if (ret < 0) | ||
1509 | goto err_mutex; | ||
1510 | |||
1511 | ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; | 1555 | ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; |
1512 | sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; | 1556 | sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; |
1513 | ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad); | 1557 | ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad); |
@@ -1563,9 +1607,19 @@ static const struct i2c_device_id ov965x_id[] = { | |||
1563 | }; | 1607 | }; |
1564 | MODULE_DEVICE_TABLE(i2c, ov965x_id); | 1608 | MODULE_DEVICE_TABLE(i2c, ov965x_id); |
1565 | 1609 | ||
1610 | #if IS_ENABLED(CONFIG_OF) | ||
1611 | static const struct of_device_id ov965x_of_match[] = { | ||
1612 | { .compatible = "ovti,ov9650", }, | ||
1613 | { .compatible = "ovti,ov9652", }, | ||
1614 | { /* sentinel */ } | ||
1615 | }; | ||
1616 | MODULE_DEVICE_TABLE(of, ov965x_of_match); | ||
1617 | #endif | ||
1618 | |||
1566 | static struct i2c_driver ov965x_i2c_driver = { | 1619 | static struct i2c_driver ov965x_i2c_driver = { |
1567 | .driver = { | 1620 | .driver = { |
1568 | .name = DRIVER_NAME, | 1621 | .name = DRIVER_NAME, |
1622 | .of_match_table = of_match_ptr(ov965x_of_match), | ||
1569 | }, | 1623 | }, |
1570 | .probe = ov965x_probe, | 1624 | .probe = ov965x_probe, |
1571 | .remove = ov965x_remove, | 1625 | .remove = ov965x_remove, |
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index cdc4f2392ef9..ce196b60f917 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c | |||
@@ -248,17 +248,17 @@ static int s5c73m3_check_status(struct s5c73m3 *state, unsigned int value) | |||
248 | { | 248 | { |
249 | unsigned long start = jiffies; | 249 | unsigned long start = jiffies; |
250 | unsigned long end = start + msecs_to_jiffies(2000); | 250 | unsigned long end = start + msecs_to_jiffies(2000); |
251 | int ret = 0; | 251 | int ret; |
252 | u16 status; | 252 | u16 status; |
253 | int count = 0; | 253 | int count = 0; |
254 | 254 | ||
255 | while (time_is_after_jiffies(end)) { | 255 | do { |
256 | ret = s5c73m3_read(state, REG_STATUS, &status); | 256 | ret = s5c73m3_read(state, REG_STATUS, &status); |
257 | if (ret < 0 || status == value) | 257 | if (ret < 0 || status == value) |
258 | break; | 258 | break; |
259 | usleep_range(500, 1000); | 259 | usleep_range(500, 1000); |
260 | ++count; | 260 | ++count; |
261 | } | 261 | } while (time_is_after_jiffies(end)); |
262 | 262 | ||
263 | if (count > 0) | 263 | if (count > 0) |
264 | v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd, | 264 | v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd, |
diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig index 72b369895b37..7c2aabc8a3f6 100644 --- a/drivers/media/i2c/soc_camera/Kconfig +++ b/drivers/media/i2c/soc_camera/Kconfig | |||
@@ -1,11 +1,5 @@ | |||
1 | comment "soc_camera sensor drivers" | 1 | comment "soc_camera sensor drivers" |
2 | 2 | ||
3 | config SOC_CAMERA_IMX074 | ||
4 | tristate "imx074 support" | ||
5 | depends on SOC_CAMERA && I2C | ||
6 | help | ||
7 | This driver supports IMX074 cameras from Sony | ||
8 | |||
9 | config SOC_CAMERA_MT9M001 | 3 | config SOC_CAMERA_MT9M001 |
10 | tristate "mt9m001 support" | 4 | tristate "mt9m001 support" |
11 | depends on SOC_CAMERA && I2C | 5 | depends on SOC_CAMERA && I2C |
@@ -23,12 +17,6 @@ config SOC_CAMERA_MT9M111 | |||
23 | This is the legacy configuration which shouldn't be used anymore, | 17 | This is the legacy configuration which shouldn't be used anymore, |
24 | while VIDEO_MT9M111 should be used instead. | 18 | while VIDEO_MT9M111 should be used instead. |
25 | 19 | ||
26 | config SOC_CAMERA_MT9T031 | ||
27 | tristate "mt9t031 support" | ||
28 | depends on SOC_CAMERA && I2C | ||
29 | help | ||
30 | This driver supports MT9T031 cameras from Micron. | ||
31 | |||
32 | config SOC_CAMERA_MT9T112 | 20 | config SOC_CAMERA_MT9T112 |
33 | tristate "mt9t112 support" | 21 | tristate "mt9t112 support" |
34 | depends on SOC_CAMERA && I2C | 22 | depends on SOC_CAMERA && I2C |
diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile index faa2df8901d2..8c7770f62997 100644 --- a/drivers/media/i2c/soc_camera/Makefile +++ b/drivers/media/i2c/soc_camera/Makefile | |||
@@ -1,7 +1,5 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o | ||
3 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o | 2 | obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o |
4 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | ||
5 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o | 3 | obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o |
6 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o | 4 | obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o |
7 | obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o | 5 | obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o |
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 297d22ebcb18..b53c36dfa469 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c | |||
@@ -85,7 +85,7 @@ struct mt9t112_format { | |||
85 | 85 | ||
86 | struct mt9t112_priv { | 86 | struct mt9t112_priv { |
87 | struct v4l2_subdev subdev; | 87 | struct v4l2_subdev subdev; |
88 | struct mt9t112_camera_info *info; | 88 | struct mt9t112_platform_data *info; |
89 | struct i2c_client *client; | 89 | struct i2c_client *client; |
90 | struct v4l2_rect frame; | 90 | struct v4l2_rect frame; |
91 | struct v4l2_clk *clk; | 91 | struct v4l2_clk *clk; |
diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c index 0bf031b7e4fa..2a4882cddc51 100644 --- a/drivers/media/i2c/sr030pc30.c +++ b/drivers/media/i2c/sr030pc30.c | |||
@@ -511,13 +511,16 @@ static int sr030pc30_get_fmt(struct v4l2_subdev *sd, | |||
511 | static const struct sr030pc30_format *try_fmt(struct v4l2_subdev *sd, | 511 | static const struct sr030pc30_format *try_fmt(struct v4l2_subdev *sd, |
512 | struct v4l2_mbus_framefmt *mf) | 512 | struct v4l2_mbus_framefmt *mf) |
513 | { | 513 | { |
514 | int i = ARRAY_SIZE(sr030pc30_formats); | 514 | int i; |
515 | 515 | ||
516 | sr030pc30_try_frame_size(mf); | 516 | sr030pc30_try_frame_size(mf); |
517 | 517 | ||
518 | while (i--) | 518 | for (i = 0; i < ARRAY_SIZE(sr030pc30_formats); i++) { |
519 | if (mf->code == sr030pc30_formats[i].code) | 519 | if (mf->code == sr030pc30_formats[i].code) |
520 | break; | 520 | break; |
521 | } | ||
522 | if (i == ARRAY_SIZE(sr030pc30_formats)) | ||
523 | i = 0; | ||
521 | 524 | ||
522 | mf->code = sr030pc30_formats[i].code; | 525 | mf->code = sr030pc30_formats[i].code; |
523 | 526 | ||
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 2b8181469b93..393bbbbbaad7 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c | |||
@@ -1,22 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * tc358743 - Toshiba HDMI to CSI-2 bridge | 3 | * tc358743 - Toshiba HDMI to CSI-2 bridge |
3 | * | 4 | * |
4 | * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights | 5 | * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights |
5 | * reserved. | 6 | * reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | * | ||
20 | */ | 7 | */ |
21 | 8 | ||
22 | /* | 9 | /* |
diff --git a/drivers/media/i2c/tc358743_regs.h b/drivers/media/i2c/tc358743_regs.h index 227b46471793..2495878dc358 100644 --- a/drivers/media/i2c/tc358743_regs.h +++ b/drivers/media/i2c/tc358743_regs.h | |||
@@ -1,22 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * tc358743 - Toshiba HDMI to CSI-2 bridge - register names and bit masks | 3 | * tc358743 - Toshiba HDMI to CSI-2 bridge - register names and bit masks |
3 | * | 4 | * |
4 | * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights | 5 | * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights |
5 | * reserved. | 6 | * reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | * | ||
20 | */ | 7 | */ |
21 | 8 | ||
22 | /* | 9 | /* |
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c new file mode 100644 index 000000000000..3021913c28fa --- /dev/null +++ b/drivers/media/i2c/tda1997x.c | |||
@@ -0,0 +1,2820 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (C) 2018 Gateworks Corporation | ||
4 | */ | ||
5 | #include <linux/delay.h> | ||
6 | #include <linux/hdmi.h> | ||
7 | #include <linux/i2c.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/of_graph.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/regulator/consumer.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/v4l2-dv-timings.h> | ||
17 | #include <linux/videodev2.h> | ||
18 | |||
19 | #include <media/v4l2-ctrls.h> | ||
20 | #include <media/v4l2-device.h> | ||
21 | #include <media/v4l2-dv-timings.h> | ||
22 | #include <media/v4l2-event.h> | ||
23 | #include <media/v4l2-fwnode.h> | ||
24 | #include <media/i2c/tda1997x.h> | ||
25 | |||
26 | #include <sound/core.h> | ||
27 | #include <sound/pcm.h> | ||
28 | #include <sound/pcm_params.h> | ||
29 | #include <sound/soc.h> | ||
30 | |||
31 | #include <dt-bindings/media/tda1997x.h> | ||
32 | |||
33 | #include "tda1997x_regs.h" | ||
34 | |||
35 | #define TDA1997X_MBUS_CODES 5 | ||
36 | |||
37 | /* debug level */ | ||
38 | static int debug; | ||
39 | module_param(debug, int, 0644); | ||
40 | MODULE_PARM_DESC(debug, "debug level (0-2)"); | ||
41 | |||
42 | /* Audio formats */ | ||
43 | static const char * const audtype_names[] = { | ||
44 | "PCM", /* PCM Samples */ | ||
45 | "HBR", /* High Bit Rate Audio */ | ||
46 | "OBA", /* One-Bit Audio */ | ||
47 | "DST" /* Direct Stream Transfer */ | ||
48 | }; | ||
49 | |||
50 | /* Audio output port formats */ | ||
51 | enum audfmt_types { | ||
52 | AUDFMT_TYPE_DISABLED = 0, | ||
53 | AUDFMT_TYPE_I2S, | ||
54 | AUDFMT_TYPE_SPDIF, | ||
55 | }; | ||
56 | static const char * const audfmt_names[] = { | ||
57 | "Disabled", | ||
58 | "I2S", | ||
59 | "SPDIF", | ||
60 | }; | ||
61 | |||
62 | /* Video input formats */ | ||
63 | static const char * const hdmi_colorspace_names[] = { | ||
64 | "RGB", "YUV422", "YUV444", "YUV420", "", "", "", "", | ||
65 | }; | ||
66 | static const char * const hdmi_colorimetry_names[] = { | ||
67 | "", "ITU601", "ITU709", "Extended", | ||
68 | }; | ||
69 | static const char * const v4l2_quantization_names[] = { | ||
70 | "Default", | ||
71 | "Full Range (0-255)", | ||
72 | "Limited Range (16-235)", | ||
73 | }; | ||
74 | |||
75 | /* Video output port formats */ | ||
76 | static const char * const vidfmt_names[] = { | ||
77 | "RGB444/YUV444", /* RGB/YUV444 16bit data bus, 8bpp */ | ||
78 | "YUV422 semi-planar", /* YUV422 16bit data base, 8bpp */ | ||
79 | "YUV422 CCIR656", /* BT656 (YUV 8bpp 2 clock per pixel) */ | ||
80 | "Invalid", | ||
81 | }; | ||
82 | |||
83 | /* | ||
84 | * Colorspace conversion matrices | ||
85 | */ | ||
86 | struct color_matrix_coefs { | ||
87 | const char *name; | ||
88 | /* Input offsets */ | ||
89 | s16 offint1; | ||
90 | s16 offint2; | ||
91 | s16 offint3; | ||
92 | /* Coeficients */ | ||
93 | s16 p11coef; | ||
94 | s16 p12coef; | ||
95 | s16 p13coef; | ||
96 | s16 p21coef; | ||
97 | s16 p22coef; | ||
98 | s16 p23coef; | ||
99 | s16 p31coef; | ||
100 | s16 p32coef; | ||
101 | s16 p33coef; | ||
102 | /* Output offsets */ | ||
103 | s16 offout1; | ||
104 | s16 offout2; | ||
105 | s16 offout3; | ||
106 | }; | ||
107 | |||
108 | enum { | ||
109 | ITU709_RGBFULL, | ||
110 | ITU601_RGBFULL, | ||
111 | RGBLIMITED_RGBFULL, | ||
112 | RGBLIMITED_ITU601, | ||
113 | RGBLIMITED_ITU709, | ||
114 | RGBFULL_ITU601, | ||
115 | RGBFULL_ITU709, | ||
116 | }; | ||
117 | |||
118 | /* NB: 4096 is 1.0 using fixed point numbers */ | ||
119 | static const struct color_matrix_coefs conv_matrix[] = { | ||
120 | { | ||
121 | "YUV709 -> RGB full", | ||
122 | -256, -2048, -2048, | ||
123 | 4769, -2183, -873, | ||
124 | 4769, 7343, 0, | ||
125 | 4769, 0, 8652, | ||
126 | 0, 0, 0, | ||
127 | }, | ||
128 | { | ||
129 | "YUV601 -> RGB full", | ||
130 | -256, -2048, -2048, | ||
131 | 4769, -3330, -1602, | ||
132 | 4769, 6538, 0, | ||
133 | 4769, 0, 8264, | ||
134 | 256, 256, 256, | ||
135 | }, | ||
136 | { | ||
137 | "RGB limited -> RGB full", | ||
138 | -256, -256, -256, | ||
139 | 0, 4769, 0, | ||
140 | 0, 0, 4769, | ||
141 | 4769, 0, 0, | ||
142 | 0, 0, 0, | ||
143 | }, | ||
144 | { | ||
145 | "RGB limited -> ITU601", | ||
146 | -256, -256, -256, | ||
147 | 2404, 1225, 467, | ||
148 | -1754, 2095, -341, | ||
149 | -1388, -707, 2095, | ||
150 | 256, 2048, 2048, | ||
151 | }, | ||
152 | { | ||
153 | "RGB limited -> ITU709", | ||
154 | -256, -256, -256, | ||
155 | 2918, 867, 295, | ||
156 | -1894, 2087, -190, | ||
157 | -1607, -477, 2087, | ||
158 | 256, 2048, 2048, | ||
159 | }, | ||
160 | { | ||
161 | "RGB full -> ITU601", | ||
162 | 0, 0, 0, | ||
163 | 2065, 1052, 401, | ||
164 | -1506, 1799, -293, | ||
165 | -1192, -607, 1799, | ||
166 | 256, 2048, 2048, | ||
167 | }, | ||
168 | { | ||
169 | "RGB full -> ITU709", | ||
170 | 0, 0, 0, | ||
171 | 2506, 745, 253, | ||
172 | -1627, 1792, -163, | ||
173 | -1380, -410, 1792, | ||
174 | 256, 2048, 2048, | ||
175 | }, | ||
176 | }; | ||
177 | |||
178 | static const struct v4l2_dv_timings_cap tda1997x_dv_timings_cap = { | ||
179 | .type = V4L2_DV_BT_656_1120, | ||
180 | /* keep this initialization for compatibility with GCC < 4.4.6 */ | ||
181 | .reserved = { 0 }, | ||
182 | |||
183 | V4L2_INIT_BT_TIMINGS( | ||
184 | 640, 1920, /* min/max width */ | ||
185 | 350, 1200, /* min/max height */ | ||
186 | 13000000, 165000000, /* min/max pixelclock */ | ||
187 | /* standards */ | ||
188 | V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | | ||
189 | V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT, | ||
190 | /* capabilities */ | ||
191 | V4L2_DV_BT_CAP_INTERLACED | V4L2_DV_BT_CAP_PROGRESSIVE | | ||
192 | V4L2_DV_BT_CAP_REDUCED_BLANKING | | ||
193 | V4L2_DV_BT_CAP_CUSTOM | ||
194 | ) | ||
195 | }; | ||
196 | |||
197 | /* regulator supplies */ | ||
198 | static const char * const tda1997x_supply_name[] = { | ||
199 | "DOVDD", /* Digital I/O supply */ | ||
200 | "DVDD", /* Digital Core supply */ | ||
201 | "AVDD", /* Analog supply */ | ||
202 | }; | ||
203 | |||
204 | #define TDA1997X_NUM_SUPPLIES ARRAY_SIZE(tda1997x_supply_name) | ||
205 | |||
206 | enum tda1997x_type { | ||
207 | TDA19971, | ||
208 | TDA19973, | ||
209 | }; | ||
210 | |||
211 | enum tda1997x_hdmi_pads { | ||
212 | TDA1997X_PAD_SOURCE, | ||
213 | TDA1997X_NUM_PADS, | ||
214 | }; | ||
215 | |||
216 | struct tda1997x_chip_info { | ||
217 | enum tda1997x_type type; | ||
218 | const char *name; | ||
219 | }; | ||
220 | |||
221 | struct tda1997x_state { | ||
222 | const struct tda1997x_chip_info *info; | ||
223 | struct tda1997x_platform_data pdata; | ||
224 | struct i2c_client *client; | ||
225 | struct i2c_client *client_cec; | ||
226 | struct v4l2_subdev sd; | ||
227 | struct regulator_bulk_data supplies[TDA1997X_NUM_SUPPLIES]; | ||
228 | struct media_pad pads[TDA1997X_NUM_PADS]; | ||
229 | struct mutex lock; | ||
230 | struct mutex page_lock; | ||
231 | char page; | ||
232 | |||
233 | /* detected info from chip */ | ||
234 | int chip_revision; | ||
235 | char port_30bit; | ||
236 | char output_2p5; | ||
237 | char tmdsb_clk; | ||
238 | char tmdsb_soc; | ||
239 | |||
240 | /* status info */ | ||
241 | char hdmi_status; | ||
242 | char mptrw_in_progress; | ||
243 | char activity_status; | ||
244 | char input_detect[2]; | ||
245 | |||
246 | /* video */ | ||
247 | struct hdmi_avi_infoframe avi_infoframe; | ||
248 | struct v4l2_hdmi_colorimetry colorimetry; | ||
249 | u32 rgb_quantization_range; | ||
250 | struct v4l2_dv_timings timings; | ||
251 | int fps; | ||
252 | const struct color_matrix_coefs *conv; | ||
253 | u32 mbus_codes[TDA1997X_MBUS_CODES]; /* available modes */ | ||
254 | u32 mbus_code; /* current mode */ | ||
255 | u8 vid_fmt; | ||
256 | |||
257 | /* controls */ | ||
258 | struct v4l2_ctrl_handler hdl; | ||
259 | struct v4l2_ctrl *detect_tx_5v_ctrl; | ||
260 | struct v4l2_ctrl *rgb_quantization_range_ctrl; | ||
261 | |||
262 | /* audio */ | ||
263 | u8 audio_ch_alloc; | ||
264 | int audio_samplerate; | ||
265 | int audio_channels; | ||
266 | int audio_samplesize; | ||
267 | int audio_type; | ||
268 | struct mutex audio_lock; | ||
269 | struct snd_pcm_substream *audio_stream; | ||
270 | |||
271 | /* EDID */ | ||
272 | struct { | ||
273 | u8 edid[256]; | ||
274 | u32 present; | ||
275 | unsigned int blocks; | ||
276 | } edid; | ||
277 | struct delayed_work delayed_work_enable_hpd; | ||
278 | }; | ||
279 | |||
280 | static const struct v4l2_event tda1997x_ev_fmt = { | ||
281 | .type = V4L2_EVENT_SOURCE_CHANGE, | ||
282 | .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, | ||
283 | }; | ||
284 | |||
285 | static const struct tda1997x_chip_info tda1997x_chip_info[] = { | ||
286 | [TDA19971] = { | ||
287 | .type = TDA19971, | ||
288 | .name = "tda19971", | ||
289 | }, | ||
290 | [TDA19973] = { | ||
291 | .type = TDA19973, | ||
292 | .name = "tda19973", | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | static inline struct tda1997x_state *to_state(struct v4l2_subdev *sd) | ||
297 | { | ||
298 | return container_of(sd, struct tda1997x_state, sd); | ||
299 | } | ||
300 | |||
301 | static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) | ||
302 | { | ||
303 | return &container_of(ctrl->handler, struct tda1997x_state, hdl)->sd; | ||
304 | } | ||
305 | |||
306 | static int tda1997x_cec_read(struct v4l2_subdev *sd, u8 reg) | ||
307 | { | ||
308 | struct tda1997x_state *state = to_state(sd); | ||
309 | int val; | ||
310 | |||
311 | val = i2c_smbus_read_byte_data(state->client_cec, reg); | ||
312 | if (val < 0) { | ||
313 | v4l_err(state->client, "read reg error: reg=%2x\n", reg); | ||
314 | val = -1; | ||
315 | } | ||
316 | |||
317 | return val; | ||
318 | } | ||
319 | |||
320 | static int tda1997x_cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) | ||
321 | { | ||
322 | struct tda1997x_state *state = to_state(sd); | ||
323 | int ret = 0; | ||
324 | |||
325 | ret = i2c_smbus_write_byte_data(state->client_cec, reg, val); | ||
326 | if (ret < 0) { | ||
327 | v4l_err(state->client, "write reg error:reg=%2x,val=%2x\n", | ||
328 | reg, val); | ||
329 | ret = -1; | ||
330 | } | ||
331 | |||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | /* ----------------------------------------------------------------------------- | ||
336 | * I2C transfer | ||
337 | */ | ||
338 | |||
339 | static int tda1997x_setpage(struct v4l2_subdev *sd, u8 page) | ||
340 | { | ||
341 | struct tda1997x_state *state = to_state(sd); | ||
342 | int ret; | ||
343 | |||
344 | if (state->page != page) { | ||
345 | ret = i2c_smbus_write_byte_data(state->client, | ||
346 | REG_CURPAGE_00H, page); | ||
347 | if (ret < 0) { | ||
348 | v4l_err(state->client, | ||
349 | "write reg error:reg=%2x,val=%2x\n", | ||
350 | REG_CURPAGE_00H, page); | ||
351 | return ret; | ||
352 | } | ||
353 | state->page = page; | ||
354 | } | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static inline int io_read(struct v4l2_subdev *sd, u16 reg) | ||
359 | { | ||
360 | struct tda1997x_state *state = to_state(sd); | ||
361 | int val; | ||
362 | |||
363 | mutex_lock(&state->page_lock); | ||
364 | if (tda1997x_setpage(sd, reg >> 8)) { | ||
365 | val = -1; | ||
366 | goto out; | ||
367 | } | ||
368 | |||
369 | val = i2c_smbus_read_byte_data(state->client, reg&0xff); | ||
370 | if (val < 0) { | ||
371 | v4l_err(state->client, "read reg error: reg=%2x\n", reg & 0xff); | ||
372 | val = -1; | ||
373 | goto out; | ||
374 | } | ||
375 | |||
376 | out: | ||
377 | mutex_unlock(&state->page_lock); | ||
378 | return val; | ||
379 | } | ||
380 | |||
381 | static inline long io_read16(struct v4l2_subdev *sd, u16 reg) | ||
382 | { | ||
383 | int val; | ||
384 | long lval = 0; | ||
385 | |||
386 | val = io_read(sd, reg); | ||
387 | if (val < 0) | ||
388 | return val; | ||
389 | lval |= (val << 8); | ||
390 | val = io_read(sd, reg + 1); | ||
391 | if (val < 0) | ||
392 | return val; | ||
393 | lval |= val; | ||
394 | |||
395 | return lval; | ||
396 | } | ||
397 | |||
398 | static inline long io_read24(struct v4l2_subdev *sd, u16 reg) | ||
399 | { | ||
400 | int val; | ||
401 | long lval = 0; | ||
402 | |||
403 | val = io_read(sd, reg); | ||
404 | if (val < 0) | ||
405 | return val; | ||
406 | lval |= (val << 16); | ||
407 | val = io_read(sd, reg + 1); | ||
408 | if (val < 0) | ||
409 | return val; | ||
410 | lval |= (val << 8); | ||
411 | val = io_read(sd, reg + 2); | ||
412 | if (val < 0) | ||
413 | return val; | ||
414 | lval |= val; | ||
415 | |||
416 | return lval; | ||
417 | } | ||
418 | |||
419 | static unsigned int io_readn(struct v4l2_subdev *sd, u16 reg, u8 len, u8 *data) | ||
420 | { | ||
421 | int i; | ||
422 | int sz = 0; | ||
423 | int val; | ||
424 | |||
425 | for (i = 0; i < len; i++) { | ||
426 | val = io_read(sd, reg + i); | ||
427 | if (val < 0) | ||
428 | break; | ||
429 | data[i] = val; | ||
430 | sz++; | ||
431 | } | ||
432 | |||
433 | return sz; | ||
434 | } | ||
435 | |||
436 | static int io_write(struct v4l2_subdev *sd, u16 reg, u8 val) | ||
437 | { | ||
438 | struct tda1997x_state *state = to_state(sd); | ||
439 | s32 ret = 0; | ||
440 | |||
441 | mutex_lock(&state->page_lock); | ||
442 | if (tda1997x_setpage(sd, reg >> 8)) { | ||
443 | ret = -1; | ||
444 | goto out; | ||
445 | } | ||
446 | |||
447 | ret = i2c_smbus_write_byte_data(state->client, reg & 0xff, val); | ||
448 | if (ret < 0) { | ||
449 | v4l_err(state->client, "write reg error:reg=%2x,val=%2x\n", | ||
450 | reg&0xff, val); | ||
451 | ret = -1; | ||
452 | goto out; | ||
453 | } | ||
454 | |||
455 | out: | ||
456 | mutex_unlock(&state->page_lock); | ||
457 | return ret; | ||
458 | } | ||
459 | |||
460 | static int io_write16(struct v4l2_subdev *sd, u16 reg, u16 val) | ||
461 | { | ||
462 | int ret; | ||
463 | |||
464 | ret = io_write(sd, reg, (val >> 8) & 0xff); | ||
465 | if (ret < 0) | ||
466 | return ret; | ||
467 | ret = io_write(sd, reg + 1, val & 0xff); | ||
468 | if (ret < 0) | ||
469 | return ret; | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int io_write24(struct v4l2_subdev *sd, u16 reg, u32 val) | ||
474 | { | ||
475 | int ret; | ||
476 | |||
477 | ret = io_write(sd, reg, (val >> 16) & 0xff); | ||
478 | if (ret < 0) | ||
479 | return ret; | ||
480 | ret = io_write(sd, reg + 1, (val >> 8) & 0xff); | ||
481 | if (ret < 0) | ||
482 | return ret; | ||
483 | ret = io_write(sd, reg + 2, val & 0xff); | ||
484 | if (ret < 0) | ||
485 | return ret; | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /* ----------------------------------------------------------------------------- | ||
490 | * Hotplug | ||
491 | */ | ||
492 | |||
493 | enum hpd_mode { | ||
494 | HPD_LOW_BP, /* HPD low and pulse of at least 100ms */ | ||
495 | HPD_LOW_OTHER, /* HPD low and pulse of at least 100ms */ | ||
496 | HPD_HIGH_BP, /* HIGH */ | ||
497 | HPD_HIGH_OTHER, | ||
498 | HPD_PULSE, /* HPD low pulse */ | ||
499 | }; | ||
500 | |||
501 | /* manual HPD (Hot Plug Detect) control */ | ||
502 | static int tda1997x_manual_hpd(struct v4l2_subdev *sd, enum hpd_mode mode) | ||
503 | { | ||
504 | u8 hpd_auto, hpd_pwr, hpd_man; | ||
505 | |||
506 | hpd_auto = io_read(sd, REG_HPD_AUTO_CTRL); | ||
507 | hpd_pwr = io_read(sd, REG_HPD_POWER); | ||
508 | hpd_man = io_read(sd, REG_HPD_MAN_CTRL); | ||
509 | |||
510 | /* mask out unused bits */ | ||
511 | hpd_man &= (HPD_MAN_CTRL_HPD_PULSE | | ||
512 | HPD_MAN_CTRL_5VEN | | ||
513 | HPD_MAN_CTRL_HPD_B | | ||
514 | HPD_MAN_CTRL_HPD_A); | ||
515 | |||
516 | switch (mode) { | ||
517 | /* HPD low and pulse of at least 100ms */ | ||
518 | case HPD_LOW_BP: | ||
519 | /* hpd_bp=0 */ | ||
520 | hpd_pwr &= ~HPD_POWER_BP_MASK; | ||
521 | /* disable HPD_A and HPD_B */ | ||
522 | hpd_man &= ~(HPD_MAN_CTRL_HPD_A | HPD_MAN_CTRL_HPD_B); | ||
523 | io_write(sd, REG_HPD_POWER, hpd_pwr); | ||
524 | io_write(sd, REG_HPD_MAN_CTRL, hpd_man); | ||
525 | break; | ||
526 | /* HPD high */ | ||
527 | case HPD_HIGH_BP: | ||
528 | /* hpd_bp=1 */ | ||
529 | hpd_pwr &= ~HPD_POWER_BP_MASK; | ||
530 | hpd_pwr |= 1 << HPD_POWER_BP_SHIFT; | ||
531 | io_write(sd, REG_HPD_POWER, hpd_pwr); | ||
532 | break; | ||
533 | /* HPD low and pulse of at least 100ms */ | ||
534 | case HPD_LOW_OTHER: | ||
535 | /* disable HPD_A and HPD_B */ | ||
536 | hpd_man &= ~(HPD_MAN_CTRL_HPD_A | HPD_MAN_CTRL_HPD_B); | ||
537 | /* hp_other=0 */ | ||
538 | hpd_auto &= ~HPD_AUTO_HP_OTHER; | ||
539 | io_write(sd, REG_HPD_AUTO_CTRL, hpd_auto); | ||
540 | io_write(sd, REG_HPD_MAN_CTRL, hpd_man); | ||
541 | break; | ||
542 | /* HPD high */ | ||
543 | case HPD_HIGH_OTHER: | ||
544 | hpd_auto |= HPD_AUTO_HP_OTHER; | ||
545 | io_write(sd, REG_HPD_AUTO_CTRL, hpd_auto); | ||
546 | break; | ||
547 | /* HPD low pulse */ | ||
548 | case HPD_PULSE: | ||
549 | /* disable HPD_A and HPD_B */ | ||
550 | hpd_man &= ~(HPD_MAN_CTRL_HPD_A | HPD_MAN_CTRL_HPD_B); | ||
551 | io_write(sd, REG_HPD_MAN_CTRL, hpd_man); | ||
552 | break; | ||
553 | } | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static void tda1997x_delayed_work_enable_hpd(struct work_struct *work) | ||
559 | { | ||
560 | struct delayed_work *dwork = to_delayed_work(work); | ||
561 | struct tda1997x_state *state = container_of(dwork, | ||
562 | struct tda1997x_state, | ||
563 | delayed_work_enable_hpd); | ||
564 | struct v4l2_subdev *sd = &state->sd; | ||
565 | |||
566 | v4l2_dbg(2, debug, sd, "%s:\n", __func__); | ||
567 | |||
568 | /* Set HPD high */ | ||
569 | tda1997x_manual_hpd(sd, HPD_HIGH_OTHER); | ||
570 | tda1997x_manual_hpd(sd, HPD_HIGH_BP); | ||
571 | |||
572 | state->edid.present = 1; | ||
573 | } | ||
574 | |||
575 | static void tda1997x_disable_edid(struct v4l2_subdev *sd) | ||
576 | { | ||
577 | struct tda1997x_state *state = to_state(sd); | ||
578 | |||
579 | v4l2_dbg(1, debug, sd, "%s\n", __func__); | ||
580 | cancel_delayed_work_sync(&state->delayed_work_enable_hpd); | ||
581 | |||
582 | /* Set HPD low */ | ||
583 | tda1997x_manual_hpd(sd, HPD_LOW_BP); | ||
584 | } | ||
585 | |||
586 | static void tda1997x_enable_edid(struct v4l2_subdev *sd) | ||
587 | { | ||
588 | struct tda1997x_state *state = to_state(sd); | ||
589 | |||
590 | v4l2_dbg(1, debug, sd, "%s\n", __func__); | ||
591 | |||
592 | /* Enable hotplug after 100ms */ | ||
593 | schedule_delayed_work(&state->delayed_work_enable_hpd, HZ / 10); | ||
594 | } | ||
595 | |||
596 | /* ----------------------------------------------------------------------------- | ||
597 | * Signal Control | ||
598 | */ | ||
599 | |||
600 | /* | ||
601 | * configure vid_fmt based on mbus_code | ||
602 | */ | ||
603 | static int | ||
604 | tda1997x_setup_format(struct tda1997x_state *state, u32 code) | ||
605 | { | ||
606 | v4l_dbg(1, debug, state->client, "%s code=0x%x\n", __func__, code); | ||
607 | switch (code) { | ||
608 | case MEDIA_BUS_FMT_RGB121212_1X36: | ||
609 | case MEDIA_BUS_FMT_RGB888_1X24: | ||
610 | case MEDIA_BUS_FMT_YUV12_1X36: | ||
611 | case MEDIA_BUS_FMT_YUV8_1X24: | ||
612 | state->vid_fmt = OF_FMT_444; | ||
613 | break; | ||
614 | case MEDIA_BUS_FMT_UYVY12_1X24: | ||
615 | case MEDIA_BUS_FMT_UYVY10_1X20: | ||
616 | case MEDIA_BUS_FMT_UYVY8_1X16: | ||
617 | state->vid_fmt = OF_FMT_422_SMPT; | ||
618 | break; | ||
619 | case MEDIA_BUS_FMT_UYVY12_2X12: | ||
620 | case MEDIA_BUS_FMT_UYVY10_2X10: | ||
621 | case MEDIA_BUS_FMT_UYVY8_2X8: | ||
622 | state->vid_fmt = OF_FMT_422_CCIR; | ||
623 | break; | ||
624 | default: | ||
625 | v4l_err(state->client, "incompatible format (0x%x)\n", code); | ||
626 | return -EINVAL; | ||
627 | } | ||
628 | v4l_dbg(1, debug, state->client, "%s code=0x%x fmt=%s\n", __func__, | ||
629 | code, vidfmt_names[state->vid_fmt]); | ||
630 | state->mbus_code = code; | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | /* | ||
636 | * The color conversion matrix will convert between the colorimetry of the | ||
637 | * HDMI input to the desired output format RGB|YUV. RGB output is to be | ||
638 | * full-range and YUV is to be limited range. | ||
639 | * | ||
640 | * RGB full-range uses values from 0 to 255 which is recommended on a monitor | ||
641 | * and RGB Limited uses values from 16 to 236 (16=black, 235=white) which is | ||
642 | * typically recommended on a TV. | ||
643 | */ | ||
644 | static void | ||
645 | tda1997x_configure_csc(struct v4l2_subdev *sd) | ||
646 | { | ||
647 | struct tda1997x_state *state = to_state(sd); | ||
648 | struct hdmi_avi_infoframe *avi = &state->avi_infoframe; | ||
649 | struct v4l2_hdmi_colorimetry *c = &state->colorimetry; | ||
650 | /* Blanking code values depend on output colorspace (RGB or YUV) */ | ||
651 | struct blanking_codes { | ||
652 | s16 code_gy; | ||
653 | s16 code_bu; | ||
654 | s16 code_rv; | ||
655 | }; | ||
656 | static const struct blanking_codes rgb_blanking = { 64, 64, 64 }; | ||
657 | static const struct blanking_codes yuv_blanking = { 64, 512, 512 }; | ||
658 | const struct blanking_codes *blanking_codes = NULL; | ||
659 | u8 reg; | ||
660 | |||
661 | v4l_dbg(1, debug, state->client, "input:%s quant:%s output:%s\n", | ||
662 | hdmi_colorspace_names[avi->colorspace], | ||
663 | v4l2_quantization_names[c->quantization], | ||
664 | vidfmt_names[state->vid_fmt]); | ||
665 | state->conv = NULL; | ||
666 | switch (state->vid_fmt) { | ||
667 | /* RGB output */ | ||
668 | case OF_FMT_444: | ||
669 | blanking_codes = &rgb_blanking; | ||
670 | if (c->colorspace == V4L2_COLORSPACE_SRGB) { | ||
671 | if (c->quantization == V4L2_QUANTIZATION_LIM_RANGE) | ||
672 | state->conv = &conv_matrix[RGBLIMITED_RGBFULL]; | ||
673 | } else { | ||
674 | if (c->colorspace == V4L2_COLORSPACE_REC709) | ||
675 | state->conv = &conv_matrix[ITU709_RGBFULL]; | ||
676 | else if (c->colorspace == V4L2_COLORSPACE_SMPTE170M) | ||
677 | state->conv = &conv_matrix[ITU601_RGBFULL]; | ||
678 | } | ||
679 | break; | ||
680 | |||
681 | /* YUV output */ | ||
682 | case OF_FMT_422_SMPT: /* semi-planar */ | ||
683 | case OF_FMT_422_CCIR: /* CCIR656 */ | ||
684 | blanking_codes = &yuv_blanking; | ||
685 | if ((c->colorspace == V4L2_COLORSPACE_SRGB) && | ||
686 | (c->quantization == V4L2_QUANTIZATION_FULL_RANGE)) { | ||
687 | if (state->timings.bt.height <= 576) | ||
688 | state->conv = &conv_matrix[RGBFULL_ITU601]; | ||
689 | else | ||
690 | state->conv = &conv_matrix[RGBFULL_ITU709]; | ||
691 | } else if ((c->colorspace == V4L2_COLORSPACE_SRGB) && | ||
692 | (c->quantization == V4L2_QUANTIZATION_LIM_RANGE)) { | ||
693 | if (state->timings.bt.height <= 576) | ||
694 | state->conv = &conv_matrix[RGBLIMITED_ITU601]; | ||
695 | else | ||
696 | state->conv = &conv_matrix[RGBLIMITED_ITU709]; | ||
697 | } | ||
698 | break; | ||
699 | } | ||
700 | |||
701 | if (state->conv) { | ||
702 | v4l_dbg(1, debug, state->client, "%s\n", | ||
703 | state->conv->name); | ||
704 | /* enable matrix conversion */ | ||
705 | reg = io_read(sd, REG_VDP_CTRL); | ||
706 | reg &= ~VDP_CTRL_MATRIX_BP; | ||
707 | io_write(sd, REG_VDP_CTRL, reg); | ||
708 | /* offset inputs */ | ||
709 | io_write16(sd, REG_VDP_MATRIX + 0, state->conv->offint1); | ||
710 | io_write16(sd, REG_VDP_MATRIX + 2, state->conv->offint2); | ||
711 | io_write16(sd, REG_VDP_MATRIX + 4, state->conv->offint3); | ||
712 | /* coefficients */ | ||
713 | io_write16(sd, REG_VDP_MATRIX + 6, state->conv->p11coef); | ||
714 | io_write16(sd, REG_VDP_MATRIX + 8, state->conv->p12coef); | ||
715 | io_write16(sd, REG_VDP_MATRIX + 10, state->conv->p13coef); | ||
716 | io_write16(sd, REG_VDP_MATRIX + 12, state->conv->p21coef); | ||
717 | io_write16(sd, REG_VDP_MATRIX + 14, state->conv->p22coef); | ||
718 | io_write16(sd, REG_VDP_MATRIX + 16, state->conv->p23coef); | ||
719 | io_write16(sd, REG_VDP_MATRIX + 18, state->conv->p31coef); | ||
720 | io_write16(sd, REG_VDP_MATRIX + 20, state->conv->p32coef); | ||
721 | io_write16(sd, REG_VDP_MATRIX + 22, state->conv->p33coef); | ||
722 | /* offset outputs */ | ||
723 | io_write16(sd, REG_VDP_MATRIX + 24, state->conv->offout1); | ||
724 | io_write16(sd, REG_VDP_MATRIX + 26, state->conv->offout2); | ||
725 | io_write16(sd, REG_VDP_MATRIX + 28, state->conv->offout3); | ||
726 | } else { | ||
727 | /* disable matrix conversion */ | ||
728 | reg = io_read(sd, REG_VDP_CTRL); | ||
729 | reg |= VDP_CTRL_MATRIX_BP; | ||
730 | io_write(sd, REG_VDP_CTRL, reg); | ||
731 | } | ||
732 | |||
733 | /* SetBlankingCodes */ | ||
734 | if (blanking_codes) { | ||
735 | io_write16(sd, REG_BLK_GY, blanking_codes->code_gy); | ||
736 | io_write16(sd, REG_BLK_BU, blanking_codes->code_bu); | ||
737 | io_write16(sd, REG_BLK_RV, blanking_codes->code_rv); | ||
738 | } | ||
739 | } | ||
740 | |||
741 | /* Configure frame detection window and VHREF timing generator */ | ||
742 | static void | ||
743 | tda1997x_configure_vhref(struct v4l2_subdev *sd) | ||
744 | { | ||
745 | struct tda1997x_state *state = to_state(sd); | ||
746 | const struct v4l2_bt_timings *bt = &state->timings.bt; | ||
747 | int width, lines; | ||
748 | u16 href_start, href_end; | ||
749 | u16 vref_f1_start, vref_f2_start; | ||
750 | u8 vref_f1_width, vref_f2_width; | ||
751 | u8 field_polarity; | ||
752 | u16 fieldref_f1_start, fieldref_f2_start; | ||
753 | u8 reg; | ||
754 | |||
755 | href_start = bt->hbackporch + bt->hsync + 1; | ||
756 | href_end = href_start + bt->width; | ||
757 | vref_f1_start = bt->height + bt->vbackporch + bt->vsync + | ||
758 | bt->il_vbackporch + bt->il_vsync + | ||
759 | bt->il_vfrontporch; | ||
760 | vref_f1_width = bt->vbackporch + bt->vsync + bt->vfrontporch; | ||
761 | vref_f2_start = 0; | ||
762 | vref_f2_width = 0; | ||
763 | fieldref_f1_start = 0; | ||
764 | fieldref_f2_start = 0; | ||
765 | if (bt->interlaced) { | ||
766 | vref_f2_start = (bt->height / 2) + | ||
767 | (bt->il_vbackporch + bt->il_vsync - 1); | ||
768 | vref_f2_width = bt->il_vbackporch + bt->il_vsync + | ||
769 | bt->il_vfrontporch; | ||
770 | fieldref_f2_start = vref_f2_start + bt->il_vfrontporch + | ||
771 | fieldref_f1_start; | ||
772 | } | ||
773 | field_polarity = 0; | ||
774 | |||
775 | width = V4L2_DV_BT_FRAME_WIDTH(bt); | ||
776 | lines = V4L2_DV_BT_FRAME_HEIGHT(bt); | ||
777 | |||
778 | /* | ||
779 | * Configure Frame Detection Window: | ||
780 | * horiz area where the VHREF module consider a VSYNC a new frame | ||
781 | */ | ||
782 | io_write16(sd, REG_FDW_S, 0x2ef); /* start position */ | ||
783 | io_write16(sd, REG_FDW_E, 0x141); /* end position */ | ||
784 | |||
785 | /* Set Pixel And Line Counters */ | ||
786 | if (state->chip_revision == 0) | ||
787 | io_write16(sd, REG_PXCNT_PR, 4); | ||
788 | else | ||
789 | io_write16(sd, REG_PXCNT_PR, 1); | ||
790 | io_write16(sd, REG_PXCNT_NPIX, width & MASK_VHREF); | ||
791 | io_write16(sd, REG_LCNT_PR, 1); | ||
792 | io_write16(sd, REG_LCNT_NLIN, lines & MASK_VHREF); | ||
793 | |||
794 | /* | ||
795 | * Configure the VHRef timing generator responsible for rebuilding all | ||
796 | * horiz and vert synch and ref signals from its input allowing auto | ||
797 | * detection algorithms and forcing predefined modes (480i & 576i) | ||
798 | */ | ||
799 | reg = VHREF_STD_DET_OFF << VHREF_STD_DET_SHIFT; | ||
800 | io_write(sd, REG_VHREF_CTRL, reg); | ||
801 | |||
802 | /* | ||
803 | * Configure the VHRef timing values. In case the VHREF generator has | ||
804 | * been configured in manual mode, this will allow to manually set all | ||
805 | * horiz and vert ref values (non-active pixel areas) of the generator | ||
806 | * and allows setting the frame reference params. | ||
807 | */ | ||
808 | /* horizontal reference start/end */ | ||
809 | io_write16(sd, REG_HREF_S, href_start & MASK_VHREF); | ||
810 | io_write16(sd, REG_HREF_E, href_end & MASK_VHREF); | ||
811 | /* vertical reference f1 start/end */ | ||
812 | io_write16(sd, REG_VREF_F1_S, vref_f1_start & MASK_VHREF); | ||
813 | io_write(sd, REG_VREF_F1_WIDTH, vref_f1_width); | ||
814 | /* vertical reference f2 start/end */ | ||
815 | io_write16(sd, REG_VREF_F2_S, vref_f2_start & MASK_VHREF); | ||
816 | io_write(sd, REG_VREF_F2_WIDTH, vref_f2_width); | ||
817 | |||
818 | /* F1/F2 FREF, field polarity */ | ||
819 | reg = fieldref_f1_start & MASK_VHREF; | ||
820 | reg |= field_polarity << 8; | ||
821 | io_write16(sd, REG_FREF_F1_S, reg); | ||
822 | reg = fieldref_f2_start & MASK_VHREF; | ||
823 | io_write16(sd, REG_FREF_F2_S, reg); | ||
824 | } | ||
825 | |||
826 | /* Configure Video Output port signals */ | ||
827 | static int | ||
828 | tda1997x_configure_vidout(struct tda1997x_state *state) | ||
829 | { | ||
830 | struct v4l2_subdev *sd = &state->sd; | ||
831 | struct tda1997x_platform_data *pdata = &state->pdata; | ||
832 | u8 prefilter; | ||
833 | u8 reg; | ||
834 | |||
835 | /* Configure pixel clock generator: delay, polarity, rate */ | ||
836 | reg = (state->vid_fmt == OF_FMT_422_CCIR) ? | ||
837 | PCLK_SEL_X2 : PCLK_SEL_X1; | ||
838 | reg |= pdata->vidout_delay_pclk << PCLK_DELAY_SHIFT; | ||
839 | reg |= pdata->vidout_inv_pclk << PCLK_INV_SHIFT; | ||
840 | io_write(sd, REG_PCLK, reg); | ||
841 | |||
842 | /* Configure pre-filter */ | ||
843 | prefilter = 0; /* filters off */ | ||
844 | /* YUV422 mode requires conversion */ | ||
845 | if ((state->vid_fmt == OF_FMT_422_SMPT) || | ||
846 | (state->vid_fmt == OF_FMT_422_CCIR)) { | ||
847 | /* 2/7 taps for Rv and Bu */ | ||
848 | prefilter = FILTERS_CTRL_2_7TAP << FILTERS_CTRL_BU_SHIFT | | ||
849 | FILTERS_CTRL_2_7TAP << FILTERS_CTRL_RV_SHIFT; | ||
850 | } | ||
851 | io_write(sd, REG_FILTERS_CTRL, prefilter); | ||
852 | |||
853 | /* Configure video port */ | ||
854 | reg = state->vid_fmt & OF_FMT_MASK; | ||
855 | if (state->vid_fmt == OF_FMT_422_CCIR) | ||
856 | reg |= (OF_BLK | OF_TRC); | ||
857 | reg |= OF_VP_ENABLE; | ||
858 | io_write(sd, REG_OF, reg); | ||
859 | |||
860 | /* Configure formatter and conversions */ | ||
861 | reg = io_read(sd, REG_VDP_CTRL); | ||
862 | /* pre-filter is needed unless (REG_FILTERS_CTRL == 0) */ | ||
863 | if (!prefilter) | ||
864 | reg |= VDP_CTRL_PREFILTER_BP; | ||
865 | else | ||
866 | reg &= ~VDP_CTRL_PREFILTER_BP; | ||
867 | /* formatter is needed for YUV422 and for trc/blc codes */ | ||
868 | if (state->vid_fmt == OF_FMT_444) | ||
869 | reg |= VDP_CTRL_FORMATTER_BP; | ||
870 | /* formatter and compdel needed for timing/blanking codes */ | ||
871 | else | ||
872 | reg &= ~(VDP_CTRL_FORMATTER_BP | VDP_CTRL_COMPDEL_BP); | ||
873 | /* activate compdel for small sync delays */ | ||
874 | if ((pdata->vidout_delay_vs < 4) || (pdata->vidout_delay_hs < 4)) | ||
875 | reg &= ~VDP_CTRL_COMPDEL_BP; | ||
876 | io_write(sd, REG_VDP_CTRL, reg); | ||
877 | |||
878 | /* Configure DE output signal: delay, polarity, and source */ | ||
879 | reg = pdata->vidout_delay_de << DE_FREF_DELAY_SHIFT | | ||
880 | pdata->vidout_inv_de << DE_FREF_INV_SHIFT | | ||
881 | pdata->vidout_sel_de << DE_FREF_SEL_SHIFT; | ||
882 | io_write(sd, REG_DE_FREF, reg); | ||
883 | |||
884 | /* Configure HS/HREF output signal: delay, polarity, and source */ | ||
885 | if (state->vid_fmt != OF_FMT_422_CCIR) { | ||
886 | reg = pdata->vidout_delay_hs << HS_HREF_DELAY_SHIFT | | ||
887 | pdata->vidout_inv_hs << HS_HREF_INV_SHIFT | | ||
888 | pdata->vidout_sel_hs << HS_HREF_SEL_SHIFT; | ||
889 | } else | ||
890 | reg = HS_HREF_SEL_NONE << HS_HREF_SEL_SHIFT; | ||
891 | io_write(sd, REG_HS_HREF, reg); | ||
892 | |||
893 | /* Configure VS/VREF output signal: delay, polarity, and source */ | ||
894 | if (state->vid_fmt != OF_FMT_422_CCIR) { | ||
895 | reg = pdata->vidout_delay_vs << VS_VREF_DELAY_SHIFT | | ||
896 | pdata->vidout_inv_vs << VS_VREF_INV_SHIFT | | ||
897 | pdata->vidout_sel_vs << VS_VREF_SEL_SHIFT; | ||
898 | } else | ||
899 | reg = VS_VREF_SEL_NONE << VS_VREF_SEL_SHIFT; | ||
900 | io_write(sd, REG_VS_VREF, reg); | ||
901 | |||
902 | return 0; | ||
903 | } | ||
904 | |||
905 | /* Configure Audio output port signals */ | ||
906 | static int | ||
907 | tda1997x_configure_audout(struct v4l2_subdev *sd, u8 channel_assignment) | ||
908 | { | ||
909 | struct tda1997x_state *state = to_state(sd); | ||
910 | struct tda1997x_platform_data *pdata = &state->pdata; | ||
911 | bool sp_used_by_fifo = 1; | ||
912 | u8 reg; | ||
913 | |||
914 | if (!pdata->audout_format) | ||
915 | return 0; | ||
916 | |||
917 | /* channel assignment (CEA-861-D Table 20) */ | ||
918 | io_write(sd, REG_AUDIO_PATH, channel_assignment); | ||
919 | |||
920 | /* Audio output configuration */ | ||
921 | reg = 0; | ||
922 | switch (pdata->audout_format) { | ||
923 | case AUDFMT_TYPE_I2S: | ||
924 | reg |= AUDCFG_BUS_I2S << AUDCFG_BUS_SHIFT; | ||
925 | break; | ||
926 | case AUDFMT_TYPE_SPDIF: | ||
927 | reg |= AUDCFG_BUS_SPDIF << AUDCFG_BUS_SHIFT; | ||
928 | break; | ||
929 | } | ||
930 | switch (state->audio_type) { | ||
931 | case AUDCFG_TYPE_PCM: | ||
932 | reg |= AUDCFG_TYPE_PCM << AUDCFG_TYPE_SHIFT; | ||
933 | break; | ||
934 | case AUDCFG_TYPE_OBA: | ||
935 | reg |= AUDCFG_TYPE_OBA << AUDCFG_TYPE_SHIFT; | ||
936 | break; | ||
937 | case AUDCFG_TYPE_DST: | ||
938 | reg |= AUDCFG_TYPE_DST << AUDCFG_TYPE_SHIFT; | ||
939 | sp_used_by_fifo = 0; | ||
940 | break; | ||
941 | case AUDCFG_TYPE_HBR: | ||
942 | reg |= AUDCFG_TYPE_HBR << AUDCFG_TYPE_SHIFT; | ||
943 | if (pdata->audout_layout == 1) { | ||
944 | /* demuxed via AP0:AP3 */ | ||
945 | reg |= AUDCFG_HBR_DEMUX << AUDCFG_HBR_SHIFT; | ||
946 | if (pdata->audout_format == AUDFMT_TYPE_SPDIF) | ||
947 | sp_used_by_fifo = 0; | ||
948 | } else { | ||
949 | /* straight via AP0 */ | ||
950 | reg |= AUDCFG_HBR_STRAIGHT << AUDCFG_HBR_SHIFT; | ||
951 | } | ||
952 | break; | ||
953 | } | ||
954 | if (pdata->audout_width == 32) | ||
955 | reg |= AUDCFG_I2SW_32 << AUDCFG_I2SW_SHIFT; | ||
956 | else | ||
957 | reg |= AUDCFG_I2SW_16 << AUDCFG_I2SW_SHIFT; | ||
958 | |||
959 | /* automatic hardware mute */ | ||
960 | if (pdata->audio_auto_mute) | ||
961 | reg |= AUDCFG_AUTO_MUTE_EN; | ||
962 | /* clock polarity */ | ||
963 | if (pdata->audout_invert_clk) | ||
964 | reg |= AUDCFG_CLK_INVERT; | ||
965 | io_write(sd, REG_AUDCFG, reg); | ||
966 | |||
967 | /* audio layout */ | ||
968 | reg = (pdata->audout_layout) ? AUDIO_LAYOUT_LAYOUT1 : 0; | ||
969 | if (!pdata->audout_layoutauto) | ||
970 | reg |= AUDIO_LAYOUT_MANUAL; | ||
971 | if (sp_used_by_fifo) | ||
972 | reg |= AUDIO_LAYOUT_SP_FLAG; | ||
973 | io_write(sd, REG_AUDIO_LAYOUT, reg); | ||
974 | |||
975 | /* FIFO Latency value */ | ||
976 | io_write(sd, REG_FIFO_LATENCY_VAL, 0x80); | ||
977 | |||
978 | /* Audio output port config */ | ||
979 | if (sp_used_by_fifo) { | ||
980 | reg = AUDIO_OUT_ENABLE_AP0; | ||
981 | if (channel_assignment >= 0x01) | ||
982 | reg |= AUDIO_OUT_ENABLE_AP1; | ||
983 | if (channel_assignment >= 0x04) | ||
984 | reg |= AUDIO_OUT_ENABLE_AP2; | ||
985 | if (channel_assignment >= 0x0c) | ||
986 | reg |= AUDIO_OUT_ENABLE_AP3; | ||
987 | /* specific cases where AP1 is not used */ | ||
988 | if ((channel_assignment == 0x04) | ||
989 | || (channel_assignment == 0x08) | ||
990 | || (channel_assignment == 0x0c) | ||
991 | || (channel_assignment == 0x10) | ||
992 | || (channel_assignment == 0x14) | ||
993 | || (channel_assignment == 0x18) | ||
994 | || (channel_assignment == 0x1c)) | ||
995 | reg &= ~AUDIO_OUT_ENABLE_AP1; | ||
996 | /* specific cases where AP2 is not used */ | ||
997 | if ((channel_assignment >= 0x14) | ||
998 | && (channel_assignment <= 0x17)) | ||
999 | reg &= ~AUDIO_OUT_ENABLE_AP2; | ||
1000 | } else { | ||
1001 | reg = AUDIO_OUT_ENABLE_AP3 | | ||
1002 | AUDIO_OUT_ENABLE_AP2 | | ||
1003 | AUDIO_OUT_ENABLE_AP1 | | ||
1004 | AUDIO_OUT_ENABLE_AP0; | ||
1005 | } | ||
1006 | if (pdata->audout_format == AUDFMT_TYPE_I2S) | ||
1007 | reg |= (AUDIO_OUT_ENABLE_ACLK | AUDIO_OUT_ENABLE_WS); | ||
1008 | io_write(sd, REG_AUDIO_OUT_ENABLE, reg); | ||
1009 | |||
1010 | /* reset test mode to normal audio freq auto selection */ | ||
1011 | io_write(sd, REG_TEST_MODE, 0x00); | ||
1012 | |||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | /* Soft Reset of specific hdmi info */ | ||
1017 | static int | ||
1018 | tda1997x_hdmi_info_reset(struct v4l2_subdev *sd, u8 info_rst, bool reset_sus) | ||
1019 | { | ||
1020 | u8 reg; | ||
1021 | |||
1022 | /* reset infoframe engine packets */ | ||
1023 | reg = io_read(sd, REG_HDMI_INFO_RST); | ||
1024 | io_write(sd, REG_HDMI_INFO_RST, info_rst); | ||
1025 | |||
1026 | /* if infoframe engine has been reset clear INT_FLG_MODE */ | ||
1027 | if (reg & RESET_IF) { | ||
1028 | reg = io_read(sd, REG_INT_FLG_CLR_MODE); | ||
1029 | io_write(sd, REG_INT_FLG_CLR_MODE, reg); | ||
1030 | } | ||
1031 | |||
1032 | /* Disable REFTIM to restart start-up-sequencer (SUS) */ | ||
1033 | reg = io_read(sd, REG_RATE_CTRL); | ||
1034 | reg &= ~RATE_REFTIM_ENABLE; | ||
1035 | if (!reset_sus) | ||
1036 | reg |= RATE_REFTIM_ENABLE; | ||
1037 | reg = io_write(sd, REG_RATE_CTRL, reg); | ||
1038 | |||
1039 | return 0; | ||
1040 | } | ||
1041 | |||
1042 | static void | ||
1043 | tda1997x_power_mode(struct tda1997x_state *state, bool enable) | ||
1044 | { | ||
1045 | struct v4l2_subdev *sd = &state->sd; | ||
1046 | u8 reg; | ||
1047 | |||
1048 | if (enable) { | ||
1049 | /* Automatic control of TMDS */ | ||
1050 | io_write(sd, REG_PON_OVR_EN, PON_DIS); | ||
1051 | /* Enable current bias unit */ | ||
1052 | io_write(sd, REG_CFG1, PON_EN); | ||
1053 | /* Enable deep color PLL */ | ||
1054 | io_write(sd, REG_DEEP_PLL7_BYP, PON_DIS); | ||
1055 | /* Output buffers active */ | ||
1056 | reg = io_read(sd, REG_OF); | ||
1057 | reg &= ~OF_VP_ENABLE; | ||
1058 | io_write(sd, REG_OF, reg); | ||
1059 | } else { | ||
1060 | /* Power down EDID mode sequence */ | ||
1061 | /* Output buffers in HiZ */ | ||
1062 | reg = io_read(sd, REG_OF); | ||
1063 | reg |= OF_VP_ENABLE; | ||
1064 | io_write(sd, REG_OF, reg); | ||
1065 | /* Disable deep color PLL */ | ||
1066 | io_write(sd, REG_DEEP_PLL7_BYP, PON_EN); | ||
1067 | /* Disable current bias unit */ | ||
1068 | io_write(sd, REG_CFG1, PON_DIS); | ||
1069 | /* Manual control of TMDS */ | ||
1070 | io_write(sd, REG_PON_OVR_EN, PON_EN); | ||
1071 | } | ||
1072 | } | ||
1073 | |||
1074 | static bool | ||
1075 | tda1997x_detect_tx_5v(struct v4l2_subdev *sd) | ||
1076 | { | ||
1077 | u8 reg = io_read(sd, REG_DETECT_5V); | ||
1078 | |||
1079 | return ((reg & DETECT_5V_SEL) ? 1 : 0); | ||
1080 | } | ||
1081 | |||
1082 | static bool | ||
1083 | tda1997x_detect_tx_hpd(struct v4l2_subdev *sd) | ||
1084 | { | ||
1085 | u8 reg = io_read(sd, REG_DETECT_5V); | ||
1086 | |||
1087 | return ((reg & DETECT_HPD) ? 1 : 0); | ||
1088 | } | ||
1089 | |||
1090 | static int | ||
1091 | tda1997x_detect_std(struct tda1997x_state *state, | ||
1092 | struct v4l2_dv_timings *timings) | ||
1093 | { | ||
1094 | struct v4l2_subdev *sd = &state->sd; | ||
1095 | u32 vper; | ||
1096 | u16 hper; | ||
1097 | u16 hsper; | ||
1098 | int i; | ||
1099 | |||
1100 | /* | ||
1101 | * Read the FMT registers | ||
1102 | * REG_V_PER: Period of a frame (or two fields) in MCLK(27MHz) cycles | ||
1103 | * REG_H_PER: Period of a line in MCLK(27MHz) cycles | ||
1104 | * REG_HS_WIDTH: Period of horiz sync pulse in MCLK(27MHz) cycles | ||
1105 | */ | ||
1106 | vper = io_read24(sd, REG_V_PER) & MASK_VPER; | ||
1107 | hper = io_read16(sd, REG_H_PER) & MASK_HPER; | ||
1108 | hsper = io_read16(sd, REG_HS_WIDTH) & MASK_HSWIDTH; | ||
1109 | v4l2_dbg(1, debug, sd, "Signal Timings: %u/%u/%u\n", vper, hper, hsper); | ||
1110 | if (!vper || !hper || !hsper) | ||
1111 | return -ENOLINK; | ||
1112 | |||
1113 | for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) { | ||
1114 | const struct v4l2_bt_timings *bt; | ||
1115 | u32 lines, width, _hper, _hsper; | ||
1116 | u32 vmin, vmax, hmin, hmax, hsmin, hsmax; | ||
1117 | bool vmatch, hmatch, hsmatch; | ||
1118 | |||
1119 | bt = &v4l2_dv_timings_presets[i].bt; | ||
1120 | width = V4L2_DV_BT_FRAME_WIDTH(bt); | ||
1121 | lines = V4L2_DV_BT_FRAME_HEIGHT(bt); | ||
1122 | _hper = (u32)bt->pixelclock / width; | ||
1123 | if (bt->interlaced) | ||
1124 | lines /= 2; | ||
1125 | /* vper +/- 0.7% */ | ||
1126 | vmin = ((27000000 / 1000) * 993) / _hper * lines; | ||
1127 | vmax = ((27000000 / 1000) * 1007) / _hper * lines; | ||
1128 | /* hper +/- 1.0% */ | ||
1129 | hmin = ((27000000 / 100) * 99) / _hper; | ||
1130 | hmax = ((27000000 / 100) * 101) / _hper; | ||
1131 | /* hsper +/- 2 (take care to avoid 32bit overflow) */ | ||
1132 | _hsper = 27000 * bt->hsync / ((u32)bt->pixelclock/1000); | ||
1133 | hsmin = _hsper - 2; | ||
1134 | hsmax = _hsper + 2; | ||
1135 | |||
1136 | /* vmatch matches the framerate */ | ||
1137 | vmatch = ((vper <= vmax) && (vper >= vmin)) ? 1 : 0; | ||
1138 | /* hmatch matches the width */ | ||
1139 | hmatch = ((hper <= hmax) && (hper >= hmin)) ? 1 : 0; | ||
1140 | /* hsmatch matches the hswidth */ | ||
1141 | hsmatch = ((hsper <= hsmax) && (hsper >= hsmin)) ? 1 : 0; | ||
1142 | if (hmatch && vmatch && hsmatch) { | ||
1143 | v4l2_print_dv_timings(sd->name, "Detected format: ", | ||
1144 | &v4l2_dv_timings_presets[i], | ||
1145 | false); | ||
1146 | if (timings) | ||
1147 | *timings = v4l2_dv_timings_presets[i]; | ||
1148 | return 0; | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | v4l_err(state->client, "no resolution match for timings: %d/%d/%d\n", | ||
1153 | vper, hper, hsper); | ||
1154 | return -ERANGE; | ||
1155 | } | ||
1156 | |||
1157 | /* some sort of errata workaround for chip revision 0 (N1) */ | ||
1158 | static void tda1997x_reset_n1(struct tda1997x_state *state) | ||
1159 | { | ||
1160 | struct v4l2_subdev *sd = &state->sd; | ||
1161 | u8 reg; | ||
1162 | |||
1163 | /* clear HDMI mode flag in BCAPS */ | ||
1164 | io_write(sd, REG_CLK_CFG, CLK_CFG_SEL_ACLK_EN | CLK_CFG_SEL_ACLK); | ||
1165 | io_write(sd, REG_PON_OVR_EN, PON_EN); | ||
1166 | io_write(sd, REG_PON_CBIAS, PON_EN); | ||
1167 | io_write(sd, REG_PON_PLL, PON_EN); | ||
1168 | |||
1169 | reg = io_read(sd, REG_MODE_REC_CFG1); | ||
1170 | reg &= ~0x06; | ||
1171 | reg |= 0x02; | ||
1172 | io_write(sd, REG_MODE_REC_CFG1, reg); | ||
1173 | io_write(sd, REG_CLK_CFG, CLK_CFG_DIS); | ||
1174 | io_write(sd, REG_PON_OVR_EN, PON_DIS); | ||
1175 | reg = io_read(sd, REG_MODE_REC_CFG1); | ||
1176 | reg &= ~0x06; | ||
1177 | io_write(sd, REG_MODE_REC_CFG1, reg); | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Activity detection must only be notified when stable_clk_x AND active_x | ||
1182 | * bits are set to 1. If only stable_clk_x bit is set to 1 but not | ||
1183 | * active_x, it means that the TMDS clock is not in the defined range | ||
1184 | * and activity detection must not be notified. | ||
1185 | */ | ||
1186 | static u8 | ||
1187 | tda1997x_read_activity_status_regs(struct v4l2_subdev *sd) | ||
1188 | { | ||
1189 | u8 reg, status = 0; | ||
1190 | |||
1191 | /* Read CLK_A_STATUS register */ | ||
1192 | reg = io_read(sd, REG_CLK_A_STATUS); | ||
1193 | /* ignore if not active */ | ||
1194 | if ((reg & MASK_CLK_STABLE) && !(reg & MASK_CLK_ACTIVE)) | ||
1195 | reg &= ~MASK_CLK_STABLE; | ||
1196 | status |= ((reg & MASK_CLK_STABLE) >> 2); | ||
1197 | |||
1198 | /* Read CLK_B_STATUS register */ | ||
1199 | reg = io_read(sd, REG_CLK_B_STATUS); | ||
1200 | /* ignore if not active */ | ||
1201 | if ((reg & MASK_CLK_STABLE) && !(reg & MASK_CLK_ACTIVE)) | ||
1202 | reg &= ~MASK_CLK_STABLE; | ||
1203 | status |= ((reg & MASK_CLK_STABLE) >> 1); | ||
1204 | |||
1205 | /* Read the SUS_STATUS register */ | ||
1206 | reg = io_read(sd, REG_SUS_STATUS); | ||
1207 | |||
1208 | /* If state = 5 => TMDS is locked */ | ||
1209 | if ((reg & MASK_SUS_STATUS) == LAST_STATE_REACHED) | ||
1210 | status |= MASK_SUS_STATE; | ||
1211 | else | ||
1212 | status &= ~MASK_SUS_STATE; | ||
1213 | |||
1214 | return status; | ||
1215 | } | ||
1216 | |||
1217 | static void | ||
1218 | set_rgb_quantization_range(struct tda1997x_state *state) | ||
1219 | { | ||
1220 | struct v4l2_hdmi_colorimetry *c = &state->colorimetry; | ||
1221 | |||
1222 | state->colorimetry = v4l2_hdmi_rx_colorimetry(&state->avi_infoframe, | ||
1223 | NULL, | ||
1224 | state->timings.bt.height); | ||
1225 | /* If ycbcr_enc is V4L2_YCBCR_ENC_DEFAULT, we receive RGB */ | ||
1226 | if (c->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT) { | ||
1227 | switch (state->rgb_quantization_range) { | ||
1228 | case V4L2_DV_RGB_RANGE_LIMITED: | ||
1229 | c->quantization = V4L2_QUANTIZATION_FULL_RANGE; | ||
1230 | break; | ||
1231 | case V4L2_DV_RGB_RANGE_FULL: | ||
1232 | c->quantization = V4L2_QUANTIZATION_LIM_RANGE; | ||
1233 | break; | ||
1234 | } | ||
1235 | } | ||
1236 | v4l_dbg(1, debug, state->client, | ||
1237 | "colorspace=%d/%d colorimetry=%d range=%s content=%d\n", | ||
1238 | state->avi_infoframe.colorspace, c->colorspace, | ||
1239 | state->avi_infoframe.colorimetry, | ||
1240 | v4l2_quantization_names[c->quantization], | ||
1241 | state->avi_infoframe.content_type); | ||
1242 | } | ||
1243 | |||
1244 | /* parse an infoframe and do some sanity checks on it */ | ||
1245 | static unsigned int | ||
1246 | tda1997x_parse_infoframe(struct tda1997x_state *state, u16 addr) | ||
1247 | { | ||
1248 | struct v4l2_subdev *sd = &state->sd; | ||
1249 | union hdmi_infoframe frame; | ||
1250 | u8 buffer[40]; | ||
1251 | u8 reg; | ||
1252 | int len, err; | ||
1253 | |||
1254 | /* read data */ | ||
1255 | len = io_readn(sd, addr, sizeof(buffer), buffer); | ||
1256 | err = hdmi_infoframe_unpack(&frame, buffer); | ||
1257 | if (err) { | ||
1258 | v4l_err(state->client, | ||
1259 | "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", | ||
1260 | len, addr, buffer[0]); | ||
1261 | return err; | ||
1262 | } | ||
1263 | hdmi_infoframe_log(KERN_INFO, &state->client->dev, &frame); | ||
1264 | switch (frame.any.type) { | ||
1265 | /* Audio InfoFrame: see HDMI spec 8.2.2 */ | ||
1266 | case HDMI_INFOFRAME_TYPE_AUDIO: | ||
1267 | /* sample rate */ | ||
1268 | switch (frame.audio.sample_frequency) { | ||
1269 | case HDMI_AUDIO_SAMPLE_FREQUENCY_32000: | ||
1270 | state->audio_samplerate = 32000; | ||
1271 | break; | ||
1272 | case HDMI_AUDIO_SAMPLE_FREQUENCY_44100: | ||
1273 | state->audio_samplerate = 44100; | ||
1274 | break; | ||
1275 | case HDMI_AUDIO_SAMPLE_FREQUENCY_48000: | ||
1276 | state->audio_samplerate = 48000; | ||
1277 | break; | ||
1278 | case HDMI_AUDIO_SAMPLE_FREQUENCY_88200: | ||
1279 | state->audio_samplerate = 88200; | ||
1280 | break; | ||
1281 | case HDMI_AUDIO_SAMPLE_FREQUENCY_96000: | ||
1282 | state->audio_samplerate = 96000; | ||
1283 | break; | ||
1284 | case HDMI_AUDIO_SAMPLE_FREQUENCY_176400: | ||
1285 | state->audio_samplerate = 176400; | ||
1286 | break; | ||
1287 | case HDMI_AUDIO_SAMPLE_FREQUENCY_192000: | ||
1288 | state->audio_samplerate = 192000; | ||
1289 | break; | ||
1290 | default: | ||
1291 | case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM: | ||
1292 | break; | ||
1293 | } | ||
1294 | |||
1295 | /* sample size */ | ||
1296 | switch (frame.audio.sample_size) { | ||
1297 | case HDMI_AUDIO_SAMPLE_SIZE_16: | ||
1298 | state->audio_samplesize = 16; | ||
1299 | break; | ||
1300 | case HDMI_AUDIO_SAMPLE_SIZE_20: | ||
1301 | state->audio_samplesize = 20; | ||
1302 | break; | ||
1303 | case HDMI_AUDIO_SAMPLE_SIZE_24: | ||
1304 | state->audio_samplesize = 24; | ||
1305 | break; | ||
1306 | case HDMI_AUDIO_SAMPLE_SIZE_STREAM: | ||
1307 | default: | ||
1308 | break; | ||
1309 | } | ||
1310 | |||
1311 | /* Channel Count */ | ||
1312 | state->audio_channels = frame.audio.channels; | ||
1313 | if (frame.audio.channel_allocation && | ||
1314 | frame.audio.channel_allocation != state->audio_ch_alloc) { | ||
1315 | /* use the channel assignment from the infoframe */ | ||
1316 | state->audio_ch_alloc = frame.audio.channel_allocation; | ||
1317 | tda1997x_configure_audout(sd, state->audio_ch_alloc); | ||
1318 | /* reset the audio FIFO */ | ||
1319 | tda1997x_hdmi_info_reset(sd, RESET_AUDIO, false); | ||
1320 | } | ||
1321 | break; | ||
1322 | |||
1323 | /* Auxiliary Video information (AVI) InfoFrame: see HDMI spec 8.2.1 */ | ||
1324 | case HDMI_INFOFRAME_TYPE_AVI: | ||
1325 | state->avi_infoframe = frame.avi; | ||
1326 | set_rgb_quantization_range(state); | ||
1327 | |||
1328 | /* configure upsampler: 0=bypass 1=repeatchroma 2=interpolate */ | ||
1329 | reg = io_read(sd, REG_PIX_REPEAT); | ||
1330 | reg &= ~PIX_REPEAT_MASK_UP_SEL; | ||
1331 | if (frame.avi.colorspace == HDMI_COLORSPACE_YUV422) | ||
1332 | reg |= (PIX_REPEAT_CHROMA << PIX_REPEAT_SHIFT); | ||
1333 | io_write(sd, REG_PIX_REPEAT, reg); | ||
1334 | |||
1335 | /* ConfigurePixelRepeater: repeat n-times each pixel */ | ||
1336 | reg = io_read(sd, REG_PIX_REPEAT); | ||
1337 | reg &= ~PIX_REPEAT_MASK_REP; | ||
1338 | reg |= frame.avi.pixel_repeat; | ||
1339 | io_write(sd, REG_PIX_REPEAT, reg); | ||
1340 | |||
1341 | /* configure the receiver with the new colorspace */ | ||
1342 | tda1997x_configure_csc(sd); | ||
1343 | break; | ||
1344 | default: | ||
1345 | break; | ||
1346 | } | ||
1347 | return 0; | ||
1348 | } | ||
1349 | |||
1350 | static void tda1997x_irq_sus(struct tda1997x_state *state, u8 *flags) | ||
1351 | { | ||
1352 | struct v4l2_subdev *sd = &state->sd; | ||
1353 | u8 reg, source; | ||
1354 | |||
1355 | source = io_read(sd, REG_INT_FLG_CLR_SUS); | ||
1356 | io_write(sd, REG_INT_FLG_CLR_SUS, source); | ||
1357 | |||
1358 | if (source & MASK_MPT) { | ||
1359 | /* reset MTP in use flag if set */ | ||
1360 | if (state->mptrw_in_progress) | ||
1361 | state->mptrw_in_progress = 0; | ||
1362 | } | ||
1363 | |||
1364 | if (source & MASK_SUS_END) { | ||
1365 | /* reset audio FIFO */ | ||
1366 | reg = io_read(sd, REG_HDMI_INFO_RST); | ||
1367 | reg |= MASK_SR_FIFO_FIFO_CTRL; | ||
1368 | io_write(sd, REG_HDMI_INFO_RST, reg); | ||
1369 | reg &= ~MASK_SR_FIFO_FIFO_CTRL; | ||
1370 | io_write(sd, REG_HDMI_INFO_RST, reg); | ||
1371 | |||
1372 | /* reset HDMI flags */ | ||
1373 | state->hdmi_status = 0; | ||
1374 | } | ||
1375 | |||
1376 | /* filter FMT interrupt based on SUS state */ | ||
1377 | reg = io_read(sd, REG_SUS_STATUS); | ||
1378 | if (((reg & MASK_SUS_STATUS) != LAST_STATE_REACHED) | ||
1379 | || (source & MASK_MPT)) { | ||
1380 | source &= ~MASK_FMT; | ||
1381 | } | ||
1382 | |||
1383 | if (source & (MASK_FMT | MASK_SUS_END)) { | ||
1384 | reg = io_read(sd, REG_SUS_STATUS); | ||
1385 | if ((reg & MASK_SUS_STATUS) != LAST_STATE_REACHED) { | ||
1386 | v4l_err(state->client, "BAD SUS STATUS\n"); | ||
1387 | return; | ||
1388 | } | ||
1389 | if (debug) | ||
1390 | tda1997x_detect_std(state, NULL); | ||
1391 | /* notify user of change in resolution */ | ||
1392 | v4l2_subdev_notify_event(&state->sd, &tda1997x_ev_fmt); | ||
1393 | } | ||
1394 | } | ||
1395 | |||
1396 | static void tda1997x_irq_ddc(struct tda1997x_state *state, u8 *flags) | ||
1397 | { | ||
1398 | struct v4l2_subdev *sd = &state->sd; | ||
1399 | u8 source; | ||
1400 | |||
1401 | source = io_read(sd, REG_INT_FLG_CLR_DDC); | ||
1402 | io_write(sd, REG_INT_FLG_CLR_DDC, source); | ||
1403 | if (source & MASK_EDID_MTP) { | ||
1404 | /* reset MTP in use flag if set */ | ||
1405 | if (state->mptrw_in_progress) | ||
1406 | state->mptrw_in_progress = 0; | ||
1407 | } | ||
1408 | |||
1409 | /* Detection of +5V */ | ||
1410 | if (source & MASK_DET_5V) { | ||
1411 | v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, | ||
1412 | tda1997x_detect_tx_5v(sd)); | ||
1413 | } | ||
1414 | } | ||
1415 | |||
1416 | static void tda1997x_irq_rate(struct tda1997x_state *state, u8 *flags) | ||
1417 | { | ||
1418 | struct v4l2_subdev *sd = &state->sd; | ||
1419 | u8 reg, source; | ||
1420 | |||
1421 | u8 irq_status; | ||
1422 | |||
1423 | source = io_read(sd, REG_INT_FLG_CLR_RATE); | ||
1424 | io_write(sd, REG_INT_FLG_CLR_RATE, source); | ||
1425 | |||
1426 | /* read status regs */ | ||
1427 | irq_status = tda1997x_read_activity_status_regs(sd); | ||
1428 | |||
1429 | /* | ||
1430 | * read clock status reg until INT_FLG_CLR_RATE is still 0 | ||
1431 | * after the read to make sure its the last one | ||
1432 | */ | ||
1433 | reg = source; | ||
1434 | while (reg != 0) { | ||
1435 | irq_status = tda1997x_read_activity_status_regs(sd); | ||
1436 | reg = io_read(sd, REG_INT_FLG_CLR_RATE); | ||
1437 | io_write(sd, REG_INT_FLG_CLR_RATE, reg); | ||
1438 | source |= reg; | ||
1439 | } | ||
1440 | |||
1441 | /* we only pay attention to stability change events */ | ||
1442 | if (source & (MASK_RATE_A_ST | MASK_RATE_B_ST)) { | ||
1443 | int input = (source & MASK_RATE_A_ST)?0:1; | ||
1444 | u8 mask = 1<<input; | ||
1445 | |||
1446 | /* state change */ | ||
1447 | if ((irq_status & mask) != (state->activity_status & mask)) { | ||
1448 | /* activity lost */ | ||
1449 | if ((irq_status & mask) == 0) { | ||
1450 | v4l_info(state->client, | ||
1451 | "HDMI-%c: Digital Activity Lost\n", | ||
1452 | input+'A'); | ||
1453 | |||
1454 | /* bypass up/down sampler and pixel repeater */ | ||
1455 | reg = io_read(sd, REG_PIX_REPEAT); | ||
1456 | reg &= ~PIX_REPEAT_MASK_UP_SEL; | ||
1457 | reg &= ~PIX_REPEAT_MASK_REP; | ||
1458 | io_write(sd, REG_PIX_REPEAT, reg); | ||
1459 | |||
1460 | if (state->chip_revision == 0) | ||
1461 | tda1997x_reset_n1(state); | ||
1462 | |||
1463 | state->input_detect[input] = 0; | ||
1464 | v4l2_subdev_notify_event(sd, &tda1997x_ev_fmt); | ||
1465 | } | ||
1466 | |||
1467 | /* activity detected */ | ||
1468 | else { | ||
1469 | v4l_info(state->client, | ||
1470 | "HDMI-%c: Digital Activity Detected\n", | ||
1471 | input+'A'); | ||
1472 | state->input_detect[input] = 1; | ||
1473 | } | ||
1474 | |||
1475 | /* hold onto current state */ | ||
1476 | state->activity_status = (irq_status & mask); | ||
1477 | } | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | static void tda1997x_irq_info(struct tda1997x_state *state, u8 *flags) | ||
1482 | { | ||
1483 | struct v4l2_subdev *sd = &state->sd; | ||
1484 | u8 source; | ||
1485 | |||
1486 | source = io_read(sd, REG_INT_FLG_CLR_INFO); | ||
1487 | io_write(sd, REG_INT_FLG_CLR_INFO, source); | ||
1488 | |||
1489 | /* Audio infoframe */ | ||
1490 | if (source & MASK_AUD_IF) { | ||
1491 | tda1997x_parse_infoframe(state, AUD_IF); | ||
1492 | source &= ~MASK_AUD_IF; | ||
1493 | } | ||
1494 | |||
1495 | /* Source Product Descriptor infoframe change */ | ||
1496 | if (source & MASK_SPD_IF) { | ||
1497 | tda1997x_parse_infoframe(state, SPD_IF); | ||
1498 | source &= ~MASK_SPD_IF; | ||
1499 | } | ||
1500 | |||
1501 | /* Auxiliary Video Information infoframe */ | ||
1502 | if (source & MASK_AVI_IF) { | ||
1503 | tda1997x_parse_infoframe(state, AVI_IF); | ||
1504 | source &= ~MASK_AVI_IF; | ||
1505 | } | ||
1506 | } | ||
1507 | |||
1508 | static void tda1997x_irq_audio(struct tda1997x_state *state, u8 *flags) | ||
1509 | { | ||
1510 | struct v4l2_subdev *sd = &state->sd; | ||
1511 | u8 reg, source; | ||
1512 | |||
1513 | source = io_read(sd, REG_INT_FLG_CLR_AUDIO); | ||
1514 | io_write(sd, REG_INT_FLG_CLR_AUDIO, source); | ||
1515 | |||
1516 | /* reset audio FIFO on FIFO pointer error or audio mute */ | ||
1517 | if (source & MASK_ERROR_FIFO_PT || | ||
1518 | source & MASK_MUTE_FLG) { | ||
1519 | /* audio reset audio FIFO */ | ||
1520 | reg = io_read(sd, REG_SUS_STATUS); | ||
1521 | if ((reg & MASK_SUS_STATUS) == LAST_STATE_REACHED) { | ||
1522 | reg = io_read(sd, REG_HDMI_INFO_RST); | ||
1523 | reg |= MASK_SR_FIFO_FIFO_CTRL; | ||
1524 | io_write(sd, REG_HDMI_INFO_RST, reg); | ||
1525 | reg &= ~MASK_SR_FIFO_FIFO_CTRL; | ||
1526 | io_write(sd, REG_HDMI_INFO_RST, reg); | ||
1527 | /* reset channel status IT if present */ | ||
1528 | source &= ~(MASK_CH_STATE); | ||
1529 | } | ||
1530 | } | ||
1531 | if (source & MASK_AUDIO_FREQ_FLG) { | ||
1532 | static const int freq[] = { | ||
1533 | 0, 32000, 44100, 48000, 88200, 96000, 176400, 192000 | ||
1534 | }; | ||
1535 | |||
1536 | reg = io_read(sd, REG_AUDIO_FREQ); | ||
1537 | state->audio_samplerate = freq[reg & 7]; | ||
1538 | v4l_info(state->client, "Audio Frequency Change: %dHz\n", | ||
1539 | state->audio_samplerate); | ||
1540 | } | ||
1541 | if (source & MASK_AUDIO_FLG) { | ||
1542 | reg = io_read(sd, REG_AUDIO_FLAGS); | ||
1543 | if (reg & BIT(AUDCFG_TYPE_DST)) | ||
1544 | state->audio_type = AUDCFG_TYPE_DST; | ||
1545 | if (reg & BIT(AUDCFG_TYPE_OBA)) | ||
1546 | state->audio_type = AUDCFG_TYPE_OBA; | ||
1547 | if (reg & BIT(AUDCFG_TYPE_HBR)) | ||
1548 | state->audio_type = AUDCFG_TYPE_HBR; | ||
1549 | if (reg & BIT(AUDCFG_TYPE_PCM)) | ||
1550 | state->audio_type = AUDCFG_TYPE_PCM; | ||
1551 | v4l_info(state->client, "Audio Type: %s\n", | ||
1552 | audtype_names[state->audio_type]); | ||
1553 | } | ||
1554 | } | ||
1555 | |||
1556 | static void tda1997x_irq_hdcp(struct tda1997x_state *state, u8 *flags) | ||
1557 | { | ||
1558 | struct v4l2_subdev *sd = &state->sd; | ||
1559 | u8 reg, source; | ||
1560 | |||
1561 | source = io_read(sd, REG_INT_FLG_CLR_HDCP); | ||
1562 | io_write(sd, REG_INT_FLG_CLR_HDCP, source); | ||
1563 | |||
1564 | /* reset MTP in use flag if set */ | ||
1565 | if (source & MASK_HDCP_MTP) | ||
1566 | state->mptrw_in_progress = 0; | ||
1567 | if (source & MASK_STATE_C5) { | ||
1568 | /* REPEATER: mask AUDIO and IF irqs to avoid IF during auth */ | ||
1569 | reg = io_read(sd, REG_INT_MASK_TOP); | ||
1570 | reg &= ~(INTERRUPT_AUDIO | INTERRUPT_INFO); | ||
1571 | io_write(sd, REG_INT_MASK_TOP, reg); | ||
1572 | *flags &= (INTERRUPT_AUDIO | INTERRUPT_INFO); | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | static irqreturn_t tda1997x_isr_thread(int irq, void *d) | ||
1577 | { | ||
1578 | struct tda1997x_state *state = d; | ||
1579 | struct v4l2_subdev *sd = &state->sd; | ||
1580 | u8 flags; | ||
1581 | |||
1582 | mutex_lock(&state->lock); | ||
1583 | do { | ||
1584 | /* read interrupt flags */ | ||
1585 | flags = io_read(sd, REG_INT_FLG_CLR_TOP); | ||
1586 | if (flags == 0) | ||
1587 | break; | ||
1588 | |||
1589 | /* SUS interrupt source (Input activity events) */ | ||
1590 | if (flags & INTERRUPT_SUS) | ||
1591 | tda1997x_irq_sus(state, &flags); | ||
1592 | /* DDC interrupt source (Display Data Channel) */ | ||
1593 | else if (flags & INTERRUPT_DDC) | ||
1594 | tda1997x_irq_ddc(state, &flags); | ||
1595 | /* RATE interrupt source (Digital Input activity) */ | ||
1596 | else if (flags & INTERRUPT_RATE) | ||
1597 | tda1997x_irq_rate(state, &flags); | ||
1598 | /* Infoframe change interrupt */ | ||
1599 | else if (flags & INTERRUPT_INFO) | ||
1600 | tda1997x_irq_info(state, &flags); | ||
1601 | /* Audio interrupt source: | ||
1602 | * freq change, DST,OBA,HBR,ASP flags, mute, FIFO err | ||
1603 | */ | ||
1604 | else if (flags & INTERRUPT_AUDIO) | ||
1605 | tda1997x_irq_audio(state, &flags); | ||
1606 | /* HDCP interrupt source (content protection) */ | ||
1607 | if (flags & INTERRUPT_HDCP) | ||
1608 | tda1997x_irq_hdcp(state, &flags); | ||
1609 | } while (flags != 0); | ||
1610 | mutex_unlock(&state->lock); | ||
1611 | |||
1612 | return IRQ_HANDLED; | ||
1613 | } | ||
1614 | |||
1615 | /* ----------------------------------------------------------------------------- | ||
1616 | * v4l2_subdev_video_ops | ||
1617 | */ | ||
1618 | |||
1619 | static int | ||
1620 | tda1997x_g_input_status(struct v4l2_subdev *sd, u32 *status) | ||
1621 | { | ||
1622 | struct tda1997x_state *state = to_state(sd); | ||
1623 | u32 vper; | ||
1624 | u16 hper; | ||
1625 | u16 hsper; | ||
1626 | |||
1627 | mutex_lock(&state->lock); | ||
1628 | vper = io_read24(sd, REG_V_PER) & MASK_VPER; | ||
1629 | hper = io_read16(sd, REG_H_PER) & MASK_HPER; | ||
1630 | hsper = io_read16(sd, REG_HS_WIDTH) & MASK_HSWIDTH; | ||
1631 | /* | ||
1632 | * The tda1997x supports A/B inputs but only a single output. | ||
1633 | * The irq handler monitors for timing changes on both inputs and | ||
1634 | * sets the input_detect array to 0|1 depending on signal presence. | ||
1635 | * I believe selection of A vs B is automatic. | ||
1636 | * | ||
1637 | * The vper/hper/hsper registers provide the frame period, line period | ||
1638 | * and horiz sync period (units of MCLK clock cycles (27MHz)) and | ||
1639 | * testing shows these values to be random if no signal is present | ||
1640 | * or locked. | ||
1641 | */ | ||
1642 | v4l2_dbg(1, debug, sd, "inputs:%d/%d timings:%d/%d/%d\n", | ||
1643 | state->input_detect[0], state->input_detect[1], | ||
1644 | vper, hper, hsper); | ||
1645 | if (!state->input_detect[0] && !state->input_detect[1]) | ||
1646 | *status = V4L2_IN_ST_NO_SIGNAL; | ||
1647 | else if (!vper || !hper || !hsper) | ||
1648 | *status = V4L2_IN_ST_NO_SYNC; | ||
1649 | else | ||
1650 | *status = 0; | ||
1651 | mutex_unlock(&state->lock); | ||
1652 | |||
1653 | return 0; | ||
1654 | }; | ||
1655 | |||
1656 | static int tda1997x_s_dv_timings(struct v4l2_subdev *sd, | ||
1657 | struct v4l2_dv_timings *timings) | ||
1658 | { | ||
1659 | struct tda1997x_state *state = to_state(sd); | ||
1660 | |||
1661 | v4l_dbg(1, debug, state->client, "%s\n", __func__); | ||
1662 | |||
1663 | if (v4l2_match_dv_timings(&state->timings, timings, 0, false)) | ||
1664 | return 0; /* no changes */ | ||
1665 | |||
1666 | if (!v4l2_valid_dv_timings(timings, &tda1997x_dv_timings_cap, | ||
1667 | NULL, NULL)) | ||
1668 | return -ERANGE; | ||
1669 | |||
1670 | mutex_lock(&state->lock); | ||
1671 | state->timings = *timings; | ||
1672 | /* setup frame detection window and VHREF timing generator */ | ||
1673 | tda1997x_configure_vhref(sd); | ||
1674 | /* configure colorspace conversion */ | ||
1675 | tda1997x_configure_csc(sd); | ||
1676 | mutex_unlock(&state->lock); | ||
1677 | |||
1678 | return 0; | ||
1679 | } | ||
1680 | |||
1681 | static int tda1997x_g_dv_timings(struct v4l2_subdev *sd, | ||
1682 | struct v4l2_dv_timings *timings) | ||
1683 | { | ||
1684 | struct tda1997x_state *state = to_state(sd); | ||
1685 | |||
1686 | v4l_dbg(1, debug, state->client, "%s\n", __func__); | ||
1687 | mutex_lock(&state->lock); | ||
1688 | *timings = state->timings; | ||
1689 | mutex_unlock(&state->lock); | ||
1690 | |||
1691 | return 0; | ||
1692 | } | ||
1693 | |||
1694 | static int tda1997x_query_dv_timings(struct v4l2_subdev *sd, | ||
1695 | struct v4l2_dv_timings *timings) | ||
1696 | { | ||
1697 | struct tda1997x_state *state = to_state(sd); | ||
1698 | |||
1699 | v4l_dbg(1, debug, state->client, "%s\n", __func__); | ||
1700 | memset(timings, 0, sizeof(struct v4l2_dv_timings)); | ||
1701 | mutex_lock(&state->lock); | ||
1702 | tda1997x_detect_std(state, timings); | ||
1703 | mutex_unlock(&state->lock); | ||
1704 | |||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1708 | static const struct v4l2_subdev_video_ops tda1997x_video_ops = { | ||
1709 | .g_input_status = tda1997x_g_input_status, | ||
1710 | .s_dv_timings = tda1997x_s_dv_timings, | ||
1711 | .g_dv_timings = tda1997x_g_dv_timings, | ||
1712 | .query_dv_timings = tda1997x_query_dv_timings, | ||
1713 | }; | ||
1714 | |||
1715 | |||
1716 | /* ----------------------------------------------------------------------------- | ||
1717 | * v4l2_subdev_pad_ops | ||
1718 | */ | ||
1719 | |||
1720 | static int tda1997x_init_cfg(struct v4l2_subdev *sd, | ||
1721 | struct v4l2_subdev_pad_config *cfg) | ||
1722 | { | ||
1723 | struct tda1997x_state *state = to_state(sd); | ||
1724 | struct v4l2_mbus_framefmt *mf; | ||
1725 | |||
1726 | mf = v4l2_subdev_get_try_format(sd, cfg, 0); | ||
1727 | mf->code = state->mbus_codes[0]; | ||
1728 | |||
1729 | return 0; | ||
1730 | } | ||
1731 | |||
1732 | static int tda1997x_enum_mbus_code(struct v4l2_subdev *sd, | ||
1733 | struct v4l2_subdev_pad_config *cfg, | ||
1734 | struct v4l2_subdev_mbus_code_enum *code) | ||
1735 | { | ||
1736 | struct tda1997x_state *state = to_state(sd); | ||
1737 | |||
1738 | v4l_dbg(1, debug, state->client, "%s %d\n", __func__, code->index); | ||
1739 | if (code->index >= ARRAY_SIZE(state->mbus_codes)) | ||
1740 | return -EINVAL; | ||
1741 | |||
1742 | if (!state->mbus_codes[code->index]) | ||
1743 | return -EINVAL; | ||
1744 | |||
1745 | code->code = state->mbus_codes[code->index]; | ||
1746 | |||
1747 | return 0; | ||
1748 | } | ||
1749 | |||
1750 | static void tda1997x_fill_format(struct tda1997x_state *state, | ||
1751 | struct v4l2_mbus_framefmt *format) | ||
1752 | { | ||
1753 | const struct v4l2_bt_timings *bt; | ||
1754 | |||
1755 | memset(format, 0, sizeof(*format)); | ||
1756 | bt = &state->timings.bt; | ||
1757 | format->width = bt->width; | ||
1758 | format->height = bt->height; | ||
1759 | format->colorspace = state->colorimetry.colorspace; | ||
1760 | format->field = (bt->interlaced) ? | ||
1761 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_NONE; | ||
1762 | } | ||
1763 | |||
1764 | static int tda1997x_get_format(struct v4l2_subdev *sd, | ||
1765 | struct v4l2_subdev_pad_config *cfg, | ||
1766 | struct v4l2_subdev_format *format) | ||
1767 | { | ||
1768 | struct tda1997x_state *state = to_state(sd); | ||
1769 | |||
1770 | v4l_dbg(1, debug, state->client, "%s pad=%d which=%d\n", | ||
1771 | __func__, format->pad, format->which); | ||
1772 | |||
1773 | tda1997x_fill_format(state, &format->format); | ||
1774 | |||
1775 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1776 | struct v4l2_mbus_framefmt *fmt; | ||
1777 | |||
1778 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); | ||
1779 | format->format.code = fmt->code; | ||
1780 | } else | ||
1781 | format->format.code = state->mbus_code; | ||
1782 | |||
1783 | return 0; | ||
1784 | } | ||
1785 | |||
1786 | static int tda1997x_set_format(struct v4l2_subdev *sd, | ||
1787 | struct v4l2_subdev_pad_config *cfg, | ||
1788 | struct v4l2_subdev_format *format) | ||
1789 | { | ||
1790 | struct tda1997x_state *state = to_state(sd); | ||
1791 | u32 code = 0; | ||
1792 | int i; | ||
1793 | |||
1794 | v4l_dbg(1, debug, state->client, "%s pad=%d which=%d fmt=0x%x\n", | ||
1795 | __func__, format->pad, format->which, format->format.code); | ||
1796 | |||
1797 | for (i = 0; i < ARRAY_SIZE(state->mbus_codes); i++) { | ||
1798 | if (format->format.code == state->mbus_codes[i]) { | ||
1799 | code = state->mbus_codes[i]; | ||
1800 | break; | ||
1801 | } | ||
1802 | } | ||
1803 | if (!code) | ||
1804 | code = state->mbus_codes[0]; | ||
1805 | |||
1806 | tda1997x_fill_format(state, &format->format); | ||
1807 | format->format.code = code; | ||
1808 | |||
1809 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1810 | struct v4l2_mbus_framefmt *fmt; | ||
1811 | |||
1812 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); | ||
1813 | *fmt = format->format; | ||
1814 | } else { | ||
1815 | int ret = tda1997x_setup_format(state, format->format.code); | ||
1816 | |||
1817 | if (ret) | ||
1818 | return ret; | ||
1819 | /* mbus_code has changed - re-configure csc/vidout */ | ||
1820 | tda1997x_configure_csc(sd); | ||
1821 | tda1997x_configure_vidout(state); | ||
1822 | } | ||
1823 | |||
1824 | return 0; | ||
1825 | } | ||
1826 | |||
1827 | static int tda1997x_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | ||
1828 | { | ||
1829 | struct tda1997x_state *state = to_state(sd); | ||
1830 | |||
1831 | v4l_dbg(1, debug, state->client, "%s pad=%d\n", __func__, edid->pad); | ||
1832 | memset(edid->reserved, 0, sizeof(edid->reserved)); | ||
1833 | |||
1834 | if (edid->start_block == 0 && edid->blocks == 0) { | ||
1835 | edid->blocks = state->edid.blocks; | ||
1836 | return 0; | ||
1837 | } | ||
1838 | |||
1839 | if (!state->edid.present) | ||
1840 | return -ENODATA; | ||
1841 | |||
1842 | if (edid->start_block >= state->edid.blocks) | ||
1843 | return -EINVAL; | ||
1844 | |||
1845 | if (edid->start_block + edid->blocks > state->edid.blocks) | ||
1846 | edid->blocks = state->edid.blocks - edid->start_block; | ||
1847 | |||
1848 | memcpy(edid->edid, state->edid.edid + edid->start_block * 128, | ||
1849 | edid->blocks * 128); | ||
1850 | |||
1851 | return 0; | ||
1852 | } | ||
1853 | |||
1854 | static int tda1997x_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) | ||
1855 | { | ||
1856 | struct tda1997x_state *state = to_state(sd); | ||
1857 | int i; | ||
1858 | |||
1859 | v4l_dbg(1, debug, state->client, "%s pad=%d\n", __func__, edid->pad); | ||
1860 | memset(edid->reserved, 0, sizeof(edid->reserved)); | ||
1861 | |||
1862 | if (edid->start_block != 0) | ||
1863 | return -EINVAL; | ||
1864 | |||
1865 | if (edid->blocks == 0) { | ||
1866 | state->edid.blocks = 0; | ||
1867 | state->edid.present = 0; | ||
1868 | tda1997x_disable_edid(sd); | ||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1872 | if (edid->blocks > 2) { | ||
1873 | edid->blocks = 2; | ||
1874 | return -E2BIG; | ||
1875 | } | ||
1876 | |||
1877 | tda1997x_disable_edid(sd); | ||
1878 | |||
1879 | /* write base EDID */ | ||
1880 | for (i = 0; i < 128; i++) | ||
1881 | io_write(sd, REG_EDID_IN_BYTE0 + i, edid->edid[i]); | ||
1882 | |||
1883 | /* write CEA Extension */ | ||
1884 | for (i = 0; i < 128; i++) | ||
1885 | io_write(sd, REG_EDID_IN_BYTE128 + i, edid->edid[i+128]); | ||
1886 | |||
1887 | tda1997x_enable_edid(sd); | ||
1888 | |||
1889 | return 0; | ||
1890 | } | ||
1891 | |||
1892 | static int tda1997x_get_dv_timings_cap(struct v4l2_subdev *sd, | ||
1893 | struct v4l2_dv_timings_cap *cap) | ||
1894 | { | ||
1895 | *cap = tda1997x_dv_timings_cap; | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1899 | static int tda1997x_enum_dv_timings(struct v4l2_subdev *sd, | ||
1900 | struct v4l2_enum_dv_timings *timings) | ||
1901 | { | ||
1902 | return v4l2_enum_dv_timings_cap(timings, &tda1997x_dv_timings_cap, | ||
1903 | NULL, NULL); | ||
1904 | } | ||
1905 | |||
1906 | static const struct v4l2_subdev_pad_ops tda1997x_pad_ops = { | ||
1907 | .init_cfg = tda1997x_init_cfg, | ||
1908 | .enum_mbus_code = tda1997x_enum_mbus_code, | ||
1909 | .get_fmt = tda1997x_get_format, | ||
1910 | .set_fmt = tda1997x_set_format, | ||
1911 | .get_edid = tda1997x_get_edid, | ||
1912 | .set_edid = tda1997x_set_edid, | ||
1913 | .dv_timings_cap = tda1997x_get_dv_timings_cap, | ||
1914 | .enum_dv_timings = tda1997x_enum_dv_timings, | ||
1915 | }; | ||
1916 | |||
1917 | /* ----------------------------------------------------------------------------- | ||
1918 | * v4l2_subdev_core_ops | ||
1919 | */ | ||
1920 | |||
1921 | static int tda1997x_log_infoframe(struct v4l2_subdev *sd, int addr) | ||
1922 | { | ||
1923 | struct tda1997x_state *state = to_state(sd); | ||
1924 | union hdmi_infoframe frame; | ||
1925 | u8 buffer[40]; | ||
1926 | int len, err; | ||
1927 | |||
1928 | /* read data */ | ||
1929 | len = io_readn(sd, addr, sizeof(buffer), buffer); | ||
1930 | v4l2_dbg(1, debug, sd, "infoframe: addr=%d len=%d\n", addr, len); | ||
1931 | err = hdmi_infoframe_unpack(&frame, buffer); | ||
1932 | if (err) { | ||
1933 | v4l_err(state->client, | ||
1934 | "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", | ||
1935 | len, addr, buffer[0]); | ||
1936 | return err; | ||
1937 | } | ||
1938 | hdmi_infoframe_log(KERN_INFO, &state->client->dev, &frame); | ||
1939 | |||
1940 | return 0; | ||
1941 | } | ||
1942 | |||
1943 | static int tda1997x_log_status(struct v4l2_subdev *sd) | ||
1944 | { | ||
1945 | struct tda1997x_state *state = to_state(sd); | ||
1946 | struct v4l2_dv_timings timings; | ||
1947 | struct hdmi_avi_infoframe *avi = &state->avi_infoframe; | ||
1948 | |||
1949 | v4l2_info(sd, "-----Chip status-----\n"); | ||
1950 | v4l2_info(sd, "Chip: %s N%d\n", state->info->name, | ||
1951 | state->chip_revision + 1); | ||
1952 | v4l2_info(sd, "EDID Enabled: %s\n", state->edid.present ? "yes" : "no"); | ||
1953 | |||
1954 | v4l2_info(sd, "-----Signal status-----\n"); | ||
1955 | v4l2_info(sd, "Cable detected (+5V power): %s\n", | ||
1956 | tda1997x_detect_tx_5v(sd) ? "yes" : "no"); | ||
1957 | v4l2_info(sd, "HPD detected: %s\n", | ||
1958 | tda1997x_detect_tx_hpd(sd) ? "yes" : "no"); | ||
1959 | |||
1960 | v4l2_info(sd, "-----Video Timings-----\n"); | ||
1961 | switch (tda1997x_detect_std(state, &timings)) { | ||
1962 | case -ENOLINK: | ||
1963 | v4l2_info(sd, "No video detected\n"); | ||
1964 | break; | ||
1965 | case -ERANGE: | ||
1966 | v4l2_info(sd, "Invalid signal detected\n"); | ||
1967 | break; | ||
1968 | } | ||
1969 | v4l2_print_dv_timings(sd->name, "Configured format: ", | ||
1970 | &state->timings, true); | ||
1971 | |||
1972 | v4l2_info(sd, "-----Color space-----\n"); | ||
1973 | v4l2_info(sd, "Input color space: %s %s %s", | ||
1974 | hdmi_colorspace_names[avi->colorspace], | ||
1975 | (avi->colorspace == HDMI_COLORSPACE_RGB) ? "" : | ||
1976 | hdmi_colorimetry_names[avi->colorimetry], | ||
1977 | v4l2_quantization_names[state->colorimetry.quantization]); | ||
1978 | v4l2_info(sd, "Output color space: %s", | ||
1979 | vidfmt_names[state->vid_fmt]); | ||
1980 | v4l2_info(sd, "Color space conversion: %s", state->conv ? | ||
1981 | state->conv->name : "None"); | ||
1982 | |||
1983 | v4l2_info(sd, "-----Audio-----\n"); | ||
1984 | if (state->audio_channels) { | ||
1985 | v4l2_info(sd, "audio: %dch %dHz\n", state->audio_channels, | ||
1986 | state->audio_samplerate); | ||
1987 | } else { | ||
1988 | v4l2_info(sd, "audio: none\n"); | ||
1989 | } | ||
1990 | |||
1991 | v4l2_info(sd, "-----Infoframes-----\n"); | ||
1992 | tda1997x_log_infoframe(sd, AUD_IF); | ||
1993 | tda1997x_log_infoframe(sd, SPD_IF); | ||
1994 | tda1997x_log_infoframe(sd, AVI_IF); | ||
1995 | |||
1996 | return 0; | ||
1997 | } | ||
1998 | |||
1999 | static int tda1997x_subscribe_event(struct v4l2_subdev *sd, | ||
2000 | struct v4l2_fh *fh, | ||
2001 | struct v4l2_event_subscription *sub) | ||
2002 | { | ||
2003 | switch (sub->type) { | ||
2004 | case V4L2_EVENT_SOURCE_CHANGE: | ||
2005 | return v4l2_src_change_event_subdev_subscribe(sd, fh, sub); | ||
2006 | case V4L2_EVENT_CTRL: | ||
2007 | return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub); | ||
2008 | default: | ||
2009 | return -EINVAL; | ||
2010 | } | ||
2011 | } | ||
2012 | |||
2013 | static const struct v4l2_subdev_core_ops tda1997x_core_ops = { | ||
2014 | .log_status = tda1997x_log_status, | ||
2015 | .subscribe_event = tda1997x_subscribe_event, | ||
2016 | .unsubscribe_event = v4l2_event_subdev_unsubscribe, | ||
2017 | }; | ||
2018 | |||
2019 | /* ----------------------------------------------------------------------------- | ||
2020 | * v4l2_subdev_ops | ||
2021 | */ | ||
2022 | |||
2023 | static const struct v4l2_subdev_ops tda1997x_subdev_ops = { | ||
2024 | .core = &tda1997x_core_ops, | ||
2025 | .video = &tda1997x_video_ops, | ||
2026 | .pad = &tda1997x_pad_ops, | ||
2027 | }; | ||
2028 | |||
2029 | /* ----------------------------------------------------------------------------- | ||
2030 | * v4l2_controls | ||
2031 | */ | ||
2032 | |||
2033 | static int tda1997x_s_ctrl(struct v4l2_ctrl *ctrl) | ||
2034 | { | ||
2035 | struct v4l2_subdev *sd = to_sd(ctrl); | ||
2036 | struct tda1997x_state *state = to_state(sd); | ||
2037 | |||
2038 | switch (ctrl->id) { | ||
2039 | /* allow overriding the default RGB quantization range */ | ||
2040 | case V4L2_CID_DV_RX_RGB_RANGE: | ||
2041 | state->rgb_quantization_range = ctrl->val; | ||
2042 | set_rgb_quantization_range(state); | ||
2043 | tda1997x_configure_csc(sd); | ||
2044 | return 0; | ||
2045 | } | ||
2046 | |||
2047 | return -EINVAL; | ||
2048 | }; | ||
2049 | |||
2050 | static int tda1997x_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
2051 | { | ||
2052 | struct v4l2_subdev *sd = to_sd(ctrl); | ||
2053 | struct tda1997x_state *state = to_state(sd); | ||
2054 | |||
2055 | if (ctrl->id == V4L2_CID_DV_RX_IT_CONTENT_TYPE) { | ||
2056 | ctrl->val = state->avi_infoframe.content_type; | ||
2057 | return 0; | ||
2058 | } | ||
2059 | return -EINVAL; | ||
2060 | }; | ||
2061 | |||
2062 | static const struct v4l2_ctrl_ops tda1997x_ctrl_ops = { | ||
2063 | .s_ctrl = tda1997x_s_ctrl, | ||
2064 | .g_volatile_ctrl = tda1997x_g_volatile_ctrl, | ||
2065 | }; | ||
2066 | |||
2067 | static int tda1997x_core_init(struct v4l2_subdev *sd) | ||
2068 | { | ||
2069 | struct tda1997x_state *state = to_state(sd); | ||
2070 | struct tda1997x_platform_data *pdata = &state->pdata; | ||
2071 | u8 reg; | ||
2072 | int i; | ||
2073 | |||
2074 | /* disable HPD */ | ||
2075 | io_write(sd, REG_HPD_AUTO_CTRL, HPD_AUTO_HPD_UNSEL); | ||
2076 | if (state->chip_revision == 0) { | ||
2077 | io_write(sd, REG_MAN_SUS_HDMI_SEL, MAN_DIS_HDCP | MAN_RST_HDCP); | ||
2078 | io_write(sd, REG_CGU_DBG_SEL, 1 << CGU_DBG_CLK_SEL_SHIFT); | ||
2079 | } | ||
2080 | |||
2081 | /* reset infoframe at end of start-up-sequencer */ | ||
2082 | io_write(sd, REG_SUS_SET_RGB2, 0x06); | ||
2083 | io_write(sd, REG_SUS_SET_RGB3, 0x06); | ||
2084 | |||
2085 | /* Enable TMDS pull-ups */ | ||
2086 | io_write(sd, REG_RT_MAN_CTRL, RT_MAN_CTRL_RT | | ||
2087 | RT_MAN_CTRL_RT_B | RT_MAN_CTRL_RT_A); | ||
2088 | |||
2089 | /* enable sync measurement timing */ | ||
2090 | tda1997x_cec_write(sd, REG_PWR_CONTROL & 0xff, 0x04); | ||
2091 | /* adjust CEC clock divider */ | ||
2092 | tda1997x_cec_write(sd, REG_OSC_DIVIDER & 0xff, 0x03); | ||
2093 | tda1997x_cec_write(sd, REG_EN_OSC_PERIOD_LSB & 0xff, 0xa0); | ||
2094 | io_write(sd, REG_TIMER_D, 0x54); | ||
2095 | /* enable power switch */ | ||
2096 | reg = tda1997x_cec_read(sd, REG_CONTROL & 0xff); | ||
2097 | reg |= 0x20; | ||
2098 | tda1997x_cec_write(sd, REG_CONTROL & 0xff, reg); | ||
2099 | mdelay(50); | ||
2100 | |||
2101 | /* read the chip version */ | ||
2102 | reg = io_read(sd, REG_VERSION); | ||
2103 | /* get the chip configuration */ | ||
2104 | reg = io_read(sd, REG_CMTP_REG10); | ||
2105 | |||
2106 | /* enable interrupts we care about */ | ||
2107 | io_write(sd, REG_INT_MASK_TOP, | ||
2108 | INTERRUPT_HDCP | INTERRUPT_AUDIO | INTERRUPT_INFO | | ||
2109 | INTERRUPT_RATE | INTERRUPT_SUS); | ||
2110 | /* config_mtp,fmt,sus_end,sus_st */ | ||
2111 | io_write(sd, REG_INT_MASK_SUS, MASK_MPT | MASK_FMT | MASK_SUS_END); | ||
2112 | /* rate stability change for inputs A/B */ | ||
2113 | io_write(sd, REG_INT_MASK_RATE, MASK_RATE_B_ST | MASK_RATE_A_ST); | ||
2114 | /* aud,spd,avi*/ | ||
2115 | io_write(sd, REG_INT_MASK_INFO, | ||
2116 | MASK_AUD_IF | MASK_SPD_IF | MASK_AVI_IF); | ||
2117 | /* audio_freq,audio_flg,mute_flg,fifo_err */ | ||
2118 | io_write(sd, REG_INT_MASK_AUDIO, | ||
2119 | MASK_AUDIO_FREQ_FLG | MASK_AUDIO_FLG | MASK_MUTE_FLG | | ||
2120 | MASK_ERROR_FIFO_PT); | ||
2121 | /* HDCP C5 state reached */ | ||
2122 | io_write(sd, REG_INT_MASK_HDCP, MASK_STATE_C5); | ||
2123 | /* 5V detect and HDP pulse end */ | ||
2124 | io_write(sd, REG_INT_MASK_DDC, MASK_DET_5V); | ||
2125 | /* don't care about AFE/MODE */ | ||
2126 | io_write(sd, REG_INT_MASK_AFE, 0); | ||
2127 | io_write(sd, REG_INT_MASK_MODE, 0); | ||
2128 | |||
2129 | /* clear all interrupts */ | ||
2130 | io_write(sd, REG_INT_FLG_CLR_TOP, 0xff); | ||
2131 | io_write(sd, REG_INT_FLG_CLR_SUS, 0xff); | ||
2132 | io_write(sd, REG_INT_FLG_CLR_DDC, 0xff); | ||
2133 | io_write(sd, REG_INT_FLG_CLR_RATE, 0xff); | ||
2134 | io_write(sd, REG_INT_FLG_CLR_MODE, 0xff); | ||
2135 | io_write(sd, REG_INT_FLG_CLR_INFO, 0xff); | ||
2136 | io_write(sd, REG_INT_FLG_CLR_AUDIO, 0xff); | ||
2137 | io_write(sd, REG_INT_FLG_CLR_HDCP, 0xff); | ||
2138 | io_write(sd, REG_INT_FLG_CLR_AFE, 0xff); | ||
2139 | |||
2140 | /* init TMDS equalizer */ | ||
2141 | if (state->chip_revision == 0) | ||
2142 | io_write(sd, REG_CGU_DBG_SEL, 1 << CGU_DBG_CLK_SEL_SHIFT); | ||
2143 | io_write24(sd, REG_CLK_MIN_RATE, CLK_MIN_RATE); | ||
2144 | io_write24(sd, REG_CLK_MAX_RATE, CLK_MAX_RATE); | ||
2145 | if (state->chip_revision == 0) | ||
2146 | io_write(sd, REG_WDL_CFG, WDL_CFG_VAL); | ||
2147 | /* DC filter */ | ||
2148 | io_write(sd, REG_DEEP_COLOR_CTRL, DC_FILTER_VAL); | ||
2149 | /* disable test pattern */ | ||
2150 | io_write(sd, REG_SVC_MODE, 0x00); | ||
2151 | /* update HDMI INFO CTRL */ | ||
2152 | io_write(sd, REG_INFO_CTRL, 0xff); | ||
2153 | /* write HDMI INFO EXCEED value */ | ||
2154 | io_write(sd, REG_INFO_EXCEED, 3); | ||
2155 | |||
2156 | if (state->chip_revision == 0) | ||
2157 | tda1997x_reset_n1(state); | ||
2158 | |||
2159 | /* | ||
2160 | * No HDCP acknowledge when HDCP is disabled | ||
2161 | * and reset SUS to force format detection | ||
2162 | */ | ||
2163 | tda1997x_hdmi_info_reset(sd, NACK_HDCP, true); | ||
2164 | |||
2165 | /* Set HPD low */ | ||
2166 | tda1997x_manual_hpd(sd, HPD_LOW_BP); | ||
2167 | |||
2168 | /* Configure receiver capabilities */ | ||
2169 | io_write(sd, REG_HDCP_BCAPS, HDCP_HDMI | HDCP_FAST_REAUTH); | ||
2170 | |||
2171 | /* Configure HDMI: Auto HDCP mode, packet controlled mute */ | ||
2172 | reg = HDMI_CTRL_MUTE_AUTO << HDMI_CTRL_MUTE_SHIFT; | ||
2173 | reg |= HDMI_CTRL_HDCP_AUTO << HDMI_CTRL_HDCP_SHIFT; | ||
2174 | io_write(sd, REG_HDMI_CTRL, reg); | ||
2175 | |||
2176 | /* reset start-up-sequencer to force format detection */ | ||
2177 | tda1997x_hdmi_info_reset(sd, 0, true); | ||
2178 | |||
2179 | /* disable matrix conversion */ | ||
2180 | reg = io_read(sd, REG_VDP_CTRL); | ||
2181 | reg |= VDP_CTRL_MATRIX_BP; | ||
2182 | io_write(sd, REG_VDP_CTRL, reg); | ||
2183 | |||
2184 | /* set video output mode */ | ||
2185 | tda1997x_configure_vidout(state); | ||
2186 | |||
2187 | /* configure video output port */ | ||
2188 | for (i = 0; i < 9; i++) { | ||
2189 | v4l_dbg(1, debug, state->client, "vidout_cfg[%d]=0x%02x\n", i, | ||
2190 | pdata->vidout_port_cfg[i]); | ||
2191 | io_write(sd, REG_VP35_32_CTRL + i, pdata->vidout_port_cfg[i]); | ||
2192 | } | ||
2193 | |||
2194 | /* configure audio output port */ | ||
2195 | tda1997x_configure_audout(sd, 0); | ||
2196 | |||
2197 | /* configure audio clock freq */ | ||
2198 | switch (pdata->audout_mclk_fs) { | ||
2199 | case 512: | ||
2200 | reg = AUDIO_CLOCK_SEL_512FS; | ||
2201 | break; | ||
2202 | case 256: | ||
2203 | reg = AUDIO_CLOCK_SEL_256FS; | ||
2204 | break; | ||
2205 | case 128: | ||
2206 | reg = AUDIO_CLOCK_SEL_128FS; | ||
2207 | break; | ||
2208 | case 64: | ||
2209 | reg = AUDIO_CLOCK_SEL_64FS; | ||
2210 | break; | ||
2211 | case 32: | ||
2212 | reg = AUDIO_CLOCK_SEL_32FS; | ||
2213 | break; | ||
2214 | default: | ||
2215 | reg = AUDIO_CLOCK_SEL_16FS; | ||
2216 | break; | ||
2217 | } | ||
2218 | io_write(sd, REG_AUDIO_CLOCK, reg); | ||
2219 | |||
2220 | /* reset advanced infoframes (ISRC1/ISRC2/ACP) */ | ||
2221 | tda1997x_hdmi_info_reset(sd, RESET_AI, false); | ||
2222 | /* reset infoframe */ | ||
2223 | tda1997x_hdmi_info_reset(sd, RESET_IF, false); | ||
2224 | /* reset audio infoframes */ | ||
2225 | tda1997x_hdmi_info_reset(sd, RESET_AUDIO, false); | ||
2226 | /* reset gamut */ | ||
2227 | tda1997x_hdmi_info_reset(sd, RESET_GAMUT, false); | ||
2228 | |||
2229 | /* get initial HDMI status */ | ||
2230 | state->hdmi_status = io_read(sd, REG_HDMI_FLAGS); | ||
2231 | |||
2232 | return 0; | ||
2233 | } | ||
2234 | |||
2235 | static int tda1997x_set_power(struct tda1997x_state *state, bool on) | ||
2236 | { | ||
2237 | int ret = 0; | ||
2238 | |||
2239 | if (on) { | ||
2240 | ret = regulator_bulk_enable(TDA1997X_NUM_SUPPLIES, | ||
2241 | state->supplies); | ||
2242 | msleep(300); | ||
2243 | } else { | ||
2244 | ret = regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, | ||
2245 | state->supplies); | ||
2246 | } | ||
2247 | |||
2248 | return ret; | ||
2249 | } | ||
2250 | |||
2251 | static const struct i2c_device_id tda1997x_i2c_id[] = { | ||
2252 | {"tda19971", (kernel_ulong_t)&tda1997x_chip_info[TDA19971]}, | ||
2253 | {"tda19973", (kernel_ulong_t)&tda1997x_chip_info[TDA19973]}, | ||
2254 | { }, | ||
2255 | }; | ||
2256 | MODULE_DEVICE_TABLE(i2c, tda1997x_i2c_id); | ||
2257 | |||
2258 | static const struct of_device_id tda1997x_of_id[] __maybe_unused = { | ||
2259 | { .compatible = "nxp,tda19971", .data = &tda1997x_chip_info[TDA19971] }, | ||
2260 | { .compatible = "nxp,tda19973", .data = &tda1997x_chip_info[TDA19973] }, | ||
2261 | { }, | ||
2262 | }; | ||
2263 | MODULE_DEVICE_TABLE(of, tda1997x_of_id); | ||
2264 | |||
2265 | static int tda1997x_parse_dt(struct tda1997x_state *state) | ||
2266 | { | ||
2267 | struct tda1997x_platform_data *pdata = &state->pdata; | ||
2268 | struct v4l2_fwnode_endpoint bus_cfg; | ||
2269 | struct device_node *ep; | ||
2270 | struct device_node *np; | ||
2271 | unsigned int flags; | ||
2272 | const char *str; | ||
2273 | int ret; | ||
2274 | u32 v; | ||
2275 | |||
2276 | /* | ||
2277 | * setup default values: | ||
2278 | * - HREF: active high from start to end of row | ||
2279 | * - VS: Vertical Sync active high at beginning of frame | ||
2280 | * - DE: Active high when data valid | ||
2281 | * - A_CLK: 128*Fs | ||
2282 | */ | ||
2283 | pdata->vidout_sel_hs = HS_HREF_SEL_HREF_VHREF; | ||
2284 | pdata->vidout_sel_vs = VS_VREF_SEL_VREF_HDMI; | ||
2285 | pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF; | ||
2286 | |||
2287 | np = state->client->dev.of_node; | ||
2288 | ep = of_graph_get_next_endpoint(np, NULL); | ||
2289 | if (!ep) | ||
2290 | return -EINVAL; | ||
2291 | |||
2292 | ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg); | ||
2293 | if (ret) { | ||
2294 | of_node_put(ep); | ||
2295 | return ret; | ||
2296 | } | ||
2297 | of_node_put(ep); | ||
2298 | pdata->vidout_bus_type = bus_cfg.bus_type; | ||
2299 | |||
2300 | /* polarity of HS/VS/DE */ | ||
2301 | flags = bus_cfg.bus.parallel.flags; | ||
2302 | if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) | ||
2303 | pdata->vidout_inv_hs = 1; | ||
2304 | if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) | ||
2305 | pdata->vidout_inv_vs = 1; | ||
2306 | if (flags & V4L2_MBUS_DATA_ACTIVE_LOW) | ||
2307 | pdata->vidout_inv_de = 1; | ||
2308 | pdata->vidout_bus_width = bus_cfg.bus.parallel.bus_width; | ||
2309 | |||
2310 | /* video output port config */ | ||
2311 | ret = of_property_count_u32_elems(np, "nxp,vidout-portcfg"); | ||
2312 | if (ret > 0) { | ||
2313 | u32 reg, val, i; | ||
2314 | |||
2315 | for (i = 0; i < ret / 2 && i < 9; i++) { | ||
2316 | of_property_read_u32_index(np, "nxp,vidout-portcfg", | ||
2317 | i * 2, ®); | ||
2318 | of_property_read_u32_index(np, "nxp,vidout-portcfg", | ||
2319 | i * 2 + 1, &val); | ||
2320 | if (reg < 9) | ||
2321 | pdata->vidout_port_cfg[reg] = val; | ||
2322 | } | ||
2323 | } else { | ||
2324 | v4l_err(state->client, "nxp,vidout-portcfg missing\n"); | ||
2325 | return -EINVAL; | ||
2326 | } | ||
2327 | |||
2328 | /* default to channel layout dictated by packet header */ | ||
2329 | pdata->audout_layoutauto = true; | ||
2330 | |||
2331 | pdata->audout_format = AUDFMT_TYPE_DISABLED; | ||
2332 | if (!of_property_read_string(np, "nxp,audout-format", &str)) { | ||
2333 | if (strcmp(str, "i2s") == 0) | ||
2334 | pdata->audout_format = AUDFMT_TYPE_I2S; | ||
2335 | else if (strcmp(str, "spdif") == 0) | ||
2336 | pdata->audout_format = AUDFMT_TYPE_SPDIF; | ||
2337 | else { | ||
2338 | v4l_err(state->client, "nxp,audout-format invalid\n"); | ||
2339 | return -EINVAL; | ||
2340 | } | ||
2341 | if (!of_property_read_u32(np, "nxp,audout-layout", &v)) { | ||
2342 | switch (v) { | ||
2343 | case 0: | ||
2344 | case 1: | ||
2345 | break; | ||
2346 | default: | ||
2347 | v4l_err(state->client, | ||
2348 | "nxp,audout-layout invalid\n"); | ||
2349 | return -EINVAL; | ||
2350 | } | ||
2351 | pdata->audout_layout = v; | ||
2352 | } | ||
2353 | if (!of_property_read_u32(np, "nxp,audout-width", &v)) { | ||
2354 | switch (v) { | ||
2355 | case 16: | ||
2356 | case 32: | ||
2357 | break; | ||
2358 | default: | ||
2359 | v4l_err(state->client, | ||
2360 | "nxp,audout-width invalid\n"); | ||
2361 | return -EINVAL; | ||
2362 | } | ||
2363 | pdata->audout_width = v; | ||
2364 | } | ||
2365 | if (!of_property_read_u32(np, "nxp,audout-mclk-fs", &v)) { | ||
2366 | switch (v) { | ||
2367 | case 512: | ||
2368 | case 256: | ||
2369 | case 128: | ||
2370 | case 64: | ||
2371 | case 32: | ||
2372 | case 16: | ||
2373 | break; | ||
2374 | default: | ||
2375 | v4l_err(state->client, | ||
2376 | "nxp,audout-mclk-fs invalid\n"); | ||
2377 | return -EINVAL; | ||
2378 | } | ||
2379 | pdata->audout_mclk_fs = v; | ||
2380 | } | ||
2381 | } | ||
2382 | |||
2383 | return 0; | ||
2384 | } | ||
2385 | |||
2386 | static int tda1997x_get_regulators(struct tda1997x_state *state) | ||
2387 | { | ||
2388 | int i; | ||
2389 | |||
2390 | for (i = 0; i < TDA1997X_NUM_SUPPLIES; i++) | ||
2391 | state->supplies[i].supply = tda1997x_supply_name[i]; | ||
2392 | |||
2393 | return devm_regulator_bulk_get(&state->client->dev, | ||
2394 | TDA1997X_NUM_SUPPLIES, | ||
2395 | state->supplies); | ||
2396 | } | ||
2397 | |||
2398 | static int tda1997x_identify_module(struct tda1997x_state *state) | ||
2399 | { | ||
2400 | struct v4l2_subdev *sd = &state->sd; | ||
2401 | enum tda1997x_type type; | ||
2402 | u8 reg; | ||
2403 | |||
2404 | /* Read chip configuration*/ | ||
2405 | reg = io_read(sd, REG_CMTP_REG10); | ||
2406 | state->tmdsb_clk = (reg >> 6) & 0x01; /* use tmds clock B_inv for B */ | ||
2407 | state->tmdsb_soc = (reg >> 5) & 0x01; /* tmds of input B */ | ||
2408 | state->port_30bit = (reg >> 2) & 0x03; /* 30bit vs 24bit */ | ||
2409 | state->output_2p5 = (reg >> 1) & 0x01; /* output supply 2.5v */ | ||
2410 | switch ((reg >> 4) & 0x03) { | ||
2411 | case 0x00: | ||
2412 | type = TDA19971; | ||
2413 | break; | ||
2414 | case 0x02: | ||
2415 | case 0x03: | ||
2416 | type = TDA19973; | ||
2417 | break; | ||
2418 | default: | ||
2419 | dev_err(&state->client->dev, "unsupported chip ID\n"); | ||
2420 | return -EIO; | ||
2421 | } | ||
2422 | if (state->info->type != type) { | ||
2423 | dev_err(&state->client->dev, "chip id mismatch\n"); | ||
2424 | return -EIO; | ||
2425 | } | ||
2426 | |||
2427 | /* read chip revision */ | ||
2428 | state->chip_revision = io_read(sd, REG_CMTP_REG11); | ||
2429 | |||
2430 | return 0; | ||
2431 | } | ||
2432 | |||
2433 | static const struct media_entity_operations tda1997x_media_ops = { | ||
2434 | .link_validate = v4l2_subdev_link_validate, | ||
2435 | }; | ||
2436 | |||
2437 | |||
2438 | /* ----------------------------------------------------------------------------- | ||
2439 | * HDMI Audio Codec | ||
2440 | */ | ||
2441 | |||
2442 | /* refine sample-rate based on HDMI source */ | ||
2443 | static int tda1997x_pcm_startup(struct snd_pcm_substream *substream, | ||
2444 | struct snd_soc_dai *dai) | ||
2445 | { | ||
2446 | struct tda1997x_state *state = snd_soc_dai_get_drvdata(dai); | ||
2447 | struct snd_soc_codec *codec = dai->codec; | ||
2448 | struct snd_pcm_runtime *rtd = substream->runtime; | ||
2449 | int rate, err; | ||
2450 | |||
2451 | rate = state->audio_samplerate; | ||
2452 | err = snd_pcm_hw_constraint_minmax(rtd, SNDRV_PCM_HW_PARAM_RATE, | ||
2453 | rate, rate); | ||
2454 | if (err < 0) { | ||
2455 | dev_err(codec->dev, "failed to constrain samplerate to %dHz\n", | ||
2456 | rate); | ||
2457 | return err; | ||
2458 | } | ||
2459 | dev_info(codec->dev, "set samplerate constraint to %dHz\n", rate); | ||
2460 | |||
2461 | return 0; | ||
2462 | } | ||
2463 | |||
2464 | static const struct snd_soc_dai_ops tda1997x_dai_ops = { | ||
2465 | .startup = tda1997x_pcm_startup, | ||
2466 | }; | ||
2467 | |||
2468 | static struct snd_soc_dai_driver tda1997x_audio_dai = { | ||
2469 | .name = "tda1997x", | ||
2470 | .capture = { | ||
2471 | .stream_name = "Capture", | ||
2472 | .channels_min = 2, | ||
2473 | .channels_max = 8, | ||
2474 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | | ||
2475 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | | ||
2476 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | | ||
2477 | SNDRV_PCM_RATE_192000, | ||
2478 | }, | ||
2479 | .ops = &tda1997x_dai_ops, | ||
2480 | }; | ||
2481 | |||
2482 | static int tda1997x_codec_probe(struct snd_soc_codec *codec) | ||
2483 | { | ||
2484 | return 0; | ||
2485 | } | ||
2486 | |||
2487 | static int tda1997x_codec_remove(struct snd_soc_codec *codec) | ||
2488 | { | ||
2489 | return 0; | ||
2490 | } | ||
2491 | |||
2492 | static struct snd_soc_codec_driver tda1997x_codec_driver = { | ||
2493 | .probe = tda1997x_codec_probe, | ||
2494 | .remove = tda1997x_codec_remove, | ||
2495 | .reg_word_size = sizeof(u16), | ||
2496 | }; | ||
2497 | |||
2498 | static int tda1997x_probe(struct i2c_client *client, | ||
2499 | const struct i2c_device_id *id) | ||
2500 | { | ||
2501 | struct tda1997x_state *state; | ||
2502 | struct tda1997x_platform_data *pdata; | ||
2503 | struct v4l2_subdev *sd; | ||
2504 | struct v4l2_ctrl_handler *hdl; | ||
2505 | struct v4l2_ctrl *ctrl; | ||
2506 | static const struct v4l2_dv_timings cea1920x1080 = | ||
2507 | V4L2_DV_BT_CEA_1920X1080P60; | ||
2508 | u32 *mbus_codes; | ||
2509 | int i, ret; | ||
2510 | |||
2511 | /* Check if the adapter supports the needed features */ | ||
2512 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
2513 | return -EIO; | ||
2514 | |||
2515 | state = kzalloc(sizeof(struct tda1997x_state), GFP_KERNEL); | ||
2516 | if (!state) | ||
2517 | return -ENOMEM; | ||
2518 | |||
2519 | state->client = client; | ||
2520 | pdata = &state->pdata; | ||
2521 | if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) { | ||
2522 | const struct of_device_id *oid; | ||
2523 | |||
2524 | oid = of_match_node(tda1997x_of_id, client->dev.of_node); | ||
2525 | state->info = oid->data; | ||
2526 | |||
2527 | ret = tda1997x_parse_dt(state); | ||
2528 | if (ret < 0) { | ||
2529 | v4l_err(client, "DT parsing error\n"); | ||
2530 | goto err_free_state; | ||
2531 | } | ||
2532 | } else if (client->dev.platform_data) { | ||
2533 | struct tda1997x_platform_data *pdata = | ||
2534 | client->dev.platform_data; | ||
2535 | state->info = | ||
2536 | (const struct tda1997x_chip_info *)id->driver_data; | ||
2537 | state->pdata = *pdata; | ||
2538 | } else { | ||
2539 | v4l_err(client, "No platform data\n"); | ||
2540 | ret = -ENODEV; | ||
2541 | goto err_free_state; | ||
2542 | } | ||
2543 | |||
2544 | ret = tda1997x_get_regulators(state); | ||
2545 | if (ret) | ||
2546 | goto err_free_state; | ||
2547 | |||
2548 | ret = tda1997x_set_power(state, 1); | ||
2549 | if (ret) | ||
2550 | goto err_free_state; | ||
2551 | |||
2552 | mutex_init(&state->page_lock); | ||
2553 | mutex_init(&state->lock); | ||
2554 | state->page = 0xff; | ||
2555 | |||
2556 | INIT_DELAYED_WORK(&state->delayed_work_enable_hpd, | ||
2557 | tda1997x_delayed_work_enable_hpd); | ||
2558 | |||
2559 | /* set video format based on chip and bus width */ | ||
2560 | ret = tda1997x_identify_module(state); | ||
2561 | if (ret) | ||
2562 | goto err_free_mutex; | ||
2563 | |||
2564 | /* initialize subdev */ | ||
2565 | sd = &state->sd; | ||
2566 | v4l2_i2c_subdev_init(sd, client, &tda1997x_subdev_ops); | ||
2567 | snprintf(sd->name, sizeof(sd->name), "%s %d-%04x", | ||
2568 | id->name, i2c_adapter_id(client->adapter), | ||
2569 | client->addr); | ||
2570 | sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; | ||
2571 | sd->entity.function = MEDIA_ENT_F_DTV_DECODER; | ||
2572 | sd->entity.ops = &tda1997x_media_ops; | ||
2573 | |||
2574 | /* set allowed mbus modes based on chip, bus-type, and bus-width */ | ||
2575 | i = 0; | ||
2576 | mbus_codes = state->mbus_codes; | ||
2577 | switch (state->info->type) { | ||
2578 | case TDA19973: | ||
2579 | switch (pdata->vidout_bus_type) { | ||
2580 | case V4L2_MBUS_PARALLEL: | ||
2581 | switch (pdata->vidout_bus_width) { | ||
2582 | case 36: | ||
2583 | mbus_codes[i++] = MEDIA_BUS_FMT_RGB121212_1X36; | ||
2584 | mbus_codes[i++] = MEDIA_BUS_FMT_YUV12_1X36; | ||
2585 | /* fall-through */ | ||
2586 | case 24: | ||
2587 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY12_1X24; | ||
2588 | break; | ||
2589 | } | ||
2590 | break; | ||
2591 | case V4L2_MBUS_BT656: | ||
2592 | switch (pdata->vidout_bus_width) { | ||
2593 | case 36: | ||
2594 | case 24: | ||
2595 | case 12: | ||
2596 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY12_2X12; | ||
2597 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY10_2X10; | ||
2598 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY8_2X8; | ||
2599 | break; | ||
2600 | } | ||
2601 | break; | ||
2602 | default: | ||
2603 | break; | ||
2604 | } | ||
2605 | break; | ||
2606 | case TDA19971: | ||
2607 | switch (pdata->vidout_bus_type) { | ||
2608 | case V4L2_MBUS_PARALLEL: | ||
2609 | switch (pdata->vidout_bus_width) { | ||
2610 | case 24: | ||
2611 | mbus_codes[i++] = MEDIA_BUS_FMT_RGB888_1X24; | ||
2612 | mbus_codes[i++] = MEDIA_BUS_FMT_YUV8_1X24; | ||
2613 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY12_1X24; | ||
2614 | /* fall through */ | ||
2615 | case 20: | ||
2616 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY10_1X20; | ||
2617 | /* fall through */ | ||
2618 | case 16: | ||
2619 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY8_1X16; | ||
2620 | break; | ||
2621 | } | ||
2622 | break; | ||
2623 | case V4L2_MBUS_BT656: | ||
2624 | switch (pdata->vidout_bus_width) { | ||
2625 | case 24: | ||
2626 | case 20: | ||
2627 | case 16: | ||
2628 | case 12: | ||
2629 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY12_2X12; | ||
2630 | /* fall through */ | ||
2631 | case 10: | ||
2632 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY10_2X10; | ||
2633 | /* fall through */ | ||
2634 | case 8: | ||
2635 | mbus_codes[i++] = MEDIA_BUS_FMT_UYVY8_2X8; | ||
2636 | break; | ||
2637 | } | ||
2638 | break; | ||
2639 | default: | ||
2640 | break; | ||
2641 | } | ||
2642 | break; | ||
2643 | } | ||
2644 | if (WARN_ON(i > ARRAY_SIZE(state->mbus_codes))) { | ||
2645 | ret = -EINVAL; | ||
2646 | goto err_free_mutex; | ||
2647 | } | ||
2648 | |||
2649 | /* default format */ | ||
2650 | tda1997x_setup_format(state, state->mbus_codes[0]); | ||
2651 | state->timings = cea1920x1080; | ||
2652 | |||
2653 | /* | ||
2654 | * default to SRGB full range quantization | ||
2655 | * (in case we don't get an infoframe such as DVI signal | ||
2656 | */ | ||
2657 | state->colorimetry.colorspace = V4L2_COLORSPACE_SRGB; | ||
2658 | state->colorimetry.quantization = V4L2_QUANTIZATION_FULL_RANGE; | ||
2659 | |||
2660 | /* disable/reset HDCP to get correct I2C access to Rx HDMI */ | ||
2661 | io_write(sd, REG_MAN_SUS_HDMI_SEL, MAN_RST_HDCP | MAN_DIS_HDCP); | ||
2662 | |||
2663 | /* | ||
2664 | * if N2 version, reset compdel_bp as it may generate some small pixel | ||
2665 | * shifts in case of embedded sync/or delay lower than 4 | ||
2666 | */ | ||
2667 | if (state->chip_revision != 0) { | ||
2668 | io_write(sd, REG_MAN_SUS_HDMI_SEL, 0x00); | ||
2669 | io_write(sd, REG_VDP_CTRL, 0x1f); | ||
2670 | } | ||
2671 | |||
2672 | v4l_info(client, "NXP %s N%d detected\n", state->info->name, | ||
2673 | state->chip_revision + 1); | ||
2674 | v4l_info(client, "video: %dbit %s %d formats available\n", | ||
2675 | pdata->vidout_bus_width, | ||
2676 | (pdata->vidout_bus_type == V4L2_MBUS_PARALLEL) ? | ||
2677 | "parallel" : "BT656", | ||
2678 | i); | ||
2679 | if (pdata->audout_format) { | ||
2680 | v4l_info(client, "audio: %dch %s layout%d sysclk=%d*fs\n", | ||
2681 | pdata->audout_layout ? 2 : 8, | ||
2682 | audfmt_names[pdata->audout_format], | ||
2683 | pdata->audout_layout, | ||
2684 | pdata->audout_mclk_fs); | ||
2685 | } | ||
2686 | |||
2687 | ret = 0x34 + ((io_read(sd, REG_SLAVE_ADDR)>>4) & 0x03); | ||
2688 | state->client_cec = i2c_new_dummy(client->adapter, ret); | ||
2689 | v4l_info(client, "CEC slave address 0x%02x\n", ret); | ||
2690 | |||
2691 | ret = tda1997x_core_init(sd); | ||
2692 | if (ret) | ||
2693 | goto err_free_mutex; | ||
2694 | |||
2695 | /* control handlers */ | ||
2696 | hdl = &state->hdl; | ||
2697 | v4l2_ctrl_handler_init(hdl, 3); | ||
2698 | ctrl = v4l2_ctrl_new_std_menu(hdl, &tda1997x_ctrl_ops, | ||
2699 | V4L2_CID_DV_RX_IT_CONTENT_TYPE, | ||
2700 | V4L2_DV_IT_CONTENT_TYPE_NO_ITC, 0, | ||
2701 | V4L2_DV_IT_CONTENT_TYPE_NO_ITC); | ||
2702 | if (ctrl) | ||
2703 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; | ||
2704 | /* custom controls */ | ||
2705 | state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL, | ||
2706 | V4L2_CID_DV_RX_POWER_PRESENT, 0, 1, 0, 0); | ||
2707 | state->rgb_quantization_range_ctrl = v4l2_ctrl_new_std_menu(hdl, | ||
2708 | &tda1997x_ctrl_ops, | ||
2709 | V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 0, | ||
2710 | V4L2_DV_RGB_RANGE_AUTO); | ||
2711 | state->sd.ctrl_handler = hdl; | ||
2712 | if (hdl->error) { | ||
2713 | ret = hdl->error; | ||
2714 | goto err_free_handler; | ||
2715 | } | ||
2716 | v4l2_ctrl_handler_setup(hdl); | ||
2717 | |||
2718 | /* initialize source pads */ | ||
2719 | state->pads[TDA1997X_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; | ||
2720 | ret = media_entity_pads_init(&sd->entity, TDA1997X_NUM_PADS, | ||
2721 | state->pads); | ||
2722 | if (ret) { | ||
2723 | v4l_err(client, "failed entity_init: %d", ret); | ||
2724 | goto err_free_mutex; | ||
2725 | } | ||
2726 | |||
2727 | ret = v4l2_async_register_subdev(sd); | ||
2728 | if (ret) | ||
2729 | goto err_free_media; | ||
2730 | |||
2731 | /* register audio DAI */ | ||
2732 | if (pdata->audout_format) { | ||
2733 | u64 formats; | ||
2734 | |||
2735 | if (pdata->audout_width == 32) | ||
2736 | formats = SNDRV_PCM_FMTBIT_S32_LE; | ||
2737 | else | ||
2738 | formats = SNDRV_PCM_FMTBIT_S16_LE; | ||
2739 | tda1997x_audio_dai.capture.formats = formats; | ||
2740 | ret = snd_soc_register_codec(&state->client->dev, | ||
2741 | &tda1997x_codec_driver, | ||
2742 | &tda1997x_audio_dai, 1); | ||
2743 | if (ret) { | ||
2744 | dev_err(&client->dev, "register audio codec failed\n"); | ||
2745 | goto err_free_media; | ||
2746 | } | ||
2747 | dev_set_drvdata(&state->client->dev, state); | ||
2748 | v4l_info(state->client, "registered audio codec\n"); | ||
2749 | } | ||
2750 | |||
2751 | /* request irq */ | ||
2752 | ret = devm_request_threaded_irq(&client->dev, client->irq, | ||
2753 | NULL, tda1997x_isr_thread, | ||
2754 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
2755 | KBUILD_MODNAME, state); | ||
2756 | if (ret) { | ||
2757 | v4l_err(client, "irq%d reg failed: %d\n", client->irq, ret); | ||
2758 | goto err_free_media; | ||
2759 | } | ||
2760 | |||
2761 | return 0; | ||
2762 | |||
2763 | err_free_media: | ||
2764 | media_entity_cleanup(&sd->entity); | ||
2765 | err_free_handler: | ||
2766 | v4l2_ctrl_handler_free(&state->hdl); | ||
2767 | err_free_mutex: | ||
2768 | cancel_delayed_work(&state->delayed_work_enable_hpd); | ||
2769 | mutex_destroy(&state->page_lock); | ||
2770 | mutex_destroy(&state->lock); | ||
2771 | err_free_state: | ||
2772 | kfree(state); | ||
2773 | dev_err(&client->dev, "%s failed: %d\n", __func__, ret); | ||
2774 | |||
2775 | return ret; | ||
2776 | } | ||
2777 | |||
2778 | static int tda1997x_remove(struct i2c_client *client) | ||
2779 | { | ||
2780 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
2781 | struct tda1997x_state *state = to_state(sd); | ||
2782 | struct tda1997x_platform_data *pdata = &state->pdata; | ||
2783 | |||
2784 | if (pdata->audout_format) { | ||
2785 | snd_soc_unregister_codec(&client->dev); | ||
2786 | mutex_destroy(&state->audio_lock); | ||
2787 | } | ||
2788 | |||
2789 | disable_irq(state->client->irq); | ||
2790 | tda1997x_power_mode(state, 0); | ||
2791 | |||
2792 | v4l2_async_unregister_subdev(sd); | ||
2793 | media_entity_cleanup(&sd->entity); | ||
2794 | v4l2_ctrl_handler_free(&state->hdl); | ||
2795 | regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies); | ||
2796 | i2c_unregister_device(state->client_cec); | ||
2797 | cancel_delayed_work(&state->delayed_work_enable_hpd); | ||
2798 | mutex_destroy(&state->page_lock); | ||
2799 | mutex_destroy(&state->lock); | ||
2800 | |||
2801 | kfree(state); | ||
2802 | |||
2803 | return 0; | ||
2804 | } | ||
2805 | |||
2806 | static struct i2c_driver tda1997x_i2c_driver = { | ||
2807 | .driver = { | ||
2808 | .name = "tda1997x", | ||
2809 | .of_match_table = of_match_ptr(tda1997x_of_id), | ||
2810 | }, | ||
2811 | .probe = tda1997x_probe, | ||
2812 | .remove = tda1997x_remove, | ||
2813 | .id_table = tda1997x_i2c_id, | ||
2814 | }; | ||
2815 | |||
2816 | module_i2c_driver(tda1997x_i2c_driver); | ||
2817 | |||
2818 | MODULE_AUTHOR("Tim Harvey <tharvey@gateworks.com>"); | ||
2819 | MODULE_DESCRIPTION("TDA1997X HDMI Receiver driver"); | ||
2820 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/tda1997x_regs.h b/drivers/media/i2c/tda1997x_regs.h new file mode 100644 index 000000000000..f55dfc423a86 --- /dev/null +++ b/drivers/media/i2c/tda1997x_regs.h | |||
@@ -0,0 +1,641 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright (C) 2018 Gateworks Corporation | ||
4 | */ | ||
5 | |||
6 | /* Page 0x00 - General Control */ | ||
7 | #define REG_VERSION 0x0000 | ||
8 | #define REG_INPUT_SEL 0x0001 | ||
9 | #define REG_SVC_MODE 0x0002 | ||
10 | #define REG_HPD_MAN_CTRL 0x0003 | ||
11 | #define REG_RT_MAN_CTRL 0x0004 | ||
12 | #define REG_STANDBY_SOFT_RST 0x000A | ||
13 | #define REG_HDMI_SOFT_RST 0x000B | ||
14 | #define REG_HDMI_INFO_RST 0x000C | ||
15 | #define REG_INT_FLG_CLR_TOP 0x000E | ||
16 | #define REG_INT_FLG_CLR_SUS 0x000F | ||
17 | #define REG_INT_FLG_CLR_DDC 0x0010 | ||
18 | #define REG_INT_FLG_CLR_RATE 0x0011 | ||
19 | #define REG_INT_FLG_CLR_MODE 0x0012 | ||
20 | #define REG_INT_FLG_CLR_INFO 0x0013 | ||
21 | #define REG_INT_FLG_CLR_AUDIO 0x0014 | ||
22 | #define REG_INT_FLG_CLR_HDCP 0x0015 | ||
23 | #define REG_INT_FLG_CLR_AFE 0x0016 | ||
24 | #define REG_INT_MASK_TOP 0x0017 | ||
25 | #define REG_INT_MASK_SUS 0x0018 | ||
26 | #define REG_INT_MASK_DDC 0x0019 | ||
27 | #define REG_INT_MASK_RATE 0x001A | ||
28 | #define REG_INT_MASK_MODE 0x001B | ||
29 | #define REG_INT_MASK_INFO 0x001C | ||
30 | #define REG_INT_MASK_AUDIO 0x001D | ||
31 | #define REG_INT_MASK_HDCP 0x001E | ||
32 | #define REG_INT_MASK_AFE 0x001F | ||
33 | #define REG_DETECT_5V 0x0020 | ||
34 | #define REG_SUS_STATUS 0x0021 | ||
35 | #define REG_V_PER 0x0022 | ||
36 | #define REG_H_PER 0x0025 | ||
37 | #define REG_HS_WIDTH 0x0027 | ||
38 | #define REG_FMT_H_TOT 0x0029 | ||
39 | #define REG_FMT_H_ACT 0x002b | ||
40 | #define REG_FMT_H_FRONT 0x002d | ||
41 | #define REG_FMT_H_SYNC 0x002f | ||
42 | #define REG_FMT_H_BACK 0x0031 | ||
43 | #define REG_FMT_V_TOT 0x0033 | ||
44 | #define REG_FMT_V_ACT 0x0035 | ||
45 | #define REG_FMT_V_FRONT_F1 0x0037 | ||
46 | #define REG_FMT_V_FRONT_F2 0x0038 | ||
47 | #define REG_FMT_V_SYNC 0x0039 | ||
48 | #define REG_FMT_V_BACK_F1 0x003a | ||
49 | #define REG_FMT_V_BACK_F2 0x003b | ||
50 | #define REG_FMT_DE_ACT 0x003c | ||
51 | #define REG_RATE_CTRL 0x0040 | ||
52 | #define REG_CLK_MIN_RATE 0x0043 | ||
53 | #define REG_CLK_MAX_RATE 0x0046 | ||
54 | #define REG_CLK_A_STATUS 0x0049 | ||
55 | #define REG_CLK_A_RATE 0x004A | ||
56 | #define REG_DRIFT_CLK_A_REG 0x004D | ||
57 | #define REG_CLK_B_STATUS 0x004E | ||
58 | #define REG_CLK_B_RATE 0x004F | ||
59 | #define REG_DRIFT_CLK_B_REG 0x0052 | ||
60 | #define REG_HDCP_CTRL 0x0060 | ||
61 | #define REG_HDCP_KDS 0x0061 | ||
62 | #define REG_HDCP_BCAPS 0x0063 | ||
63 | #define REG_HDCP_KEY_CTRL 0x0064 | ||
64 | #define REG_INFO_CTRL 0x0076 | ||
65 | #define REG_INFO_EXCEED 0x0077 | ||
66 | #define REG_PIX_REPEAT 0x007B | ||
67 | #define REG_AUDIO_PATH 0x007C | ||
68 | #define REG_AUDCFG 0x007D | ||
69 | #define REG_AUDIO_OUT_ENABLE 0x007E | ||
70 | #define REG_AUDIO_OUT_HIZ 0x007F | ||
71 | #define REG_VDP_CTRL 0x0080 | ||
72 | #define REG_VDP_MATRIX 0x0081 | ||
73 | #define REG_VHREF_CTRL 0x00A0 | ||
74 | #define REG_PXCNT_PR 0x00A2 | ||
75 | #define REG_PXCNT_NPIX 0x00A4 | ||
76 | #define REG_LCNT_PR 0x00A6 | ||
77 | #define REG_LCNT_NLIN 0x00A8 | ||
78 | #define REG_HREF_S 0x00AA | ||
79 | #define REG_HREF_E 0x00AC | ||
80 | #define REG_HS_S 0x00AE | ||
81 | #define REG_HS_E 0x00B0 | ||
82 | #define REG_VREF_F1_S 0x00B2 | ||
83 | #define REG_VREF_F1_WIDTH 0x00B4 | ||
84 | #define REG_VREF_F2_S 0x00B5 | ||
85 | #define REG_VREF_F2_WIDTH 0x00B7 | ||
86 | #define REG_VS_F1_LINE_S 0x00B8 | ||
87 | #define REG_VS_F1_LINE_WIDTH 0x00BA | ||
88 | #define REG_VS_F2_LINE_S 0x00BB | ||
89 | #define REG_VS_F2_LINE_WIDTH 0x00BD | ||
90 | #define REG_VS_F1_PIX_S 0x00BE | ||
91 | #define REG_VS_F1_PIX_E 0x00C0 | ||
92 | #define REG_VS_F2_PIX_S 0x00C2 | ||
93 | #define REG_VS_F2_PIX_E 0x00C4 | ||
94 | #define REG_FREF_F1_S 0x00C6 | ||
95 | #define REG_FREF_F2_S 0x00C8 | ||
96 | #define REG_FDW_S 0x00ca | ||
97 | #define REG_FDW_E 0x00cc | ||
98 | #define REG_BLK_GY 0x00da | ||
99 | #define REG_BLK_BU 0x00dc | ||
100 | #define REG_BLK_RV 0x00de | ||
101 | #define REG_FILTERS_CTRL 0x00e0 | ||
102 | #define REG_DITHERING_CTRL 0x00E9 | ||
103 | #define REG_OF 0x00EA | ||
104 | #define REG_PCLK 0x00EB | ||
105 | #define REG_HS_HREF 0x00EC | ||
106 | #define REG_VS_VREF 0x00ED | ||
107 | #define REG_DE_FREF 0x00EE | ||
108 | #define REG_VP35_32_CTRL 0x00EF | ||
109 | #define REG_VP31_28_CTRL 0x00F0 | ||
110 | #define REG_VP27_24_CTRL 0x00F1 | ||
111 | #define REG_VP23_20_CTRL 0x00F2 | ||
112 | #define REG_VP19_16_CTRL 0x00F3 | ||
113 | #define REG_VP15_12_CTRL 0x00F4 | ||
114 | #define REG_VP11_08_CTRL 0x00F5 | ||
115 | #define REG_VP07_04_CTRL 0x00F6 | ||
116 | #define REG_VP03_00_CTRL 0x00F7 | ||
117 | #define REG_CURPAGE_00H 0xFF | ||
118 | |||
119 | #define MASK_VPER 0x3fffff | ||
120 | #define MASK_VHREF 0x3fff | ||
121 | #define MASK_HPER 0x0fff | ||
122 | #define MASK_HSWIDTH 0x03ff | ||
123 | |||
124 | /* HPD Detection */ | ||
125 | #define DETECT_UTIL BIT(7) /* utility of HDMI level */ | ||
126 | #define DETECT_HPD BIT(6) /* HPD of HDMI level */ | ||
127 | #define DETECT_5V_SEL BIT(2) /* 5V present on selected input */ | ||
128 | #define DETECT_5V_B BIT(1) /* 5V present on input B */ | ||
129 | #define DETECT_5V_A BIT(0) /* 5V present on input A */ | ||
130 | |||
131 | /* Input Select */ | ||
132 | #define INPUT_SEL_RST_FMT BIT(7) /* 1=reset format measurement */ | ||
133 | #define INPUT_SEL_RST_VDP BIT(2) /* 1=reset video data path */ | ||
134 | #define INPUT_SEL_OUT_MODE BIT(1) /* 0=loop 1=bypass */ | ||
135 | #define INPUT_SEL_B BIT(0) /* 0=inputA 1=inputB */ | ||
136 | |||
137 | /* Service Mode */ | ||
138 | #define SVC_MODE_CLK2_MASK 0xc0 | ||
139 | #define SVC_MODE_CLK2_SHIFT 6 | ||
140 | #define SVC_MODE_CLK2_XTL 0L | ||
141 | #define SVC_MODE_CLK2_XTLDIV2 1L | ||
142 | #define SVC_MODE_CLK2_HDMIX2 3L | ||
143 | #define SVC_MODE_CLK1_MASK 0x30 | ||
144 | #define SVC_MODE_CLK1_SHIFT 4 | ||
145 | #define SVC_MODE_CLK1_XTAL 0L | ||
146 | #define SVC_MODE_CLK1_XTLDIV2 1L | ||
147 | #define SVC_MODE_CLK1_HDMI 3L | ||
148 | #define SVC_MODE_RAMP BIT(3) /* 0=colorbar 1=ramp */ | ||
149 | #define SVC_MODE_PAL BIT(2) /* 0=NTSC(480i/p) 1=PAL(576i/p) */ | ||
150 | #define SVC_MODE_INT_PROG BIT(1) /* 0=interlaced 1=progressive */ | ||
151 | #define SVC_MODE_SM_ON BIT(0) /* Enable color bars and tone gen */ | ||
152 | |||
153 | /* HDP Manual Control */ | ||
154 | #define HPD_MAN_CTRL_HPD_PULSE BIT(7) /* HPD Pulse low 110ms */ | ||
155 | #define HPD_MAN_CTRL_5VEN BIT(2) /* Output 5V */ | ||
156 | #define HPD_MAN_CTRL_HPD_B BIT(1) /* Assert HPD High for Input A */ | ||
157 | #define HPD_MAN_CTRL_HPD_A BIT(0) /* Assert HPD High for Input A */ | ||
158 | |||
159 | /* RT_MAN_CTRL */ | ||
160 | #define RT_MAN_CTRL_RT_AUTO BIT(7) | ||
161 | #define RT_MAN_CTRL_RT BIT(6) | ||
162 | #define RT_MAN_CTRL_RT_B BIT(1) /* enable TMDS pull-up on Input B */ | ||
163 | #define RT_MAN_CTRL_RT_A BIT(0) /* enable TMDS pull-up on Input A */ | ||
164 | |||
165 | /* VDP_CTRL */ | ||
166 | #define VDP_CTRL_COMPDEL_BP BIT(5) /* bypass compdel */ | ||
167 | #define VDP_CTRL_FORMATTER_BP BIT(4) /* bypass formatter */ | ||
168 | #define VDP_CTRL_PREFILTER_BP BIT(1) /* bypass prefilter */ | ||
169 | #define VDP_CTRL_MATRIX_BP BIT(0) /* bypass matrix conversion */ | ||
170 | |||
171 | /* REG_VHREF_CTRL */ | ||
172 | #define VHREF_INT_DET BIT(7) /* interlace detect: 1=alt 0=frame */ | ||
173 | #define VHREF_VSYNC_MASK 0x60 | ||
174 | #define VHREF_VSYNC_SHIFT 6 | ||
175 | #define VHREF_VSYNC_AUTO 0L | ||
176 | #define VHREF_VSYNC_FDW 1L | ||
177 | #define VHREF_VSYNC_EVEN 2L | ||
178 | #define VHREF_VSYNC_ODD 3L | ||
179 | #define VHREF_STD_DET_MASK 0x18 | ||
180 | #define VHREF_STD_DET_SHIFT 3 | ||
181 | #define VHREF_STD_DET_PAL 0L | ||
182 | #define VHREF_STD_DET_NTSC 1L | ||
183 | #define VHREF_STD_DET_AUTO 2L | ||
184 | #define VHREF_STD_DET_OFF 3L | ||
185 | #define VHREF_VREF_SRC_STD BIT(2) /* 1=from standard 0=manual */ | ||
186 | #define VHREF_HREF_SRC_STD BIT(1) /* 1=from standard 0=manual */ | ||
187 | #define VHREF_HSYNC_SEL_HS BIT(0) /* 1=HS 0=VS */ | ||
188 | |||
189 | /* AUDIO_OUT_ENABLE */ | ||
190 | #define AUDIO_OUT_ENABLE_ACLK BIT(5) | ||
191 | #define AUDIO_OUT_ENABLE_WS BIT(4) | ||
192 | #define AUDIO_OUT_ENABLE_AP3 BIT(3) | ||
193 | #define AUDIO_OUT_ENABLE_AP2 BIT(2) | ||
194 | #define AUDIO_OUT_ENABLE_AP1 BIT(1) | ||
195 | #define AUDIO_OUT_ENABLE_AP0 BIT(0) | ||
196 | |||
197 | /* Prefilter Control */ | ||
198 | #define FILTERS_CTRL_BU_MASK 0x0c | ||
199 | #define FILTERS_CTRL_BU_SHIFT 2 | ||
200 | #define FILTERS_CTRL_RV_MASK 0x03 | ||
201 | #define FILTERS_CTRL_RV_SHIFT 0 | ||
202 | #define FILTERS_CTRL_OFF 0L /* off */ | ||
203 | #define FILTERS_CTRL_2TAP 1L /* 2 Taps */ | ||
204 | #define FILTERS_CTRL_7TAP 2L /* 7 Taps */ | ||
205 | #define FILTERS_CTRL_2_7TAP 3L /* 2/7 Taps */ | ||
206 | |||
207 | /* PCLK Configuration */ | ||
208 | #define PCLK_DELAY_MASK 0x70 | ||
209 | #define PCLK_DELAY_SHIFT 4 /* Pixel delay (-8..+7) */ | ||
210 | #define PCLK_INV_SHIFT 2 | ||
211 | #define PCLK_SEL_MASK 0x03 /* clock scaler */ | ||
212 | #define PCLK_SEL_SHIFT 0 | ||
213 | #define PCLK_SEL_X1 0L | ||
214 | #define PCLK_SEL_X2 1L | ||
215 | #define PCLK_SEL_DIV2 2L | ||
216 | #define PCLK_SEL_DIV4 3L | ||
217 | |||
218 | /* Pixel Repeater */ | ||
219 | #define PIX_REPEAT_MASK_UP_SEL 0x30 | ||
220 | #define PIX_REPEAT_MASK_REP 0x0f | ||
221 | #define PIX_REPEAT_SHIFT 4 | ||
222 | #define PIX_REPEAT_CHROMA 1 | ||
223 | |||
224 | /* Page 0x01 - HDMI info and packets */ | ||
225 | #define REG_HDMI_FLAGS 0x0100 | ||
226 | #define REG_DEEP_COLOR_MODE 0x0101 | ||
227 | #define REG_AUDIO_FLAGS 0x0108 | ||
228 | #define REG_AUDIO_FREQ 0x0109 | ||
229 | #define REG_ACP_PACKET_TYPE 0x0141 | ||
230 | #define REG_ISRC1_PACKET_TYPE 0x0161 | ||
231 | #define REG_ISRC2_PACKET_TYPE 0x0181 | ||
232 | #define REG_GBD_PACKET_TYPE 0x01a1 | ||
233 | |||
234 | /* HDMI_FLAGS */ | ||
235 | #define HDMI_FLAGS_AUDIO BIT(7) /* Audio packet in last videoframe */ | ||
236 | #define HDMI_FLAGS_HDMI BIT(6) /* HDMI detected */ | ||
237 | #define HDMI_FLAGS_EESS BIT(5) /* EESS detected */ | ||
238 | #define HDMI_FLAGS_HDCP BIT(4) /* HDCP detected */ | ||
239 | #define HDMI_FLAGS_AVMUTE BIT(3) /* AVMUTE */ | ||
240 | #define HDMI_FLAGS_AUD_LAYOUT BIT(2) /* Layout status Audio sample packet */ | ||
241 | #define HDMI_FLAGS_AUD_FIFO_OF BIT(1) /* FIFO read/write pointers crossed */ | ||
242 | #define HDMI_FLAGS_AUD_FIFO_LOW BIT(0) /* FIFO read ptr within 2 of write */ | ||
243 | |||
244 | /* Page 0x12 - HDMI Extra control and debug */ | ||
245 | #define REG_CLK_CFG 0x1200 | ||
246 | #define REG_CLK_OUT_CFG 0x1201 | ||
247 | #define REG_CFG1 0x1202 | ||
248 | #define REG_CFG2 0x1203 | ||
249 | #define REG_WDL_CFG 0x1210 | ||
250 | #define REG_DELOCK_DELAY 0x1212 | ||
251 | #define REG_PON_OVR_EN 0x12A0 | ||
252 | #define REG_PON_CBIAS 0x12A1 | ||
253 | #define REG_PON_RESCAL 0x12A2 | ||
254 | #define REG_PON_RES 0x12A3 | ||
255 | #define REG_PON_CLK 0x12A4 | ||
256 | #define REG_PON_PLL 0x12A5 | ||
257 | #define REG_PON_EQ 0x12A6 | ||
258 | #define REG_PON_DES 0x12A7 | ||
259 | #define REG_PON_OUT 0x12A8 | ||
260 | #define REG_PON_MUX 0x12A9 | ||
261 | #define REG_MODE_REC_CFG1 0x12F8 | ||
262 | #define REG_MODE_REC_CFG2 0x12F9 | ||
263 | #define REG_MODE_REC_STS 0x12FA | ||
264 | #define REG_AUDIO_LAYOUT 0x12D0 | ||
265 | |||
266 | #define PON_EN 1 | ||
267 | #define PON_DIS 0 | ||
268 | |||
269 | /* CLK CFG */ | ||
270 | #define CLK_CFG_INV_OUT_CLK BIT(7) | ||
271 | #define CLK_CFG_INV_BUS_CLK BIT(6) | ||
272 | #define CLK_CFG_SEL_ACLK_EN BIT(1) | ||
273 | #define CLK_CFG_SEL_ACLK BIT(0) | ||
274 | #define CLK_CFG_DIS 0 | ||
275 | |||
276 | /* Page 0x13 - HDMI Extra control and debug */ | ||
277 | #define REG_DEEP_COLOR_CTRL 0x1300 | ||
278 | #define REG_CGU_DBG_SEL 0x1305 | ||
279 | #define REG_HDCP_DDC_ADDR 0x1310 | ||
280 | #define REG_HDCP_KIDX 0x1316 | ||
281 | #define REG_DEEP_PLL7_BYP 0x1347 | ||
282 | #define REG_HDCP_DE_CTRL 0x1370 | ||
283 | #define REG_HDCP_EP_FILT_CTRL 0x1371 | ||
284 | #define REG_HDMI_CTRL 0x1377 | ||
285 | #define REG_HMTP_CTRL 0x137a | ||
286 | #define REG_TIMER_D 0x13CF | ||
287 | #define REG_SUS_SET_RGB0 0x13E1 | ||
288 | #define REG_SUS_SET_RGB1 0x13E2 | ||
289 | #define REG_SUS_SET_RGB2 0x13E3 | ||
290 | #define REG_SUS_SET_RGB3 0x13E4 | ||
291 | #define REG_SUS_SET_RGB4 0x13E5 | ||
292 | #define REG_MAN_SUS_HDMI_SEL 0x13E8 | ||
293 | #define REG_MAN_HDMI_SET 0x13E9 | ||
294 | #define REG_SUS_CLOCK_GOOD 0x13EF | ||
295 | |||
296 | /* HDCP DE Control */ | ||
297 | #define HDCP_DE_MODE_MASK 0xc0 /* DE Measurement mode */ | ||
298 | #define HDCP_DE_MODE_SHIFT 6 | ||
299 | #define HDCP_DE_REGEN_EN BIT(5) /* enable regen mode */ | ||
300 | #define HDCP_DE_FILTER_MASK 0x18 /* DE filter sensitivity */ | ||
301 | #define HDCP_DE_FILTER_SHIFT 3 | ||
302 | #define HDCP_DE_COMP_MASK 0x07 /* DE Composition mode */ | ||
303 | #define HDCP_DE_COMP_MIXED 6L | ||
304 | #define HDCP_DE_COMP_OR 5L | ||
305 | #define HDCP_DE_COMP_AND 4L | ||
306 | #define HDCP_DE_COMP_CH3 3L | ||
307 | #define HDCP_DE_COMP_CH2 2L | ||
308 | #define HDCP_DE_COMP_CH1 1L | ||
309 | #define HDCP_DE_COMP_CH0 0L | ||
310 | |||
311 | /* HDCP EP Filter Control */ | ||
312 | #define HDCP_EP_FIL_CTL_MASK 0x30 | ||
313 | #define HDCP_EP_FIL_CTL_SHIFT 4 | ||
314 | #define HDCP_EP_FIL_VS_MASK 0x0c | ||
315 | #define HDCP_EP_FIL_VS_SHIFT 2 | ||
316 | #define HDCP_EP_FIL_HS_MASK 0x03 | ||
317 | #define HDCP_EP_FIL_HS_SHIFT 0 | ||
318 | |||
319 | /* HDMI_CTRL */ | ||
320 | #define HDMI_CTRL_MUTE_MASK 0x0c | ||
321 | #define HDMI_CTRL_MUTE_SHIFT 2 | ||
322 | #define HDMI_CTRL_MUTE_AUTO 0L | ||
323 | #define HDMI_CTRL_MUTE_OFF 1L | ||
324 | #define HDMI_CTRL_MUTE_ON 2L | ||
325 | #define HDMI_CTRL_HDCP_MASK 0x03 | ||
326 | #define HDMI_CTRL_HDCP_SHIFT 0 | ||
327 | #define HDMI_CTRL_HDCP_EESS 2L | ||
328 | #define HDMI_CTRL_HDCP_OESS 1L | ||
329 | #define HDMI_CTRL_HDCP_AUTO 0L | ||
330 | |||
331 | /* CGU_DBG_SEL bits */ | ||
332 | #define CGU_DBG_CLK_SEL_MASK 0x18 | ||
333 | #define CGU_DBG_CLK_SEL_SHIFT 3 | ||
334 | #define CGU_DBG_XO_FRO_SEL BIT(2) | ||
335 | #define CGU_DBG_VDP_CLK_SEL BIT(1) | ||
336 | #define CGU_DBG_PIX_CLK_SEL BIT(0) | ||
337 | |||
338 | /* REG_MAN_SUS_HDMI_SEL / REG_MAN_HDMI_SET bits */ | ||
339 | #define MAN_DIS_OUT_BUF BIT(7) | ||
340 | #define MAN_DIS_ANA_PATH BIT(6) | ||
341 | #define MAN_DIS_HDCP BIT(5) | ||
342 | #define MAN_DIS_TMDS_ENC BIT(4) | ||
343 | #define MAN_DIS_TMDS_FLOW BIT(3) | ||
344 | #define MAN_RST_HDCP BIT(2) | ||
345 | #define MAN_RST_TMDS_ENC BIT(1) | ||
346 | #define MAN_RST_TMDS_FLOW BIT(0) | ||
347 | |||
348 | /* Page 0x14 - Audio Extra control and debug */ | ||
349 | #define REG_FIFO_LATENCY_VAL 0x1403 | ||
350 | #define REG_AUDIO_CLOCK 0x1411 | ||
351 | #define REG_TEST_NCTS_CTRL 0x1415 | ||
352 | #define REG_TEST_AUDIO_FREQ 0x1426 | ||
353 | #define REG_TEST_MODE 0x1437 | ||
354 | |||
355 | /* Audio Clock Configuration */ | ||
356 | #define AUDIO_CLOCK_PLL_PD BIT(7) /* powerdown PLL */ | ||
357 | #define AUDIO_CLOCK_SEL_MASK 0x7f | ||
358 | #define AUDIO_CLOCK_SEL_16FS 0L /* 16*fs */ | ||
359 | #define AUDIO_CLOCK_SEL_32FS 1L /* 32*fs */ | ||
360 | #define AUDIO_CLOCK_SEL_64FS 2L /* 64*fs */ | ||
361 | #define AUDIO_CLOCK_SEL_128FS 3L /* 128*fs */ | ||
362 | #define AUDIO_CLOCK_SEL_256FS 4L /* 256*fs */ | ||
363 | #define AUDIO_CLOCK_SEL_512FS 5L /* 512*fs */ | ||
364 | |||
365 | /* Page 0x20: EDID and Hotplug Detect */ | ||
366 | #define REG_EDID_IN_BYTE0 0x2000 /* EDID base */ | ||
367 | #define REG_EDID_IN_VERSION 0x2080 | ||
368 | #define REG_EDID_ENABLE 0x2081 | ||
369 | #define REG_HPD_POWER 0x2084 | ||
370 | #define REG_HPD_AUTO_CTRL 0x2085 | ||
371 | #define REG_HPD_DURATION 0x2086 | ||
372 | #define REG_RX_HPD_HEAC 0x2087 | ||
373 | |||
374 | /* EDID_ENABLE */ | ||
375 | #define EDID_ENABLE_NACK_OFF BIT(7) | ||
376 | #define EDID_ENABLE_EDID_ONLY BIT(6) | ||
377 | #define EDID_ENABLE_B_EN BIT(1) | ||
378 | #define EDID_ENABLE_A_EN BIT(0) | ||
379 | |||
380 | /* HPD Power */ | ||
381 | #define HPD_POWER_BP_MASK 0x0c | ||
382 | #define HPD_POWER_BP_SHIFT 2 | ||
383 | #define HPD_POWER_BP_LOW 0L | ||
384 | #define HPD_POWER_BP_HIGH 1L | ||
385 | #define HPD_POWER_EDID_ONLY BIT(1) | ||
386 | |||
387 | /* HPD Auto control */ | ||
388 | #define HPD_AUTO_READ_EDID BIT(7) | ||
389 | #define HPD_AUTO_HPD_F3TECH BIT(5) | ||
390 | #define HPD_AUTO_HP_OTHER BIT(4) | ||
391 | #define HPD_AUTO_HPD_UNSEL BIT(3) | ||
392 | #define HPD_AUTO_HPD_ALL_CH BIT(2) | ||
393 | #define HPD_AUTO_HPD_PRV_CH BIT(1) | ||
394 | #define HPD_AUTO_HPD_NEW_CH BIT(0) | ||
395 | |||
396 | /* Page 0x21 - EDID content */ | ||
397 | #define REG_EDID_IN_BYTE128 0x2100 /* CEA Extension block */ | ||
398 | #define REG_EDID_IN_SPA_SUB 0x2180 | ||
399 | #define REG_EDID_IN_SPA_AB_A 0x2181 | ||
400 | #define REG_EDID_IN_SPA_CD_A 0x2182 | ||
401 | #define REG_EDID_IN_CKSUM_A 0x2183 | ||
402 | #define REG_EDID_IN_SPA_AB_B 0x2184 | ||
403 | #define REG_EDID_IN_SPA_CD_B 0x2185 | ||
404 | #define REG_EDID_IN_CKSUM_B 0x2186 | ||
405 | |||
406 | /* Page 0x30 - NV Configuration */ | ||
407 | #define REG_RT_AUTO_CTRL 0x3000 | ||
408 | #define REG_EQ_MAN_CTRL0 0x3001 | ||
409 | #define REG_EQ_MAN_CTRL1 0x3002 | ||
410 | #define REG_OUTPUT_CFG 0x3003 | ||
411 | #define REG_MUTE_CTRL 0x3004 | ||
412 | #define REG_SLAVE_ADDR 0x3005 | ||
413 | #define REG_CMTP_REG6 0x3006 | ||
414 | #define REG_CMTP_REG7 0x3007 | ||
415 | #define REG_CMTP_REG8 0x3008 | ||
416 | #define REG_CMTP_REG9 0x3009 | ||
417 | #define REG_CMTP_REGA 0x300A | ||
418 | #define REG_CMTP_REGB 0x300B | ||
419 | #define REG_CMTP_REGC 0x300C | ||
420 | #define REG_CMTP_REGD 0x300D | ||
421 | #define REG_CMTP_REGE 0x300E | ||
422 | #define REG_CMTP_REGF 0x300F | ||
423 | #define REG_CMTP_REG10 0x3010 | ||
424 | #define REG_CMTP_REG11 0x3011 | ||
425 | |||
426 | /* Page 0x80 - CEC */ | ||
427 | #define REG_PWR_CONTROL 0x80F4 | ||
428 | #define REG_OSC_DIVIDER 0x80F5 | ||
429 | #define REG_EN_OSC_PERIOD_LSB 0x80F8 | ||
430 | #define REG_CONTROL 0x80FF | ||
431 | |||
432 | /* global interrupt flags (INT_FLG_CRL_TOP) */ | ||
433 | #define INTERRUPT_AFE BIT(7) /* AFE module */ | ||
434 | #define INTERRUPT_HDCP BIT(6) /* HDCP module */ | ||
435 | #define INTERRUPT_AUDIO BIT(5) /* Audio module */ | ||
436 | #define INTERRUPT_INFO BIT(4) /* Infoframe module */ | ||
437 | #define INTERRUPT_MODE BIT(3) /* HDMI mode module */ | ||
438 | #define INTERRUPT_RATE BIT(2) /* rate module */ | ||
439 | #define INTERRUPT_DDC BIT(1) /* DDC module */ | ||
440 | #define INTERRUPT_SUS BIT(0) /* SUS module */ | ||
441 | |||
442 | /* INT_FLG_CLR_HDCP bits */ | ||
443 | #define MASK_HDCP_MTP BIT(7) /* HDCP MTP busy */ | ||
444 | #define MASK_HDCP_DLMTP BIT(4) /* HDCP end download MTP to SRAM */ | ||
445 | #define MASK_HDCP_DLRAM BIT(3) /* HDCP end download keys from SRAM */ | ||
446 | #define MASK_HDCP_ENC BIT(2) /* HDCP ENC */ | ||
447 | #define MASK_STATE_C5 BIT(1) /* HDCP State C5 reached */ | ||
448 | #define MASK_AKSV BIT(0) /* AKSV received (start of auth) */ | ||
449 | |||
450 | /* INT_FLG_CLR_RATE bits */ | ||
451 | #define MASK_RATE_B_DRIFT BIT(7) /* Rate measurement drifted */ | ||
452 | #define MASK_RATE_B_ST BIT(6) /* Rate measurement stability change */ | ||
453 | #define MASK_RATE_B_ACT BIT(5) /* Rate measurement activity change */ | ||
454 | #define MASK_RATE_B_PST BIT(4) /* Rate measreument presence change */ | ||
455 | #define MASK_RATE_A_DRIFT BIT(3) /* Rate measurement drifted */ | ||
456 | #define MASK_RATE_A_ST BIT(2) /* Rate measurement stability change */ | ||
457 | #define MASK_RATE_A_ACT BIT(1) /* Rate measurement presence change */ | ||
458 | #define MASK_RATE_A_PST BIT(0) /* Rate measreument presence change */ | ||
459 | |||
460 | /* INT_FLG_CLR_SUS (Start Up Sequencer) bits */ | ||
461 | #define MASK_MPT BIT(7) /* Config MTP end of process */ | ||
462 | #define MASK_FMT BIT(5) /* Video format changed */ | ||
463 | #define MASK_RT_PULSE BIT(4) /* End of termination resistance pulse */ | ||
464 | #define MASK_SUS_END BIT(3) /* SUS last state reached */ | ||
465 | #define MASK_SUS_ACT BIT(2) /* Activity of selected input changed */ | ||
466 | #define MASK_SUS_CH BIT(1) /* Selected input changed */ | ||
467 | #define MASK_SUS_ST BIT(0) /* SUS state changed */ | ||
468 | |||
469 | /* INT_FLG_CLR_DDC bits */ | ||
470 | #define MASK_EDID_MTP BIT(7) /* EDID MTP end of process */ | ||
471 | #define MASK_DDC_ERR BIT(6) /* master DDC error */ | ||
472 | #define MASK_DDC_CMD_DONE BIT(5) /* master DDC cmd send correct */ | ||
473 | #define MASK_READ_DONE BIT(4) /* End of down EDID read */ | ||
474 | #define MASK_RX_DDC_SW BIT(3) /* Output DDC switching finished */ | ||
475 | #define MASK_HDCP_DDC_SW BIT(2) /* HDCP DDC switching finished */ | ||
476 | #define MASK_HDP_PULSE_END BIT(1) /* End of Hot Plug Detect pulse */ | ||
477 | #define MASK_DET_5V BIT(0) /* Detection of +5V */ | ||
478 | |||
479 | /* INT_FLG_CLR_MODE bits */ | ||
480 | #define MASK_HDMI_FLG BIT(7) /* HDMI mode/avmute/encrypt/FIFO fail */ | ||
481 | #define MASK_GAMUT BIT(6) /* Gamut packet */ | ||
482 | #define MASK_ISRC2 BIT(5) /* ISRC2 packet */ | ||
483 | #define MASK_ISRC1 BIT(4) /* ISRC1 packet */ | ||
484 | #define MASK_ACP BIT(3) /* Audio Content Protection packet */ | ||
485 | #define MASK_DC_NO_GCP BIT(2) /* GCP not received in 5 frames */ | ||
486 | #define MASK_DC_PHASE BIT(1) /* deepcolor pixel phase needs update */ | ||
487 | #define MASK_DC_MODE BIT(0) /* deepcolor color depth changed */ | ||
488 | |||
489 | /* INT_FLG_CLR_INFO bits (Infoframe Change Status) */ | ||
490 | #define MASK_MPS_IF BIT(6) /* MPEG Source Product */ | ||
491 | #define MASK_AUD_IF BIT(5) /* Audio */ | ||
492 | #define MASK_SPD_IF BIT(4) /* Source Product Descriptor */ | ||
493 | #define MASK_AVI_IF BIT(3) /* Auxiliary Video IF */ | ||
494 | #define MASK_VS_IF_OTHER_BK2 BIT(2) /* Vendor Specific (bank2) */ | ||
495 | #define MASK_VS_IF_OTHER_BK1 BIT(1) /* Vendor Specific (bank1) */ | ||
496 | #define MASK_VS_IF_HDMI BIT(0) /* Vendor Specific (w/ HDMI LLC code) */ | ||
497 | |||
498 | /* INT_FLG_CLR_AUDIO bits */ | ||
499 | #define MASK_AUDIO_FREQ_FLG BIT(5) /* Audio freq change */ | ||
500 | #define MASK_AUDIO_FLG BIT(4) /* DST, OBA, HBR, ASP change */ | ||
501 | #define MASK_MUTE_FLG BIT(3) /* Audio Mute */ | ||
502 | #define MASK_CH_STATE BIT(2) /* Channel status */ | ||
503 | #define MASK_UNMUTE_FIFO BIT(1) /* Audio Unmute */ | ||
504 | #define MASK_ERROR_FIFO_PT BIT(0) /* Audio FIFO pointer error */ | ||
505 | |||
506 | /* INT_FLG_CLR_AFE bits */ | ||
507 | #define MASK_AFE_WDL_UNLOCKED BIT(7) /* Wordlocker was unlocked */ | ||
508 | #define MASK_AFE_GAIN_DONE BIT(6) /* Gain calibration done */ | ||
509 | #define MASK_AFE_OFFSET_DONE BIT(5) /* Offset calibration done */ | ||
510 | #define MASK_AFE_ACTIVITY_DET BIT(4) /* Activity detected on data */ | ||
511 | #define MASK_AFE_PLL_LOCK BIT(3) /* TMDS PLL is locked */ | ||
512 | #define MASK_AFE_TRMCAL_DONE BIT(2) /* Termination calibration done */ | ||
513 | #define MASK_AFE_ASU_STATE BIT(1) /* ASU state is reached */ | ||
514 | #define MASK_AFE_ASU_READY BIT(0) /* AFE calibration done: TMDS ready */ | ||
515 | |||
516 | /* Audio Output */ | ||
517 | #define AUDCFG_CLK_INVERT BIT(7) /* invert A_CLK polarity */ | ||
518 | #define AUDCFG_TEST_TONE BIT(6) /* enable test tone generator */ | ||
519 | #define AUDCFG_BUS_SHIFT 5 | ||
520 | #define AUDCFG_BUS_I2S 0L | ||
521 | #define AUDCFG_BUS_SPDIF 1L | ||
522 | #define AUDCFG_I2SW_SHIFT 4 | ||
523 | #define AUDCFG_I2SW_16 0L | ||
524 | #define AUDCFG_I2SW_32 1L | ||
525 | #define AUDCFG_AUTO_MUTE_EN BIT(3) /* Enable Automatic audio mute */ | ||
526 | #define AUDCFG_HBR_SHIFT 2 | ||
527 | #define AUDCFG_HBR_STRAIGHT 0L /* straight via AP0 */ | ||
528 | #define AUDCFG_HBR_DEMUX 1L /* demuxed via AP0:AP3 */ | ||
529 | #define AUDCFG_TYPE_MASK 0x03 | ||
530 | #define AUDCFG_TYPE_SHIFT 0 | ||
531 | #define AUDCFG_TYPE_DST 3L /* Direct Stream Transfer (DST) */ | ||
532 | #define AUDCFG_TYPE_OBA 2L /* One Bit Audio (OBA) */ | ||
533 | #define AUDCFG_TYPE_HBR 1L /* High Bit Rate (HBR) */ | ||
534 | #define AUDCFG_TYPE_PCM 0L /* Audio samples */ | ||
535 | |||
536 | /* Video Formatter */ | ||
537 | #define OF_VP_ENABLE BIT(7) /* VP[35:0]/HS/VS/DE/CLK */ | ||
538 | #define OF_BLK BIT(4) /* blanking codes */ | ||
539 | #define OF_TRC BIT(3) /* timing codes (SAV/EAV) */ | ||
540 | #define OF_FMT_MASK 0x3 | ||
541 | #define OF_FMT_444 0L /* RGB444/YUV444 */ | ||
542 | #define OF_FMT_422_SMPT 1L /* YUV422 semi-planar */ | ||
543 | #define OF_FMT_422_CCIR 2L /* YUV422 CCIR656 */ | ||
544 | |||
545 | /* HS/HREF output control */ | ||
546 | #define HS_HREF_DELAY_MASK 0xf0 | ||
547 | #define HS_HREF_DELAY_SHIFT 4 /* Pixel delay (-8..+7) */ | ||
548 | #define HS_HREF_PXQ_SHIFT 3 /* Timing codes from HREF */ | ||
549 | #define HS_HREF_INV_SHIFT 2 /* polarity (1=invert) */ | ||
550 | #define HS_HREF_SEL_MASK 0x03 | ||
551 | #define HS_HREF_SEL_SHIFT 0 | ||
552 | #define HS_HREF_SEL_HS_VHREF 0L /* HS from VHREF */ | ||
553 | #define HS_HREF_SEL_HREF_VHREF 1L /* HREF from VHREF */ | ||
554 | #define HS_HREF_SEL_HREF_HDMI 2L /* HREF from HDMI */ | ||
555 | #define HS_HREF_SEL_NONE 3L /* not generated */ | ||
556 | |||
557 | /* VS output control */ | ||
558 | #define VS_VREF_DELAY_MASK 0xf0 | ||
559 | #define VS_VREF_DELAY_SHIFT 4 /* Pixel delay (-8..+7) */ | ||
560 | #define VS_VREF_INV_SHIFT 2 /* polarity (1=invert) */ | ||
561 | #define VS_VREF_SEL_MASK 0x03 | ||
562 | #define VS_VREF_SEL_SHIFT 0 | ||
563 | #define VS_VREF_SEL_VS_VHREF 0L /* VS from VHREF */ | ||
564 | #define VS_VREF_SEL_VREF_VHREF 1L /* VREF from VHREF */ | ||
565 | #define VS_VREF_SEL_VREF_HDMI 2L /* VREF from HDMI */ | ||
566 | #define VS_VREF_SEL_NONE 3L /* not generated */ | ||
567 | |||
568 | /* DE/FREF output control */ | ||
569 | #define DE_FREF_DELAY_MASK 0xf0 | ||
570 | #define DE_FREF_DELAY_SHIFT 4 /* Pixel delay (-8..+7) */ | ||
571 | #define DE_FREF_DE_PXQ_SHIFT 3 /* Timing codes from DE */ | ||
572 | #define DE_FREF_INV_SHIFT 2 /* polarity (1=invert) */ | ||
573 | #define DE_FREF_SEL_MASK 0x03 | ||
574 | #define DE_FREF_SEL_SHIFT 0 | ||
575 | #define DE_FREF_SEL_DE_VHREF 0L /* DE from VHREF (HREF and not(VREF) */ | ||
576 | #define DE_FREF_SEL_FREF_VHREF 1L /* FREF from VHREF */ | ||
577 | #define DE_FREF_SEL_FREF_HDMI 2L /* FREF from HDMI */ | ||
578 | #define DE_FREF_SEL_NONE 3L /* not generated */ | ||
579 | |||
580 | /* HDMI_SOFT_RST bits */ | ||
581 | #define RESET_DC BIT(7) /* Reset deep color module */ | ||
582 | #define RESET_HDCP BIT(6) /* Reset HDCP module */ | ||
583 | #define RESET_KSV BIT(5) /* Reset KSV-FIFO */ | ||
584 | #define RESET_SCFG BIT(4) /* Reset HDCP and repeater function */ | ||
585 | #define RESET_HCFG BIT(3) /* Reset HDCP DDC part */ | ||
586 | #define RESET_PA BIT(2) /* Reset polarity adjust */ | ||
587 | #define RESET_EP BIT(1) /* Reset Error protection */ | ||
588 | #define RESET_TMDS BIT(0) /* Reset TMDS (calib, encoding, flow) */ | ||
589 | |||
590 | /* HDMI_INFO_RST bits */ | ||
591 | #define NACK_HDCP BIT(7) /* No ACK on HDCP request */ | ||
592 | #define RESET_FIFO BIT(4) /* Reset Audio FIFO control */ | ||
593 | #define RESET_GAMUT BIT(3) /* Clear Gamut packet */ | ||
594 | #define RESET_AI BIT(2) /* Clear ACP and ISRC packets */ | ||
595 | #define RESET_IF BIT(1) /* Clear all Audio infoframe packets */ | ||
596 | #define RESET_AUDIO BIT(0) /* Reset Audio FIFO control */ | ||
597 | |||
598 | /* HDCP_BCAPS bits */ | ||
599 | #define HDCP_HDMI BIT(7) /* HDCP suports HDMI (vs DVI only) */ | ||
600 | #define HDCP_REPEATER BIT(6) /* HDCP supports repeater function */ | ||
601 | #define HDCP_READY BIT(5) /* set by repeater function */ | ||
602 | #define HDCP_FAST BIT(4) /* Up to 400kHz */ | ||
603 | #define HDCP_11 BIT(1) /* HDCP 1.1 supported */ | ||
604 | #define HDCP_FAST_REAUTH BIT(0) /* fast reauthentication supported */ | ||
605 | |||
606 | /* Audio output formatter */ | ||
607 | #define AUDIO_LAYOUT_SP_FLAG BIT(2) /* sp flag used by FIFO */ | ||
608 | #define AUDIO_LAYOUT_MANUAL BIT(1) /* manual layout (vs per pkt) */ | ||
609 | #define AUDIO_LAYOUT_LAYOUT1 BIT(0) /* Layout1: AP0-3 vs Layout0:AP0 */ | ||
610 | |||
611 | /* masks for interrupt status registers */ | ||
612 | #define MASK_SUS_STATUS 0x1F | ||
613 | #define LAST_STATE_REACHED 0x1B | ||
614 | #define MASK_CLK_STABLE 0x04 | ||
615 | #define MASK_CLK_ACTIVE 0x02 | ||
616 | #define MASK_SUS_STATE 0x10 | ||
617 | #define MASK_SR_FIFO_FIFO_CTRL 0x30 | ||
618 | #define MASK_AUDIO_FLAG 0x10 | ||
619 | |||
620 | /* Rate measurement */ | ||
621 | #define RATE_REFTIM_ENABLE 0x01 | ||
622 | #define CLK_MIN_RATE 0x0057e4 | ||
623 | #define CLK_MAX_RATE 0x0395f8 | ||
624 | #define WDL_CFG_VAL 0x82 | ||
625 | #define DC_FILTER_VAL 0x31 | ||
626 | |||
627 | /* Infoframe */ | ||
628 | #define VS_HDMI_IF_UPDATE 0x0200 | ||
629 | #define VS_HDMI_IF 0x0201 | ||
630 | #define VS_BK1_IF_UPDATE 0x0220 | ||
631 | #define VS_BK1_IF 0x0221 | ||
632 | #define VS_BK2_IF_UPDATE 0x0240 | ||
633 | #define VS_BK2_IF 0x0241 | ||
634 | #define AVI_IF_UPDATE 0x0260 | ||
635 | #define AVI_IF 0x0261 | ||
636 | #define SPD_IF_UPDATE 0x0280 | ||
637 | #define SPD_IF 0x0281 | ||
638 | #define AUD_IF_UPDATE 0x02a0 | ||
639 | #define AUD_IF 0x02a1 | ||
640 | #define MPS_IF_UPDATE 0x02c0 | ||
641 | #define MPS_IF 0x02c1 | ||
diff --git a/drivers/media/i2c/tda9840.c b/drivers/media/i2c/tda9840.c index f31e659588ac..0dd6ff3e6201 100644 --- a/drivers/media/i2c/tda9840.c +++ b/drivers/media/i2c/tda9840.c | |||
@@ -68,11 +68,15 @@ static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val) | |||
68 | static int tda9840_status(struct v4l2_subdev *sd) | 68 | static int tda9840_status(struct v4l2_subdev *sd) |
69 | { | 69 | { |
70 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 70 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
71 | int rc; | ||
71 | u8 byte; | 72 | u8 byte; |
72 | 73 | ||
73 | if (1 != i2c_master_recv(client, &byte, 1)) { | 74 | rc = i2c_master_recv(client, &byte, 1); |
75 | if (rc != 1) { | ||
74 | v4l2_dbg(1, debug, sd, | 76 | v4l2_dbg(1, debug, sd, |
75 | "i2c_master_recv() failed\n"); | 77 | "i2c_master_recv() failed\n"); |
78 | if (rc < 0) | ||
79 | return rc; | ||
76 | return -EIO; | 80 | return -EIO; |
77 | } | 81 | } |
78 | 82 | ||
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index 772164b848ef..5919214a56bf 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c | |||
@@ -156,14 +156,18 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
156 | struct v4l2_subdev *sd = &chip->sd; | 156 | struct v4l2_subdev *sd = &chip->sd; |
157 | struct i2c_client *c = v4l2_get_subdevdata(sd); | 157 | struct i2c_client *c = v4l2_get_subdevdata(sd); |
158 | unsigned char buffer[2]; | 158 | unsigned char buffer[2]; |
159 | int rc; | ||
159 | 160 | ||
160 | if (subaddr < 0) { | 161 | if (subaddr < 0) { |
161 | v4l2_dbg(1, debug, sd, "chip_write: 0x%x\n", val); | 162 | v4l2_dbg(1, debug, sd, "chip_write: 0x%x\n", val); |
162 | chip->shadow.bytes[1] = val; | 163 | chip->shadow.bytes[1] = val; |
163 | buffer[0] = val; | 164 | buffer[0] = val; |
164 | if (1 != i2c_master_send(c, buffer, 1)) { | 165 | rc = i2c_master_send(c, buffer, 1); |
166 | if (rc != 1) { | ||
165 | v4l2_warn(sd, "I/O error (write 0x%x)\n", val); | 167 | v4l2_warn(sd, "I/O error (write 0x%x)\n", val); |
166 | return -1; | 168 | if (rc < 0) |
169 | return rc; | ||
170 | return -EIO; | ||
167 | } | 171 | } |
168 | } else { | 172 | } else { |
169 | if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | 173 | if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { |
@@ -178,10 +182,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
178 | chip->shadow.bytes[subaddr+1] = val; | 182 | chip->shadow.bytes[subaddr+1] = val; |
179 | buffer[0] = subaddr; | 183 | buffer[0] = subaddr; |
180 | buffer[1] = val; | 184 | buffer[1] = val; |
181 | if (2 != i2c_master_send(c, buffer, 2)) { | 185 | rc = i2c_master_send(c, buffer, 2); |
186 | if (rc != 2) { | ||
182 | v4l2_warn(sd, "I/O error (write reg%d=0x%x)\n", | 187 | v4l2_warn(sd, "I/O error (write reg%d=0x%x)\n", |
183 | subaddr, val); | 188 | subaddr, val); |
184 | return -1; | 189 | if (rc < 0) |
190 | return rc; | ||
191 | return -EIO; | ||
185 | } | 192 | } |
186 | } | 193 | } |
187 | return 0; | 194 | return 0; |
@@ -214,10 +221,14 @@ static int chip_read(struct CHIPSTATE *chip) | |||
214 | struct v4l2_subdev *sd = &chip->sd; | 221 | struct v4l2_subdev *sd = &chip->sd; |
215 | struct i2c_client *c = v4l2_get_subdevdata(sd); | 222 | struct i2c_client *c = v4l2_get_subdevdata(sd); |
216 | unsigned char buffer; | 223 | unsigned char buffer; |
224 | int rc; | ||
217 | 225 | ||
218 | if (1 != i2c_master_recv(c, &buffer, 1)) { | 226 | rc = i2c_master_recv(c, &buffer, 1); |
227 | if (rc != 1) { | ||
219 | v4l2_warn(sd, "I/O error (read)\n"); | 228 | v4l2_warn(sd, "I/O error (read)\n"); |
220 | return -1; | 229 | if (rc < 0) |
230 | return rc; | ||
231 | return -EIO; | ||
221 | } | 232 | } |
222 | v4l2_dbg(1, debug, sd, "chip_read: 0x%x\n", buffer); | 233 | v4l2_dbg(1, debug, sd, "chip_read: 0x%x\n", buffer); |
223 | return buffer; | 234 | return buffer; |
@@ -227,6 +238,7 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) | |||
227 | { | 238 | { |
228 | struct v4l2_subdev *sd = &chip->sd; | 239 | struct v4l2_subdev *sd = &chip->sd; |
229 | struct i2c_client *c = v4l2_get_subdevdata(sd); | 240 | struct i2c_client *c = v4l2_get_subdevdata(sd); |
241 | int rc; | ||
230 | unsigned char write[1]; | 242 | unsigned char write[1]; |
231 | unsigned char read[1]; | 243 | unsigned char read[1]; |
232 | struct i2c_msg msgs[2] = { | 244 | struct i2c_msg msgs[2] = { |
@@ -245,9 +257,12 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) | |||
245 | 257 | ||
246 | write[0] = subaddr; | 258 | write[0] = subaddr; |
247 | 259 | ||
248 | if (2 != i2c_transfer(c->adapter, msgs, 2)) { | 260 | rc = i2c_transfer(c->adapter, msgs, 2); |
261 | if (rc != 2) { | ||
249 | v4l2_warn(sd, "I/O error (read2)\n"); | 262 | v4l2_warn(sd, "I/O error (read2)\n"); |
250 | return -1; | 263 | if (rc < 0) |
264 | return rc; | ||
265 | return -EIO; | ||
251 | } | 266 | } |
252 | v4l2_dbg(1, debug, sd, "chip_read2: reg%d=0x%x\n", | 267 | v4l2_dbg(1, debug, sd, "chip_read2: reg%d=0x%x\n", |
253 | subaddr, read[0]); | 268 | subaddr, read[0]); |
@@ -258,7 +273,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) | |||
258 | { | 273 | { |
259 | struct v4l2_subdev *sd = &chip->sd; | 274 | struct v4l2_subdev *sd = &chip->sd; |
260 | struct i2c_client *c = v4l2_get_subdevdata(sd); | 275 | struct i2c_client *c = v4l2_get_subdevdata(sd); |
261 | int i; | 276 | int i, rc; |
262 | 277 | ||
263 | if (0 == cmd->count) | 278 | if (0 == cmd->count) |
264 | return 0; | 279 | return 0; |
@@ -284,9 +299,12 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) | |||
284 | printk(KERN_CONT "\n"); | 299 | printk(KERN_CONT "\n"); |
285 | 300 | ||
286 | /* send data to the chip */ | 301 | /* send data to the chip */ |
287 | if (cmd->count != i2c_master_send(c, cmd->bytes, cmd->count)) { | 302 | rc = i2c_master_send(c, cmd->bytes, cmd->count); |
303 | if (rc != cmd->count) { | ||
288 | v4l2_warn(sd, "I/O error (%s)\n", name); | 304 | v4l2_warn(sd, "I/O error (%s)\n", name); |
289 | return -1; | 305 | if (rc < 0) |
306 | return rc; | ||
307 | return -EIO; | ||
290 | } | 308 | } |
291 | return 0; | 309 | return 0; |
292 | } | 310 | } |
@@ -400,8 +418,12 @@ static int tda9840_getrxsubchans(struct CHIPSTATE *chip) | |||
400 | struct v4l2_subdev *sd = &chip->sd; | 418 | struct v4l2_subdev *sd = &chip->sd; |
401 | int val, mode; | 419 | int val, mode; |
402 | 420 | ||
403 | val = chip_read(chip); | ||
404 | mode = V4L2_TUNER_SUB_MONO; | 421 | mode = V4L2_TUNER_SUB_MONO; |
422 | |||
423 | val = chip_read(chip); | ||
424 | if (val < 0) | ||
425 | return mode; | ||
426 | |||
405 | if (val & TDA9840_DS_DUAL) | 427 | if (val & TDA9840_DS_DUAL) |
406 | mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | 428 | mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
407 | if (val & TDA9840_ST_STEREO) | 429 | if (val & TDA9840_ST_STEREO) |
@@ -445,7 +467,12 @@ static void tda9840_setaudmode(struct CHIPSTATE *chip, int mode) | |||
445 | static int tda9840_checkit(struct CHIPSTATE *chip) | 467 | static int tda9840_checkit(struct CHIPSTATE *chip) |
446 | { | 468 | { |
447 | int rc; | 469 | int rc; |
470 | |||
448 | rc = chip_read(chip); | 471 | rc = chip_read(chip); |
472 | if (rc < 0) | ||
473 | return 0; | ||
474 | |||
475 | |||
449 | /* lower 5 bits should be 0 */ | 476 | /* lower 5 bits should be 0 */ |
450 | return ((rc & 0x1f) == 0) ? 1 : 0; | 477 | return ((rc & 0x1f) == 0) ? 1 : 0; |
451 | } | 478 | } |
@@ -563,6 +590,9 @@ static int tda985x_getrxsubchans(struct CHIPSTATE *chip) | |||
563 | /* Allows forced mono */ | 590 | /* Allows forced mono */ |
564 | mode = V4L2_TUNER_SUB_MONO; | 591 | mode = V4L2_TUNER_SUB_MONO; |
565 | val = chip_read(chip); | 592 | val = chip_read(chip); |
593 | if (val < 0) | ||
594 | return mode; | ||
595 | |||
566 | if (val & TDA985x_STP) | 596 | if (val & TDA985x_STP) |
567 | mode = V4L2_TUNER_SUB_STEREO; | 597 | mode = V4L2_TUNER_SUB_STEREO; |
568 | if (val & TDA985x_SAPP) | 598 | if (val & TDA985x_SAPP) |
@@ -720,8 +750,12 @@ static int tda9873_getrxsubchans(struct CHIPSTATE *chip) | |||
720 | struct v4l2_subdev *sd = &chip->sd; | 750 | struct v4l2_subdev *sd = &chip->sd; |
721 | int val,mode; | 751 | int val,mode; |
722 | 752 | ||
723 | val = chip_read(chip); | ||
724 | mode = V4L2_TUNER_SUB_MONO; | 753 | mode = V4L2_TUNER_SUB_MONO; |
754 | |||
755 | val = chip_read(chip); | ||
756 | if (val < 0) | ||
757 | return mode; | ||
758 | |||
725 | if (val & TDA9873_STEREO) | 759 | if (val & TDA9873_STEREO) |
726 | mode = V4L2_TUNER_SUB_STEREO; | 760 | mode = V4L2_TUNER_SUB_STEREO; |
727 | if (val & TDA9873_DUAL) | 761 | if (val & TDA9873_DUAL) |
@@ -780,7 +814,8 @@ static int tda9873_checkit(struct CHIPSTATE *chip) | |||
780 | { | 814 | { |
781 | int rc; | 815 | int rc; |
782 | 816 | ||
783 | if (-1 == (rc = chip_read2(chip,254))) | 817 | rc = chip_read2(chip, 254); |
818 | if (rc < 0) | ||
784 | return 0; | 819 | return 0; |
785 | return (rc & ~0x1f) == 0x80; | 820 | return (rc & ~0x1f) == 0x80; |
786 | } | 821 | } |
@@ -926,11 +961,14 @@ static int tda9874a_getrxsubchans(struct CHIPSTATE *chip) | |||
926 | 961 | ||
927 | mode = V4L2_TUNER_SUB_MONO; | 962 | mode = V4L2_TUNER_SUB_MONO; |
928 | 963 | ||
929 | if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR))) | 964 | dsr = chip_read2(chip, TDA9874A_DSR); |
965 | if (dsr < 0) | ||
930 | return mode; | 966 | return mode; |
931 | if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR))) | 967 | nsr = chip_read2(chip, TDA9874A_NSR); |
968 | if (nsr < 0) | ||
932 | return mode; | 969 | return mode; |
933 | if(-1 == (necr = chip_read2(chip,TDA9874A_NECR))) | 970 | necr = chip_read2(chip, TDA9874A_NECR); |
971 | if (necr < 0) | ||
934 | return mode; | 972 | return mode; |
935 | 973 | ||
936 | /* need to store dsr/nsr somewhere */ | 974 | /* need to store dsr/nsr somewhere */ |
@@ -1059,9 +1097,11 @@ static int tda9874a_checkit(struct CHIPSTATE *chip) | |||
1059 | struct v4l2_subdev *sd = &chip->sd; | 1097 | struct v4l2_subdev *sd = &chip->sd; |
1060 | int dic,sic; /* device id. and software id. codes */ | 1098 | int dic,sic; /* device id. and software id. codes */ |
1061 | 1099 | ||
1062 | if(-1 == (dic = chip_read2(chip,TDA9874A_DIC))) | 1100 | dic = chip_read2(chip, TDA9874A_DIC); |
1101 | if (dic < 0) | ||
1063 | return 0; | 1102 | return 0; |
1064 | if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) | 1103 | sic = chip_read2(chip, TDA9874A_SIC); |
1104 | if (sic < 0) | ||
1065 | return 0; | 1105 | return 0; |
1066 | 1106 | ||
1067 | v4l2_dbg(1, debug, sd, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); | 1107 | v4l2_dbg(1, debug, sd, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); |
@@ -1201,7 +1241,11 @@ static int tda9875_checkit(struct CHIPSTATE *chip) | |||
1201 | int dic, rev; | 1241 | int dic, rev; |
1202 | 1242 | ||
1203 | dic = chip_read2(chip, 254); | 1243 | dic = chip_read2(chip, 254); |
1244 | if (dic < 0) | ||
1245 | return 0; | ||
1204 | rev = chip_read2(chip, 255); | 1246 | rev = chip_read2(chip, 255); |
1247 | if (rev < 0) | ||
1248 | return 0; | ||
1205 | 1249 | ||
1206 | if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */ | 1250 | if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */ |
1207 | v4l2_info(sd, "found tda9875%s rev. %d.\n", | 1251 | v4l2_info(sd, "found tda9875%s rev. %d.\n", |
@@ -1377,8 +1421,12 @@ static int ta8874z_getrxsubchans(struct CHIPSTATE *chip) | |||
1377 | { | 1421 | { |
1378 | int val, mode; | 1422 | int val, mode; |
1379 | 1423 | ||
1380 | val = chip_read(chip); | ||
1381 | mode = V4L2_TUNER_SUB_MONO; | 1424 | mode = V4L2_TUNER_SUB_MONO; |
1425 | |||
1426 | val = chip_read(chip); | ||
1427 | if (val < 0) | ||
1428 | return mode; | ||
1429 | |||
1382 | if (val & TA8874Z_B1){ | 1430 | if (val & TA8874Z_B1){ |
1383 | mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | 1431 | mode |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; |
1384 | }else if (!(val & TA8874Z_B0)){ | 1432 | }else if (!(val & TA8874Z_B0)){ |
@@ -1431,7 +1479,11 @@ static void ta8874z_setaudmode(struct CHIPSTATE *chip, int mode) | |||
1431 | static int ta8874z_checkit(struct CHIPSTATE *chip) | 1479 | static int ta8874z_checkit(struct CHIPSTATE *chip) |
1432 | { | 1480 | { |
1433 | int rc; | 1481 | int rc; |
1482 | |||
1434 | rc = chip_read(chip); | 1483 | rc = chip_read(chip); |
1484 | if (rc < 0) | ||
1485 | return rc; | ||
1486 | |||
1435 | return ((rc & 0x1f) == 0x1f) ? 1 : 0; | 1487 | return ((rc & 0x1f) == 0x1f) ? 1 : 0; |
1436 | } | 1488 | } |
1437 | 1489 | ||
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 8b0aa9297bde..6a9890531d01 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c | |||
@@ -747,60 +747,47 @@ static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl) | |||
747 | } | 747 | } |
748 | 748 | ||
749 | /** | 749 | /** |
750 | * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm | 750 | * tvp514x_g_frame_interval() - V4L2 decoder interface handler |
751 | * @sd: pointer to standard V4L2 sub-device structure | 751 | * @sd: pointer to standard V4L2 sub-device structure |
752 | * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure | 752 | * @ival: pointer to a v4l2_subdev_frame_interval structure |
753 | * | 753 | * |
754 | * Returns the decoder's video CAPTURE parameters. | 754 | * Returns the decoder's video CAPTURE parameters. |
755 | */ | 755 | */ |
756 | static int | 756 | static int |
757 | tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) | 757 | tvp514x_g_frame_interval(struct v4l2_subdev *sd, |
758 | struct v4l2_subdev_frame_interval *ival) | ||
758 | { | 759 | { |
759 | struct tvp514x_decoder *decoder = to_decoder(sd); | 760 | struct tvp514x_decoder *decoder = to_decoder(sd); |
760 | struct v4l2_captureparm *cparm; | ||
761 | enum tvp514x_std current_std; | 761 | enum tvp514x_std current_std; |
762 | 762 | ||
763 | if (a == NULL) | ||
764 | return -EINVAL; | ||
765 | |||
766 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
767 | /* only capture is supported */ | ||
768 | return -EINVAL; | ||
769 | 763 | ||
770 | /* get the current standard */ | 764 | /* get the current standard */ |
771 | current_std = decoder->current_std; | 765 | current_std = decoder->current_std; |
772 | 766 | ||
773 | cparm = &a->parm.capture; | 767 | ival->interval = |
774 | cparm->capability = V4L2_CAP_TIMEPERFRAME; | ||
775 | cparm->timeperframe = | ||
776 | decoder->std_list[current_std].standard.frameperiod; | 768 | decoder->std_list[current_std].standard.frameperiod; |
777 | 769 | ||
778 | return 0; | 770 | return 0; |
779 | } | 771 | } |
780 | 772 | ||
781 | /** | 773 | /** |
782 | * tvp514x_s_parm() - V4L2 decoder interface handler for s_parm | 774 | * tvp514x_s_frame_interval() - V4L2 decoder interface handler |
783 | * @sd: pointer to standard V4L2 sub-device structure | 775 | * @sd: pointer to standard V4L2 sub-device structure |
784 | * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure | 776 | * @ival: pointer to a v4l2_subdev_frame_interval structure |
785 | * | 777 | * |
786 | * Configures the decoder to use the input parameters, if possible. If | 778 | * Configures the decoder to use the input parameters, if possible. If |
787 | * not possible, returns the appropriate error code. | 779 | * not possible, returns the appropriate error code. |
788 | */ | 780 | */ |
789 | static int | 781 | static int |
790 | tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a) | 782 | tvp514x_s_frame_interval(struct v4l2_subdev *sd, |
783 | struct v4l2_subdev_frame_interval *ival) | ||
791 | { | 784 | { |
792 | struct tvp514x_decoder *decoder = to_decoder(sd); | 785 | struct tvp514x_decoder *decoder = to_decoder(sd); |
793 | struct v4l2_fract *timeperframe; | 786 | struct v4l2_fract *timeperframe; |
794 | enum tvp514x_std current_std; | 787 | enum tvp514x_std current_std; |
795 | 788 | ||
796 | if (a == NULL) | ||
797 | return -EINVAL; | ||
798 | |||
799 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
800 | /* only capture is supported */ | ||
801 | return -EINVAL; | ||
802 | 789 | ||
803 | timeperframe = &a->parm.capture.timeperframe; | 790 | timeperframe = &ival->interval; |
804 | 791 | ||
805 | /* get the current standard */ | 792 | /* get the current standard */ |
806 | current_std = decoder->current_std; | 793 | current_std = decoder->current_std; |
@@ -961,8 +948,8 @@ static const struct v4l2_subdev_video_ops tvp514x_video_ops = { | |||
961 | .s_std = tvp514x_s_std, | 948 | .s_std = tvp514x_s_std, |
962 | .s_routing = tvp514x_s_routing, | 949 | .s_routing = tvp514x_s_routing, |
963 | .querystd = tvp514x_querystd, | 950 | .querystd = tvp514x_querystd, |
964 | .g_parm = tvp514x_g_parm, | 951 | .g_frame_interval = tvp514x_g_frame_interval, |
965 | .s_parm = tvp514x_s_parm, | 952 | .s_frame_interval = tvp514x_s_frame_interval, |
966 | .s_stream = tvp514x_s_stream, | 953 | .s_stream = tvp514x_s_stream, |
967 | }; | 954 | }; |
968 | 955 | ||
diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c new file mode 100644 index 000000000000..a54548cc4285 --- /dev/null +++ b/drivers/media/i2c/tw9910.c | |||
@@ -0,0 +1,1027 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * tw9910 Video Driver | ||
4 | * | ||
5 | * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org> | ||
6 | * | ||
7 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
8 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
9 | * | ||
10 | * Based on ov772x driver, | ||
11 | * | ||
12 | * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com> | ||
13 | * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net> | ||
14 | * Copyright (C) 2008 Magnus Damm | ||
15 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
16 | */ | ||
17 | |||
18 | #include <linux/clk.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/gpio/consumer.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/v4l2-mediabus.h> | ||
27 | #include <linux/videodev2.h> | ||
28 | |||
29 | #include <media/i2c/tw9910.h> | ||
30 | #include <media/v4l2-subdev.h> | ||
31 | |||
32 | #define GET_ID(val) ((val & 0xF8) >> 3) | ||
33 | #define GET_REV(val) (val & 0x07) | ||
34 | |||
35 | /* | ||
36 | * register offset | ||
37 | */ | ||
38 | #define ID 0x00 /* Product ID Code Register */ | ||
39 | #define STATUS1 0x01 /* Chip Status Register I */ | ||
40 | #define INFORM 0x02 /* Input Format */ | ||
41 | #define OPFORM 0x03 /* Output Format Control Register */ | ||
42 | #define DLYCTR 0x04 /* Hysteresis and HSYNC Delay Control */ | ||
43 | #define OUTCTR1 0x05 /* Output Control I */ | ||
44 | #define ACNTL1 0x06 /* Analog Control Register 1 */ | ||
45 | #define CROP_HI 0x07 /* Cropping Register, High */ | ||
46 | #define VDELAY_LO 0x08 /* Vertical Delay Register, Low */ | ||
47 | #define VACTIVE_LO 0x09 /* Vertical Active Register, Low */ | ||
48 | #define HDELAY_LO 0x0A /* Horizontal Delay Register, Low */ | ||
49 | #define HACTIVE_LO 0x0B /* Horizontal Active Register, Low */ | ||
50 | #define CNTRL1 0x0C /* Control Register I */ | ||
51 | #define VSCALE_LO 0x0D /* Vertical Scaling Register, Low */ | ||
52 | #define SCALE_HI 0x0E /* Scaling Register, High */ | ||
53 | #define HSCALE_LO 0x0F /* Horizontal Scaling Register, Low */ | ||
54 | #define BRIGHT 0x10 /* BRIGHTNESS Control Register */ | ||
55 | #define CONTRAST 0x11 /* CONTRAST Control Register */ | ||
56 | #define SHARPNESS 0x12 /* SHARPNESS Control Register I */ | ||
57 | #define SAT_U 0x13 /* Chroma (U) Gain Register */ | ||
58 | #define SAT_V 0x14 /* Chroma (V) Gain Register */ | ||
59 | #define HUE 0x15 /* Hue Control Register */ | ||
60 | #define CORING1 0x17 | ||
61 | #define CORING2 0x18 /* Coring and IF compensation */ | ||
62 | #define VBICNTL 0x19 /* VBI Control Register */ | ||
63 | #define ACNTL2 0x1A /* Analog Control 2 */ | ||
64 | #define OUTCTR2 0x1B /* Output Control 2 */ | ||
65 | #define SDT 0x1C /* Standard Selection */ | ||
66 | #define SDTR 0x1D /* Standard Recognition */ | ||
67 | #define TEST 0x1F /* Test Control Register */ | ||
68 | #define CLMPG 0x20 /* Clamping Gain */ | ||
69 | #define IAGC 0x21 /* Individual AGC Gain */ | ||
70 | #define AGCGAIN 0x22 /* AGC Gain */ | ||
71 | #define PEAKWT 0x23 /* White Peak Threshold */ | ||
72 | #define CLMPL 0x24 /* Clamp level */ | ||
73 | #define SYNCT 0x25 /* Sync Amplitude */ | ||
74 | #define MISSCNT 0x26 /* Sync Miss Count Register */ | ||
75 | #define PCLAMP 0x27 /* Clamp Position Register */ | ||
76 | #define VCNTL1 0x28 /* Vertical Control I */ | ||
77 | #define VCNTL2 0x29 /* Vertical Control II */ | ||
78 | #define CKILL 0x2A /* Color Killer Level Control */ | ||
79 | #define COMB 0x2B /* Comb Filter Control */ | ||
80 | #define LDLY 0x2C /* Luma Delay and H Filter Control */ | ||
81 | #define MISC1 0x2D /* Miscellaneous Control I */ | ||
82 | #define LOOP 0x2E /* LOOP Control Register */ | ||
83 | #define MISC2 0x2F /* Miscellaneous Control II */ | ||
84 | #define MVSN 0x30 /* Macrovision Detection */ | ||
85 | #define STATUS2 0x31 /* Chip STATUS II */ | ||
86 | #define HFREF 0x32 /* H monitor */ | ||
87 | #define CLMD 0x33 /* CLAMP MODE */ | ||
88 | #define IDCNTL 0x34 /* ID Detection Control */ | ||
89 | #define CLCNTL1 0x35 /* Clamp Control I */ | ||
90 | #define ANAPLLCTL 0x4C | ||
91 | #define VBIMIN 0x4D | ||
92 | #define HSLOWCTL 0x4E | ||
93 | #define WSS3 0x4F | ||
94 | #define FILLDATA 0x50 | ||
95 | #define SDID 0x51 | ||
96 | #define DID 0x52 | ||
97 | #define WSS1 0x53 | ||
98 | #define WSS2 0x54 | ||
99 | #define VVBI 0x55 | ||
100 | #define LCTL6 0x56 | ||
101 | #define LCTL7 0x57 | ||
102 | #define LCTL8 0x58 | ||
103 | #define LCTL9 0x59 | ||
104 | #define LCTL10 0x5A | ||
105 | #define LCTL11 0x5B | ||
106 | #define LCTL12 0x5C | ||
107 | #define LCTL13 0x5D | ||
108 | #define LCTL14 0x5E | ||
109 | #define LCTL15 0x5F | ||
110 | #define LCTL16 0x60 | ||
111 | #define LCTL17 0x61 | ||
112 | #define LCTL18 0x62 | ||
113 | #define LCTL19 0x63 | ||
114 | #define LCTL20 0x64 | ||
115 | #define LCTL21 0x65 | ||
116 | #define LCTL22 0x66 | ||
117 | #define LCTL23 0x67 | ||
118 | #define LCTL24 0x68 | ||
119 | #define LCTL25 0x69 | ||
120 | #define LCTL26 0x6A | ||
121 | #define HSBEGIN 0x6B | ||
122 | #define HSEND 0x6C | ||
123 | #define OVSDLY 0x6D | ||
124 | #define OVSEND 0x6E | ||
125 | #define VBIDELAY 0x6F | ||
126 | |||
127 | /* | ||
128 | * register detail | ||
129 | */ | ||
130 | |||
131 | /* INFORM */ | ||
132 | #define FC27_ON 0x40 /* 1 : Input crystal clock frequency is 27MHz */ | ||
133 | #define FC27_FF 0x00 /* 0 : Square pixel mode. */ | ||
134 | /* Must use 24.54MHz for 60Hz field rate */ | ||
135 | /* source or 29.5MHz for 50Hz field rate */ | ||
136 | #define IFSEL_S 0x10 /* 01 : S-video decoding */ | ||
137 | #define IFSEL_C 0x00 /* 00 : Composite video decoding */ | ||
138 | /* Y input video selection */ | ||
139 | #define YSEL_M0 0x00 /* 00 : Mux0 selected */ | ||
140 | #define YSEL_M1 0x04 /* 01 : Mux1 selected */ | ||
141 | #define YSEL_M2 0x08 /* 10 : Mux2 selected */ | ||
142 | #define YSEL_M3 0x10 /* 11 : Mux3 selected */ | ||
143 | |||
144 | /* OPFORM */ | ||
145 | #define MODE 0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */ | ||
146 | /* 1 : ITU-R-656 compatible data sequence format */ | ||
147 | #define LEN 0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */ | ||
148 | /* 1 : 16-bit YCrCb 4:2:2 output format.*/ | ||
149 | #define LLCMODE 0x20 /* 1 : LLC output mode. */ | ||
150 | /* 0 : free-run output mode */ | ||
151 | #define AINC 0x10 /* Serial interface auto-indexing control */ | ||
152 | /* 0 : auto-increment */ | ||
153 | /* 1 : non-auto */ | ||
154 | #define VSCTL 0x08 /* 1 : Vertical out ctrl by DVALID */ | ||
155 | /* 0 : Vertical out ctrl by HACTIVE and DVALID */ | ||
156 | #define OEN_TRI_SEL_MASK 0x07 | ||
157 | #define OEN_TRI_SEL_ALL_ON 0x00 /* Enable output for Rev0/Rev1 */ | ||
158 | #define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */ | ||
159 | #define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */ | ||
160 | |||
161 | /* OUTCTR1 */ | ||
162 | #define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */ | ||
163 | #define VSP_HI 0x80 /* 1 : VS pin output polarity is active high. */ | ||
164 | /* VS pin output control */ | ||
165 | #define VSSL_VSYNC 0x00 /* 0 : VSYNC */ | ||
166 | #define VSSL_VACT 0x10 /* 1 : VACT */ | ||
167 | #define VSSL_FIELD 0x20 /* 2 : FIELD */ | ||
168 | #define VSSL_VVALID 0x30 /* 3 : VVALID */ | ||
169 | #define VSSL_ZERO 0x70 /* 7 : 0 */ | ||
170 | #define HSP_LOW 0x00 /* 0 : HS pin output polarity is active low */ | ||
171 | #define HSP_HI 0x08 /* 1 : HS pin output polarity is active high.*/ | ||
172 | /* HS pin output control */ | ||
173 | #define HSSL_HACT 0x00 /* 0 : HACT */ | ||
174 | #define HSSL_HSYNC 0x01 /* 1 : HSYNC */ | ||
175 | #define HSSL_DVALID 0x02 /* 2 : DVALID */ | ||
176 | #define HSSL_HLOCK 0x03 /* 3 : HLOCK */ | ||
177 | #define HSSL_ASYNCW 0x04 /* 4 : ASYNCW */ | ||
178 | #define HSSL_ZERO 0x07 /* 7 : 0 */ | ||
179 | |||
180 | /* ACNTL1 */ | ||
181 | #define SRESET 0x80 /* resets the device to its default state | ||
182 | * but all register content remain unchanged. | ||
183 | * This bit is self-resetting. | ||
184 | */ | ||
185 | #define ACNTL1_PDN_MASK 0x0e | ||
186 | #define CLK_PDN 0x08 /* system clock power down */ | ||
187 | #define Y_PDN 0x04 /* Luma ADC power down */ | ||
188 | #define C_PDN 0x02 /* Chroma ADC power down */ | ||
189 | |||
190 | /* ACNTL2 */ | ||
191 | #define ACNTL2_PDN_MASK 0x40 | ||
192 | #define PLL_PDN 0x40 /* PLL power down */ | ||
193 | |||
194 | /* VBICNTL */ | ||
195 | |||
196 | /* RTSEL : control the real time signal output from the MPOUT pin */ | ||
197 | #define RTSEL_MASK 0x07 | ||
198 | #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */ | ||
199 | #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */ | ||
200 | #define RTSEL_SLOCK 0x02 /* 0010 = S-lock */ | ||
201 | #define RTSEL_VLOCK 0x03 /* 0011 = V-lock */ | ||
202 | #define RTSEL_MONO 0x04 /* 0100 = MONO */ | ||
203 | #define RTSEL_DET50 0x05 /* 0101 = DET50 */ | ||
204 | #define RTSEL_FIELD 0x06 /* 0110 = FIELD */ | ||
205 | #define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */ | ||
206 | |||
207 | /* HSYNC start and end are constant for now */ | ||
208 | #define HSYNC_START 0x0260 | ||
209 | #define HSYNC_END 0x0300 | ||
210 | |||
211 | /* | ||
212 | * structure | ||
213 | */ | ||
214 | |||
215 | struct regval_list { | ||
216 | unsigned char reg_num; | ||
217 | unsigned char value; | ||
218 | }; | ||
219 | |||
220 | struct tw9910_scale_ctrl { | ||
221 | char *name; | ||
222 | unsigned short width; | ||
223 | unsigned short height; | ||
224 | u16 hscale; | ||
225 | u16 vscale; | ||
226 | }; | ||
227 | |||
228 | struct tw9910_priv { | ||
229 | struct v4l2_subdev subdev; | ||
230 | struct clk *clk; | ||
231 | struct tw9910_video_info *info; | ||
232 | struct gpio_desc *pdn_gpio; | ||
233 | struct gpio_desc *rstb_gpio; | ||
234 | const struct tw9910_scale_ctrl *scale; | ||
235 | v4l2_std_id norm; | ||
236 | u32 revision; | ||
237 | }; | ||
238 | |||
239 | static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = { | ||
240 | { | ||
241 | .name = "NTSC SQ", | ||
242 | .width = 640, | ||
243 | .height = 480, | ||
244 | .hscale = 0x0100, | ||
245 | .vscale = 0x0100, | ||
246 | }, | ||
247 | { | ||
248 | .name = "NTSC CCIR601", | ||
249 | .width = 720, | ||
250 | .height = 480, | ||
251 | .hscale = 0x0100, | ||
252 | .vscale = 0x0100, | ||
253 | }, | ||
254 | { | ||
255 | .name = "NTSC SQ (CIF)", | ||
256 | .width = 320, | ||
257 | .height = 240, | ||
258 | .hscale = 0x0200, | ||
259 | .vscale = 0x0200, | ||
260 | }, | ||
261 | { | ||
262 | .name = "NTSC CCIR601 (CIF)", | ||
263 | .width = 360, | ||
264 | .height = 240, | ||
265 | .hscale = 0x0200, | ||
266 | .vscale = 0x0200, | ||
267 | }, | ||
268 | { | ||
269 | .name = "NTSC SQ (QCIF)", | ||
270 | .width = 160, | ||
271 | .height = 120, | ||
272 | .hscale = 0x0400, | ||
273 | .vscale = 0x0400, | ||
274 | }, | ||
275 | { | ||
276 | .name = "NTSC CCIR601 (QCIF)", | ||
277 | .width = 180, | ||
278 | .height = 120, | ||
279 | .hscale = 0x0400, | ||
280 | .vscale = 0x0400, | ||
281 | }, | ||
282 | }; | ||
283 | |||
284 | static const struct tw9910_scale_ctrl tw9910_pal_scales[] = { | ||
285 | { | ||
286 | .name = "PAL SQ", | ||
287 | .width = 768, | ||
288 | .height = 576, | ||
289 | .hscale = 0x0100, | ||
290 | .vscale = 0x0100, | ||
291 | }, | ||
292 | { | ||
293 | .name = "PAL CCIR601", | ||
294 | .width = 720, | ||
295 | .height = 576, | ||
296 | .hscale = 0x0100, | ||
297 | .vscale = 0x0100, | ||
298 | }, | ||
299 | { | ||
300 | .name = "PAL SQ (CIF)", | ||
301 | .width = 384, | ||
302 | .height = 288, | ||
303 | .hscale = 0x0200, | ||
304 | .vscale = 0x0200, | ||
305 | }, | ||
306 | { | ||
307 | .name = "PAL CCIR601 (CIF)", | ||
308 | .width = 360, | ||
309 | .height = 288, | ||
310 | .hscale = 0x0200, | ||
311 | .vscale = 0x0200, | ||
312 | }, | ||
313 | { | ||
314 | .name = "PAL SQ (QCIF)", | ||
315 | .width = 192, | ||
316 | .height = 144, | ||
317 | .hscale = 0x0400, | ||
318 | .vscale = 0x0400, | ||
319 | }, | ||
320 | { | ||
321 | .name = "PAL CCIR601 (QCIF)", | ||
322 | .width = 180, | ||
323 | .height = 144, | ||
324 | .hscale = 0x0400, | ||
325 | .vscale = 0x0400, | ||
326 | }, | ||
327 | }; | ||
328 | |||
329 | /* | ||
330 | * general function | ||
331 | */ | ||
332 | static struct tw9910_priv *to_tw9910(const struct i2c_client *client) | ||
333 | { | ||
334 | return container_of(i2c_get_clientdata(client), struct tw9910_priv, | ||
335 | subdev); | ||
336 | } | ||
337 | |||
338 | static int tw9910_mask_set(struct i2c_client *client, u8 command, | ||
339 | u8 mask, u8 set) | ||
340 | { | ||
341 | s32 val = i2c_smbus_read_byte_data(client, command); | ||
342 | |||
343 | if (val < 0) | ||
344 | return val; | ||
345 | |||
346 | val &= ~mask; | ||
347 | val |= set & mask; | ||
348 | |||
349 | return i2c_smbus_write_byte_data(client, command, val); | ||
350 | } | ||
351 | |||
352 | static int tw9910_set_scale(struct i2c_client *client, | ||
353 | const struct tw9910_scale_ctrl *scale) | ||
354 | { | ||
355 | int ret; | ||
356 | |||
357 | ret = i2c_smbus_write_byte_data(client, SCALE_HI, | ||
358 | (scale->vscale & 0x0F00) >> 4 | | ||
359 | (scale->hscale & 0x0F00) >> 8); | ||
360 | if (ret < 0) | ||
361 | return ret; | ||
362 | |||
363 | ret = i2c_smbus_write_byte_data(client, HSCALE_LO, | ||
364 | scale->hscale & 0x00FF); | ||
365 | if (ret < 0) | ||
366 | return ret; | ||
367 | |||
368 | ret = i2c_smbus_write_byte_data(client, VSCALE_LO, | ||
369 | scale->vscale & 0x00FF); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static int tw9910_set_hsync(struct i2c_client *client) | ||
375 | { | ||
376 | struct tw9910_priv *priv = to_tw9910(client); | ||
377 | int ret; | ||
378 | |||
379 | /* bit 10 - 3 */ | ||
380 | ret = i2c_smbus_write_byte_data(client, HSBEGIN, | ||
381 | (HSYNC_START & 0x07F8) >> 3); | ||
382 | if (ret < 0) | ||
383 | return ret; | ||
384 | |||
385 | /* bit 10 - 3 */ | ||
386 | ret = i2c_smbus_write_byte_data(client, HSEND, | ||
387 | (HSYNC_END & 0x07F8) >> 3); | ||
388 | if (ret < 0) | ||
389 | return ret; | ||
390 | |||
391 | /* So far only revisions 0 and 1 have been seen. */ | ||
392 | /* bit 2 - 0 */ | ||
393 | if (priv->revision == 1) | ||
394 | ret = tw9910_mask_set(client, HSLOWCTL, 0x77, | ||
395 | (HSYNC_START & 0x0007) << 4 | | ||
396 | (HSYNC_END & 0x0007)); | ||
397 | |||
398 | return ret; | ||
399 | } | ||
400 | |||
401 | static void tw9910_reset(struct i2c_client *client) | ||
402 | { | ||
403 | tw9910_mask_set(client, ACNTL1, SRESET, SRESET); | ||
404 | usleep_range(1000, 5000); | ||
405 | } | ||
406 | |||
407 | static int tw9910_power(struct i2c_client *client, int enable) | ||
408 | { | ||
409 | int ret; | ||
410 | u8 acntl1; | ||
411 | u8 acntl2; | ||
412 | |||
413 | if (enable) { | ||
414 | acntl1 = 0; | ||
415 | acntl2 = 0; | ||
416 | } else { | ||
417 | acntl1 = CLK_PDN | Y_PDN | C_PDN; | ||
418 | acntl2 = PLL_PDN; | ||
419 | } | ||
420 | |||
421 | ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1); | ||
422 | if (ret < 0) | ||
423 | return ret; | ||
424 | |||
425 | return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2); | ||
426 | } | ||
427 | |||
428 | static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm, | ||
429 | u32 width, u32 height) | ||
430 | { | ||
431 | const struct tw9910_scale_ctrl *scale; | ||
432 | const struct tw9910_scale_ctrl *ret = NULL; | ||
433 | __u32 diff = 0xffffffff, tmp; | ||
434 | int size, i; | ||
435 | |||
436 | if (norm & V4L2_STD_NTSC) { | ||
437 | scale = tw9910_ntsc_scales; | ||
438 | size = ARRAY_SIZE(tw9910_ntsc_scales); | ||
439 | } else if (norm & V4L2_STD_PAL) { | ||
440 | scale = tw9910_pal_scales; | ||
441 | size = ARRAY_SIZE(tw9910_pal_scales); | ||
442 | } else { | ||
443 | return NULL; | ||
444 | } | ||
445 | |||
446 | for (i = 0; i < size; i++) { | ||
447 | tmp = abs(width - scale[i].width) + | ||
448 | abs(height - scale[i].height); | ||
449 | if (tmp < diff) { | ||
450 | diff = tmp; | ||
451 | ret = scale + i; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | /* | ||
459 | * subdevice operations | ||
460 | */ | ||
461 | static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) | ||
462 | { | ||
463 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
464 | struct tw9910_priv *priv = to_tw9910(client); | ||
465 | u8 val; | ||
466 | int ret; | ||
467 | |||
468 | if (!enable) { | ||
469 | switch (priv->revision) { | ||
470 | case 0: | ||
471 | val = OEN_TRI_SEL_ALL_OFF_r0; | ||
472 | break; | ||
473 | case 1: | ||
474 | val = OEN_TRI_SEL_ALL_OFF_r1; | ||
475 | break; | ||
476 | default: | ||
477 | dev_err(&client->dev, "un-supported revision\n"); | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | } else { | ||
481 | val = OEN_TRI_SEL_ALL_ON; | ||
482 | |||
483 | if (!priv->scale) { | ||
484 | dev_err(&client->dev, "norm select error\n"); | ||
485 | return -EPERM; | ||
486 | } | ||
487 | |||
488 | dev_dbg(&client->dev, "%s %dx%d\n", | ||
489 | priv->scale->name, | ||
490 | priv->scale->width, | ||
491 | priv->scale->height); | ||
492 | } | ||
493 | |||
494 | ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val); | ||
495 | if (ret < 0) | ||
496 | return ret; | ||
497 | |||
498 | return tw9910_power(client, enable); | ||
499 | } | ||
500 | |||
501 | static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm) | ||
502 | { | ||
503 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
504 | struct tw9910_priv *priv = to_tw9910(client); | ||
505 | |||
506 | *norm = priv->norm; | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) | ||
512 | { | ||
513 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
514 | struct tw9910_priv *priv = to_tw9910(client); | ||
515 | const unsigned int hact = 720; | ||
516 | const unsigned int hdelay = 15; | ||
517 | unsigned int vact; | ||
518 | unsigned int vdelay; | ||
519 | int ret; | ||
520 | |||
521 | if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL))) | ||
522 | return -EINVAL; | ||
523 | |||
524 | priv->norm = norm; | ||
525 | if (norm & V4L2_STD_525_60) { | ||
526 | vact = 240; | ||
527 | vdelay = 18; | ||
528 | ret = tw9910_mask_set(client, VVBI, 0x10, 0x10); | ||
529 | } else { | ||
530 | vact = 288; | ||
531 | vdelay = 24; | ||
532 | ret = tw9910_mask_set(client, VVBI, 0x10, 0x00); | ||
533 | } | ||
534 | if (!ret) | ||
535 | ret = i2c_smbus_write_byte_data(client, CROP_HI, | ||
536 | ((vdelay >> 2) & 0xc0) | | ||
537 | ((vact >> 4) & 0x30) | | ||
538 | ((hdelay >> 6) & 0x0c) | | ||
539 | ((hact >> 8) & 0x03)); | ||
540 | if (!ret) | ||
541 | ret = i2c_smbus_write_byte_data(client, VDELAY_LO, | ||
542 | vdelay & 0xff); | ||
543 | if (!ret) | ||
544 | ret = i2c_smbus_write_byte_data(client, VACTIVE_LO, | ||
545 | vact & 0xff); | ||
546 | |||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
551 | static int tw9910_g_register(struct v4l2_subdev *sd, | ||
552 | struct v4l2_dbg_register *reg) | ||
553 | { | ||
554 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
555 | int ret; | ||
556 | |||
557 | if (reg->reg > 0xff) | ||
558 | return -EINVAL; | ||
559 | |||
560 | reg->size = 1; | ||
561 | ret = i2c_smbus_read_byte_data(client, reg->reg); | ||
562 | if (ret < 0) | ||
563 | return ret; | ||
564 | |||
565 | /* | ||
566 | * ret = int | ||
567 | * reg->val = __u64 | ||
568 | */ | ||
569 | reg->val = (__u64)ret; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static int tw9910_s_register(struct v4l2_subdev *sd, | ||
575 | const struct v4l2_dbg_register *reg) | ||
576 | { | ||
577 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
578 | |||
579 | if (reg->reg > 0xff || | ||
580 | reg->val > 0xff) | ||
581 | return -EINVAL; | ||
582 | |||
583 | return i2c_smbus_write_byte_data(client, reg->reg, reg->val); | ||
584 | } | ||
585 | #endif | ||
586 | |||
587 | static int tw9910_power_on(struct tw9910_priv *priv) | ||
588 | { | ||
589 | struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); | ||
590 | int ret; | ||
591 | |||
592 | if (priv->clk) { | ||
593 | ret = clk_prepare_enable(priv->clk); | ||
594 | if (ret) | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | if (priv->pdn_gpio) { | ||
599 | gpiod_set_value(priv->pdn_gpio, 0); | ||
600 | usleep_range(500, 1000); | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * FIXME: The reset signal is connected to a shared GPIO on some | ||
605 | * platforms (namely the SuperH Migo-R). Until a framework becomes | ||
606 | * available to handle this cleanly, request the GPIO temporarily | ||
607 | * to avoid conflicts. | ||
608 | */ | ||
609 | priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb", | ||
610 | GPIOD_OUT_LOW); | ||
611 | if (IS_ERR(priv->rstb_gpio)) { | ||
612 | dev_info(&client->dev, "Unable to get GPIO \"rstb\""); | ||
613 | return PTR_ERR(priv->rstb_gpio); | ||
614 | } | ||
615 | |||
616 | if (priv->rstb_gpio) { | ||
617 | gpiod_set_value(priv->rstb_gpio, 1); | ||
618 | usleep_range(500, 1000); | ||
619 | gpiod_set_value(priv->rstb_gpio, 0); | ||
620 | usleep_range(500, 1000); | ||
621 | |||
622 | gpiod_put(priv->rstb_gpio); | ||
623 | } | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static int tw9910_power_off(struct tw9910_priv *priv) | ||
629 | { | ||
630 | clk_disable_unprepare(priv->clk); | ||
631 | |||
632 | if (priv->pdn_gpio) { | ||
633 | gpiod_set_value(priv->pdn_gpio, 1); | ||
634 | usleep_range(500, 1000); | ||
635 | } | ||
636 | |||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | static int tw9910_s_power(struct v4l2_subdev *sd, int on) | ||
641 | { | ||
642 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
643 | struct tw9910_priv *priv = to_tw9910(client); | ||
644 | |||
645 | return on ? tw9910_power_on(priv) : tw9910_power_off(priv); | ||
646 | } | ||
647 | |||
648 | static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height) | ||
649 | { | ||
650 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
651 | struct tw9910_priv *priv = to_tw9910(client); | ||
652 | int ret = -EINVAL; | ||
653 | u8 val; | ||
654 | |||
655 | /* Select suitable norm. */ | ||
656 | priv->scale = tw9910_select_norm(priv->norm, *width, *height); | ||
657 | if (!priv->scale) | ||
658 | goto tw9910_set_fmt_error; | ||
659 | |||
660 | /* Reset hardware. */ | ||
661 | tw9910_reset(client); | ||
662 | |||
663 | /* Set bus width. */ | ||
664 | val = 0x00; | ||
665 | if (priv->info->buswidth == 16) | ||
666 | val = LEN; | ||
667 | |||
668 | ret = tw9910_mask_set(client, OPFORM, LEN, val); | ||
669 | if (ret < 0) | ||
670 | goto tw9910_set_fmt_error; | ||
671 | |||
672 | /* Select MPOUT behavior. */ | ||
673 | switch (priv->info->mpout) { | ||
674 | case TW9910_MPO_VLOSS: | ||
675 | val = RTSEL_VLOSS; break; | ||
676 | case TW9910_MPO_HLOCK: | ||
677 | val = RTSEL_HLOCK; break; | ||
678 | case TW9910_MPO_SLOCK: | ||
679 | val = RTSEL_SLOCK; break; | ||
680 | case TW9910_MPO_VLOCK: | ||
681 | val = RTSEL_VLOCK; break; | ||
682 | case TW9910_MPO_MONO: | ||
683 | val = RTSEL_MONO; break; | ||
684 | case TW9910_MPO_DET50: | ||
685 | val = RTSEL_DET50; break; | ||
686 | case TW9910_MPO_FIELD: | ||
687 | val = RTSEL_FIELD; break; | ||
688 | case TW9910_MPO_RTCO: | ||
689 | val = RTSEL_RTCO; break; | ||
690 | default: | ||
691 | val = 0; | ||
692 | } | ||
693 | |||
694 | ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val); | ||
695 | if (ret < 0) | ||
696 | goto tw9910_set_fmt_error; | ||
697 | |||
698 | /* Set scale. */ | ||
699 | ret = tw9910_set_scale(client, priv->scale); | ||
700 | if (ret < 0) | ||
701 | goto tw9910_set_fmt_error; | ||
702 | |||
703 | /* Set hsync. */ | ||
704 | ret = tw9910_set_hsync(client); | ||
705 | if (ret < 0) | ||
706 | goto tw9910_set_fmt_error; | ||
707 | |||
708 | *width = priv->scale->width; | ||
709 | *height = priv->scale->height; | ||
710 | |||
711 | return ret; | ||
712 | |||
713 | tw9910_set_fmt_error: | ||
714 | |||
715 | tw9910_reset(client); | ||
716 | priv->scale = NULL; | ||
717 | |||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | static int tw9910_get_selection(struct v4l2_subdev *sd, | ||
722 | struct v4l2_subdev_pad_config *cfg, | ||
723 | struct v4l2_subdev_selection *sel) | ||
724 | { | ||
725 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
726 | struct tw9910_priv *priv = to_tw9910(client); | ||
727 | |||
728 | if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) | ||
729 | return -EINVAL; | ||
730 | /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported. */ | ||
731 | if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS) | ||
732 | return -EINVAL; | ||
733 | |||
734 | sel->r.left = 0; | ||
735 | sel->r.top = 0; | ||
736 | if (priv->norm & V4L2_STD_NTSC) { | ||
737 | sel->r.width = 640; | ||
738 | sel->r.height = 480; | ||
739 | } else { | ||
740 | sel->r.width = 768; | ||
741 | sel->r.height = 576; | ||
742 | } | ||
743 | |||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | static int tw9910_get_fmt(struct v4l2_subdev *sd, | ||
748 | struct v4l2_subdev_pad_config *cfg, | ||
749 | struct v4l2_subdev_format *format) | ||
750 | { | ||
751 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
752 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
753 | struct tw9910_priv *priv = to_tw9910(client); | ||
754 | |||
755 | if (format->pad) | ||
756 | return -EINVAL; | ||
757 | |||
758 | if (!priv->scale) { | ||
759 | priv->scale = tw9910_select_norm(priv->norm, 640, 480); | ||
760 | if (!priv->scale) | ||
761 | return -EINVAL; | ||
762 | } | ||
763 | |||
764 | mf->width = priv->scale->width; | ||
765 | mf->height = priv->scale->height; | ||
766 | mf->code = MEDIA_BUS_FMT_UYVY8_2X8; | ||
767 | mf->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
768 | mf->field = V4L2_FIELD_INTERLACED_BT; | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static int tw9910_s_fmt(struct v4l2_subdev *sd, | ||
774 | struct v4l2_mbus_framefmt *mf) | ||
775 | { | ||
776 | u32 width = mf->width, height = mf->height; | ||
777 | int ret; | ||
778 | |||
779 | WARN_ON(mf->field != V4L2_FIELD_ANY && | ||
780 | mf->field != V4L2_FIELD_INTERLACED_BT); | ||
781 | |||
782 | /* Check color format. */ | ||
783 | if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8) | ||
784 | return -EINVAL; | ||
785 | |||
786 | mf->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
787 | |||
788 | ret = tw9910_set_frame(sd, &width, &height); | ||
789 | if (ret) | ||
790 | return ret; | ||
791 | |||
792 | mf->width = width; | ||
793 | mf->height = height; | ||
794 | |||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | static int tw9910_set_fmt(struct v4l2_subdev *sd, | ||
799 | struct v4l2_subdev_pad_config *cfg, | ||
800 | struct v4l2_subdev_format *format) | ||
801 | { | ||
802 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
803 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
804 | struct tw9910_priv *priv = to_tw9910(client); | ||
805 | const struct tw9910_scale_ctrl *scale; | ||
806 | |||
807 | if (format->pad) | ||
808 | return -EINVAL; | ||
809 | |||
810 | if (mf->field == V4L2_FIELD_ANY) { | ||
811 | mf->field = V4L2_FIELD_INTERLACED_BT; | ||
812 | } else if (mf->field != V4L2_FIELD_INTERLACED_BT) { | ||
813 | dev_err(&client->dev, "Field type %d invalid\n", mf->field); | ||
814 | return -EINVAL; | ||
815 | } | ||
816 | |||
817 | mf->code = MEDIA_BUS_FMT_UYVY8_2X8; | ||
818 | mf->colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
819 | |||
820 | /* Select suitable norm. */ | ||
821 | scale = tw9910_select_norm(priv->norm, mf->width, mf->height); | ||
822 | if (!scale) | ||
823 | return -EINVAL; | ||
824 | |||
825 | mf->width = scale->width; | ||
826 | mf->height = scale->height; | ||
827 | |||
828 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) | ||
829 | return tw9910_s_fmt(sd, mf); | ||
830 | |||
831 | cfg->try_fmt = *mf; | ||
832 | |||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | static int tw9910_video_probe(struct i2c_client *client) | ||
837 | { | ||
838 | struct tw9910_priv *priv = to_tw9910(client); | ||
839 | s32 id; | ||
840 | int ret; | ||
841 | |||
842 | /* TW9910 only use 8 or 16 bit bus width. */ | ||
843 | if (priv->info->buswidth != 16 && priv->info->buswidth != 8) { | ||
844 | dev_err(&client->dev, "bus width error\n"); | ||
845 | return -ENODEV; | ||
846 | } | ||
847 | |||
848 | ret = tw9910_s_power(&priv->subdev, 1); | ||
849 | if (ret < 0) | ||
850 | return ret; | ||
851 | |||
852 | /* | ||
853 | * Check and show Product ID. | ||
854 | * So far only revisions 0 and 1 have been seen. | ||
855 | */ | ||
856 | id = i2c_smbus_read_byte_data(client, ID); | ||
857 | priv->revision = GET_REV(id); | ||
858 | id = GET_ID(id); | ||
859 | |||
860 | if (id != 0x0b || priv->revision > 0x01) { | ||
861 | dev_err(&client->dev, "Product ID error %x:%x\n", | ||
862 | id, priv->revision); | ||
863 | ret = -ENODEV; | ||
864 | goto done; | ||
865 | } | ||
866 | |||
867 | dev_info(&client->dev, "tw9910 Product ID %0x:%0x\n", | ||
868 | id, priv->revision); | ||
869 | |||
870 | priv->norm = V4L2_STD_NTSC; | ||
871 | priv->scale = &tw9910_ntsc_scales[0]; | ||
872 | |||
873 | done: | ||
874 | tw9910_s_power(&priv->subdev, 0); | ||
875 | |||
876 | return ret; | ||
877 | } | ||
878 | |||
879 | static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { | ||
880 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
881 | .g_register = tw9910_g_register, | ||
882 | .s_register = tw9910_s_register, | ||
883 | #endif | ||
884 | .s_power = tw9910_s_power, | ||
885 | }; | ||
886 | |||
887 | static int tw9910_enum_mbus_code(struct v4l2_subdev *sd, | ||
888 | struct v4l2_subdev_pad_config *cfg, | ||
889 | struct v4l2_subdev_mbus_code_enum *code) | ||
890 | { | ||
891 | if (code->pad || code->index) | ||
892 | return -EINVAL; | ||
893 | |||
894 | code->code = MEDIA_BUS_FMT_UYVY8_2X8; | ||
895 | |||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm) | ||
900 | { | ||
901 | *norm = V4L2_STD_NTSC | V4L2_STD_PAL; | ||
902 | |||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static const struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { | ||
907 | .s_std = tw9910_s_std, | ||
908 | .g_std = tw9910_g_std, | ||
909 | .s_stream = tw9910_s_stream, | ||
910 | .g_tvnorms = tw9910_g_tvnorms, | ||
911 | }; | ||
912 | |||
913 | static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = { | ||
914 | .enum_mbus_code = tw9910_enum_mbus_code, | ||
915 | .get_selection = tw9910_get_selection, | ||
916 | .get_fmt = tw9910_get_fmt, | ||
917 | .set_fmt = tw9910_set_fmt, | ||
918 | }; | ||
919 | |||
920 | static const struct v4l2_subdev_ops tw9910_subdev_ops = { | ||
921 | .core = &tw9910_subdev_core_ops, | ||
922 | .video = &tw9910_subdev_video_ops, | ||
923 | .pad = &tw9910_subdev_pad_ops, | ||
924 | }; | ||
925 | |||
926 | /* | ||
927 | * i2c_driver function | ||
928 | */ | ||
929 | |||
930 | static int tw9910_probe(struct i2c_client *client, | ||
931 | const struct i2c_device_id *did) | ||
932 | |||
933 | { | ||
934 | struct tw9910_priv *priv; | ||
935 | struct tw9910_video_info *info; | ||
936 | struct i2c_adapter *adapter = | ||
937 | to_i2c_adapter(client->dev.parent); | ||
938 | int ret; | ||
939 | |||
940 | if (!client->dev.platform_data) { | ||
941 | dev_err(&client->dev, "TW9910: missing platform data!\n"); | ||
942 | return -EINVAL; | ||
943 | } | ||
944 | |||
945 | info = client->dev.platform_data; | ||
946 | |||
947 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
948 | dev_err(&client->dev, | ||
949 | "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n"); | ||
950 | return -EIO; | ||
951 | } | ||
952 | |||
953 | priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); | ||
954 | if (!priv) | ||
955 | return -ENOMEM; | ||
956 | |||
957 | priv->info = info; | ||
958 | |||
959 | v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); | ||
960 | |||
961 | priv->clk = clk_get(&client->dev, "xti"); | ||
962 | if (PTR_ERR(priv->clk) == -ENOENT) { | ||
963 | priv->clk = NULL; | ||
964 | } else if (IS_ERR(priv->clk)) { | ||
965 | dev_err(&client->dev, "Unable to get xti clock\n"); | ||
966 | return PTR_ERR(priv->clk); | ||
967 | } | ||
968 | |||
969 | priv->pdn_gpio = gpiod_get_optional(&client->dev, "pdn", | ||
970 | GPIOD_OUT_HIGH); | ||
971 | if (IS_ERR(priv->pdn_gpio)) { | ||
972 | dev_info(&client->dev, "Unable to get GPIO \"pdn\""); | ||
973 | ret = PTR_ERR(priv->pdn_gpio); | ||
974 | goto error_clk_put; | ||
975 | } | ||
976 | |||
977 | ret = tw9910_video_probe(client); | ||
978 | if (ret < 0) | ||
979 | goto error_gpio_put; | ||
980 | |||
981 | ret = v4l2_async_register_subdev(&priv->subdev); | ||
982 | if (ret) | ||
983 | goto error_gpio_put; | ||
984 | |||
985 | return ret; | ||
986 | |||
987 | error_gpio_put: | ||
988 | if (priv->pdn_gpio) | ||
989 | gpiod_put(priv->pdn_gpio); | ||
990 | error_clk_put: | ||
991 | clk_put(priv->clk); | ||
992 | |||
993 | return ret; | ||
994 | } | ||
995 | |||
996 | static int tw9910_remove(struct i2c_client *client) | ||
997 | { | ||
998 | struct tw9910_priv *priv = to_tw9910(client); | ||
999 | |||
1000 | if (priv->pdn_gpio) | ||
1001 | gpiod_put(priv->pdn_gpio); | ||
1002 | clk_put(priv->clk); | ||
1003 | v4l2_device_unregister_subdev(&priv->subdev); | ||
1004 | |||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | static const struct i2c_device_id tw9910_id[] = { | ||
1009 | { "tw9910", 0 }, | ||
1010 | { } | ||
1011 | }; | ||
1012 | MODULE_DEVICE_TABLE(i2c, tw9910_id); | ||
1013 | |||
1014 | static struct i2c_driver tw9910_i2c_driver = { | ||
1015 | .driver = { | ||
1016 | .name = "tw9910", | ||
1017 | }, | ||
1018 | .probe = tw9910_probe, | ||
1019 | .remove = tw9910_remove, | ||
1020 | .id_table = tw9910_id, | ||
1021 | }; | ||
1022 | |||
1023 | module_i2c_driver(tw9910_i2c_driver); | ||
1024 | |||
1025 | MODULE_DESCRIPTION("V4L2 driver for TW9910 video decoder"); | ||
1026 | MODULE_AUTHOR("Kuninori Morimoto"); | ||
1027 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c index 560738213c00..1658816a9844 100644 --- a/drivers/media/i2c/vs6624.c +++ b/drivers/media/i2c/vs6624.c | |||
@@ -657,31 +657,22 @@ static int vs6624_get_fmt(struct v4l2_subdev *sd, | |||
657 | return 0; | 657 | return 0; |
658 | } | 658 | } |
659 | 659 | ||
660 | static int vs6624_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 660 | static int vs6624_g_frame_interval(struct v4l2_subdev *sd, |
661 | struct v4l2_subdev_frame_interval *ival) | ||
661 | { | 662 | { |
662 | struct vs6624 *sensor = to_vs6624(sd); | 663 | struct vs6624 *sensor = to_vs6624(sd); |
663 | struct v4l2_captureparm *cp = &parms->parm.capture; | ||
664 | 664 | ||
665 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 665 | ival->interval.numerator = sensor->frame_rate.denominator; |
666 | return -EINVAL; | 666 | ival->interval.denominator = sensor->frame_rate.numerator; |
667 | |||
668 | memset(cp, 0, sizeof(*cp)); | ||
669 | cp->capability = V4L2_CAP_TIMEPERFRAME; | ||
670 | cp->timeperframe.numerator = sensor->frame_rate.denominator; | ||
671 | cp->timeperframe.denominator = sensor->frame_rate.numerator; | ||
672 | return 0; | 667 | return 0; |
673 | } | 668 | } |
674 | 669 | ||
675 | static int vs6624_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) | 670 | static int vs6624_s_frame_interval(struct v4l2_subdev *sd, |
671 | struct v4l2_subdev_frame_interval *ival) | ||
676 | { | 672 | { |
677 | struct vs6624 *sensor = to_vs6624(sd); | 673 | struct vs6624 *sensor = to_vs6624(sd); |
678 | struct v4l2_captureparm *cp = &parms->parm.capture; | 674 | struct v4l2_fract *tpf = &ival->interval; |
679 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
680 | 675 | ||
681 | if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
682 | return -EINVAL; | ||
683 | if (cp->extendedmode != 0) | ||
684 | return -EINVAL; | ||
685 | 676 | ||
686 | if (tpf->numerator == 0 || tpf->denominator == 0 | 677 | if (tpf->numerator == 0 || tpf->denominator == 0 |
687 | || (tpf->denominator > tpf->numerator * MAX_FRAME_RATE)) { | 678 | || (tpf->denominator > tpf->numerator * MAX_FRAME_RATE)) { |
@@ -738,8 +729,8 @@ static const struct v4l2_subdev_core_ops vs6624_core_ops = { | |||
738 | }; | 729 | }; |
739 | 730 | ||
740 | static const struct v4l2_subdev_video_ops vs6624_video_ops = { | 731 | static const struct v4l2_subdev_video_ops vs6624_video_ops = { |
741 | .s_parm = vs6624_s_parm, | 732 | .s_frame_interval = vs6624_s_frame_interval, |
742 | .g_parm = vs6624_g_parm, | 733 | .g_frame_interval = vs6624_g_frame_interval, |
743 | .s_stream = vs6624_s_stream, | 734 | .s_stream = vs6624_s_stream, |
744 | }; | 735 | }; |
745 | 736 | ||
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index e79f72b8b858..35e81f7c0d2f 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c | |||
@@ -190,6 +190,7 @@ static long media_device_enum_links(struct media_device *mdev, | |||
190 | ulink_desc++; | 190 | ulink_desc++; |
191 | } | 191 | } |
192 | } | 192 | } |
193 | memset(links->reserved, 0, sizeof(links->reserved)); | ||
193 | 194 | ||
194 | return 0; | 195 | return 0; |
195 | } | 196 | } |
@@ -218,6 +219,8 @@ static long media_device_setup_link(struct media_device *mdev, | |||
218 | if (link == NULL) | 219 | if (link == NULL) |
219 | return -EINVAL; | 220 | return -EINVAL; |
220 | 221 | ||
222 | memset(linkd->reserved, 0, sizeof(linkd->reserved)); | ||
223 | |||
221 | /* Setup the link on both entities. */ | 224 | /* Setup the link on both entities. */ |
222 | return __media_entity_setup_link(link, linkd->flags); | 225 | return __media_entity_setup_link(link, linkd->flags); |
223 | } | 226 | } |
@@ -255,7 +258,7 @@ static long media_device_get_topology(struct media_device *mdev, | |||
255 | memset(&kentity, 0, sizeof(kentity)); | 258 | memset(&kentity, 0, sizeof(kentity)); |
256 | kentity.id = entity->graph_obj.id; | 259 | kentity.id = entity->graph_obj.id; |
257 | kentity.function = entity->function; | 260 | kentity.function = entity->function; |
258 | strncpy(kentity.name, entity->name, | 261 | strlcpy(kentity.name, entity->name, |
259 | sizeof(kentity.name)); | 262 | sizeof(kentity.name)); |
260 | 263 | ||
261 | if (copy_to_user(uentity, &kentity, sizeof(kentity))) | 264 | if (copy_to_user(uentity, &kentity, sizeof(kentity))) |
@@ -263,6 +266,7 @@ static long media_device_get_topology(struct media_device *mdev, | |||
263 | uentity++; | 266 | uentity++; |
264 | } | 267 | } |
265 | topo->num_entities = i; | 268 | topo->num_entities = i; |
269 | topo->reserved1 = 0; | ||
266 | 270 | ||
267 | /* Get interfaces and number of interfaces */ | 271 | /* Get interfaces and number of interfaces */ |
268 | i = 0; | 272 | i = 0; |
@@ -298,6 +302,7 @@ static long media_device_get_topology(struct media_device *mdev, | |||
298 | uintf++; | 302 | uintf++; |
299 | } | 303 | } |
300 | topo->num_interfaces = i; | 304 | topo->num_interfaces = i; |
305 | topo->reserved2 = 0; | ||
301 | 306 | ||
302 | /* Get pads and number of pads */ | 307 | /* Get pads and number of pads */ |
303 | i = 0; | 308 | i = 0; |
@@ -324,6 +329,7 @@ static long media_device_get_topology(struct media_device *mdev, | |||
324 | upad++; | 329 | upad++; |
325 | } | 330 | } |
326 | topo->num_pads = i; | 331 | topo->num_pads = i; |
332 | topo->reserved3 = 0; | ||
327 | 333 | ||
328 | /* Get links and number of links */ | 334 | /* Get links and number of links */ |
329 | i = 0; | 335 | i = 0; |
@@ -355,6 +361,7 @@ static long media_device_get_topology(struct media_device *mdev, | |||
355 | ulink++; | 361 | ulink++; |
356 | } | 362 | } |
357 | topo->num_links = i; | 363 | topo->num_links = i; |
364 | topo->reserved4 = 0; | ||
358 | 365 | ||
359 | return ret; | 366 | return ret; |
360 | } | 367 | } |
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f7c6d64e6031..3498551e618e 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c | |||
@@ -64,22 +64,6 @@ static inline const char *intf_type(struct media_interface *intf) | |||
64 | return "v4l-swradio"; | 64 | return "v4l-swradio"; |
65 | case MEDIA_INTF_T_V4L_TOUCH: | 65 | case MEDIA_INTF_T_V4L_TOUCH: |
66 | return "v4l-touch"; | 66 | return "v4l-touch"; |
67 | case MEDIA_INTF_T_ALSA_PCM_CAPTURE: | ||
68 | return "alsa-pcm-capture"; | ||
69 | case MEDIA_INTF_T_ALSA_PCM_PLAYBACK: | ||
70 | return "alsa-pcm-playback"; | ||
71 | case MEDIA_INTF_T_ALSA_CONTROL: | ||
72 | return "alsa-control"; | ||
73 | case MEDIA_INTF_T_ALSA_COMPRESS: | ||
74 | return "alsa-compress"; | ||
75 | case MEDIA_INTF_T_ALSA_RAWMIDI: | ||
76 | return "alsa-rawmidi"; | ||
77 | case MEDIA_INTF_T_ALSA_HWDEP: | ||
78 | return "alsa-hwdep"; | ||
79 | case MEDIA_INTF_T_ALSA_SEQUENCER: | ||
80 | return "alsa-sequencer"; | ||
81 | case MEDIA_INTF_T_ALSA_TIMER: | ||
82 | return "alsa-timer"; | ||
83 | default: | 67 | default: |
84 | return "unknown-intf"; | 68 | return "unknown-intf"; |
85 | } | 69 | } |
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index da49c5567db5..08266b23826e 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c | |||
@@ -332,11 +332,15 @@ static void bttv_ir_stop(struct bttv *btv) | |||
332 | static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol, | 332 | static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol, |
333 | u32 *scancode, u8 *toggle) | 333 | u32 *scancode, u8 *toggle) |
334 | { | 334 | { |
335 | int rc; | ||
335 | unsigned char b; | 336 | unsigned char b; |
336 | 337 | ||
337 | /* poll IR chip */ | 338 | /* poll IR chip */ |
338 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 339 | rc = i2c_master_recv(ir->c, &b, 1); |
340 | if (rc != 1) { | ||
339 | dprintk("read error\n"); | 341 | dprintk("read error\n"); |
342 | if (rc < 0) | ||
343 | return rc; | ||
340 | return -EIO; | 344 | return -EIO; |
341 | } | 345 | } |
342 | 346 | ||
diff --git a/drivers/media/pci/cobalt/Makefile b/drivers/media/pci/cobalt/Makefile index b328955abbd2..29eddff2f35f 100644 --- a/drivers/media/pci/cobalt/Makefile +++ b/drivers/media/pci/cobalt/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
1 | cobalt-objs := cobalt-driver.o cobalt-irq.o cobalt-v4l2.o \ | 2 | cobalt-objs := cobalt-driver.o cobalt-irq.o cobalt-v4l2.o \ |
2 | cobalt-i2c.o cobalt-omnitek.o cobalt-flash.o cobalt-cpld.o \ | 3 | cobalt-i2c.o cobalt-omnitek.o cobalt-flash.o cobalt-cpld.o \ |
3 | cobalt-alsa-main.o cobalt-alsa-pcm.o | 4 | cobalt-alsa-main.o cobalt-alsa-pcm.o |
diff --git a/drivers/media/pci/cobalt/cobalt-alsa-main.c b/drivers/media/pci/cobalt/cobalt-alsa-main.c index 720e3ad93a9e..e5022b620856 100644 --- a/drivers/media/pci/cobalt/cobalt-alsa-main.c +++ b/drivers/media/pci/cobalt/cobalt-alsa-main.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * ALSA interface to cobalt PCM capture streams | 3 | * ALSA interface to cobalt PCM capture streams |
3 | * | 4 | * |
4 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <linux/init.h> | 9 | #include <linux/init.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-alsa-pcm.c b/drivers/media/pci/cobalt/cobalt-alsa-pcm.c index b69b258d39b9..f6a7df13cd04 100644 --- a/drivers/media/pci/cobalt/cobalt-alsa-pcm.c +++ b/drivers/media/pci/cobalt/cobalt-alsa-pcm.c | |||
@@ -1,22 +1,10 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * ALSA PCM device for the | 3 | * ALSA PCM device for the |
3 | * ALSA interface to cobalt PCM capture streams | 4 | * ALSA interface to cobalt PCM capture streams |
4 | * | 5 | * |
5 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 6 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
6 | * All rights reserved. | 7 | * All rights reserved. |
7 | * | ||
8 | * This program is free software; you may redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
13 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
14 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
16 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
17 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
19 | * SOFTWARE. | ||
20 | */ | 8 | */ |
21 | 9 | ||
22 | #include <linux/init.h> | 10 | #include <linux/init.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-alsa-pcm.h b/drivers/media/pci/cobalt/cobalt-alsa-pcm.h index 513fb1f71794..0e2e9c63a23e 100644 --- a/drivers/media/pci/cobalt/cobalt-alsa-pcm.h +++ b/drivers/media/pci/cobalt/cobalt-alsa-pcm.h | |||
@@ -1,22 +1,10 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * ALSA PCM device for the | 3 | * ALSA PCM device for the |
3 | * ALSA interface to cobalt PCM capture streams | 4 | * ALSA interface to cobalt PCM capture streams |
4 | * | 5 | * |
5 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 6 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
6 | * All rights reserved. | 7 | * All rights reserved. |
7 | * | ||
8 | * This program is free software; you may redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
13 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
14 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
16 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
17 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
18 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
19 | * SOFTWARE. | ||
20 | */ | 8 | */ |
21 | 9 | ||
22 | int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc); | 10 | int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc); |
diff --git a/drivers/media/pci/cobalt/cobalt-alsa.h b/drivers/media/pci/cobalt/cobalt-alsa.h index 08db699ced37..bb7f156ad3e7 100644 --- a/drivers/media/pci/cobalt/cobalt-alsa.h +++ b/drivers/media/pci/cobalt/cobalt-alsa.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * ALSA interface to cobalt PCM capture streams | 3 | * ALSA interface to cobalt PCM capture streams |
3 | * | 4 | * |
4 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | struct snd_card; | 9 | struct snd_card; |
diff --git a/drivers/media/pci/cobalt/cobalt-cpld.c b/drivers/media/pci/cobalt/cobalt-cpld.c index bfcecef659e3..3d8026483ac3 100644 --- a/drivers/media/pci/cobalt/cobalt-cpld.c +++ b/drivers/media/pci/cobalt/cobalt-cpld.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Cobalt CPLD functions | 3 | * Cobalt CPLD functions |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-cpld.h b/drivers/media/pci/cobalt/cobalt-cpld.h index 0fc88fd5fa7b..8c880ed14cda 100644 --- a/drivers/media/pci/cobalt/cobalt-cpld.h +++ b/drivers/media/pci/cobalt/cobalt-cpld.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Cobalt CPLD functions | 3 | * Cobalt CPLD functions |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #ifndef COBALT_CPLD_H | 9 | #ifndef COBALT_CPLD_H |
diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 3f16cf3f6d74..c8b1a6206c65 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cobalt driver initialization and card probing | 3 | * cobalt driver initialization and card probing |
3 | * | 4 | * |
@@ -5,19 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 7 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
7 | * All rights reserved. | 8 | * All rights reserved. |
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | 9 | */ |
22 | 10 | ||
23 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index 00f773ec359a..429bee4ef79c 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h | |||
@@ -1,3 +1,4 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cobalt driver internal defines and structures | 3 | * cobalt driver internal defines and structures |
3 | * | 4 | * |
@@ -5,19 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 7 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
7 | * All rights reserved. | 8 | * All rights reserved. |
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | 9 | */ |
22 | 10 | ||
23 | #ifndef COBALT_DRIVER_H | 11 | #ifndef COBALT_DRIVER_H |
diff --git a/drivers/media/pci/cobalt/cobalt-flash.c b/drivers/media/pci/cobalt/cobalt-flash.c index 04dcaf9198d2..ef96e0f956d2 100644 --- a/drivers/media/pci/cobalt/cobalt-flash.c +++ b/drivers/media/pci/cobalt/cobalt-flash.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Cobalt NOR flash functions | 3 | * Cobalt NOR flash functions |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <linux/mtd/mtd.h> | 9 | #include <linux/mtd/mtd.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-flash.h b/drivers/media/pci/cobalt/cobalt-flash.h index 8077daea51cd..605ce3d37ca3 100644 --- a/drivers/media/pci/cobalt/cobalt-flash.h +++ b/drivers/media/pci/cobalt/cobalt-flash.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Cobalt NOR flash functions | 3 | * Cobalt NOR flash functions |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #ifndef COBALT_FLASH_H | 9 | #ifndef COBALT_FLASH_H |
diff --git a/drivers/media/pci/cobalt/cobalt-i2c.c b/drivers/media/pci/cobalt/cobalt-i2c.c index 1a5c55673ea8..c374dae78bf7 100644 --- a/drivers/media/pci/cobalt/cobalt-i2c.c +++ b/drivers/media/pci/cobalt/cobalt-i2c.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cobalt I2C functions | 3 | * cobalt I2C functions |
3 | * | 4 | * |
@@ -5,19 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 7 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
7 | * All rights reserved. | 8 | * All rights reserved. |
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | 9 | */ |
22 | 10 | ||
23 | #include "cobalt-driver.h" | 11 | #include "cobalt-driver.h" |
diff --git a/drivers/media/pci/cobalt/cobalt-i2c.h b/drivers/media/pci/cobalt/cobalt-i2c.h index a4c1cfaacf95..7a9057c8bff6 100644 --- a/drivers/media/pci/cobalt/cobalt-i2c.h +++ b/drivers/media/pci/cobalt/cobalt-i2c.h | |||
@@ -1,3 +1,4 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cobalt I2C functions | 3 | * cobalt I2C functions |
3 | * | 4 | * |
@@ -5,19 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 7 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
7 | * All rights reserved. | 8 | * All rights reserved. |
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | 9 | */ |
22 | 10 | ||
23 | /* init + register i2c algo-bit adapter */ | 11 | /* init + register i2c algo-bit adapter */ |
diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c index b190d4f81c6e..04783e78cc12 100644 --- a/drivers/media/pci/cobalt/cobalt-irq.c +++ b/drivers/media/pci/cobalt/cobalt-irq.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cobalt interrupt handling | 3 | * cobalt interrupt handling |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <media/i2c/adv7604.h> | 9 | #include <media/i2c/adv7604.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-irq.h b/drivers/media/pci/cobalt/cobalt-irq.h index 5119484a24d9..0b4078ce6555 100644 --- a/drivers/media/pci/cobalt/cobalt-irq.h +++ b/drivers/media/pci/cobalt/cobalt-irq.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cobalt interrupt handling | 3 | * cobalt interrupt handling |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-omnitek.c b/drivers/media/pci/cobalt/cobalt-omnitek.c index a28a8482c1d4..4c137453e679 100644 --- a/drivers/media/pci/cobalt/cobalt-omnitek.c +++ b/drivers/media/pci/cobalt/cobalt-omnitek.c | |||
@@ -1,21 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Omnitek Scatter-Gather DMA Controller | 3 | * Omnitek Scatter-Gather DMA Controller |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #include <linux/string.h> | 9 | #include <linux/string.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-omnitek.h b/drivers/media/pci/cobalt/cobalt-omnitek.h index e5c6d032c6f2..129c5fccbe39 100644 --- a/drivers/media/pci/cobalt/cobalt-omnitek.h +++ b/drivers/media/pci/cobalt/cobalt-omnitek.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Omnitek Scatter-Gather DMA Controller | 3 | * Omnitek Scatter-Gather DMA Controller |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #ifndef COBALT_OMNITEK_H | 9 | #ifndef COBALT_OMNITEK_H |
diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c index def4a3b37084..e2a4c705d353 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.c +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * cobalt V4L2 API | 3 | * cobalt V4L2 API |
3 | * | 4 | * |
@@ -5,19 +6,6 @@ | |||
5 | * | 6 | * |
6 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 7 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
7 | * All rights reserved. | 8 | * All rights reserved. |
8 | * | ||
9 | * This program is free software; you may redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
14 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
15 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
16 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
17 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
20 | * SOFTWARE. | ||
21 | */ | 9 | */ |
22 | 10 | ||
23 | #include <linux/dma-mapping.h> | 11 | #include <linux/dma-mapping.h> |
diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.h b/drivers/media/pci/cobalt/cobalt-v4l2.h index 62be553cd8e2..dc43974b2d86 100644 --- a/drivers/media/pci/cobalt/cobalt-v4l2.h +++ b/drivers/media/pci/cobalt/cobalt-v4l2.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cobalt V4L2 API | 3 | * cobalt V4L2 API |
3 | * | 4 | * |
4 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. | 5 | * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. |
5 | * All rights reserved. | 6 | * All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | int cobalt_nodes_register(struct cobalt *cobalt); | 9 | int cobalt_nodes_register(struct cobalt *cobalt); |
diff --git a/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h b/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h index 9bc9ef1fd3a8..4c6ad1cee87e 100644 --- a/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h +++ b/drivers/media/pci/cobalt/m00233_video_measure_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_H | 7 | #ifndef M00233_VIDEO_MEASURE_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h b/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h index a480529f561e..6cc1ad7d98c9 100644 --- a/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h +++ b/drivers/media/pci/cobalt/m00235_fdma_packer_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00235_FDMA_PACKER_MEMMAP_PACKAGE_H | 7 | #ifndef M00235_FDMA_PACKER_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h b/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h index 602419e589d3..f0c6fe304247 100644 --- a/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h +++ b/drivers/media/pci/cobalt/m00389_cvi_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00389_CVI_MEMMAP_PACKAGE_H | 7 | #ifndef M00389_CVI_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h b/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h index 95471c995067..27f05aca632f 100644 --- a/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h +++ b/drivers/media/pci/cobalt/m00460_evcnt_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00460_EVCNT_MEMMAP_PACKAGE_H | 7 | #ifndef M00460_EVCNT_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h b/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h index 384a3e156301..8a5bf008750a 100644 --- a/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h +++ b/drivers/media/pci/cobalt/m00473_freewheel_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00473_FREEWHEEL_MEMMAP_PACKAGE_H | 7 | #ifndef M00473_FREEWHEEL_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h b/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h index 2a029026bf82..18bd4fcd2db8 100644 --- a/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h +++ b/drivers/media/pci/cobalt/m00479_clk_loss_detector_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_H | 7 | #ifndef M00479_CLK_LOSS_DETECTOR_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h b/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h index bdef2df5d689..86da49033cd8 100644 --- a/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h +++ b/drivers/media/pci/cobalt/m00514_syncgen_flow_evcnt_memmap_package.h | |||
@@ -1,19 +1,7 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2014-2015 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | #ifndef M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_H | 7 | #ifndef M00514_SYNCGEN_FLOW_EVCNT_MEMMAP_PACKAGE_H |
diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c index 2531e4b81b60..93443d1457c5 100644 --- a/drivers/media/pci/cx18/cx18-alsa-main.c +++ b/drivers/media/pci/cx18/cx18-alsa-main.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include "cx18-driver.h" | 32 | #include "cx18-driver.h" |
33 | #include "cx18-version.h" | 33 | #include "cx18-version.h" |
34 | #include "cx18-alsa.h" | 34 | #include "cx18-alsa.h" |
35 | #include "cx18-alsa-mixer.h" | ||
36 | #include "cx18-alsa-pcm.h" | 35 | #include "cx18-alsa-pcm.h" |
37 | 36 | ||
38 | int cx18_alsa_debug; | 37 | int cx18_alsa_debug; |
diff --git a/drivers/media/pci/cx18/cx18-alsa-mixer.c b/drivers/media/pci/cx18/cx18-alsa-mixer.c deleted file mode 100644 index cb04c3d820e2..000000000000 --- a/drivers/media/pci/cx18/cx18-alsa-mixer.c +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | /* | ||
2 | * ALSA mixer controls for the | ||
3 | * ALSA interface to cx18 PCM capture streams | ||
4 | * | ||
5 | * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/videodev2.h> | ||
23 | |||
24 | #include <media/v4l2-device.h> | ||
25 | |||
26 | #include <sound/core.h> | ||
27 | #include <sound/control.h> | ||
28 | #include <sound/tlv.h> | ||
29 | |||
30 | #include "cx18-alsa.h" | ||
31 | #include "cx18-driver.h" | ||
32 | |||
33 | /* | ||
34 | * Note the cx18-av-core volume scale is funny, due to the alignment of the | ||
35 | * scale with another chip's range: | ||
36 | * | ||
37 | * v4l2_control value /512 indicated dB actual dB reg 0x8d4 | ||
38 | * 0x0000 - 0x01ff 0 -119 -96 228 | ||
39 | * 0x0200 - 0x02ff 1 -118 -96 228 | ||
40 | * ... | ||
41 | * 0x2c00 - 0x2dff 22 -97 -96 228 | ||
42 | * 0x2e00 - 0x2fff 23 -96 -96 228 | ||
43 | * 0x3000 - 0x31ff 24 -95 -95 226 | ||
44 | * ... | ||
45 | * 0xee00 - 0xefff 119 0 0 36 | ||
46 | * ... | ||
47 | * 0xfe00 - 0xffff 127 +8 +8 20 | ||
48 | */ | ||
49 | static inline int dB_to_cx18_av_vol(int dB) | ||
50 | { | ||
51 | if (dB < -96) | ||
52 | dB = -96; | ||
53 | else if (dB > 8) | ||
54 | dB = 8; | ||
55 | return (dB + 119) << 9; | ||
56 | } | ||
57 | |||
58 | static inline int cx18_av_vol_to_dB(int v) | ||
59 | { | ||
60 | if (v < (23 << 9)) | ||
61 | v = (23 << 9); | ||
62 | else if (v > (127 << 9)) | ||
63 | v = (127 << 9); | ||
64 | return (v >> 9) - 119; | ||
65 | } | ||
66 | |||
67 | static int snd_cx18_mixer_tv_vol_info(struct snd_kcontrol *kcontrol, | ||
68 | struct snd_ctl_elem_info *uinfo) | ||
69 | { | ||
70 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
71 | uinfo->count = 1; | ||
72 | /* We're already translating values, just keep this control in dB */ | ||
73 | uinfo->value.integer.min = -96; | ||
74 | uinfo->value.integer.max = 8; | ||
75 | uinfo->value.integer.step = 1; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl, | ||
80 | struct snd_ctl_elem_value *uctl) | ||
81 | { | ||
82 | struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl); | ||
83 | struct cx18 *cx = to_cx18(cxsc->v4l2_dev); | ||
84 | struct v4l2_control vctrl; | ||
85 | int ret; | ||
86 | |||
87 | vctrl.id = V4L2_CID_AUDIO_VOLUME; | ||
88 | vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]); | ||
89 | |||
90 | snd_cx18_lock(cxsc); | ||
91 | ret = v4l2_g_ctrl(cx->sd_av->ctrl_handler, &vctrl); | ||
92 | snd_cx18_unlock(cxsc); | ||
93 | |||
94 | if (!ret) | ||
95 | uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl, | ||
100 | struct snd_ctl_elem_value *uctl) | ||
101 | { | ||
102 | struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl); | ||
103 | struct cx18 *cx = to_cx18(cxsc->v4l2_dev); | ||
104 | struct v4l2_control vctrl; | ||
105 | int ret; | ||
106 | |||
107 | vctrl.id = V4L2_CID_AUDIO_VOLUME; | ||
108 | vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]); | ||
109 | |||
110 | snd_cx18_lock(cxsc); | ||
111 | |||
112 | /* Fetch current state */ | ||
113 | ret = v4l2_g_ctrl(cx->sd_av->ctrl_handler, &vctrl); | ||
114 | |||
115 | if (ret || | ||
116 | (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) { | ||
117 | |||
118 | /* Set, if needed */ | ||
119 | vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]); | ||
120 | ret = v4l2_s_ctrl(cx->sd_av->ctrl_handler, &vctrl); | ||
121 | if (!ret) | ||
122 | ret = 1; /* Indicate control was changed w/o error */ | ||
123 | } | ||
124 | snd_cx18_unlock(cxsc); | ||
125 | |||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | |||
130 | /* This is a bit of overkill, the slider is already in dB internally */ | ||
131 | static DECLARE_TLV_DB_SCALE(snd_cx18_mixer_tv_vol_db_scale, -9600, 100, 0); | ||
132 | |||
133 | static struct snd_kcontrol_new snd_cx18_mixer_tv_vol __initdata = { | ||
134 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
135 | .name = "Analog TV Capture Volume", | ||
136 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
137 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
138 | .info = snd_cx18_mixer_tv_volume_info, | ||
139 | .get = snd_cx18_mixer_tv_volume_get, | ||
140 | .put = snd_cx18_mixer_tv_volume_put, | ||
141 | .tlv.p = snd_cx18_mixer_tv_vol_db_scale | ||
142 | }; | ||
143 | |||
144 | /* FIXME - add mute switch and balance, bass, treble sliders: | ||
145 | V4L2_CID_AUDIO_MUTE | ||
146 | |||
147 | V4L2_CID_AUDIO_BALANCE | ||
148 | |||
149 | V4L2_CID_AUDIO_BASS | ||
150 | V4L2_CID_AUDIO_TREBLE | ||
151 | */ | ||
152 | |||
153 | /* FIXME - add stereo, lang1, lang2, mono menu */ | ||
154 | /* FIXME - add CS5345 I2S volume for HVR-1600 */ | ||
155 | |||
156 | int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc) | ||
157 | { | ||
158 | struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; | ||
159 | struct snd_card *sc = cxsc->sc; | ||
160 | int ret; | ||
161 | |||
162 | strlcpy(sc->mixername, "CX23418 Mixer", sizeof(sc->mixername)); | ||
163 | |||
164 | ret = snd_ctl_add(sc, snd_ctl_new1(&snd_cx18_mixer_tv_vol, cxsc)); | ||
165 | if (ret) { | ||
166 | CX18_ALSA_WARN("%s: failed to add %s control, err %d\n", | ||
167 | __func__, snd_cx18_mixer_tv_vol.name, ret); | ||
168 | } | ||
169 | return ret; | ||
170 | } | ||
diff --git a/drivers/media/pci/cx18/cx18-alsa-mixer.h b/drivers/media/pci/cx18/cx18-alsa-mixer.h deleted file mode 100644 index 3aed123955dd..000000000000 --- a/drivers/media/pci/cx18/cx18-alsa-mixer.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * ALSA mixer controls for the | ||
3 | * ALSA interface to cx18 PCM capture streams | ||
4 | * | ||
5 | * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | int __init snd_cx18_mixer_create(struct snd_cx18_card *cxsc); | ||
diff --git a/drivers/media/pci/cx18/cx18-dvb.c b/drivers/media/pci/cx18/cx18-dvb.c index 53f4d6bf81fb..010f39eafce1 100644 --- a/drivers/media/pci/cx18/cx18-dvb.c +++ b/drivers/media/pci/cx18/cx18-dvb.c | |||
@@ -72,7 +72,7 @@ static struct s5h1409_config hauppauge_hvr1600_config = { | |||
72 | .qam_if = 44000, | 72 | .qam_if = 44000, |
73 | .inversion = S5H1409_INVERSION_OFF, | 73 | .inversion = S5H1409_INVERSION_OFF, |
74 | .status_mode = S5H1409_DEMODLOCKING, | 74 | .status_mode = S5H1409_DEMODLOCKING, |
75 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 75 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
76 | .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE | 76 | .hvr1600_opt = S5H1409_HVR1600_OPTIMIZE |
77 | }; | 77 | }; |
78 | 78 | ||
@@ -86,7 +86,7 @@ static struct s5h1411_config hcw_s5h1411_config = { | |||
86 | .qam_if = S5H1411_IF_4000, | 86 | .qam_if = S5H1411_IF_4000, |
87 | .inversion = S5H1411_INVERSION_ON, | 87 | .inversion = S5H1411_INVERSION_ON, |
88 | .status_mode = S5H1411_DEMODLOCKING, | 88 | .status_mode = S5H1411_DEMODLOCKING, |
89 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 89 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static struct tda18271_std_map hauppauge_tda18271_std_map = { | 92 | static struct tda18271_std_map hauppauge_tda18271_std_map = { |
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index d8c3637e492e..20b3cb17f97f 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c | |||
@@ -89,9 +89,8 @@ static int cx23885_alsa_dma_init(struct cx23885_audio_dev *chip, int nr_pages) | |||
89 | return -ENOMEM; | 89 | return -ENOMEM; |
90 | } | 90 | } |
91 | 91 | ||
92 | dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n", | 92 | dprintk(1, "vmalloc is at addr %p, size=%d\n", |
93 | (unsigned long)buf->vaddr, | 93 | buf->vaddr, nr_pages << PAGE_SHIFT); |
94 | nr_pages << PAGE_SHIFT); | ||
95 | 94 | ||
96 | memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); | 95 | memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); |
97 | buf->nr_pages = nr_pages; | 96 | buf->nr_pages = nr_pages; |
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 3622521431f5..3a1c55187b2a 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c | |||
@@ -771,11 +771,46 @@ struct cx23885_board cx23885_boards[] = { | |||
771 | .portb = CX23885_MPEG_DVB, | 771 | .portb = CX23885_MPEG_DVB, |
772 | .portc = CX23885_MPEG_DVB, | 772 | .portc = CX23885_MPEG_DVB, |
773 | }, | 773 | }, |
774 | [CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885] = { | ||
775 | .name = "Hauppauge WinTV-QuadHD-DVB(885)", | ||
776 | .portb = CX23885_MPEG_DVB, | ||
777 | .portc = CX23885_MPEG_DVB, | ||
778 | }, | ||
774 | [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC] = { | 779 | [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC] = { |
775 | .name = "Hauppauge WinTV-QuadHD-ATSC", | 780 | .name = "Hauppauge WinTV-QuadHD-ATSC", |
776 | .portb = CX23885_MPEG_DVB, | 781 | .portb = CX23885_MPEG_DVB, |
777 | .portc = CX23885_MPEG_DVB, | 782 | .portc = CX23885_MPEG_DVB, |
778 | }, | 783 | }, |
784 | [CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885] = { | ||
785 | .name = "Hauppauge WinTV-QuadHD-ATSC(885)", | ||
786 | .portb = CX23885_MPEG_DVB, | ||
787 | .portc = CX23885_MPEG_DVB, | ||
788 | }, | ||
789 | [CX23885_BOARD_HAUPPAUGE_HVR1265_K4] = { | ||
790 | .name = "Hauppauge WinTV-HVR-1265(161111)", | ||
791 | .porta = CX23885_ANALOG_VIDEO, | ||
792 | .portc = CX23885_MPEG_DVB, | ||
793 | .tuner_type = TUNER_ABSENT, | ||
794 | .force_bff = 1, | ||
795 | .input = {{ | ||
796 | .type = CX23885_VMUX_COMPOSITE1, | ||
797 | .vmux = CX25840_VIN7_CH3 | | ||
798 | CX25840_VIN4_CH2 | | ||
799 | CX25840_VIN6_CH1, | ||
800 | .amux = CX25840_AUDIO7, | ||
801 | }, { | ||
802 | .type = CX23885_VMUX_SVIDEO, | ||
803 | .vmux = CX25840_VIN7_CH3 | | ||
804 | CX25840_VIN4_CH2 | | ||
805 | CX25840_VIN8_CH1 | | ||
806 | CX25840_SVIDEO_ON, | ||
807 | .amux = CX25840_AUDIO7, | ||
808 | } }, | ||
809 | }, | ||
810 | [CX23885_BOARD_HAUPPAUGE_STARBURST2] = { | ||
811 | .name = "Hauppauge WinTV-Starburst2", | ||
812 | .portb = CX23885_MPEG_DVB, | ||
813 | }, | ||
779 | }; | 814 | }; |
780 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); | 815 | const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); |
781 | 816 | ||
@@ -1028,6 +1063,10 @@ struct cx23885_subid cx23885_subids[] = { | |||
1028 | .subdevice = 0x7133, | 1063 | .subdevice = 0x7133, |
1029 | .card = CX23885_BOARD_HAUPPAUGE_IMPACTVCBE, | 1064 | .card = CX23885_BOARD_HAUPPAUGE_IMPACTVCBE, |
1030 | }, { | 1065 | }, { |
1066 | .subvendor = 0x0070, | ||
1067 | .subdevice = 0x7137, | ||
1068 | .card = CX23885_BOARD_HAUPPAUGE_IMPACTVCBE, | ||
1069 | }, { | ||
1031 | .subvendor = 0x18ac, | 1070 | .subvendor = 0x18ac, |
1032 | .subdevice = 0xdb98, | 1071 | .subdevice = 0xdb98, |
1033 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2, | 1072 | .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2, |
@@ -1087,6 +1126,14 @@ struct cx23885_subid cx23885_subids[] = { | |||
1087 | .subvendor = 0x0070, | 1126 | .subvendor = 0x0070, |
1088 | .subdevice = 0x6b18, | 1127 | .subdevice = 0x6b18, |
1089 | .card = CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC, /* Tuner Pair 2 */ | 1128 | .card = CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC, /* Tuner Pair 2 */ |
1129 | }, { | ||
1130 | .subvendor = 0x0070, | ||
1131 | .subdevice = 0x2a18, | ||
1132 | .card = CX23885_BOARD_HAUPPAUGE_HVR1265_K4, /* Hauppauge WinTV HVR-1265 (Model 161xx1, Hybrid ATSC/QAM-B) */ | ||
1133 | }, { | ||
1134 | .subvendor = 0x0070, | ||
1135 | .subdevice = 0xf02a, | ||
1136 | .card = CX23885_BOARD_HAUPPAUGE_STARBURST2, | ||
1090 | }, | 1137 | }, |
1091 | }; | 1138 | }; |
1092 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); | 1139 | const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); |
@@ -1287,25 +1334,28 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) | |||
1287 | case 150329: | 1334 | case 150329: |
1288 | /* WinTV-HVR5525 (PCIe, DVB-S/S2, DVB-T/T2/C) */ | 1335 | /* WinTV-HVR5525 (PCIe, DVB-S/S2, DVB-T/T2/C) */ |
1289 | break; | 1336 | break; |
1290 | case 166100: | 1337 | case 161111: |
1338 | /* WinTV-HVR-1265 K4 (PCIe, Analog/ATSC/QAM-B) */ | ||
1339 | break; | ||
1340 | case 166100: /* 888 version, hybrid */ | ||
1341 | case 166200: /* 885 version, DVB only */ | ||
1291 | /* WinTV-QuadHD (DVB) Tuner Pair 1 (PCIe, IR, half height, | 1342 | /* WinTV-QuadHD (DVB) Tuner Pair 1 (PCIe, IR, half height, |
1292 | DVB-T/T2/C, DVB-T/T2/C */ | 1343 | DVB-T/T2/C, DVB-T/T2/C */ |
1293 | break; | 1344 | break; |
1294 | case 166101: | 1345 | case 166101: /* 888 version, hybrid */ |
1346 | case 166201: /* 885 version, DVB only */ | ||
1295 | /* WinTV-QuadHD (DVB) Tuner Pair 2 (PCIe, IR, half height, | 1347 | /* WinTV-QuadHD (DVB) Tuner Pair 2 (PCIe, IR, half height, |
1296 | DVB-T/T2/C, DVB-T/T2/C */ | 1348 | DVB-T/T2/C, DVB-T/T2/C */ |
1297 | break; | 1349 | break; |
1298 | case 165100: | 1350 | case 165100: /* 888 version, hybrid */ |
1299 | /* | 1351 | case 165200: /* 885 version, digital only */ |
1300 | * WinTV-QuadHD (ATSC) Tuner Pair 1 (PCIe, IR, half height, | 1352 | /* WinTV-QuadHD (ATSC) Tuner Pair 1 (PCIe, IR, half height, |
1301 | * ATSC, ATSC | 1353 | * ATSC/QAM-B, ATSC/QAM-B */ |
1302 | */ | ||
1303 | break; | 1354 | break; |
1304 | case 165101: | 1355 | case 165101: /* 888 version, hybrid */ |
1305 | /* | 1356 | case 165201: /* 885 version, digital only */ |
1306 | * WinTV-QuadHD (DVB) Tuner Pair 2 (PCIe, IR, half height, | 1357 | /* WinTV-QuadHD (ATSC) Tuner Pair 2 (PCIe, IR, half height, |
1307 | * ATSC, ATSC | 1358 | * ATSC/QAM-B, ATSC/QAM-B */ |
1308 | */ | ||
1309 | break; | 1359 | break; |
1310 | default: | 1360 | default: |
1311 | pr_warn("%s: warning: unknown hauppauge model #%d\n", | 1361 | pr_warn("%s: warning: unknown hauppauge model #%d\n", |
@@ -1778,8 +1828,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1778 | cx23885_gpio_set(dev, GPIO_2); | 1828 | cx23885_gpio_set(dev, GPIO_2); |
1779 | break; | 1829 | break; |
1780 | case CX23885_BOARD_HAUPPAUGE_HVR5525: | 1830 | case CX23885_BOARD_HAUPPAUGE_HVR5525: |
1781 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: | 1831 | case CX23885_BOARD_HAUPPAUGE_STARBURST2: |
1782 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: | ||
1783 | /* | 1832 | /* |
1784 | * HVR5525 GPIO Details: | 1833 | * HVR5525 GPIO Details: |
1785 | * GPIO-00 IR_WIDE | 1834 | * GPIO-00 IR_WIDE |
@@ -1809,6 +1858,22 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1809 | * card does not have any GPIO's connected to subcomponents. | 1858 | * card does not have any GPIO's connected to subcomponents. |
1810 | */ | 1859 | */ |
1811 | break; | 1860 | break; |
1861 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
1862 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: | ||
1863 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: | ||
1864 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: | ||
1865 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: | ||
1866 | /* | ||
1867 | * GPIO-08 TER1_RESN | ||
1868 | * GPIO-09 TER2_RESN | ||
1869 | */ | ||
1870 | /* Put the parts into reset and back */ | ||
1871 | cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); | ||
1872 | cx23885_gpio_clear(dev, GPIO_8 | GPIO_9); | ||
1873 | msleep(100); | ||
1874 | cx23885_gpio_set(dev, GPIO_8 | GPIO_9); | ||
1875 | msleep(100); | ||
1876 | break; | ||
1812 | } | 1877 | } |
1813 | } | 1878 | } |
1814 | 1879 | ||
@@ -2054,8 +2119,12 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
2054 | case CX23885_BOARD_HAUPPAUGE_STARBURST: | 2119 | case CX23885_BOARD_HAUPPAUGE_STARBURST: |
2055 | case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: | 2120 | case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: |
2056 | case CX23885_BOARD_HAUPPAUGE_HVR5525: | 2121 | case CX23885_BOARD_HAUPPAUGE_HVR5525: |
2122 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
2123 | case CX23885_BOARD_HAUPPAUGE_STARBURST2: | ||
2057 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: | 2124 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
2125 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: | ||
2058 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: | 2126 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
2127 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: | ||
2059 | if (dev->i2c_bus[0].i2c_rc == 0) | 2128 | if (dev->i2c_bus[0].i2c_rc == 0) |
2060 | hauppauge_eeprom(dev, eeprom+0xc0); | 2129 | hauppauge_eeprom(dev, eeprom+0xc0); |
2061 | break; | 2130 | break; |
@@ -2194,6 +2263,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
2194 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 2263 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
2195 | break; | 2264 | break; |
2196 | case CX23885_BOARD_HAUPPAUGE_HVR5525: | 2265 | case CX23885_BOARD_HAUPPAUGE_HVR5525: |
2266 | case CX23885_BOARD_HAUPPAUGE_STARBURST2: | ||
2197 | ts1->gen_ctrl_val = 0x5; /* Parallel */ | 2267 | ts1->gen_ctrl_val = 0x5; /* Parallel */ |
2198 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 2268 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
2199 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 2269 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
@@ -2201,8 +2271,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
2201 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 2271 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
2202 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 2272 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
2203 | break; | 2273 | break; |
2274 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
2204 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: | 2275 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
2276 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: | ||
2205 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: | 2277 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
2278 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: | ||
2206 | ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | 2279 | ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ |
2207 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 2280 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
2208 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 2281 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
@@ -2259,6 +2332,9 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
2259 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: | 2332 | case CX23885_BOARD_COMPRO_VIDEOMATE_E800: |
2260 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | 2333 | case CX23885_BOARD_HAUPPAUGE_HVR1255: |
2261 | case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: | 2334 | case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: |
2335 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
2336 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: | ||
2337 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: | ||
2262 | case CX23885_BOARD_HAUPPAUGE_HVR1270: | 2338 | case CX23885_BOARD_HAUPPAUGE_HVR1270: |
2263 | case CX23885_BOARD_HAUPPAUGE_HVR1850: | 2339 | case CX23885_BOARD_HAUPPAUGE_HVR1850: |
2264 | case CX23885_BOARD_MYGICA_X8506: | 2340 | case CX23885_BOARD_MYGICA_X8506: |
@@ -2286,6 +2362,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
2286 | &dev->i2c_bus[2].i2c_adap, | 2362 | &dev->i2c_bus[2].i2c_adap, |
2287 | "cx25840", 0x88 >> 1, NULL); | 2363 | "cx25840", 0x88 >> 1, NULL); |
2288 | if (dev->sd_cx25840) { | 2364 | if (dev->sd_cx25840) { |
2365 | /* set host data for clk_freq configuration */ | ||
2366 | v4l2_set_subdev_hostdata(dev->sd_cx25840, | ||
2367 | &dev->clk_freq); | ||
2368 | |||
2289 | dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; | 2369 | dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; |
2290 | v4l2_subdev_call(dev->sd_cx25840, core, load_fw); | 2370 | v4l2_subdev_call(dev->sd_cx25840, core, load_fw); |
2291 | } | 2371 | } |
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 8f63df1cb418..019fac49db5b 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c | |||
@@ -839,10 +839,10 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
839 | 839 | ||
840 | /* Configure the internal memory */ | 840 | /* Configure the internal memory */ |
841 | if (dev->pci->device == 0x8880) { | 841 | if (dev->pci->device == 0x8880) { |
842 | /* Could be 887 or 888, assume a default */ | 842 | /* Could be 887 or 888, assume an 888 default */ |
843 | dev->bridge = CX23885_BRIDGE_887; | 843 | dev->bridge = CX23885_BRIDGE_888; |
844 | /* Apply a sensible clock frequency for the PCIe bridge */ | 844 | /* Apply a sensible clock frequency for the PCIe bridge */ |
845 | dev->clk_freq = 25000000; | 845 | dev->clk_freq = 50000000; |
846 | dev->sram_channels = cx23887_sram_channels; | 846 | dev->sram_channels = cx23887_sram_channels; |
847 | } else | 847 | } else |
848 | if (dev->pci->device == 0x8852) { | 848 | if (dev->pci->device == 0x8852) { |
@@ -869,10 +869,28 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
869 | cx23885_card_list(dev); | 869 | cx23885_card_list(dev); |
870 | } | 870 | } |
871 | 871 | ||
872 | if (dev->pci->device == 0x8852) { | ||
873 | /* no DIF on cx23885, so no analog tuner support possible */ | ||
874 | if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC) | ||
875 | dev->board = CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885; | ||
876 | else if (dev->board == CX23885_BOARD_HAUPPAUGE_QUADHD_DVB) | ||
877 | dev->board = CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885; | ||
878 | } | ||
879 | |||
872 | /* If the user specific a clk freq override, apply it */ | 880 | /* If the user specific a clk freq override, apply it */ |
873 | if (cx23885_boards[dev->board].clk_freq > 0) | 881 | if (cx23885_boards[dev->board].clk_freq > 0) |
874 | dev->clk_freq = cx23885_boards[dev->board].clk_freq; | 882 | dev->clk_freq = cx23885_boards[dev->board].clk_freq; |
875 | 883 | ||
884 | if (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE && | ||
885 | dev->pci->subsystem_device == 0x7137) { | ||
886 | /* Hauppauge ImpactVCBe device ID 0x7137 is populated | ||
887 | * with an 888, and a 25Mhz crystal, instead of the | ||
888 | * usual third overtone 50Mhz. The default clock rate must | ||
889 | * be overridden so the cx25840 is properly configured | ||
890 | */ | ||
891 | dev->clk_freq = 25000000; | ||
892 | } | ||
893 | |||
876 | dev->pci_bus = dev->pci->bus->number; | 894 | dev->pci_bus = dev->pci->bus->number; |
877 | dev->pci_slot = PCI_SLOT(dev->pci->devfn); | 895 | dev->pci_slot = PCI_SLOT(dev->pci->devfn); |
878 | cx23885_irq_add(dev, 0x001f00); | 896 | cx23885_irq_add(dev, 0x001f00); |
@@ -965,7 +983,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) | |||
965 | cx23885_i2c_register(&dev->i2c_bus[1]); | 983 | cx23885_i2c_register(&dev->i2c_bus[1]); |
966 | cx23885_i2c_register(&dev->i2c_bus[2]); | 984 | cx23885_i2c_register(&dev->i2c_bus[2]); |
967 | cx23885_card_setup(dev); | 985 | cx23885_card_setup(dev); |
968 | call_all(dev, core, s_power, 0); | 986 | call_all(dev, tuner, standby); |
969 | cx23885_ir_init(dev); | 987 | cx23885_ir_init(dev); |
970 | 988 | ||
971 | if (dev->board == CX23885_BOARD_VIEWCAST_460E) { | 989 | if (dev->board == CX23885_BOARD_VIEWCAST_460E) { |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 700422b538c0..114d9bcbe4f4 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
@@ -193,7 +193,7 @@ static struct s5h1409_config hauppauge_generic_config = { | |||
193 | .qam_if = 44000, | 193 | .qam_if = 44000, |
194 | .inversion = S5H1409_INVERSION_OFF, | 194 | .inversion = S5H1409_INVERSION_OFF, |
195 | .status_mode = S5H1409_DEMODLOCKING, | 195 | .status_mode = S5H1409_DEMODLOCKING, |
196 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 196 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static struct tda10048_config hauppauge_hvr1200_config = { | 199 | static struct tda10048_config hauppauge_hvr1200_config = { |
@@ -225,7 +225,7 @@ static struct s5h1409_config hauppauge_ezqam_config = { | |||
225 | .qam_if = 4000, | 225 | .qam_if = 4000, |
226 | .inversion = S5H1409_INVERSION_ON, | 226 | .inversion = S5H1409_INVERSION_ON, |
227 | .status_mode = S5H1409_DEMODLOCKING, | 227 | .status_mode = S5H1409_DEMODLOCKING, |
228 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 228 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | static struct s5h1409_config hauppauge_hvr1800lp_config = { | 231 | static struct s5h1409_config hauppauge_hvr1800lp_config = { |
@@ -235,7 +235,7 @@ static struct s5h1409_config hauppauge_hvr1800lp_config = { | |||
235 | .qam_if = 44000, | 235 | .qam_if = 44000, |
236 | .inversion = S5H1409_INVERSION_OFF, | 236 | .inversion = S5H1409_INVERSION_OFF, |
237 | .status_mode = S5H1409_DEMODLOCKING, | 237 | .status_mode = S5H1409_DEMODLOCKING, |
238 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 238 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
239 | }; | 239 | }; |
240 | 240 | ||
241 | static struct s5h1409_config hauppauge_hvr1500_config = { | 241 | static struct s5h1409_config hauppauge_hvr1500_config = { |
@@ -244,7 +244,7 @@ static struct s5h1409_config hauppauge_hvr1500_config = { | |||
244 | .gpio = S5H1409_GPIO_OFF, | 244 | .gpio = S5H1409_GPIO_OFF, |
245 | .inversion = S5H1409_INVERSION_OFF, | 245 | .inversion = S5H1409_INVERSION_OFF, |
246 | .status_mode = S5H1409_DEMODLOCKING, | 246 | .status_mode = S5H1409_DEMODLOCKING, |
247 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 247 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
248 | }; | 248 | }; |
249 | 249 | ||
250 | static struct mt2131_config hauppauge_generic_tunerconfig = { | 250 | static struct mt2131_config hauppauge_generic_tunerconfig = { |
@@ -264,7 +264,7 @@ static struct s5h1409_config hauppauge_hvr1500q_config = { | |||
264 | .qam_if = 44000, | 264 | .qam_if = 44000, |
265 | .inversion = S5H1409_INVERSION_OFF, | 265 | .inversion = S5H1409_INVERSION_OFF, |
266 | .status_mode = S5H1409_DEMODLOCKING, | 266 | .status_mode = S5H1409_DEMODLOCKING, |
267 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 267 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
268 | }; | 268 | }; |
269 | 269 | ||
270 | static struct s5h1409_config dvico_s5h1409_config = { | 270 | static struct s5h1409_config dvico_s5h1409_config = { |
@@ -274,7 +274,7 @@ static struct s5h1409_config dvico_s5h1409_config = { | |||
274 | .qam_if = 44000, | 274 | .qam_if = 44000, |
275 | .inversion = S5H1409_INVERSION_OFF, | 275 | .inversion = S5H1409_INVERSION_OFF, |
276 | .status_mode = S5H1409_DEMODLOCKING, | 276 | .status_mode = S5H1409_DEMODLOCKING, |
277 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 277 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
278 | }; | 278 | }; |
279 | 279 | ||
280 | static struct s5h1411_config dvico_s5h1411_config = { | 280 | static struct s5h1411_config dvico_s5h1411_config = { |
@@ -284,7 +284,7 @@ static struct s5h1411_config dvico_s5h1411_config = { | |||
284 | .vsb_if = S5H1411_IF_44000, | 284 | .vsb_if = S5H1411_IF_44000, |
285 | .inversion = S5H1411_INVERSION_OFF, | 285 | .inversion = S5H1411_INVERSION_OFF, |
286 | .status_mode = S5H1411_DEMODLOCKING, | 286 | .status_mode = S5H1411_DEMODLOCKING, |
287 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 287 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
288 | }; | 288 | }; |
289 | 289 | ||
290 | static struct s5h1411_config hcw_s5h1411_config = { | 290 | static struct s5h1411_config hcw_s5h1411_config = { |
@@ -294,7 +294,7 @@ static struct s5h1411_config hcw_s5h1411_config = { | |||
294 | .qam_if = S5H1411_IF_4000, | 294 | .qam_if = S5H1411_IF_4000, |
295 | .inversion = S5H1411_INVERSION_ON, | 295 | .inversion = S5H1411_INVERSION_ON, |
296 | .status_mode = S5H1411_DEMODLOCKING, | 296 | .status_mode = S5H1411_DEMODLOCKING, |
297 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 297 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
298 | }; | 298 | }; |
299 | 299 | ||
300 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { | 300 | static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { |
@@ -930,6 +930,18 @@ static const struct m88ds3103_config hauppauge_hvr5525_m88ds3103_config = { | |||
930 | .agc = 0x99, | 930 | .agc = 0x99, |
931 | }; | 931 | }; |
932 | 932 | ||
933 | static struct lgdt3306a_config hauppauge_hvr1265k4_config = { | ||
934 | .i2c_addr = 0x59, | ||
935 | .qam_if_khz = 4000, | ||
936 | .vsb_if_khz = 3250, | ||
937 | .deny_i2c_rptr = 1, /* Disabled */ | ||
938 | .spectral_inversion = 0, /* Disabled */ | ||
939 | .mpeg_mode = LGDT3306A_MPEG_SERIAL, | ||
940 | .tpclk_edge = LGDT3306A_TPCLK_RISING_EDGE, | ||
941 | .tpvalid_polarity = LGDT3306A_TP_VALID_HIGH, | ||
942 | .xtalMHz = 25, /* 24 or 25 */ | ||
943 | }; | ||
944 | |||
933 | static int netup_altera_fpga_rw(void *device, int flag, int data, int read) | 945 | static int netup_altera_fpga_rw(void *device, int flag, int data, int read) |
934 | { | 946 | { |
935 | struct cx23885_dev *dev = (struct cx23885_dev *)device; | 947 | struct cx23885_dev *dev = (struct cx23885_dev *)device; |
@@ -1194,6 +1206,8 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1194 | struct si2157_config si2157_config; | 1206 | struct si2157_config si2157_config; |
1195 | struct ts2020_config ts2020_config; | 1207 | struct ts2020_config ts2020_config; |
1196 | struct m88ds3103_platform_data m88ds3103_pdata; | 1208 | struct m88ds3103_platform_data m88ds3103_pdata; |
1209 | struct m88rs6000t_config m88rs6000t_config = {}; | ||
1210 | struct a8293_platform_data a8293_pdata = {}; | ||
1197 | struct i2c_board_info info; | 1211 | struct i2c_board_info info; |
1198 | struct i2c_adapter *adapter; | 1212 | struct i2c_adapter *adapter; |
1199 | struct i2c_client *client_demod = NULL, *client_tuner = NULL; | 1213 | struct i2c_client *client_demod = NULL, *client_tuner = NULL; |
@@ -2217,9 +2231,10 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2217 | } | 2231 | } |
2218 | port->i2c_client_tuner = client_tuner; | 2232 | port->i2c_client_tuner = client_tuner; |
2219 | break; | 2233 | break; |
2220 | case CX23885_BOARD_HAUPPAUGE_HVR5525: { | 2234 | case CX23885_BOARD_HAUPPAUGE_STARBURST2: |
2221 | struct m88rs6000t_config m88rs6000t_config; | 2235 | case CX23885_BOARD_HAUPPAUGE_HVR5525: |
2222 | struct a8293_platform_data a8293_pdata = {}; | 2236 | i2c_bus = &dev->i2c_bus[0]; |
2237 | i2c_bus2 = &dev->i2c_bus[1]; | ||
2223 | 2238 | ||
2224 | switch (port->nr) { | 2239 | switch (port->nr) { |
2225 | 2240 | ||
@@ -2228,7 +2243,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2228 | /* attach frontend */ | 2243 | /* attach frontend */ |
2229 | fe0->dvb.frontend = dvb_attach(m88ds3103_attach, | 2244 | fe0->dvb.frontend = dvb_attach(m88ds3103_attach, |
2230 | &hauppauge_hvr5525_m88ds3103_config, | 2245 | &hauppauge_hvr5525_m88ds3103_config, |
2231 | &dev->i2c_bus[0].i2c_adap, &adapter); | 2246 | &i2c_bus->i2c_adap, &adapter); |
2232 | if (fe0->dvb.frontend == NULL) | 2247 | if (fe0->dvb.frontend == NULL) |
2233 | break; | 2248 | break; |
2234 | 2249 | ||
@@ -2239,7 +2254,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2239 | info.addr = 0x0b; | 2254 | info.addr = 0x0b; |
2240 | info.platform_data = &a8293_pdata; | 2255 | info.platform_data = &a8293_pdata; |
2241 | request_module("a8293"); | 2256 | request_module("a8293"); |
2242 | client_sec = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); | 2257 | client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info); |
2243 | if (!client_sec || !client_sec->dev.driver) | 2258 | if (!client_sec || !client_sec->dev.driver) |
2244 | goto frontend_detach; | 2259 | goto frontend_detach; |
2245 | if (!try_module_get(client_sec->dev.driver->owner)) { | 2260 | if (!try_module_get(client_sec->dev.driver->owner)) { |
@@ -2281,7 +2296,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2281 | info.addr = 0x64; | 2296 | info.addr = 0x64; |
2282 | info.platform_data = &si2168_config; | 2297 | info.platform_data = &si2168_config; |
2283 | request_module("%s", info.type); | 2298 | request_module("%s", info.type); |
2284 | client_demod = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info); | 2299 | client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info); |
2285 | if (!client_demod || !client_demod->dev.driver) | 2300 | if (!client_demod || !client_demod->dev.driver) |
2286 | goto frontend_detach; | 2301 | goto frontend_detach; |
2287 | if (!try_module_get(client_demod->dev.driver->owner)) { | 2302 | if (!try_module_get(client_demod->dev.driver->owner)) { |
@@ -2299,7 +2314,7 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2299 | info.addr = 0x60; | 2314 | info.addr = 0x60; |
2300 | info.platform_data = &si2157_config; | 2315 | info.platform_data = &si2157_config; |
2301 | request_module("%s", info.type); | 2316 | request_module("%s", info.type); |
2302 | client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info); | 2317 | client_tuner = i2c_new_device(&i2c_bus2->i2c_adap, &info); |
2303 | if (!client_tuner || !client_tuner->dev.driver) { | 2318 | if (!client_tuner || !client_tuner->dev.driver) { |
2304 | module_put(client_demod->dev.driver->owner); | 2319 | module_put(client_demod->dev.driver->owner); |
2305 | i2c_unregister_device(client_demod); | 2320 | i2c_unregister_device(client_demod); |
@@ -2317,8 +2332,10 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2317 | break; | 2332 | break; |
2318 | } | 2333 | } |
2319 | break; | 2334 | break; |
2320 | } | ||
2321 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: | 2335 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB: |
2336 | case CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885: | ||
2337 | pr_info("%s(): board=%d port=%d\n", __func__, | ||
2338 | dev->board, port->nr); | ||
2322 | switch (port->nr) { | 2339 | switch (port->nr) { |
2323 | /* port b - Terrestrial/cable */ | 2340 | /* port b - Terrestrial/cable */ |
2324 | case 1: | 2341 | case 1: |
@@ -2416,6 +2433,9 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2416 | } | 2433 | } |
2417 | break; | 2434 | break; |
2418 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: | 2435 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC: |
2436 | case CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885: | ||
2437 | pr_info("%s(): board=%d port=%d\n", __func__, | ||
2438 | dev->board, port->nr); | ||
2419 | switch (port->nr) { | 2439 | switch (port->nr) { |
2420 | /* port b - Terrestrial/cable */ | 2440 | /* port b - Terrestrial/cable */ |
2421 | case 1: | 2441 | case 1: |
@@ -2490,7 +2510,41 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2490 | break; | 2510 | break; |
2491 | } | 2511 | } |
2492 | break; | 2512 | break; |
2513 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
2514 | switch (port->nr) { | ||
2515 | /* port c - Terrestrial/cable */ | ||
2516 | case 2: | ||
2517 | /* attach frontend */ | ||
2518 | i2c_bus = &dev->i2c_bus[0]; | ||
2519 | fe0->dvb.frontend = dvb_attach(lgdt3306a_attach, | ||
2520 | &hauppauge_hvr1265k4_config, | ||
2521 | &i2c_bus->i2c_adap); | ||
2522 | if (fe0->dvb.frontend == NULL) | ||
2523 | break; | ||
2524 | |||
2525 | /* attach tuner */ | ||
2526 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
2527 | si2157_config.fe = fe0->dvb.frontend; | ||
2528 | si2157_config.if_port = 1; | ||
2529 | si2157_config.inversion = 1; | ||
2530 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
2531 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
2532 | info.addr = 0x60; | ||
2533 | info.platform_data = &si2157_config; | ||
2534 | request_module("%s", info.type); | ||
2535 | client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info); | ||
2536 | if (!client_tuner || !client_tuner->dev.driver) | ||
2537 | goto frontend_detach; | ||
2493 | 2538 | ||
2539 | if (!try_module_get(client_tuner->dev.driver->owner)) { | ||
2540 | i2c_unregister_device(client_tuner); | ||
2541 | client_tuner = NULL; | ||
2542 | goto frontend_detach; | ||
2543 | } | ||
2544 | port->i2c_client_tuner = client_tuner; | ||
2545 | break; | ||
2546 | } | ||
2547 | break; | ||
2494 | default: | 2548 | default: |
2495 | pr_info("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 2549 | pr_info("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
2496 | dev->name); | 2550 | dev->name); |
@@ -2514,8 +2568,8 @@ static int dvb_register(struct cx23885_tsport *port) | |||
2514 | fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; | 2568 | fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; |
2515 | #endif | 2569 | #endif |
2516 | 2570 | ||
2517 | /* Put the analog decoder in standby to keep it quiet */ | 2571 | /* Put the tuner in standby to keep it quiet */ |
2518 | call_all(dev, core, s_power, 0); | 2572 | call_all(dev, tuner, standby); |
2519 | 2573 | ||
2520 | if (fe0->dvb.frontend->ops.analog_ops.standby) | 2574 | if (fe0->dvb.frontend->ops.analog_ops.standby) |
2521 | fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); | 2575 | fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); |
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 0f4e54294bb7..be49589a61d2 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c | |||
@@ -94,6 +94,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) | |||
94 | case CX23885_BOARD_DVBSKY_S950: | 94 | case CX23885_BOARD_DVBSKY_S950: |
95 | case CX23885_BOARD_DVBSKY_S952: | 95 | case CX23885_BOARD_DVBSKY_S952: |
96 | case CX23885_BOARD_DVBSKY_T982: | 96 | case CX23885_BOARD_DVBSKY_T982: |
97 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
97 | /* | 98 | /* |
98 | * The only boards we handle right now. However other boards | 99 | * The only boards we handle right now. However other boards |
99 | * using the CX2388x integrated IR controller should be similar | 100 | * using the CX2388x integrated IR controller should be similar |
@@ -153,6 +154,7 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) | |||
153 | case CX23885_BOARD_DVBSKY_S950: | 154 | case CX23885_BOARD_DVBSKY_S950: |
154 | case CX23885_BOARD_DVBSKY_S952: | 155 | case CX23885_BOARD_DVBSKY_S952: |
155 | case CX23885_BOARD_DVBSKY_T982: | 156 | case CX23885_BOARD_DVBSKY_T982: |
157 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
156 | /* | 158 | /* |
157 | * The IR controller on this board only returns pulse widths. | 159 | * The IR controller on this board only returns pulse widths. |
158 | * Any other mode setting will fail to set up the device. | 160 | * Any other mode setting will fail to set up the device. |
@@ -283,6 +285,7 @@ int cx23885_input_init(struct cx23885_dev *dev) | |||
283 | case CX23885_BOARD_HAUPPAUGE_HVR1850: | 285 | case CX23885_BOARD_HAUPPAUGE_HVR1850: |
284 | case CX23885_BOARD_HAUPPAUGE_HVR1290: | 286 | case CX23885_BOARD_HAUPPAUGE_HVR1290: |
285 | case CX23885_BOARD_HAUPPAUGE_HVR1250: | 287 | case CX23885_BOARD_HAUPPAUGE_HVR1250: |
288 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
286 | /* Integrated CX2388[58] IR controller */ | 289 | /* Integrated CX2388[58] IR controller */ |
287 | allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; | 290 | allowed_protos = RC_PROTO_BIT_ALL_IR_DECODER; |
288 | /* The grey Hauppauge RC-5 remote */ | 291 | /* The grey Hauppauge RC-5 remote */ |
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index a03dcb662953..f8a3deadc77a 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c | |||
@@ -263,6 +263,7 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) | |||
263 | (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE) || | 263 | (dev->board == CX23885_BOARD_HAUPPAUGE_IMPACTVCBE) || |
264 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || | 264 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || |
265 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || | 265 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || |
266 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4) || | ||
266 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || | 267 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || |
267 | (dev->board == CX23885_BOARD_MYGICA_X8507) || | 268 | (dev->board == CX23885_BOARD_MYGICA_X8507) || |
268 | (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) || | 269 | (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) || |
@@ -993,7 +994,8 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, | |||
993 | 994 | ||
994 | if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || | 995 | if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || |
995 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || | 996 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || |
996 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111)) | 997 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || |
998 | (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1265_K4)) | ||
997 | fe = &dev->ts1.analog_fe; | 999 | fe = &dev->ts1.analog_fe; |
998 | 1000 | ||
999 | if (fe && fe->ops.tuner_ops.set_analog_params) { | 1001 | if (fe && fe->ops.tuner_ops.set_analog_params) { |
@@ -1022,6 +1024,7 @@ int cx23885_set_frequency(struct file *file, void *priv, | |||
1022 | switch (dev->board) { | 1024 | switch (dev->board) { |
1023 | case CX23885_BOARD_HAUPPAUGE_HVR1255: | 1025 | case CX23885_BOARD_HAUPPAUGE_HVR1255: |
1024 | case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: | 1026 | case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: |
1027 | case CX23885_BOARD_HAUPPAUGE_HVR1265_K4: | ||
1025 | case CX23885_BOARD_HAUPPAUGE_HVR1850: | 1028 | case CX23885_BOARD_HAUPPAUGE_HVR1850: |
1026 | ret = cx23885_set_freq_via_ops(dev, f); | 1029 | ret = cx23885_set_freq_via_ops(dev, f); |
1027 | break; | 1030 | break; |
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 2a17209eb4f6..d54c7ee1ab21 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h | |||
@@ -107,6 +107,10 @@ | |||
107 | #define CX23885_BOARD_VIEWCAST_460E 55 | 107 | #define CX23885_BOARD_VIEWCAST_460E 55 |
108 | #define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB 56 | 108 | #define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB 56 |
109 | #define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC 57 | 109 | #define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC 57 |
110 | #define CX23885_BOARD_HAUPPAUGE_HVR1265_K4 58 | ||
111 | #define CX23885_BOARD_HAUPPAUGE_STARBURST2 59 | ||
112 | #define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885 60 | ||
113 | #define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885 61 | ||
110 | 114 | ||
111 | #define GPIO_0 0x00000001 | 115 | #define GPIO_0 0x00000001 |
112 | #define GPIO_1 0x00000002 | 116 | #define GPIO_1 0x00000002 |
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 04aa4a68a0ae..040c6c251d3a 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c | |||
@@ -867,6 +867,10 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
867 | dev->nr = ++cx25821_devcount; | 867 | dev->nr = ++cx25821_devcount; |
868 | sprintf(dev->name, "cx25821[%d]", dev->nr); | 868 | sprintf(dev->name, "cx25821[%d]", dev->nr); |
869 | 869 | ||
870 | if (dev->nr >= ARRAY_SIZE(card)) { | ||
871 | CX25821_INFO("dev->nr >= %zd", ARRAY_SIZE(card)); | ||
872 | return -ENODEV; | ||
873 | } | ||
870 | if (dev->pci->device != 0x8210) { | 874 | if (dev->pci->device != 0x8210) { |
871 | pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", | 875 | pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", |
872 | __func__, dev->pci->device); | 876 | __func__, dev->pci->device); |
@@ -882,9 +886,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
882 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; | 886 | dev->channels[i].sram_channels = &cx25821_sram_channels[i]; |
883 | } | 887 | } |
884 | 888 | ||
885 | if (dev->nr > 1) | ||
886 | CX25821_INFO("dev->nr > 1!"); | ||
887 | |||
888 | /* board config */ | 889 | /* board config */ |
889 | dev->board = 1; /* card[dev->nr]; */ | 890 | dev->board = 1; /* card[dev->nr]; */ |
890 | dev->_max_num_decoders = MAX_DECODERS; | 891 | dev->_max_num_decoders = MAX_DECODERS; |
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 9740326bc93f..ab09bb55cf45 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c | |||
@@ -292,8 +292,8 @@ static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) | |||
292 | return -ENOMEM; | 292 | return -ENOMEM; |
293 | } | 293 | } |
294 | 294 | ||
295 | dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n", | 295 | dprintk(1, "vmalloc is at addr %p, size=%d\n", |
296 | (unsigned long)buf->vaddr, nr_pages << PAGE_SHIFT); | 296 | buf->vaddr, nr_pages << PAGE_SHIFT); |
297 | 297 | ||
298 | memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); | 298 | memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); |
299 | buf->nr_pages = nr_pages; | 299 | buf->nr_pages = nr_pages; |
@@ -656,8 +656,8 @@ static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol, | |||
656 | { | 656 | { |
657 | struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); | 657 | struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); |
658 | struct cx88_core *core = chip->core; | 658 | struct cx88_core *core = chip->core; |
659 | int left = value->value.integer.value[0]; | 659 | u16 left = value->value.integer.value[0]; |
660 | int right = value->value.integer.value[1]; | 660 | u16 right = value->value.integer.value[1]; |
661 | int v, b; | 661 | int v, b; |
662 | 662 | ||
663 | /* Pass volume & balance onto any WM8775 */ | 663 | /* Pass volume & balance onto any WM8775 */ |
diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index 6df21b29ea17..4c92d2388c26 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c | |||
@@ -3592,7 +3592,7 @@ static void cx88_card_setup(struct cx88_core *core) | |||
3592 | ctl.fname); | 3592 | ctl.fname); |
3593 | call_all(core, tuner, s_config, &xc2028_cfg); | 3593 | call_all(core, tuner, s_config, &xc2028_cfg); |
3594 | } | 3594 | } |
3595 | call_all(core, core, s_power, 0); | 3595 | call_all(core, tuner, standby); |
3596 | } | 3596 | } |
3597 | 3597 | ||
3598 | /* ------------------------------------------------------------------ */ | 3598 | /* ------------------------------------------------------------------ */ |
diff --git a/drivers/media/pci/cx88/cx88-dvb.c b/drivers/media/pci/cx88/cx88-dvb.c index 49a335f4603e..2f886140dd2e 100644 --- a/drivers/media/pci/cx88/cx88-dvb.c +++ b/drivers/media/pci/cx88/cx88-dvb.c | |||
@@ -558,7 +558,7 @@ static const struct s5h1409_config pinnacle_pctv_hd_800i_config = { | |||
558 | .qam_if = 44000, | 558 | .qam_if = 44000, |
559 | .inversion = S5H1409_INVERSION_OFF, | 559 | .inversion = S5H1409_INVERSION_OFF, |
560 | .status_mode = S5H1409_DEMODLOCKING, | 560 | .status_mode = S5H1409_DEMODLOCKING, |
561 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, | 561 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK, |
562 | }; | 562 | }; |
563 | 563 | ||
564 | static const struct s5h1409_config dvico_hdtv5_pci_nano_config = { | 564 | static const struct s5h1409_config dvico_hdtv5_pci_nano_config = { |
@@ -567,7 +567,7 @@ static const struct s5h1409_config dvico_hdtv5_pci_nano_config = { | |||
567 | .gpio = S5H1409_GPIO_OFF, | 567 | .gpio = S5H1409_GPIO_OFF, |
568 | .inversion = S5H1409_INVERSION_OFF, | 568 | .inversion = S5H1409_INVERSION_OFF, |
569 | .status_mode = S5H1409_DEMODLOCKING, | 569 | .status_mode = S5H1409_DEMODLOCKING, |
570 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 570 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
571 | }; | 571 | }; |
572 | 572 | ||
573 | static const struct s5h1409_config kworld_atsc_120_config = { | 573 | static const struct s5h1409_config kworld_atsc_120_config = { |
@@ -576,7 +576,7 @@ static const struct s5h1409_config kworld_atsc_120_config = { | |||
576 | .gpio = S5H1409_GPIO_OFF, | 576 | .gpio = S5H1409_GPIO_OFF, |
577 | .inversion = S5H1409_INVERSION_OFF, | 577 | .inversion = S5H1409_INVERSION_OFF, |
578 | .status_mode = S5H1409_DEMODLOCKING, | 578 | .status_mode = S5H1409_DEMODLOCKING, |
579 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 579 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
580 | }; | 580 | }; |
581 | 581 | ||
582 | static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { | 582 | static const struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { |
@@ -599,7 +599,7 @@ static const struct zl10353_config cx88_geniatech_x8000_mt = { | |||
599 | static const struct s5h1411_config dvico_fusionhdtv7_config = { | 599 | static const struct s5h1411_config dvico_fusionhdtv7_config = { |
600 | .output_mode = S5H1411_SERIAL_OUTPUT, | 600 | .output_mode = S5H1411_SERIAL_OUTPUT, |
601 | .gpio = S5H1411_GPIO_ON, | 601 | .gpio = S5H1411_GPIO_ON, |
602 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 602 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
603 | .qam_if = S5H1411_IF_44000, | 603 | .qam_if = S5H1411_IF_44000, |
604 | .vsb_if = S5H1411_IF_44000, | 604 | .vsb_if = S5H1411_IF_44000, |
605 | .inversion = S5H1411_INVERSION_OFF, | 605 | .inversion = S5H1411_INVERSION_OFF, |
@@ -1631,8 +1631,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
1631 | if (fe1) | 1631 | if (fe1) |
1632 | fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | 1632 | fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; |
1633 | 1633 | ||
1634 | /* Put the analog decoder in standby to keep it quiet */ | 1634 | /* Put the tuner in standby to keep it quiet */ |
1635 | call_all(core, core, s_power, 0); | 1635 | call_all(core, tuner, standby); |
1636 | 1636 | ||
1637 | /* register everything */ | 1637 | /* register everything */ |
1638 | res = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, | 1638 | res = vb2_dvb_register_bus(&dev->frontends, THIS_MODULE, dev, |
diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index 4e9953e61a12..6f4e6923a91a 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c | |||
@@ -180,7 +180,7 @@ static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer) | |||
180 | struct cx88_IR *ir = container_of(timer, struct cx88_IR, timer); | 180 | struct cx88_IR *ir = container_of(timer, struct cx88_IR, timer); |
181 | 181 | ||
182 | cx88_ir_handle_key(ir); | 182 | cx88_ir_handle_key(ir); |
183 | missed = hrtimer_forward_now(&ir->timer, ir->polling * 1000000); | 183 | missed = hrtimer_forward_now(&ir->timer, ir->polling * 1000000LL); |
184 | if (missed > 1) | 184 | if (missed > 1) |
185 | ir_dprintk("Missed ticks %ld\n", missed - 1); | 185 | ir_dprintk("Missed ticks %ld\n", missed - 1); |
186 | 186 | ||
@@ -200,7 +200,7 @@ static int __cx88_ir_start(void *priv) | |||
200 | if (ir->polling) { | 200 | if (ir->polling) { |
201 | hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 201 | hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
202 | ir->timer.function = cx88_ir_work; | 202 | ir->timer.function = cx88_ir_work; |
203 | hrtimer_start(&ir->timer, ir->polling * 1000000, | 203 | hrtimer_start(&ir->timer, ir->polling * 1000000LL, |
204 | HRTIMER_MODE_REL); | 204 | HRTIMER_MODE_REL); |
205 | } | 205 | } |
206 | if (ir->sampling) { | 206 | if (ir->sampling) { |
diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index f43d0b83fc0c..a422dde2f34a 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig | |||
@@ -13,6 +13,7 @@ config DVB_DDBRIDGE | |||
13 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT | 13 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT |
14 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT | 14 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT |
15 | select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT | 15 | select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT |
16 | select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT | ||
16 | ---help--- | 17 | ---help--- |
17 | Support for cards with the Digital Devices PCI express bridge: | 18 | Support for cards with the Digital Devices PCI express bridge: |
18 | - Octopus PCIe Bridge | 19 | - Octopus PCIe Bridge |
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile index f58fdec50eab..745b37d07558 100644 --- a/drivers/media/pci/ddbridge/Makefile +++ b/drivers/media/pci/ddbridge/Makefile | |||
@@ -10,6 +10,3 @@ obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o | |||
10 | 10 | ||
11 | ccflags-y += -Idrivers/media/dvb-frontends/ | 11 | ccflags-y += -Idrivers/media/dvb-frontends/ |
12 | ccflags-y += -Idrivers/media/tuners/ | 12 | ccflags-y += -Idrivers/media/tuners/ |
13 | |||
14 | # For the staging CI driver cxd2099 | ||
15 | ccflags-y += -Idrivers/staging/media/cxd2099/ | ||
diff --git a/drivers/media/pci/ddbridge/ddbridge-ci.c b/drivers/media/pci/ddbridge/ddbridge-ci.c index 5828111487b0..a9dbc4ebf94f 100644 --- a/drivers/media/pci/ddbridge/ddbridge-ci.c +++ b/drivers/media/pci/ddbridge/ddbridge-ci.c | |||
@@ -172,6 +172,7 @@ static void ci_attach(struct ddb_port *port) | |||
172 | memcpy(&ci->en, &en_templ, sizeof(en_templ)); | 172 | memcpy(&ci->en, &en_templ, sizeof(en_templ)); |
173 | ci->en.data = ci; | 173 | ci->en.data = ci; |
174 | port->en = &ci->en; | 174 | port->en = &ci->en; |
175 | port->en_freedata = 1; | ||
175 | ci->port = port; | 176 | ci->port = port; |
176 | ci->nr = port->nr - 2; | 177 | ci->nr = port->nr - 2; |
177 | } | 178 | } |
@@ -304,6 +305,7 @@ static void ci_xo2_attach(struct ddb_port *port) | |||
304 | memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ)); | 305 | memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ)); |
305 | ci->en.data = ci; | 306 | ci->en.data = ci; |
306 | port->en = &ci->en; | 307 | port->en = &ci->en; |
308 | port->en_freedata = 1; | ||
307 | ci->port = port; | 309 | ci->port = port; |
308 | ci->nr = port->nr - 2; | 310 | ci->nr = port->nr - 2; |
309 | ci->port->creg = 0; | 311 | ci->port->creg = 0; |
@@ -311,38 +313,58 @@ static void ci_xo2_attach(struct ddb_port *port) | |||
311 | write_creg(ci, 0x08, 0x08); | 313 | write_creg(ci, 0x08, 0x08); |
312 | } | 314 | } |
313 | 315 | ||
314 | static struct cxd2099_cfg cxd_cfg = { | 316 | static const struct cxd2099_cfg cxd_cfgtmpl = { |
315 | .bitrate = 72000, | 317 | .bitrate = 72000, |
316 | .adr = 0x40, | ||
317 | .polarity = 1, | 318 | .polarity = 1, |
318 | .clock_mode = 1, | 319 | .clock_mode = 1, |
319 | .max_i2c = 512, | 320 | .max_i2c = 512, |
320 | }; | 321 | }; |
321 | 322 | ||
323 | static int ci_cxd2099_attach(struct ddb_port *port, u32 bitrate) | ||
324 | { | ||
325 | struct cxd2099_cfg cxd_cfg = cxd_cfgtmpl; | ||
326 | struct i2c_client *client; | ||
327 | |||
328 | cxd_cfg.bitrate = bitrate; | ||
329 | cxd_cfg.en = &port->en; | ||
330 | |||
331 | client = dvb_module_probe("cxd2099", NULL, &port->i2c->adap, | ||
332 | 0x40, &cxd_cfg); | ||
333 | if (!client) | ||
334 | goto err; | ||
335 | |||
336 | port->dvb[0].i2c_client[0] = client; | ||
337 | port->en_freedata = 0; | ||
338 | return 0; | ||
339 | |||
340 | err: | ||
341 | dev_err(port->dev->dev, "CXD2099AR attach failed\n"); | ||
342 | return -ENODEV; | ||
343 | } | ||
344 | |||
322 | int ddb_ci_attach(struct ddb_port *port, u32 bitrate) | 345 | int ddb_ci_attach(struct ddb_port *port, u32 bitrate) |
323 | { | 346 | { |
347 | int ret; | ||
348 | |||
324 | switch (port->type) { | 349 | switch (port->type) { |
325 | case DDB_CI_EXTERNAL_SONY: | 350 | case DDB_CI_EXTERNAL_SONY: |
326 | cxd_cfg.bitrate = bitrate; | 351 | ret = ci_cxd2099_attach(port, bitrate); |
327 | port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); | 352 | if (ret) |
328 | if (!port->en) | ||
329 | return -ENODEV; | 353 | return -ENODEV; |
330 | break; | 354 | break; |
331 | |||
332 | case DDB_CI_EXTERNAL_XO2: | 355 | case DDB_CI_EXTERNAL_XO2: |
333 | case DDB_CI_EXTERNAL_XO2_B: | 356 | case DDB_CI_EXTERNAL_XO2_B: |
334 | ci_xo2_attach(port); | 357 | ci_xo2_attach(port); |
335 | if (!port->en) | ||
336 | return -ENODEV; | ||
337 | break; | 358 | break; |
338 | |||
339 | case DDB_CI_INTERNAL: | 359 | case DDB_CI_INTERNAL: |
340 | ci_attach(port); | 360 | ci_attach(port); |
341 | if (!port->en) | ||
342 | return -ENODEV; | ||
343 | break; | 361 | break; |
362 | default: | ||
363 | return -ENODEV; | ||
344 | } | 364 | } |
345 | 365 | ||
366 | if (!port->en) | ||
367 | return -ENODEV; | ||
346 | dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); | 368 | dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1); |
347 | return 0; | 369 | return 0; |
348 | } | 370 | } |
@@ -353,7 +375,14 @@ void ddb_ci_detach(struct ddb_port *port) | |||
353 | dvb_unregister_device(port->dvb[0].dev); | 375 | dvb_unregister_device(port->dvb[0].dev); |
354 | if (port->en) { | 376 | if (port->en) { |
355 | dvb_ca_en50221_release(port->en); | 377 | dvb_ca_en50221_release(port->en); |
356 | kfree(port->en->data); | 378 | |
379 | dvb_module_release(port->dvb[0].i2c_client[0]); | ||
380 | port->dvb[0].i2c_client[0] = NULL; | ||
381 | |||
382 | /* free alloc'ed memory if needed */ | ||
383 | if (port->en_freedata) | ||
384 | kfree(port->en->data); | ||
385 | |||
357 | port->en = NULL; | 386 | port->en = NULL; |
358 | } | 387 | } |
359 | } | 388 | } |
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index f9bee36f1cad..90687eff5909 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c | |||
@@ -999,37 +999,21 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype) | |||
999 | .if_dvbt2_8 = 4000, | 999 | .if_dvbt2_8 = 4000, |
1000 | .if_dvbc = 5000, | 1000 | .if_dvbc = 5000, |
1001 | }; | 1001 | }; |
1002 | struct i2c_board_info board_info = { | 1002 | u8 addr = (input->nr & 1) ? 0x63 : 0x60; |
1003 | .type = "tda18212", | ||
1004 | .platform_data = &config, | ||
1005 | }; | ||
1006 | |||
1007 | if (input->nr & 1) | ||
1008 | board_info.addr = 0x63; | ||
1009 | else | ||
1010 | board_info.addr = 0x60; | ||
1011 | 1003 | ||
1012 | /* due to a hardware quirk with the I2C gate on the stv0367+tda18212 | 1004 | /* due to a hardware quirk with the I2C gate on the stv0367+tda18212 |
1013 | * combo, the tda18212 must be probed by reading it's id _twice_ when | 1005 | * combo, the tda18212 must be probed by reading it's id _twice_ when |
1014 | * cold started, or it very likely will fail. | 1006 | * cold started, or it very likely will fail. |
1015 | */ | 1007 | */ |
1016 | if (porttype == DDB_TUNER_DVBCT_ST) | 1008 | if (porttype == DDB_TUNER_DVBCT_ST) |
1017 | tuner_tda18212_ping(input, board_info.addr); | 1009 | tuner_tda18212_ping(input, addr); |
1018 | |||
1019 | request_module(board_info.type); | ||
1020 | |||
1021 | /* perform tuner init/attach */ | ||
1022 | client = i2c_new_device(adapter, &board_info); | ||
1023 | if (!client || !client->dev.driver) | ||
1024 | goto err; | ||
1025 | 1010 | ||
1026 | if (!try_module_get(client->dev.driver->owner)) { | 1011 | /* perform tuner probe/init/attach */ |
1027 | i2c_unregister_device(client); | 1012 | client = dvb_module_probe("tda18212", NULL, adapter, addr, &config); |
1013 | if (!client) | ||
1028 | goto err; | 1014 | goto err; |
1029 | } | ||
1030 | 1015 | ||
1031 | dvb->i2c_client[0] = client; | 1016 | dvb->i2c_client[0] = client; |
1032 | |||
1033 | return 0; | 1017 | return 0; |
1034 | err: | 1018 | err: |
1035 | dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); | 1019 | dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); |
@@ -1253,7 +1237,6 @@ static void dvb_input_detach(struct ddb_input *input) | |||
1253 | { | 1237 | { |
1254 | struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; | 1238 | struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; |
1255 | struct dvb_demux *dvbdemux = &dvb->demux; | 1239 | struct dvb_demux *dvbdemux = &dvb->demux; |
1256 | struct i2c_client *client; | ||
1257 | 1240 | ||
1258 | switch (dvb->attached) { | 1241 | switch (dvb->attached) { |
1259 | case 0x31: | 1242 | case 0x31: |
@@ -1263,13 +1246,8 @@ static void dvb_input_detach(struct ddb_input *input) | |||
1263 | dvb_unregister_frontend(dvb->fe); | 1246 | dvb_unregister_frontend(dvb->fe); |
1264 | /* fallthrough */ | 1247 | /* fallthrough */ |
1265 | case 0x30: | 1248 | case 0x30: |
1266 | client = dvb->i2c_client[0]; | 1249 | dvb_module_release(dvb->i2c_client[0]); |
1267 | if (client) { | 1250 | dvb->i2c_client[0] = NULL; |
1268 | module_put(client->dev.driver->owner); | ||
1269 | i2c_unregister_device(client); | ||
1270 | dvb->i2c_client[0] = NULL; | ||
1271 | client = NULL; | ||
1272 | } | ||
1273 | 1251 | ||
1274 | if (dvb->fe2) | 1252 | if (dvb->fe2) |
1275 | dvb_frontend_detach(dvb->fe2); | 1253 | dvb_frontend_detach(dvb->fe2); |
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h index 095457737bc1..f223dc6c9963 100644 --- a/drivers/media/pci/ddbridge/ddbridge.h +++ b/drivers/media/pci/ddbridge/ddbridge.h | |||
@@ -276,6 +276,7 @@ struct ddb_port { | |||
276 | struct ddb_input *input[2]; | 276 | struct ddb_input *input[2]; |
277 | struct ddb_output *output; | 277 | struct ddb_output *output; |
278 | struct dvb_ca_en50221 *en; | 278 | struct dvb_ca_en50221 *en; |
279 | u8 en_freedata; | ||
279 | struct ddb_dvb dvb[2]; | 280 | struct ddb_dvb dvb[2]; |
280 | u32 gap; | 281 | u32 gap; |
281 | u32 obr; | 282 | u32 obr; |
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index 6c4444b31f4b..7d768ec0f824 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c | |||
@@ -1,14 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright (c) 2017 Intel Corporation. | 3 | * Copyright (C) 2017 Intel Corporation |
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License version | ||
6 | * 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | 4 | * |
13 | * Based partially on Intel IPU4 driver written by | 5 | * Based partially on Intel IPU4 driver written by |
14 | * Sakari Ailus <sakari.ailus@linux.intel.com> | 6 | * Sakari Ailus <sakari.ailus@linux.intel.com> |
@@ -526,6 +518,8 @@ static void cio2_hw_exit(struct cio2_device *cio2, struct cio2_queue *q) | |||
526 | unsigned int i, maxloops = 1000; | 518 | unsigned int i, maxloops = 1000; |
527 | 519 | ||
528 | /* Disable CSI receiver and MIPI backend devices */ | 520 | /* Disable CSI receiver and MIPI backend devices */ |
521 | writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_MASK); | ||
522 | writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_ENABLE); | ||
529 | writel(0, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE); | 523 | writel(0, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE); |
530 | writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE); | 524 | writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE); |
531 | 525 | ||
@@ -1035,6 +1029,7 @@ static void cio2_vb2_stop_streaming(struct vb2_queue *vq) | |||
1035 | "failed to stop sensor streaming\n"); | 1029 | "failed to stop sensor streaming\n"); |
1036 | 1030 | ||
1037 | cio2_hw_exit(cio2, q); | 1031 | cio2_hw_exit(cio2, q); |
1032 | synchronize_irq(cio2->pci_dev->irq); | ||
1038 | cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_ERROR); | 1033 | cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_ERROR); |
1039 | media_pipeline_stop(&q->vdev.entity); | 1034 | media_pipeline_stop(&q->vdev.entity); |
1040 | pm_runtime_put(&cio2->pci_dev->dev); | 1035 | pm_runtime_put(&cio2->pci_dev->dev); |
@@ -1976,6 +1971,7 @@ static int __maybe_unused cio2_suspend(struct device *dev) | |||
1976 | 1971 | ||
1977 | /* Stop stream */ | 1972 | /* Stop stream */ |
1978 | cio2_hw_exit(cio2, q); | 1973 | cio2_hw_exit(cio2, q); |
1974 | synchronize_irq(pci_dev->irq); | ||
1979 | 1975 | ||
1980 | pm_runtime_force_suspend(dev); | 1976 | pm_runtime_force_suspend(dev); |
1981 | 1977 | ||
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h index 78a5799f08e7..240635be7a31 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.h +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h | |||
@@ -1,15 +1,5 @@ | |||
1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | * Copyright (c) 2017 Intel Corporation. | 2 | /* Copyright (C) 2017 Intel Corporation */ |
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License version | ||
6 | * 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | 3 | ||
14 | #ifndef __IPU3_CIO2_H | 4 | #ifndef __IPU3_CIO2_H |
15 | #define __IPU3_CIO2_H | 5 | #define __IPU3_CIO2_H |
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c index 029f52733f70..c1856f609d2c 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-main.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include "ivtv-driver.h" | 20 | #include "ivtv-driver.h" |
21 | #include "ivtv-version.h" | 21 | #include "ivtv-version.h" |
22 | #include "ivtv-alsa.h" | 22 | #include "ivtv-alsa.h" |
23 | #include "ivtv-alsa-mixer.h" | ||
24 | #include "ivtv-alsa-pcm.h" | 23 | #include "ivtv-alsa-pcm.h" |
25 | 24 | ||
26 | #include <sound/core.h> | 25 | #include <sound/core.h> |
@@ -160,15 +159,7 @@ static int snd_ivtv_init(struct v4l2_device *v4l2_dev) | |||
160 | /* (4) Set the driver ID and name strings */ | 159 | /* (4) Set the driver ID and name strings */ |
161 | snd_ivtv_card_set_names(itvsc); | 160 | snd_ivtv_card_set_names(itvsc); |
162 | 161 | ||
163 | /* (5) Create other components: mixer, PCM, & proc files */ | 162 | /* (5) Create other components: PCM, & proc files */ |
164 | #if 0 | ||
165 | ret = snd_ivtv_mixer_create(itvsc); | ||
166 | if (ret) { | ||
167 | IVTV_ALSA_WARN("%s: snd_ivtv_mixer_create() failed with err %d: proceeding anyway\n", | ||
168 | __func__, ret); | ||
169 | } | ||
170 | #endif | ||
171 | |||
172 | ret = snd_ivtv_pcm_create(itvsc); | 163 | ret = snd_ivtv_pcm_create(itvsc); |
173 | if (ret) { | 164 | if (ret) { |
174 | IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n", | 165 | IVTV_ALSA_ERR("%s: snd_ivtv_pcm_create() failed with err %d\n", |
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-mixer.c b/drivers/media/pci/ivtv/ivtv-alsa-mixer.c deleted file mode 100644 index aee453fcff37..000000000000 --- a/drivers/media/pci/ivtv/ivtv-alsa-mixer.c +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * ALSA mixer controls for the | ||
3 | * ALSA interface to ivtv PCM capture streams | ||
4 | * | ||
5 | * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net> | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include "ivtv-alsa.h" | ||
19 | #include "ivtv-alsa-mixer.h" | ||
20 | #include "ivtv-driver.h" | ||
21 | |||
22 | #include <linux/videodev2.h> | ||
23 | |||
24 | #include <sound/core.h> | ||
25 | #include <sound/control.h> | ||
26 | #include <sound/tlv.h> | ||
27 | |||
28 | /* | ||
29 | * Note the cx25840-core volume scale is funny, due to the alignment of the | ||
30 | * scale with another chip's range: | ||
31 | * | ||
32 | * v4l2_control value /512 indicated dB actual dB reg 0x8d4 | ||
33 | * 0x0000 - 0x01ff 0 -119 -96 228 | ||
34 | * 0x0200 - 0x02ff 1 -118 -96 228 | ||
35 | * ... | ||
36 | * 0x2c00 - 0x2dff 22 -97 -96 228 | ||
37 | * 0x2e00 - 0x2fff 23 -96 -96 228 | ||
38 | * 0x3000 - 0x31ff 24 -95 -95 226 | ||
39 | * ... | ||
40 | * 0xee00 - 0xefff 119 0 0 36 | ||
41 | * ... | ||
42 | * 0xfe00 - 0xffff 127 +8 +8 20 | ||
43 | */ | ||
44 | static inline int dB_to_cx25840_vol(int dB) | ||
45 | { | ||
46 | if (dB < -96) | ||
47 | dB = -96; | ||
48 | else if (dB > 8) | ||
49 | dB = 8; | ||
50 | return (dB + 119) << 9; | ||
51 | } | ||
52 | |||
53 | static inline int cx25840_vol_to_dB(int v) | ||
54 | { | ||
55 | if (v < (23 << 9)) | ||
56 | v = (23 << 9); | ||
57 | else if (v > (127 << 9)) | ||
58 | v = (127 << 9); | ||
59 | return (v >> 9) - 119; | ||
60 | } | ||
61 | |||
62 | static int snd_ivtv_mixer_tv_vol_info(struct snd_kcontrol *kcontrol, | ||
63 | struct snd_ctl_elem_info *uinfo) | ||
64 | { | ||
65 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
66 | uinfo->count = 1; | ||
67 | /* We're already translating values, just keep this control in dB */ | ||
68 | uinfo->value.integer.min = -96; | ||
69 | uinfo->value.integer.max = 8; | ||
70 | uinfo->value.integer.step = 1; | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | static int snd_ivtv_mixer_tv_vol_get(struct snd_kcontrol *kctl, | ||
75 | struct snd_ctl_elem_value *uctl) | ||
76 | { | ||
77 | struct snd_ivtv_card *itvsc = snd_kcontrol_chip(kctl); | ||
78 | struct ivtv *itv = to_ivtv(itvsc->v4l2_dev); | ||
79 | struct v4l2_control vctrl; | ||
80 | int ret; | ||
81 | |||
82 | vctrl.id = V4L2_CID_AUDIO_VOLUME; | ||
83 | vctrl.value = dB_to_cx25840_vol(uctl->value.integer.value[0]); | ||
84 | |||
85 | snd_ivtv_lock(itvsc); | ||
86 | ret = v4l2_g_ctrl(itv->sd_audio->ctrl_handler, &vctrl); | ||
87 | snd_ivtv_unlock(itvsc); | ||
88 | |||
89 | if (!ret) | ||
90 | uctl->value.integer.value[0] = cx25840_vol_to_dB(vctrl.value); | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | static int snd_ivtv_mixer_tv_vol_put(struct snd_kcontrol *kctl, | ||
95 | struct snd_ctl_elem_value *uctl) | ||
96 | { | ||
97 | struct snd_ivtv_card *itvsc = snd_kcontrol_chip(kctl); | ||
98 | struct ivtv *itv = to_ivtv(itvsc->v4l2_dev); | ||
99 | struct v4l2_control vctrl; | ||
100 | int ret; | ||
101 | |||
102 | vctrl.id = V4L2_CID_AUDIO_VOLUME; | ||
103 | vctrl.value = dB_to_cx25840_vol(uctl->value.integer.value[0]); | ||
104 | |||
105 | snd_ivtv_lock(itvsc); | ||
106 | |||
107 | /* Fetch current state */ | ||
108 | ret = v4l2_g_ctrl(itv->sd_audio->ctrl_handler, &vctrl); | ||
109 | |||
110 | if (ret || | ||
111 | (cx25840_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) { | ||
112 | |||
113 | /* Set, if needed */ | ||
114 | vctrl.value = dB_to_cx25840_vol(uctl->value.integer.value[0]); | ||
115 | ret = v4l2_s_ctrl(itv->sd_audio->ctrl_handler, &vctrl); | ||
116 | if (!ret) | ||
117 | ret = 1; /* Indicate control was changed w/o error */ | ||
118 | } | ||
119 | snd_ivtv_unlock(itvsc); | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | |||
125 | /* This is a bit of overkill, the slider is already in dB internally */ | ||
126 | static DECLARE_TLV_DB_SCALE(snd_ivtv_mixer_tv_vol_db_scale, -9600, 100, 0); | ||
127 | |||
128 | static struct snd_kcontrol_new snd_ivtv_mixer_tv_vol __initdata = { | ||
129 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
130 | .name = "Analog TV Capture Volume", | ||
131 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
132 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
133 | .info = snd_ivtv_mixer_tv_volume_info, | ||
134 | .get = snd_ivtv_mixer_tv_volume_get, | ||
135 | .put = snd_ivtv_mixer_tv_volume_put, | ||
136 | .tlv.p = snd_ivtv_mixer_tv_vol_db_scale | ||
137 | }; | ||
138 | |||
139 | /* FIXME - add mute switch and balance, bass, treble sliders: | ||
140 | V4L2_CID_AUDIO_MUTE | ||
141 | |||
142 | V4L2_CID_AUDIO_BALANCE | ||
143 | |||
144 | V4L2_CID_AUDIO_BASS | ||
145 | V4L2_CID_AUDIO_TREBLE | ||
146 | */ | ||
147 | |||
148 | /* FIXME - add stereo, lang1, lang2, mono menu */ | ||
149 | /* FIXME - add I2S volume */ | ||
150 | |||
151 | int __init snd_ivtv_mixer_create(struct snd_ivtv_card *itvsc) | ||
152 | { | ||
153 | struct v4l2_device *v4l2_dev = itvsc->v4l2_dev; | ||
154 | struct snd_card *sc = itvsc->sc; | ||
155 | int ret; | ||
156 | |||
157 | strlcpy(sc->mixername, "CX2341[56] Mixer", sizeof(sc->mixername)); | ||
158 | |||
159 | ret = snd_ctl_add(sc, snd_ctl_new1(&snd_ivtv_mixer_tv_vol, itvsc)); | ||
160 | if (ret) { | ||
161 | IVTV_ALSA_WARN("%s: failed to add %s control, err %d\n", | ||
162 | __func__, snd_ivtv_mixer_tv_vol.name, ret); | ||
163 | } | ||
164 | return ret; | ||
165 | } | ||
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-mixer.h b/drivers/media/pci/ivtv/ivtv-alsa-mixer.h deleted file mode 100644 index 382bc36bc529..000000000000 --- a/drivers/media/pci/ivtv/ivtv-alsa-mixer.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * ALSA mixer controls for the | ||
3 | * ALSA interface to ivtv PCM capture streams | ||
4 | * | ||
5 | * Copyright (C) 2009,2012 Andy Walls <awalls@md.metrocast.net> | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | int __init snd_ivtv_mixer_create(struct snd_ivtv_card *itvsc); | ||
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 621b2f613d81..8e62b8be6529 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c | |||
@@ -346,8 +346,8 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | |||
346 | 346 | ||
347 | /* Not fatal, but will have undesirable results */ | 347 | /* Not fatal, but will have undesirable results */ |
348 | if ((unsigned long)source & 3) | 348 | if ((unsigned long)source & 3) |
349 | IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n", | 349 | IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (%p)\n", |
350 | (unsigned long)source); | 350 | source); |
351 | 351 | ||
352 | if (dest_offset & 3) | 352 | if (dest_offset & 3) |
353 | IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset); | 353 | IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset); |
@@ -357,12 +357,10 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | |||
357 | 357 | ||
358 | /* Check Source */ | 358 | /* Check Source */ |
359 | if (!access_ok(VERIFY_READ, source + dest_offset, count)) { | 359 | if (!access_ok(VERIFY_READ, source + dest_offset, count)) { |
360 | IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", | 360 | IVTVFB_WARN("Invalid userspace pointer %p\n", source); |
361 | (unsigned long)source); | ||
362 | 361 | ||
363 | IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n", | 362 | IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source %p count %d\n", |
364 | dest_offset, (unsigned long)source, | 363 | dest_offset, source, count); |
365 | count); | ||
366 | return -EINVAL; | 364 | return -EINVAL; |
367 | } | 365 | } |
368 | 366 | ||
diff --git a/drivers/media/pci/mantis/mantis_vp3028.c b/drivers/media/pci/mantis/mantis_vp3028.c deleted file mode 100644 index 4155c838a18a..000000000000 --- a/drivers/media/pci/mantis/mantis_vp3028.c +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@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 | (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 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include "mantis_common.h" | ||
22 | #include "mantis_vp3028.h" | ||
23 | |||
24 | struct zl10353_config mantis_vp3028_config = { | ||
25 | .demod_address = 0x0f, | ||
26 | }; | ||
27 | |||
28 | #define MANTIS_MODEL_NAME "VP-3028" | ||
29 | #define MANTIS_DEV_TYPE "DVB-T" | ||
30 | |||
31 | struct mantis_hwconfig vp3028_mantis_config = { | ||
32 | .model_name = MANTIS_MODEL_NAME, | ||
33 | .dev_type = MANTIS_DEV_TYPE, | ||
34 | .ts_size = MANTIS_TS_188, | ||
35 | .baud_rate = MANTIS_BAUD_9600, | ||
36 | .parity = MANTIS_PARITY_NONE, | ||
37 | .bytes = 0, | ||
38 | }; | ||
diff --git a/drivers/media/pci/mantis/mantis_vp3028.h b/drivers/media/pci/mantis/mantis_vp3028.h deleted file mode 100644 index 34130d29e0aa..000000000000 --- a/drivers/media/pci/mantis/mantis_vp3028.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | Mantis VP-3028 driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@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 | (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 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __MANTIS_VP3028_H | ||
22 | #define __MANTIS_VP3028_H | ||
23 | |||
24 | #include <media/dvb_frontend.h> | ||
25 | #include "mantis_common.h" | ||
26 | #include "zl10353.h" | ||
27 | |||
28 | #define MANTIS_VP_3028_DVB_T 0x0028 | ||
29 | |||
30 | extern struct zl10353_config mantis_vp3028_config; | ||
31 | extern struct mantis_hwconfig vp3028_mantis_config; | ||
32 | |||
33 | #endif /* __MANTIS_VP3028_H */ | ||
diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig index 637d506b23c5..e06d019996f3 100644 --- a/drivers/media/pci/ngene/Kconfig +++ b/drivers/media/pci/ngene/Kconfig | |||
@@ -8,6 +8,13 @@ config DVB_NGENE | |||
8 | select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT | 8 | select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT |
9 | select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT | 9 | select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT |
10 | select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT | 10 | select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT |
11 | select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT | ||
12 | select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT | ||
13 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT | ||
14 | select DVB_STV0910 if MEDIA_SUBDRV_AUTOSELECT | ||
15 | select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT | ||
16 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT | ||
17 | select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT | ||
11 | ---help--- | 18 | ---help--- |
12 | Support for Micronas PCI express cards with nGene bridge. | 19 | Support for Micronas PCI express cards with nGene bridge. |
13 | 20 | ||
diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile index e4208f5ed215..ec450ad19281 100644 --- a/drivers/media/pci/ngene/Makefile +++ b/drivers/media/pci/ngene/Makefile | |||
@@ -9,6 +9,3 @@ obj-$(CONFIG_DVB_NGENE) += ngene.o | |||
9 | 9 | ||
10 | ccflags-y += -Idrivers/media/dvb-frontends/ | 10 | ccflags-y += -Idrivers/media/dvb-frontends/ |
11 | ccflags-y += -Idrivers/media/tuners/ | 11 | ccflags-y += -Idrivers/media/tuners/ |
12 | |||
13 | # For the staging CI driver cxd2099 | ||
14 | ccflags-y += -Idrivers/staging/media/cxd2099/ | ||
diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c index bb49620540c5..65fc8f23ad86 100644 --- a/drivers/media/pci/ngene/ngene-cards.c +++ b/drivers/media/pci/ngene/ngene-cards.c | |||
@@ -23,6 +23,8 @@ | |||
23 | * http://www.gnu.org/copyleft/gpl.html | 23 | * http://www.gnu.org/copyleft/gpl.html |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
27 | |||
26 | #include <linux/module.h> | 28 | #include <linux/module.h> |
27 | #include <linux/init.h> | 29 | #include <linux/init.h> |
28 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
@@ -40,22 +42,101 @@ | |||
40 | #include "drxk.h" | 42 | #include "drxk.h" |
41 | #include "drxd.h" | 43 | #include "drxd.h" |
42 | #include "dvb-pll.h" | 44 | #include "dvb-pll.h" |
45 | #include "stv0367.h" | ||
46 | #include "stv0367_priv.h" | ||
47 | #include "tda18212.h" | ||
48 | #include "cxd2841er.h" | ||
49 | #include "stv0910.h" | ||
50 | #include "stv6111.h" | ||
51 | #include "lnbh25.h" | ||
52 | |||
53 | /****************************************************************************/ | ||
54 | /* I2C transfer functions used for demod/tuner probing***********************/ | ||
55 | /****************************************************************************/ | ||
56 | |||
57 | static int i2c_io(struct i2c_adapter *adapter, u8 adr, | ||
58 | u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) | ||
59 | { | ||
60 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
61 | .buf = wbuf, .len = wlen }, | ||
62 | {.addr = adr, .flags = I2C_M_RD, | ||
63 | .buf = rbuf, .len = rlen } }; | ||
64 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
65 | } | ||
66 | |||
67 | static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) | ||
68 | { | ||
69 | struct i2c_msg msg = {.addr = adr, .flags = 0, | ||
70 | .buf = data, .len = len}; | ||
71 | |||
72 | return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; | ||
73 | } | ||
74 | |||
75 | static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, | ||
76 | u8 reg, u8 val) | ||
77 | { | ||
78 | u8 msg[2] = {reg, val}; | ||
79 | |||
80 | return i2c_write(adap, adr, msg, 2); | ||
81 | } | ||
82 | |||
83 | static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) | ||
84 | { | ||
85 | struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, | ||
86 | .buf = val, .len = 1 } }; | ||
87 | return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; | ||
88 | } | ||
89 | |||
90 | static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, | ||
91 | u16 reg, u8 *val) | ||
92 | { | ||
93 | u8 msg[2] = {reg >> 8, reg & 0xff}; | ||
94 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
95 | .buf = msg, .len = 2}, | ||
96 | {.addr = adr, .flags = I2C_M_RD, | ||
97 | .buf = val, .len = 1} }; | ||
98 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
99 | } | ||
43 | 100 | ||
101 | static int i2c_read_regs(struct i2c_adapter *adapter, | ||
102 | u8 adr, u8 reg, u8 *val, u8 len) | ||
103 | { | ||
104 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
105 | .buf = ®, .len = 1}, | ||
106 | {.addr = adr, .flags = I2C_M_RD, | ||
107 | .buf = val, .len = len} }; | ||
108 | |||
109 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
110 | } | ||
111 | |||
112 | static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) | ||
113 | { | ||
114 | return i2c_read_regs(adapter, adr, reg, val, 1); | ||
115 | } | ||
44 | 116 | ||
45 | /****************************************************************************/ | 117 | /****************************************************************************/ |
46 | /* Demod/tuner attachment ***************************************************/ | 118 | /* Demod/tuner attachment ***************************************************/ |
47 | /****************************************************************************/ | 119 | /****************************************************************************/ |
48 | 120 | ||
121 | static struct i2c_adapter *i2c_adapter_from_chan(struct ngene_channel *chan) | ||
122 | { | ||
123 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | ||
124 | if (chan->number < 2) | ||
125 | return &chan->dev->channel[0].i2c_adapter; | ||
126 | |||
127 | return &chan->dev->channel[1].i2c_adapter; | ||
128 | } | ||
129 | |||
49 | static int tuner_attach_stv6110(struct ngene_channel *chan) | 130 | static int tuner_attach_stv6110(struct ngene_channel *chan) |
50 | { | 131 | { |
51 | struct i2c_adapter *i2c; | 132 | struct device *pdev = &chan->dev->pci_dev->dev; |
133 | struct i2c_adapter *i2c = i2c_adapter_from_chan(chan); | ||
52 | struct stv090x_config *feconf = (struct stv090x_config *) | 134 | struct stv090x_config *feconf = (struct stv090x_config *) |
53 | chan->dev->card_info->fe_config[chan->number]; | 135 | chan->dev->card_info->fe_config[chan->number]; |
54 | struct stv6110x_config *tunerconf = (struct stv6110x_config *) | 136 | struct stv6110x_config *tunerconf = (struct stv6110x_config *) |
55 | chan->dev->card_info->tuner_config[chan->number]; | 137 | chan->dev->card_info->tuner_config[chan->number]; |
56 | const struct stv6110x_devctl *ctl; | 138 | const struct stv6110x_devctl *ctl; |
57 | 139 | ||
58 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | ||
59 | if (chan->number < 2) | 140 | if (chan->number < 2) |
60 | i2c = &chan->dev->channel[0].i2c_adapter; | 141 | i2c = &chan->dev->channel[0].i2c_adapter; |
61 | else | 142 | else |
@@ -63,7 +144,7 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) | |||
63 | 144 | ||
64 | ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c); | 145 | ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c); |
65 | if (ctl == NULL) { | 146 | if (ctl == NULL) { |
66 | printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); | 147 | dev_err(pdev, "No STV6110X found!\n"); |
67 | return -ENODEV; | 148 | return -ENODEV; |
68 | } | 149 | } |
69 | 150 | ||
@@ -82,6 +163,23 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) | |||
82 | return 0; | 163 | return 0; |
83 | } | 164 | } |
84 | 165 | ||
166 | static int tuner_attach_stv6111(struct ngene_channel *chan) | ||
167 | { | ||
168 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
169 | struct i2c_adapter *i2c = i2c_adapter_from_chan(chan); | ||
170 | struct dvb_frontend *fe; | ||
171 | u8 adr = 4 + ((chan->number & 1) ? 0x63 : 0x60); | ||
172 | |||
173 | fe = dvb_attach(stv6111_attach, chan->fe, i2c, adr); | ||
174 | if (!fe) { | ||
175 | fe = dvb_attach(stv6111_attach, chan->fe, i2c, adr & ~4); | ||
176 | if (!fe) { | ||
177 | dev_err(pdev, "stv6111_attach() failed!\n"); | ||
178 | return -ENODEV; | ||
179 | } | ||
180 | } | ||
181 | return 0; | ||
182 | } | ||
85 | 183 | ||
86 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | 184 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) |
87 | { | 185 | { |
@@ -100,35 +198,109 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
100 | 198 | ||
101 | static int tuner_attach_tda18271(struct ngene_channel *chan) | 199 | static int tuner_attach_tda18271(struct ngene_channel *chan) |
102 | { | 200 | { |
103 | struct i2c_adapter *i2c; | 201 | struct device *pdev = &chan->dev->pci_dev->dev; |
202 | struct i2c_adapter *i2c = i2c_adapter_from_chan(chan); | ||
104 | struct dvb_frontend *fe; | 203 | struct dvb_frontend *fe; |
105 | 204 | ||
106 | i2c = &chan->dev->channel[0].i2c_adapter; | ||
107 | if (chan->fe->ops.i2c_gate_ctrl) | 205 | if (chan->fe->ops.i2c_gate_ctrl) |
108 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 1); | 206 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 1); |
109 | fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60); | 207 | fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60); |
110 | if (chan->fe->ops.i2c_gate_ctrl) | 208 | if (chan->fe->ops.i2c_gate_ctrl) |
111 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 0); | 209 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 0); |
112 | if (!fe) { | 210 | if (!fe) { |
113 | printk(KERN_ERR "No TDA18271 found!\n"); | 211 | dev_err(pdev, "No TDA18271 found!\n"); |
114 | return -ENODEV; | 212 | return -ENODEV; |
115 | } | 213 | } |
116 | 214 | ||
117 | return 0; | 215 | return 0; |
118 | } | 216 | } |
119 | 217 | ||
218 | static int tuner_tda18212_ping(struct ngene_channel *chan, | ||
219 | struct i2c_adapter *i2c, | ||
220 | unsigned short adr) | ||
221 | { | ||
222 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
223 | u8 tda_id[2]; | ||
224 | u8 subaddr = 0x00; | ||
225 | |||
226 | dev_dbg(pdev, "stv0367-tda18212 tuner ping\n"); | ||
227 | if (chan->fe->ops.i2c_gate_ctrl) | ||
228 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 1); | ||
229 | |||
230 | if (i2c_read_regs(i2c, adr, subaddr, tda_id, sizeof(tda_id)) < 0) | ||
231 | dev_dbg(pdev, "tda18212 ping 1 fail\n"); | ||
232 | if (i2c_read_regs(i2c, adr, subaddr, tda_id, sizeof(tda_id)) < 0) | ||
233 | dev_warn(pdev, "tda18212 ping failed, expect problems\n"); | ||
234 | |||
235 | if (chan->fe->ops.i2c_gate_ctrl) | ||
236 | chan->fe->ops.i2c_gate_ctrl(chan->fe, 0); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int tuner_attach_tda18212(struct ngene_channel *chan, u32 dmdtype) | ||
242 | { | ||
243 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
244 | struct i2c_adapter *i2c = i2c_adapter_from_chan(chan); | ||
245 | struct i2c_client *client; | ||
246 | struct tda18212_config config = { | ||
247 | .fe = chan->fe, | ||
248 | .if_dvbt_6 = 3550, | ||
249 | .if_dvbt_7 = 3700, | ||
250 | .if_dvbt_8 = 4150, | ||
251 | .if_dvbt2_6 = 3250, | ||
252 | .if_dvbt2_7 = 4000, | ||
253 | .if_dvbt2_8 = 4000, | ||
254 | .if_dvbc = 5000, | ||
255 | }; | ||
256 | u8 addr = (chan->number & 1) ? 0x63 : 0x60; | ||
257 | |||
258 | /* | ||
259 | * due to a hardware quirk with the I2C gate on the stv0367+tda18212 | ||
260 | * combo, the tda18212 must be probed by reading it's id _twice_ when | ||
261 | * cold started, or it very likely will fail. | ||
262 | */ | ||
263 | if (dmdtype == DEMOD_TYPE_STV0367) | ||
264 | tuner_tda18212_ping(chan, i2c, addr); | ||
265 | |||
266 | /* perform tuner probe/init/attach */ | ||
267 | client = dvb_module_probe("tda18212", NULL, i2c, addr, &config); | ||
268 | if (!client) | ||
269 | goto err; | ||
270 | |||
271 | chan->i2c_client[0] = client; | ||
272 | chan->i2c_client_fe = 1; | ||
273 | |||
274 | return 0; | ||
275 | err: | ||
276 | dev_err(pdev, "TDA18212 tuner not found. Device is not fully operational.\n"); | ||
277 | return -ENODEV; | ||
278 | } | ||
279 | |||
120 | static int tuner_attach_probe(struct ngene_channel *chan) | 280 | static int tuner_attach_probe(struct ngene_channel *chan) |
121 | { | 281 | { |
122 | if (chan->demod_type == 0) | 282 | switch (chan->demod_type) { |
283 | case DEMOD_TYPE_STV090X: | ||
123 | return tuner_attach_stv6110(chan); | 284 | return tuner_attach_stv6110(chan); |
124 | if (chan->demod_type == 1) | 285 | case DEMOD_TYPE_DRXK: |
125 | return tuner_attach_tda18271(chan); | 286 | return tuner_attach_tda18271(chan); |
287 | case DEMOD_TYPE_STV0367: | ||
288 | case DEMOD_TYPE_SONY_CT2: | ||
289 | case DEMOD_TYPE_SONY_ISDBT: | ||
290 | case DEMOD_TYPE_SONY_C2T2: | ||
291 | case DEMOD_TYPE_SONY_C2T2I: | ||
292 | return tuner_attach_tda18212(chan, chan->demod_type); | ||
293 | case DEMOD_TYPE_STV0910: | ||
294 | return tuner_attach_stv6111(chan); | ||
295 | } | ||
296 | |||
126 | return -EINVAL; | 297 | return -EINVAL; |
127 | } | 298 | } |
128 | 299 | ||
129 | static int demod_attach_stv0900(struct ngene_channel *chan) | 300 | static int demod_attach_stv0900(struct ngene_channel *chan) |
130 | { | 301 | { |
131 | struct i2c_adapter *i2c; | 302 | struct device *pdev = &chan->dev->pci_dev->dev; |
303 | struct i2c_adapter *i2c = i2c_adapter_from_chan(chan); | ||
132 | struct stv090x_config *feconf = (struct stv090x_config *) | 304 | struct stv090x_config *feconf = (struct stv090x_config *) |
133 | chan->dev->card_info->fe_config[chan->number]; | 305 | chan->dev->card_info->fe_config[chan->number]; |
134 | 306 | ||
@@ -144,7 +316,7 @@ static int demod_attach_stv0900(struct ngene_channel *chan) | |||
144 | (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0 | 316 | (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0 |
145 | : STV090x_DEMODULATOR_1); | 317 | : STV090x_DEMODULATOR_1); |
146 | if (chan->fe == NULL) { | 318 | if (chan->fe == NULL) { |
147 | printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); | 319 | dev_err(pdev, "No STV0900 found!\n"); |
148 | return -ENODEV; | 320 | return -ENODEV; |
149 | } | 321 | } |
150 | 322 | ||
@@ -154,7 +326,7 @@ static int demod_attach_stv0900(struct ngene_channel *chan) | |||
154 | 326 | ||
155 | if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0, | 327 | if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0, |
156 | 0, chan->dev->card_info->lnb[chan->number])) { | 328 | 0, chan->dev->card_info->lnb[chan->number])) { |
157 | printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); | 329 | dev_err(pdev, "No LNBH24 found!\n"); |
158 | dvb_frontend_detach(chan->fe); | 330 | dvb_frontend_detach(chan->fe); |
159 | chan->fe = NULL; | 331 | chan->fe = NULL; |
160 | return -ENODEV; | 332 | return -ENODEV; |
@@ -163,6 +335,119 @@ static int demod_attach_stv0900(struct ngene_channel *chan) | |||
163 | return 0; | 335 | return 0; |
164 | } | 336 | } |
165 | 337 | ||
338 | static struct stv0910_cfg stv0910_p = { | ||
339 | .adr = 0x68, | ||
340 | .parallel = 1, | ||
341 | .rptlvl = 4, | ||
342 | .clk = 30000000, | ||
343 | }; | ||
344 | |||
345 | static struct lnbh25_config lnbh25_cfg = { | ||
346 | .i2c_address = 0x0c << 1, | ||
347 | .data2_config = LNBH25_TEN | ||
348 | }; | ||
349 | |||
350 | static int demod_attach_stv0910(struct ngene_channel *chan, | ||
351 | struct i2c_adapter *i2c) | ||
352 | { | ||
353 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
354 | struct stv0910_cfg cfg = stv0910_p; | ||
355 | struct lnbh25_config lnbcfg = lnbh25_cfg; | ||
356 | |||
357 | chan->fe = dvb_attach(stv0910_attach, i2c, &cfg, (chan->number & 1)); | ||
358 | if (!chan->fe) { | ||
359 | cfg.adr = 0x6c; | ||
360 | chan->fe = dvb_attach(stv0910_attach, i2c, | ||
361 | &cfg, (chan->number & 1)); | ||
362 | } | ||
363 | if (!chan->fe) { | ||
364 | dev_err(pdev, "stv0910_attach() failed!\n"); | ||
365 | return -ENODEV; | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * attach lnbh25 - leftshift by one as the lnbh25 driver expects 8bit | ||
370 | * i2c addresses | ||
371 | */ | ||
372 | lnbcfg.i2c_address = (((chan->number & 1) ? 0x0d : 0x0c) << 1); | ||
373 | if (!dvb_attach(lnbh25_attach, chan->fe, &lnbcfg, i2c)) { | ||
374 | lnbcfg.i2c_address = (((chan->number & 1) ? 0x09 : 0x08) << 1); | ||
375 | if (!dvb_attach(lnbh25_attach, chan->fe, &lnbcfg, i2c)) { | ||
376 | dev_err(pdev, "lnbh25_attach() failed!\n"); | ||
377 | dvb_frontend_detach(chan->fe); | ||
378 | chan->fe = NULL; | ||
379 | return -ENODEV; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static struct stv0367_config ddb_stv0367_config[] = { | ||
387 | { | ||
388 | .demod_address = 0x1f, | ||
389 | .xtal = 27000000, | ||
390 | .if_khz = 0, | ||
391 | .if_iq_mode = FE_TER_NORMAL_IF_TUNER, | ||
392 | .ts_mode = STV0367_SERIAL_PUNCT_CLOCK, | ||
393 | .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT, | ||
394 | }, { | ||
395 | .demod_address = 0x1e, | ||
396 | .xtal = 27000000, | ||
397 | .if_khz = 0, | ||
398 | .if_iq_mode = FE_TER_NORMAL_IF_TUNER, | ||
399 | .ts_mode = STV0367_SERIAL_PUNCT_CLOCK, | ||
400 | .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT, | ||
401 | }, | ||
402 | }; | ||
403 | |||
404 | static int demod_attach_stv0367(struct ngene_channel *chan, | ||
405 | struct i2c_adapter *i2c) | ||
406 | { | ||
407 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
408 | |||
409 | chan->fe = dvb_attach(stv0367ddb_attach, | ||
410 | &ddb_stv0367_config[(chan->number & 1)], i2c); | ||
411 | |||
412 | if (!chan->fe) { | ||
413 | dev_err(pdev, "stv0367ddb_attach() failed!\n"); | ||
414 | return -ENODEV; | ||
415 | } | ||
416 | |||
417 | chan->fe->sec_priv = chan; | ||
418 | chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; | ||
419 | chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int demod_attach_cxd28xx(struct ngene_channel *chan, | ||
424 | struct i2c_adapter *i2c, int osc24) | ||
425 | { | ||
426 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
427 | struct cxd2841er_config cfg; | ||
428 | |||
429 | /* the cxd2841er driver expects 8bit/shifted I2C addresses */ | ||
430 | cfg.i2c_addr = ((chan->number & 1) ? 0x6d : 0x6c) << 1; | ||
431 | |||
432 | cfg.xtal = osc24 ? SONY_XTAL_24000 : SONY_XTAL_20500; | ||
433 | cfg.flags = CXD2841ER_AUTO_IFHZ | CXD2841ER_EARLY_TUNE | | ||
434 | CXD2841ER_NO_WAIT_LOCK | CXD2841ER_NO_AGCNEG | | ||
435 | CXD2841ER_TSBITS | CXD2841ER_TS_SERIAL; | ||
436 | |||
437 | /* attach frontend */ | ||
438 | chan->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c); | ||
439 | |||
440 | if (!chan->fe) { | ||
441 | dev_err(pdev, "CXD28XX attach failed!\n"); | ||
442 | return -ENODEV; | ||
443 | } | ||
444 | |||
445 | chan->fe->sec_priv = chan; | ||
446 | chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; | ||
447 | chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
448 | return 0; | ||
449 | } | ||
450 | |||
166 | static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock) | 451 | static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock) |
167 | { | 452 | { |
168 | struct ngene_channel *chan = fe->analog_demod_priv; | 453 | struct ngene_channel *chan = fe->analog_demod_priv; |
@@ -173,44 +458,61 @@ static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock) | |||
173 | up(&chan->dev->pll_mutex); | 458 | up(&chan->dev->pll_mutex); |
174 | } | 459 | } |
175 | 460 | ||
176 | static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) | 461 | static int port_has_stv0900(struct i2c_adapter *i2c, int port) |
177 | { | 462 | { |
178 | struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, | 463 | u8 val; |
179 | .buf = val, .len = 1 } }; | 464 | if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0) |
180 | return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; | 465 | return 0; |
466 | return 1; | ||
181 | } | 467 | } |
182 | 468 | ||
183 | static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, | 469 | static int port_has_drxk(struct i2c_adapter *i2c, int port) |
184 | u16 reg, u8 *val) | ||
185 | { | 470 | { |
186 | u8 msg[2] = {reg>>8, reg&0xff}; | 471 | u8 val; |
187 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | 472 | |
188 | .buf = msg, .len = 2}, | 473 | if (i2c_read(i2c, 0x29+port, &val) < 0) |
189 | {.addr = adr, .flags = I2C_M_RD, | 474 | return 0; |
190 | .buf = val, .len = 1} }; | 475 | return 1; |
191 | return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||
192 | } | 476 | } |
193 | 477 | ||
194 | static int port_has_stv0900(struct i2c_adapter *i2c, int port) | 478 | static int port_has_stv0367(struct i2c_adapter *i2c) |
195 | { | 479 | { |
196 | u8 val; | 480 | u8 val; |
197 | if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0) | 481 | |
482 | if (i2c_read_reg16(i2c, 0x1e, 0xf000, &val) < 0) | ||
483 | return 0; | ||
484 | if (val != 0x60) | ||
485 | return 0; | ||
486 | if (i2c_read_reg16(i2c, 0x1f, 0xf000, &val) < 0) | ||
487 | return 0; | ||
488 | if (val != 0x60) | ||
198 | return 0; | 489 | return 0; |
199 | return 1; | 490 | return 1; |
200 | } | 491 | } |
201 | 492 | ||
202 | static int port_has_drxk(struct i2c_adapter *i2c, int port) | 493 | int ngene_port_has_cxd2099(struct i2c_adapter *i2c, u8 *type) |
203 | { | 494 | { |
204 | u8 val; | 495 | u8 val; |
205 | 496 | u8 probe[4] = { 0xe0, 0x00, 0x00, 0x00 }, data[4]; | |
206 | if (i2c_read(i2c, 0x29+port, &val) < 0) | 497 | struct i2c_msg msgs[2] = {{ .addr = 0x40, .flags = 0, |
498 | .buf = probe, .len = 4 }, | ||
499 | { .addr = 0x40, .flags = I2C_M_RD, | ||
500 | .buf = data, .len = 4 } }; | ||
501 | val = i2c_transfer(i2c, msgs, 2); | ||
502 | if (val != 2) | ||
207 | return 0; | 503 | return 0; |
504 | |||
505 | if (data[0] == 0x02 && data[1] == 0x2b && data[3] == 0x43) | ||
506 | *type = 2; | ||
507 | else | ||
508 | *type = 1; | ||
208 | return 1; | 509 | return 1; |
209 | } | 510 | } |
210 | 511 | ||
211 | static int demod_attach_drxk(struct ngene_channel *chan, | 512 | static int demod_attach_drxk(struct ngene_channel *chan, |
212 | struct i2c_adapter *i2c) | 513 | struct i2c_adapter *i2c) |
213 | { | 514 | { |
515 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
214 | struct drxk_config config; | 516 | struct drxk_config config; |
215 | 517 | ||
216 | memset(&config, 0, sizeof(config)); | 518 | memset(&config, 0, sizeof(config)); |
@@ -220,7 +522,7 @@ static int demod_attach_drxk(struct ngene_channel *chan, | |||
220 | 522 | ||
221 | chan->fe = dvb_attach(drxk_attach, &config, i2c); | 523 | chan->fe = dvb_attach(drxk_attach, &config, i2c); |
222 | if (!chan->fe) { | 524 | if (!chan->fe) { |
223 | printk(KERN_ERR "No DRXK found!\n"); | 525 | dev_err(pdev, "No DRXK found!\n"); |
224 | return -ENODEV; | 526 | return -ENODEV; |
225 | } | 527 | } |
226 | chan->fe->sec_priv = chan; | 528 | chan->fe->sec_priv = chan; |
@@ -229,22 +531,153 @@ static int demod_attach_drxk(struct ngene_channel *chan, | |||
229 | return 0; | 531 | return 0; |
230 | } | 532 | } |
231 | 533 | ||
534 | /****************************************************************************/ | ||
535 | /* XO2 related lists and functions ******************************************/ | ||
536 | /****************************************************************************/ | ||
537 | |||
538 | static char *xo2names[] = { | ||
539 | "DUAL DVB-S2", | ||
540 | "DUAL DVB-C/T/T2", | ||
541 | "DUAL DVB-ISDBT", | ||
542 | "DUAL DVB-C/C2/T/T2", | ||
543 | "DUAL ATSC", | ||
544 | "DUAL DVB-C/C2/T/T2/I", | ||
545 | }; | ||
546 | |||
547 | static int init_xo2(struct ngene_channel *chan, struct i2c_adapter *i2c) | ||
548 | { | ||
549 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
550 | u8 addr = 0x10; | ||
551 | u8 val, data[2]; | ||
552 | int res; | ||
553 | |||
554 | res = i2c_read_regs(i2c, addr, 0x04, data, 2); | ||
555 | if (res < 0) | ||
556 | return res; | ||
557 | |||
558 | if (data[0] != 0x01) { | ||
559 | dev_info(pdev, "Invalid XO2 on channel %d\n", chan->number); | ||
560 | return -1; | ||
561 | } | ||
562 | |||
563 | i2c_read_reg(i2c, addr, 0x08, &val); | ||
564 | if (val != 0) { | ||
565 | i2c_write_reg(i2c, addr, 0x08, 0x00); | ||
566 | msleep(100); | ||
567 | } | ||
568 | /* Enable tuner power, disable pll, reset demods */ | ||
569 | i2c_write_reg(i2c, addr, 0x08, 0x04); | ||
570 | usleep_range(2000, 3000); | ||
571 | /* Release demod resets */ | ||
572 | i2c_write_reg(i2c, addr, 0x08, 0x07); | ||
573 | |||
574 | /* | ||
575 | * speed: 0=55,1=75,2=90,3=104 MBit/s | ||
576 | * Note: The ngene hardware must be run at 75 MBit/s compared | ||
577 | * to more modern ddbridge hardware which runs at 90 MBit/s, | ||
578 | * else there will be issues with the data transport and non- | ||
579 | * working secondary/slave demods/tuners. | ||
580 | */ | ||
581 | i2c_write_reg(i2c, addr, 0x09, 1); | ||
582 | |||
583 | i2c_write_reg(i2c, addr, 0x0a, 0x01); | ||
584 | i2c_write_reg(i2c, addr, 0x0b, 0x01); | ||
585 | |||
586 | usleep_range(2000, 3000); | ||
587 | /* Start XO2 PLL */ | ||
588 | i2c_write_reg(i2c, addr, 0x08, 0x87); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static int port_has_xo2(struct i2c_adapter *i2c, u8 *type, u8 *id) | ||
594 | { | ||
595 | u8 probe[1] = { 0x00 }, data[4]; | ||
596 | u8 addr = 0x10; | ||
597 | |||
598 | *type = NGENE_XO2_TYPE_NONE; | ||
599 | |||
600 | if (i2c_io(i2c, addr, probe, 1, data, 4)) | ||
601 | return 0; | ||
602 | if (data[0] == 'D' && data[1] == 'F') { | ||
603 | *id = data[2]; | ||
604 | *type = NGENE_XO2_TYPE_DUOFLEX; | ||
605 | return 1; | ||
606 | } | ||
607 | if (data[0] == 'C' && data[1] == 'I') { | ||
608 | *id = data[2]; | ||
609 | *type = NGENE_XO2_TYPE_CI; | ||
610 | return 1; | ||
611 | } | ||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | /****************************************************************************/ | ||
616 | /* Probing and port/channel handling ****************************************/ | ||
617 | /****************************************************************************/ | ||
618 | |||
232 | static int cineS2_probe(struct ngene_channel *chan) | 619 | static int cineS2_probe(struct ngene_channel *chan) |
233 | { | 620 | { |
234 | struct i2c_adapter *i2c; | 621 | struct device *pdev = &chan->dev->pci_dev->dev; |
622 | struct i2c_adapter *i2c = i2c_adapter_from_chan(chan); | ||
235 | struct stv090x_config *fe_conf; | 623 | struct stv090x_config *fe_conf; |
236 | u8 buf[3]; | 624 | u8 buf[3]; |
625 | u8 xo2_type, xo2_id, xo2_demodtype; | ||
626 | u8 sony_osc24 = 0; | ||
237 | struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; | 627 | struct i2c_msg i2c_msg = { .flags = 0, .buf = buf }; |
238 | int rc; | 628 | int rc; |
239 | 629 | ||
240 | /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */ | 630 | if (port_has_xo2(i2c, &xo2_type, &xo2_id)) { |
241 | if (chan->number < 2) | 631 | xo2_id >>= 2; |
242 | i2c = &chan->dev->channel[0].i2c_adapter; | 632 | dev_dbg(pdev, "XO2 on channel %d (type %d, id %d)\n", |
243 | else | 633 | chan->number, xo2_type, xo2_id); |
244 | i2c = &chan->dev->channel[1].i2c_adapter; | 634 | |
245 | 635 | switch (xo2_type) { | |
246 | if (port_has_stv0900(i2c, chan->number)) { | 636 | case NGENE_XO2_TYPE_DUOFLEX: |
247 | chan->demod_type = 0; | 637 | if (chan->number & 1) |
638 | dev_dbg(pdev, | ||
639 | "skipping XO2 init on odd channel %d", | ||
640 | chan->number); | ||
641 | else | ||
642 | init_xo2(chan, i2c); | ||
643 | |||
644 | xo2_demodtype = DEMOD_TYPE_XO2 + xo2_id; | ||
645 | |||
646 | switch (xo2_demodtype) { | ||
647 | case DEMOD_TYPE_SONY_CT2: | ||
648 | case DEMOD_TYPE_SONY_ISDBT: | ||
649 | case DEMOD_TYPE_SONY_C2T2: | ||
650 | case DEMOD_TYPE_SONY_C2T2I: | ||
651 | dev_info(pdev, "%s (XO2) on channel %d\n", | ||
652 | xo2names[xo2_id], chan->number); | ||
653 | chan->demod_type = xo2_demodtype; | ||
654 | if (xo2_demodtype == DEMOD_TYPE_SONY_C2T2I) | ||
655 | sony_osc24 = 1; | ||
656 | |||
657 | demod_attach_cxd28xx(chan, i2c, sony_osc24); | ||
658 | break; | ||
659 | case DEMOD_TYPE_STV0910: | ||
660 | dev_info(pdev, "%s (XO2) on channel %d\n", | ||
661 | xo2names[xo2_id], chan->number); | ||
662 | chan->demod_type = xo2_demodtype; | ||
663 | demod_attach_stv0910(chan, i2c); | ||
664 | break; | ||
665 | default: | ||
666 | dev_warn(pdev, | ||
667 | "Unsupported XO2 module on channel %d\n", | ||
668 | chan->number); | ||
669 | return -ENODEV; | ||
670 | } | ||
671 | break; | ||
672 | case NGENE_XO2_TYPE_CI: | ||
673 | dev_info(pdev, "DuoFlex CI modules not supported\n"); | ||
674 | return -ENODEV; | ||
675 | default: | ||
676 | dev_info(pdev, "Unsupported XO2 module type\n"); | ||
677 | return -ENODEV; | ||
678 | } | ||
679 | } else if (port_has_stv0900(i2c, chan->number)) { | ||
680 | chan->demod_type = DEMOD_TYPE_STV090X; | ||
248 | fe_conf = chan->dev->card_info->fe_config[chan->number]; | 681 | fe_conf = chan->dev->card_info->fe_config[chan->number]; |
249 | /* demod found, attach it */ | 682 | /* demod found, attach it */ |
250 | rc = demod_attach_stv0900(chan); | 683 | rc = demod_attach_stv0900(chan); |
@@ -269,14 +702,18 @@ static int cineS2_probe(struct ngene_channel *chan) | |||
269 | } | 702 | } |
270 | rc = i2c_transfer(i2c, &i2c_msg, 1); | 703 | rc = i2c_transfer(i2c, &i2c_msg, 1); |
271 | if (rc != 1) { | 704 | if (rc != 1) { |
272 | printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); | 705 | dev_err(pdev, "Could not setup DPNx\n"); |
273 | return -EIO; | 706 | return -EIO; |
274 | } | 707 | } |
275 | } else if (port_has_drxk(i2c, chan->number^2)) { | 708 | } else if (port_has_drxk(i2c, chan->number^2)) { |
276 | chan->demod_type = 1; | 709 | chan->demod_type = DEMOD_TYPE_DRXK; |
277 | demod_attach_drxk(chan, i2c); | 710 | demod_attach_drxk(chan, i2c); |
711 | } else if (port_has_stv0367(i2c)) { | ||
712 | chan->demod_type = DEMOD_TYPE_STV0367; | ||
713 | dev_info(pdev, "STV0367 on channel %d\n", chan->number); | ||
714 | demod_attach_stv0367(chan, i2c); | ||
278 | } else { | 715 | } else { |
279 | printk(KERN_ERR "No demod found on chan %d\n", chan->number); | 716 | dev_info(pdev, "No demod found on chan %d\n", chan->number); |
280 | return -ENODEV; | 717 | return -ENODEV; |
281 | } | 718 | } |
282 | return 0; | 719 | return 0; |
@@ -299,9 +736,11 @@ static struct mt2131_config m780_tunerconfig = { | |||
299 | */ | 736 | */ |
300 | static int demod_attach_lg330x(struct ngene_channel *chan) | 737 | static int demod_attach_lg330x(struct ngene_channel *chan) |
301 | { | 738 | { |
739 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
740 | |||
302 | chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter); | 741 | chan->fe = dvb_attach(lgdt330x_attach, &aver_m780, &chan->i2c_adapter); |
303 | if (chan->fe == NULL) { | 742 | if (chan->fe == NULL) { |
304 | printk(KERN_ERR DEVICE_NAME ": No LGDT330x found!\n"); | 743 | dev_err(pdev, "No LGDT330x found!\n"); |
305 | return -ENODEV; | 744 | return -ENODEV; |
306 | } | 745 | } |
307 | 746 | ||
@@ -313,6 +752,7 @@ static int demod_attach_lg330x(struct ngene_channel *chan) | |||
313 | 752 | ||
314 | static int demod_attach_drxd(struct ngene_channel *chan) | 753 | static int demod_attach_drxd(struct ngene_channel *chan) |
315 | { | 754 | { |
755 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
316 | struct drxd_config *feconf; | 756 | struct drxd_config *feconf; |
317 | 757 | ||
318 | feconf = chan->dev->card_info->fe_config[chan->number]; | 758 | feconf = chan->dev->card_info->fe_config[chan->number]; |
@@ -320,7 +760,7 @@ static int demod_attach_drxd(struct ngene_channel *chan) | |||
320 | chan->fe = dvb_attach(drxd_attach, feconf, chan, | 760 | chan->fe = dvb_attach(drxd_attach, feconf, chan, |
321 | &chan->i2c_adapter, &chan->dev->pci_dev->dev); | 761 | &chan->i2c_adapter, &chan->dev->pci_dev->dev); |
322 | if (!chan->fe) { | 762 | if (!chan->fe) { |
323 | pr_err("No DRXD found!\n"); | 763 | dev_err(pdev, "No DRXD found!\n"); |
324 | return -ENODEV; | 764 | return -ENODEV; |
325 | } | 765 | } |
326 | return 0; | 766 | return 0; |
@@ -328,6 +768,7 @@ static int demod_attach_drxd(struct ngene_channel *chan) | |||
328 | 768 | ||
329 | static int tuner_attach_dtt7520x(struct ngene_channel *chan) | 769 | static int tuner_attach_dtt7520x(struct ngene_channel *chan) |
330 | { | 770 | { |
771 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
331 | struct drxd_config *feconf; | 772 | struct drxd_config *feconf; |
332 | 773 | ||
333 | feconf = chan->dev->card_info->fe_config[chan->number]; | 774 | feconf = chan->dev->card_info->fe_config[chan->number]; |
@@ -335,7 +776,7 @@ static int tuner_attach_dtt7520x(struct ngene_channel *chan) | |||
335 | if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address, | 776 | if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address, |
336 | &chan->i2c_adapter, | 777 | &chan->i2c_adapter, |
337 | feconf->pll_type)) { | 778 | feconf->pll_type)) { |
338 | pr_err("No pll(%d) found!\n", feconf->pll_type); | 779 | dev_err(pdev, "No pll(%d) found!\n", feconf->pll_type); |
339 | return -ENODEV; | 780 | return -ENODEV; |
340 | } | 781 | } |
341 | return 0; | 782 | return 0; |
@@ -371,12 +812,13 @@ static int tuner_attach_dtt7520x(struct ngene_channel *chan) | |||
371 | static int i2c_write_eeprom(struct i2c_adapter *adapter, | 812 | static int i2c_write_eeprom(struct i2c_adapter *adapter, |
372 | u8 adr, u16 reg, u8 data) | 813 | u8 adr, u16 reg, u8 data) |
373 | { | 814 | { |
815 | struct device *pdev = adapter->dev.parent; | ||
374 | u8 m[3] = {(reg >> 8), (reg & 0xff), data}; | 816 | u8 m[3] = {(reg >> 8), (reg & 0xff), data}; |
375 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, | 817 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, |
376 | .len = sizeof(m)}; | 818 | .len = sizeof(m)}; |
377 | 819 | ||
378 | if (i2c_transfer(adapter, &msg, 1) != 1) { | 820 | if (i2c_transfer(adapter, &msg, 1) != 1) { |
379 | pr_err(DEVICE_NAME ": Error writing EEPROM!\n"); | 821 | dev_err(pdev, "Error writing EEPROM!\n"); |
380 | return -EIO; | 822 | return -EIO; |
381 | } | 823 | } |
382 | return 0; | 824 | return 0; |
@@ -385,6 +827,7 @@ static int i2c_write_eeprom(struct i2c_adapter *adapter, | |||
385 | static int i2c_read_eeprom(struct i2c_adapter *adapter, | 827 | static int i2c_read_eeprom(struct i2c_adapter *adapter, |
386 | u8 adr, u16 reg, u8 *data, int len) | 828 | u8 adr, u16 reg, u8 *data, int len) |
387 | { | 829 | { |
830 | struct device *pdev = adapter->dev.parent; | ||
388 | u8 msg[2] = {(reg >> 8), (reg & 0xff)}; | 831 | u8 msg[2] = {(reg >> 8), (reg & 0xff)}; |
389 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | 832 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, |
390 | .buf = msg, .len = 2 }, | 833 | .buf = msg, .len = 2 }, |
@@ -392,7 +835,7 @@ static int i2c_read_eeprom(struct i2c_adapter *adapter, | |||
392 | .buf = data, .len = len} }; | 835 | .buf = data, .len = len} }; |
393 | 836 | ||
394 | if (i2c_transfer(adapter, msgs, 2) != 2) { | 837 | if (i2c_transfer(adapter, msgs, 2) != 2) { |
395 | pr_err(DEVICE_NAME ": Error reading EEPROM\n"); | 838 | dev_err(pdev, "Error reading EEPROM\n"); |
396 | return -EIO; | 839 | return -EIO; |
397 | } | 840 | } |
398 | return 0; | 841 | return 0; |
@@ -401,6 +844,7 @@ static int i2c_read_eeprom(struct i2c_adapter *adapter, | |||
401 | static int ReadEEProm(struct i2c_adapter *adapter, | 844 | static int ReadEEProm(struct i2c_adapter *adapter, |
402 | u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) | 845 | u16 Tag, u32 MaxLen, u8 *data, u32 *pLength) |
403 | { | 846 | { |
847 | struct device *pdev = adapter->dev.parent; | ||
404 | int status = 0; | 848 | int status = 0; |
405 | u16 Addr = MICNG_EE_START, Length, tag = 0; | 849 | u16 Addr = MICNG_EE_START, Length, tag = 0; |
406 | u8 EETag[3]; | 850 | u8 EETag[3]; |
@@ -416,9 +860,8 @@ static int ReadEEProm(struct i2c_adapter *adapter, | |||
416 | Addr += sizeof(u16) + 1 + EETag[2]; | 860 | Addr += sizeof(u16) + 1 + EETag[2]; |
417 | } | 861 | } |
418 | if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { | 862 | if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { |
419 | pr_err(DEVICE_NAME | 863 | dev_err(pdev, "Reached EOEE @ Tag = %04x Length = %3d\n", |
420 | ": Reached EOEE @ Tag = %04x Length = %3d\n", | 864 | tag, EETag[2]); |
421 | tag, EETag[2]); | ||
422 | return -1; | 865 | return -1; |
423 | } | 866 | } |
424 | Length = EETag[2]; | 867 | Length = EETag[2]; |
@@ -441,6 +884,7 @@ static int ReadEEProm(struct i2c_adapter *adapter, | |||
441 | static int WriteEEProm(struct i2c_adapter *adapter, | 884 | static int WriteEEProm(struct i2c_adapter *adapter, |
442 | u16 Tag, u32 Length, u8 *data) | 885 | u16 Tag, u32 Length, u8 *data) |
443 | { | 886 | { |
887 | struct device *pdev = adapter->dev.parent; | ||
444 | int status = 0; | 888 | int status = 0; |
445 | u16 Addr = MICNG_EE_START; | 889 | u16 Addr = MICNG_EE_START; |
446 | u8 EETag[3]; | 890 | u8 EETag[3]; |
@@ -458,9 +902,8 @@ static int WriteEEProm(struct i2c_adapter *adapter, | |||
458 | Addr += sizeof(u16) + 1 + EETag[2]; | 902 | Addr += sizeof(u16) + 1 + EETag[2]; |
459 | } | 903 | } |
460 | if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { | 904 | if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) { |
461 | pr_err(DEVICE_NAME | 905 | dev_err(pdev, "Reached EOEE @ Tag = %04x Length = %3d\n", |
462 | ": Reached EOEE @ Tag = %04x Length = %3d\n", | 906 | tag, EETag[2]); |
463 | tag, EETag[2]); | ||
464 | return -1; | 907 | return -1; |
465 | } | 908 | } |
466 | 909 | ||
@@ -487,13 +930,11 @@ static int WriteEEProm(struct i2c_adapter *adapter, | |||
487 | if (status) | 930 | if (status) |
488 | break; | 931 | break; |
489 | if (Tmp != data[i]) | 932 | if (Tmp != data[i]) |
490 | pr_err(DEVICE_NAME | 933 | dev_err(pdev, "eeprom write error\n"); |
491 | "eeprom write error\n"); | ||
492 | retry -= 1; | 934 | retry -= 1; |
493 | } | 935 | } |
494 | if (status) { | 936 | if (status) { |
495 | pr_err(DEVICE_NAME | 937 | dev_err(pdev, "Timeout polling eeprom\n"); |
496 | ": Timeout polling eeprom\n"); | ||
497 | break; | 938 | break; |
498 | } | 939 | } |
499 | } | 940 | } |
@@ -532,19 +973,20 @@ static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data) | |||
532 | static s16 osc_deviation(void *priv, s16 deviation, int flag) | 973 | static s16 osc_deviation(void *priv, s16 deviation, int flag) |
533 | { | 974 | { |
534 | struct ngene_channel *chan = priv; | 975 | struct ngene_channel *chan = priv; |
976 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
535 | struct i2c_adapter *adap = &chan->i2c_adapter; | 977 | struct i2c_adapter *adap = &chan->i2c_adapter; |
536 | u16 data = 0; | 978 | u16 data = 0; |
537 | 979 | ||
538 | if (flag) { | 980 | if (flag) { |
539 | data = (u16) deviation; | 981 | data = (u16) deviation; |
540 | pr_info(DEVICE_NAME ": write deviation %d\n", | 982 | dev_info(pdev, "write deviation %d\n", |
541 | deviation); | 983 | deviation); |
542 | eeprom_write_ushort(adap, 0x1000 + chan->number, data); | 984 | eeprom_write_ushort(adap, 0x1000 + chan->number, data); |
543 | } else { | 985 | } else { |
544 | if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data)) | 986 | if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data)) |
545 | data = 0; | 987 | data = 0; |
546 | pr_info(DEVICE_NAME ": read deviation %d\n", | 988 | dev_info(pdev, "read deviation %d\n", |
547 | (s16) data); | 989 | (s16)data); |
548 | } | 990 | } |
549 | 991 | ||
550 | return (s16) data; | 992 | return (s16) data; |
@@ -749,6 +1191,8 @@ static const struct ngene_info ngene_info_terratec = { | |||
749 | /****************************************************************************/ | 1191 | /****************************************************************************/ |
750 | 1192 | ||
751 | static const struct pci_device_id ngene_id_tbl[] = { | 1193 | static const struct pci_device_id ngene_id_tbl[] = { |
1194 | NGENE_ID(0x18c3, 0xab04, ngene_info_cineS2), | ||
1195 | NGENE_ID(0x18c3, 0xab05, ngene_info_cineS2v5), | ||
752 | NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), | 1196 | NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), |
753 | NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), | 1197 | NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), |
754 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), | 1198 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), |
@@ -769,7 +1213,7 @@ MODULE_DEVICE_TABLE(pci, ngene_id_tbl); | |||
769 | static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, | 1213 | static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, |
770 | enum pci_channel_state state) | 1214 | enum pci_channel_state state) |
771 | { | 1215 | { |
772 | printk(KERN_ERR DEVICE_NAME ": PCI error\n"); | 1216 | dev_err(&dev->dev, "PCI error\n"); |
773 | if (state == pci_channel_io_perm_failure) | 1217 | if (state == pci_channel_io_perm_failure) |
774 | return PCI_ERS_RESULT_DISCONNECT; | 1218 | return PCI_ERS_RESULT_DISCONNECT; |
775 | if (state == pci_channel_io_frozen) | 1219 | if (state == pci_channel_io_frozen) |
@@ -779,13 +1223,13 @@ static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, | |||
779 | 1223 | ||
780 | static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev) | 1224 | static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev) |
781 | { | 1225 | { |
782 | printk(KERN_INFO DEVICE_NAME ": slot reset\n"); | 1226 | dev_info(&dev->dev, "slot reset\n"); |
783 | return 0; | 1227 | return 0; |
784 | } | 1228 | } |
785 | 1229 | ||
786 | static void ngene_resume(struct pci_dev *dev) | 1230 | static void ngene_resume(struct pci_dev *dev) |
787 | { | 1231 | { |
788 | printk(KERN_INFO DEVICE_NAME ": resume\n"); | 1232 | dev_info(&dev->dev, "resume\n"); |
789 | } | 1233 | } |
790 | 1234 | ||
791 | static const struct pci_error_handlers ngene_errors = { | 1235 | static const struct pci_error_handlers ngene_errors = { |
@@ -805,8 +1249,9 @@ static struct pci_driver ngene_pci_driver = { | |||
805 | 1249 | ||
806 | static __init int module_init_ngene(void) | 1250 | static __init int module_init_ngene(void) |
807 | { | 1251 | { |
808 | printk(KERN_INFO | 1252 | /* pr_*() since we don't have a device to use with dev_*() yet */ |
809 | "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n"); | 1253 | pr_info("nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n"); |
1254 | |||
810 | return pci_register_driver(&ngene_pci_driver); | 1255 | return pci_register_driver(&ngene_pci_driver); |
811 | } | 1256 | } |
812 | 1257 | ||
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 8c92cb7f7e72..25f16833a475 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c | |||
@@ -51,8 +51,6 @@ MODULE_PARM_DESC(debug, "Print debugging information."); | |||
51 | 51 | ||
52 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 52 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
53 | 53 | ||
54 | #define dprintk if (debug) printk | ||
55 | |||
56 | #define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) | 54 | #define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) |
57 | #define ngwritel(dat, adr) writel((dat), dev->iomem + (adr)) | 55 | #define ngwritel(dat, adr) writel((dat), dev->iomem + (adr)) |
58 | #define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) | 56 | #define ngwriteb(dat, adr) writeb((dat), dev->iomem + (adr)) |
@@ -86,6 +84,7 @@ static void event_tasklet(unsigned long data) | |||
86 | static void demux_tasklet(unsigned long data) | 84 | static void demux_tasklet(unsigned long data) |
87 | { | 85 | { |
88 | struct ngene_channel *chan = (struct ngene_channel *)data; | 86 | struct ngene_channel *chan = (struct ngene_channel *)data; |
87 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
89 | struct SBufferHeader *Cur = chan->nextBuffer; | 88 | struct SBufferHeader *Cur = chan->nextBuffer; |
90 | 89 | ||
91 | spin_lock_irq(&chan->state_lock); | 90 | spin_lock_irq(&chan->state_lock); |
@@ -124,16 +123,15 @@ static void demux_tasklet(unsigned long data) | |||
124 | chan->HWState = HWSTATE_RUN; | 123 | chan->HWState = HWSTATE_RUN; |
125 | } | 124 | } |
126 | } else { | 125 | } else { |
127 | printk(KERN_ERR DEVICE_NAME ": OOPS\n"); | 126 | dev_err(pdev, "OOPS\n"); |
128 | if (chan->HWState == HWSTATE_RUN) { | 127 | if (chan->HWState == HWSTATE_RUN) { |
129 | Cur->ngeneBuffer.SR.Flags &= ~0x40; | 128 | Cur->ngeneBuffer.SR.Flags &= ~0x40; |
130 | break; /* Stop processing stream */ | 129 | break; /* Stop processing stream */ |
131 | } | 130 | } |
132 | } | 131 | } |
133 | if (chan->AudioDTOUpdated) { | 132 | if (chan->AudioDTOUpdated) { |
134 | printk(KERN_INFO DEVICE_NAME | 133 | dev_info(pdev, "Update AudioDTO = %d\n", |
135 | ": Update AudioDTO = %d\n", | 134 | chan->AudioDTOValue); |
136 | chan->AudioDTOValue); | ||
137 | Cur->ngeneBuffer.SR.DTOUpdate = | 135 | Cur->ngeneBuffer.SR.DTOUpdate = |
138 | chan->AudioDTOValue; | 136 | chan->AudioDTOValue; |
139 | chan->AudioDTOUpdated = 0; | 137 | chan->AudioDTOUpdated = 0; |
@@ -173,6 +171,7 @@ static void demux_tasklet(unsigned long data) | |||
173 | static irqreturn_t irq_handler(int irq, void *dev_id) | 171 | static irqreturn_t irq_handler(int irq, void *dev_id) |
174 | { | 172 | { |
175 | struct ngene *dev = (struct ngene *)dev_id; | 173 | struct ngene *dev = (struct ngene *)dev_id; |
174 | struct device *pdev = &dev->pci_dev->dev; | ||
176 | u32 icounts = 0; | 175 | u32 icounts = 0; |
177 | irqreturn_t rc = IRQ_NONE; | 176 | irqreturn_t rc = IRQ_NONE; |
178 | u32 i = MAX_STREAM; | 177 | u32 i = MAX_STREAM; |
@@ -213,7 +212,7 @@ static irqreturn_t irq_handler(int irq, void *dev_id) | |||
213 | *(dev->EventBuffer); | 212 | *(dev->EventBuffer); |
214 | dev->EventQueueWriteIndex = nextWriteIndex; | 213 | dev->EventQueueWriteIndex = nextWriteIndex; |
215 | } else { | 214 | } else { |
216 | printk(KERN_ERR DEVICE_NAME ": event overflow\n"); | 215 | dev_err(pdev, "event overflow\n"); |
217 | dev->EventQueueOverflowCount += 1; | 216 | dev->EventQueueOverflowCount += 1; |
218 | dev->EventQueueOverflowFlag = 1; | 217 | dev->EventQueueOverflowFlag = 1; |
219 | } | 218 | } |
@@ -249,23 +248,25 @@ static irqreturn_t irq_handler(int irq, void *dev_id) | |||
249 | 248 | ||
250 | static void dump_command_io(struct ngene *dev) | 249 | static void dump_command_io(struct ngene *dev) |
251 | { | 250 | { |
251 | struct device *pdev = &dev->pci_dev->dev; | ||
252 | u8 buf[8], *b; | 252 | u8 buf[8], *b; |
253 | 253 | ||
254 | ngcpyfrom(buf, HOST_TO_NGENE, 8); | 254 | ngcpyfrom(buf, HOST_TO_NGENE, 8); |
255 | printk(KERN_ERR "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf); | 255 | dev_err(pdev, "host_to_ngene (%04x): %*ph\n", HOST_TO_NGENE, 8, buf); |
256 | 256 | ||
257 | ngcpyfrom(buf, NGENE_TO_HOST, 8); | 257 | ngcpyfrom(buf, NGENE_TO_HOST, 8); |
258 | printk(KERN_ERR "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf); | 258 | dev_err(pdev, "ngene_to_host (%04x): %*ph\n", NGENE_TO_HOST, 8, buf); |
259 | 259 | ||
260 | b = dev->hosttongene; | 260 | b = dev->hosttongene; |
261 | printk(KERN_ERR "dev->hosttongene (%p): %*ph\n", b, 8, b); | 261 | dev_err(pdev, "dev->hosttongene (%p): %*ph\n", b, 8, b); |
262 | 262 | ||
263 | b = dev->ngenetohost; | 263 | b = dev->ngenetohost; |
264 | printk(KERN_ERR "dev->ngenetohost (%p): %*ph\n", b, 8, b); | 264 | dev_err(pdev, "dev->ngenetohost (%p): %*ph\n", b, 8, b); |
265 | } | 265 | } |
266 | 266 | ||
267 | static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) | 267 | static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) |
268 | { | 268 | { |
269 | struct device *pdev = &dev->pci_dev->dev; | ||
269 | int ret; | 270 | int ret; |
270 | u8 *tmpCmdDoneByte; | 271 | u8 *tmpCmdDoneByte; |
271 | 272 | ||
@@ -313,9 +314,8 @@ static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) | |||
313 | if (!ret) { | 314 | if (!ret) { |
314 | /*ngwritel(0, FORCE_NMI);*/ | 315 | /*ngwritel(0, FORCE_NMI);*/ |
315 | 316 | ||
316 | printk(KERN_ERR DEVICE_NAME | 317 | dev_err(pdev, "Command timeout cmd=%02x prev=%02x\n", |
317 | ": Command timeout cmd=%02x prev=%02x\n", | 318 | com->cmd.hdr.Opcode, dev->prev_cmd); |
318 | com->cmd.hdr.Opcode, dev->prev_cmd); | ||
319 | dump_command_io(dev); | 319 | dump_command_io(dev); |
320 | return -1; | 320 | return -1; |
321 | } | 321 | } |
@@ -553,6 +553,7 @@ static void clear_buffers(struct ngene_channel *chan) | |||
553 | static int ngene_command_stream_control(struct ngene *dev, u8 stream, | 553 | static int ngene_command_stream_control(struct ngene *dev, u8 stream, |
554 | u8 control, u8 mode, u8 flags) | 554 | u8 control, u8 mode, u8 flags) |
555 | { | 555 | { |
556 | struct device *pdev = &dev->pci_dev->dev; | ||
556 | struct ngene_channel *chan = &dev->channel[stream]; | 557 | struct ngene_channel *chan = &dev->channel[stream]; |
557 | struct ngene_command com; | 558 | struct ngene_command com; |
558 | u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300); | 559 | u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300); |
@@ -572,8 +573,7 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream, | |||
572 | com.in_len = sizeof(struct FW_STREAM_CONTROL); | 573 | com.in_len = sizeof(struct FW_STREAM_CONTROL); |
573 | com.out_len = 0; | 574 | com.out_len = 0; |
574 | 575 | ||
575 | dprintk(KERN_INFO DEVICE_NAME | 576 | dev_dbg(pdev, "Stream=%02x, Control=%02x, Mode=%02x\n", |
576 | ": Stream=%02x, Control=%02x, Mode=%02x\n", | ||
577 | com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control, | 577 | com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control, |
578 | com.cmd.StreamControl.Mode); | 578 | com.cmd.StreamControl.Mode); |
579 | 579 | ||
@@ -695,23 +695,24 @@ static int ngene_command_stream_control(struct ngene *dev, u8 stream, | |||
695 | 695 | ||
696 | void set_transfer(struct ngene_channel *chan, int state) | 696 | void set_transfer(struct ngene_channel *chan, int state) |
697 | { | 697 | { |
698 | struct device *pdev = &chan->dev->pci_dev->dev; | ||
698 | u8 control = 0, mode = 0, flags = 0; | 699 | u8 control = 0, mode = 0, flags = 0; |
699 | struct ngene *dev = chan->dev; | 700 | struct ngene *dev = chan->dev; |
700 | int ret; | 701 | int ret; |
701 | 702 | ||
702 | /* | 703 | /* |
703 | printk(KERN_INFO DEVICE_NAME ": st %d\n", state); | 704 | dev_info(pdev, "st %d\n", state); |
704 | msleep(100); | 705 | msleep(100); |
705 | */ | 706 | */ |
706 | 707 | ||
707 | if (state) { | 708 | if (state) { |
708 | if (chan->running) { | 709 | if (chan->running) { |
709 | printk(KERN_INFO DEVICE_NAME ": already running\n"); | 710 | dev_info(pdev, "already running\n"); |
710 | return; | 711 | return; |
711 | } | 712 | } |
712 | } else { | 713 | } else { |
713 | if (!chan->running) { | 714 | if (!chan->running) { |
714 | printk(KERN_INFO DEVICE_NAME ": already stopped\n"); | 715 | dev_info(pdev, "already stopped\n"); |
715 | return; | 716 | return; |
716 | } | 717 | } |
717 | } | 718 | } |
@@ -722,7 +723,7 @@ void set_transfer(struct ngene_channel *chan, int state) | |||
722 | if (state) { | 723 | if (state) { |
723 | spin_lock_irq(&chan->state_lock); | 724 | spin_lock_irq(&chan->state_lock); |
724 | 725 | ||
725 | /* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | 726 | /* dev_info(pdev, "lock=%08x\n", |
726 | ngreadl(0x9310)); */ | 727 | ngreadl(0x9310)); */ |
727 | dvb_ringbuffer_flush(&dev->tsout_rbuf); | 728 | dvb_ringbuffer_flush(&dev->tsout_rbuf); |
728 | control = 0x80; | 729 | control = 0x80; |
@@ -740,7 +741,7 @@ void set_transfer(struct ngene_channel *chan, int state) | |||
740 | chan->pBufferExchange = tsin_exchange; | 741 | chan->pBufferExchange = tsin_exchange; |
741 | spin_unlock_irq(&chan->state_lock); | 742 | spin_unlock_irq(&chan->state_lock); |
742 | } | 743 | } |
743 | /* else printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | 744 | /* else dev_info(pdev, "lock=%08x\n", |
744 | ngreadl(0x9310)); */ | 745 | ngreadl(0x9310)); */ |
745 | 746 | ||
746 | mutex_lock(&dev->stream_mutex); | 747 | mutex_lock(&dev->stream_mutex); |
@@ -751,8 +752,7 @@ void set_transfer(struct ngene_channel *chan, int state) | |||
751 | if (!ret) | 752 | if (!ret) |
752 | chan->running = state; | 753 | chan->running = state; |
753 | else | 754 | else |
754 | printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n", | 755 | dev_err(pdev, "%s %d failed\n", __func__, state); |
755 | state); | ||
756 | if (!state) { | 756 | if (!state) { |
757 | spin_lock_irq(&chan->state_lock); | 757 | spin_lock_irq(&chan->state_lock); |
758 | chan->pBufferExchange = NULL; | 758 | chan->pBufferExchange = NULL; |
@@ -1195,6 +1195,7 @@ static int ngene_get_buffers(struct ngene *dev) | |||
1195 | 1195 | ||
1196 | static void ngene_init(struct ngene *dev) | 1196 | static void ngene_init(struct ngene *dev) |
1197 | { | 1197 | { |
1198 | struct device *pdev = &dev->pci_dev->dev; | ||
1198 | int i; | 1199 | int i; |
1199 | 1200 | ||
1200 | tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev); | 1201 | tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev); |
@@ -1214,12 +1215,12 @@ static void ngene_init(struct ngene *dev) | |||
1214 | dev->icounts = ngreadl(NGENE_INT_COUNTS); | 1215 | dev->icounts = ngreadl(NGENE_INT_COUNTS); |
1215 | 1216 | ||
1216 | dev->device_version = ngreadl(DEV_VER) & 0x0f; | 1217 | dev->device_version = ngreadl(DEV_VER) & 0x0f; |
1217 | printk(KERN_INFO DEVICE_NAME ": Device version %d\n", | 1218 | dev_info(pdev, "Device version %d\n", dev->device_version); |
1218 | dev->device_version); | ||
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | static int ngene_load_firm(struct ngene *dev) | 1221 | static int ngene_load_firm(struct ngene *dev) |
1222 | { | 1222 | { |
1223 | struct device *pdev = &dev->pci_dev->dev; | ||
1223 | u32 size; | 1224 | u32 size; |
1224 | const struct firmware *fw = NULL; | 1225 | const struct firmware *fw = NULL; |
1225 | u8 *ngene_fw; | 1226 | u8 *ngene_fw; |
@@ -1253,21 +1254,18 @@ static int ngene_load_firm(struct ngene *dev) | |||
1253 | } | 1254 | } |
1254 | 1255 | ||
1255 | if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { | 1256 | if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { |
1256 | printk(KERN_ERR DEVICE_NAME | 1257 | dev_err(pdev, "Could not load firmware file %s.\n", fw_name); |
1257 | ": Could not load firmware file %s.\n", fw_name); | 1258 | dev_info(pdev, "Copy %s to your hotplug directory!\n", |
1258 | printk(KERN_INFO DEVICE_NAME | 1259 | fw_name); |
1259 | ": Copy %s to your hotplug directory!\n", fw_name); | ||
1260 | return -1; | 1260 | return -1; |
1261 | } | 1261 | } |
1262 | if (size == 0) | 1262 | if (size == 0) |
1263 | size = fw->size; | 1263 | size = fw->size; |
1264 | if (size != fw->size) { | 1264 | if (size != fw->size) { |
1265 | printk(KERN_ERR DEVICE_NAME | 1265 | dev_err(pdev, "Firmware %s has invalid size!", fw_name); |
1266 | ": Firmware %s has invalid size!", fw_name); | ||
1267 | err = -1; | 1266 | err = -1; |
1268 | } else { | 1267 | } else { |
1269 | printk(KERN_INFO DEVICE_NAME | 1268 | dev_info(pdev, "Loading firmware file %s.\n", fw_name); |
1270 | ": Loading firmware file %s.\n", fw_name); | ||
1271 | ngene_fw = (u8 *) fw->data; | 1269 | ngene_fw = (u8 *) fw->data; |
1272 | err = ngene_command_load_firmware(dev, ngene_fw, size); | 1270 | err = ngene_command_load_firmware(dev, ngene_fw, size); |
1273 | } | 1271 | } |
@@ -1360,14 +1358,14 @@ static int ngene_start(struct ngene *dev) | |||
1360 | #ifdef CONFIG_PCI_MSI | 1358 | #ifdef CONFIG_PCI_MSI |
1361 | /* enable MSI if kernel and card support it */ | 1359 | /* enable MSI if kernel and card support it */ |
1362 | if (pci_msi_enabled() && dev->card_info->msi_supported) { | 1360 | if (pci_msi_enabled() && dev->card_info->msi_supported) { |
1361 | struct device *pdev = &dev->pci_dev->dev; | ||
1363 | unsigned long flags; | 1362 | unsigned long flags; |
1364 | 1363 | ||
1365 | ngwritel(0, NGENE_INT_ENABLE); | 1364 | ngwritel(0, NGENE_INT_ENABLE); |
1366 | free_irq(dev->pci_dev->irq, dev); | 1365 | free_irq(dev->pci_dev->irq, dev); |
1367 | stat = pci_enable_msi(dev->pci_dev); | 1366 | stat = pci_enable_msi(dev->pci_dev); |
1368 | if (stat) { | 1367 | if (stat) { |
1369 | printk(KERN_INFO DEVICE_NAME | 1368 | dev_info(pdev, "MSI not available\n"); |
1370 | ": MSI not available\n"); | ||
1371 | flags = IRQF_SHARED; | 1369 | flags = IRQF_SHARED; |
1372 | } else { | 1370 | } else { |
1373 | flags = 0; | 1371 | flags = 0; |
@@ -1426,6 +1424,13 @@ static void release_channel(struct ngene_channel *chan) | |||
1426 | 1424 | ||
1427 | if (chan->fe) { | 1425 | if (chan->fe) { |
1428 | dvb_unregister_frontend(chan->fe); | 1426 | dvb_unregister_frontend(chan->fe); |
1427 | |||
1428 | /* release I2C client (tuner) if needed */ | ||
1429 | if (chan->i2c_client_fe) { | ||
1430 | dvb_module_release(chan->i2c_client[0]); | ||
1431 | chan->i2c_client[0] = NULL; | ||
1432 | } | ||
1433 | |||
1429 | dvb_frontend_detach(chan->fe); | 1434 | dvb_frontend_detach(chan->fe); |
1430 | chan->fe = NULL; | 1435 | chan->fe = NULL; |
1431 | } | 1436 | } |
@@ -1461,6 +1466,7 @@ static int init_channel(struct ngene_channel *chan) | |||
1461 | chan->users = 0; | 1466 | chan->users = 0; |
1462 | chan->type = io; | 1467 | chan->type = io; |
1463 | chan->mode = chan->type; /* for now only one mode */ | 1468 | chan->mode = chan->type; /* for now only one mode */ |
1469 | chan->i2c_client_fe = 0; /* be sure this is set to zero */ | ||
1464 | 1470 | ||
1465 | if (io & NGENE_IO_TSIN) { | 1471 | if (io & NGENE_IO_TSIN) { |
1466 | chan->fe = NULL; | 1472 | chan->fe = NULL; |
@@ -1562,19 +1568,46 @@ static int init_channels(struct ngene *dev) | |||
1562 | return 0; | 1568 | return 0; |
1563 | } | 1569 | } |
1564 | 1570 | ||
1565 | static struct cxd2099_cfg cxd_cfg = { | 1571 | static const struct cxd2099_cfg cxd_cfgtmpl = { |
1566 | .bitrate = 62000, | 1572 | .bitrate = 62000, |
1567 | .adr = 0x40, | ||
1568 | .polarity = 0, | 1573 | .polarity = 0, |
1569 | .clock_mode = 0, | 1574 | .clock_mode = 0, |
1570 | }; | 1575 | }; |
1571 | 1576 | ||
1572 | static void cxd_attach(struct ngene *dev) | 1577 | static void cxd_attach(struct ngene *dev) |
1573 | { | 1578 | { |
1579 | struct device *pdev = &dev->pci_dev->dev; | ||
1574 | struct ngene_ci *ci = &dev->ci; | 1580 | struct ngene_ci *ci = &dev->ci; |
1581 | struct cxd2099_cfg cxd_cfg = cxd_cfgtmpl; | ||
1582 | struct i2c_client *client; | ||
1583 | int ret; | ||
1584 | u8 type; | ||
1585 | |||
1586 | /* check for CXD2099AR presence before attaching */ | ||
1587 | ret = ngene_port_has_cxd2099(&dev->channel[0].i2c_adapter, &type); | ||
1588 | if (!ret) { | ||
1589 | dev_dbg(pdev, "No CXD2099AR found\n"); | ||
1590 | return; | ||
1591 | } | ||
1592 | |||
1593 | if (type != 1) { | ||
1594 | dev_warn(pdev, "CXD2099AR is uninitialized!\n"); | ||
1595 | return; | ||
1596 | } | ||
1597 | |||
1598 | cxd_cfg.en = &ci->en; | ||
1599 | client = dvb_module_probe("cxd2099", NULL, | ||
1600 | &dev->channel[0].i2c_adapter, | ||
1601 | 0x40, &cxd_cfg); | ||
1602 | if (!client) | ||
1603 | goto err; | ||
1575 | 1604 | ||
1576 | ci->en = cxd2099_attach(&cxd_cfg, dev, &dev->channel[0].i2c_adapter); | ||
1577 | ci->dev = dev; | 1605 | ci->dev = dev; |
1606 | dev->channel[0].i2c_client[0] = client; | ||
1607 | return; | ||
1608 | |||
1609 | err: | ||
1610 | dev_err(pdev, "CXD2099AR attach failed\n"); | ||
1578 | return; | 1611 | return; |
1579 | } | 1612 | } |
1580 | 1613 | ||
@@ -1583,7 +1616,9 @@ static void cxd_detach(struct ngene *dev) | |||
1583 | struct ngene_ci *ci = &dev->ci; | 1616 | struct ngene_ci *ci = &dev->ci; |
1584 | 1617 | ||
1585 | dvb_ca_en50221_release(ci->en); | 1618 | dvb_ca_en50221_release(ci->en); |
1586 | kfree(ci->en); | 1619 | |
1620 | dvb_module_release(dev->channel[0].i2c_client[0]); | ||
1621 | dev->channel[0].i2c_client[0] = NULL; | ||
1587 | ci->en = NULL; | 1622 | ci->en = NULL; |
1588 | } | 1623 | } |
1589 | 1624 | ||
@@ -1615,7 +1650,7 @@ void ngene_shutdown(struct pci_dev *pdev) | |||
1615 | if (!dev || !shutdown_workaround) | 1650 | if (!dev || !shutdown_workaround) |
1616 | return; | 1651 | return; |
1617 | 1652 | ||
1618 | printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n"); | 1653 | dev_info(&pdev->dev, "shutdown workaround...\n"); |
1619 | ngene_unlink(dev); | 1654 | ngene_unlink(dev); |
1620 | pci_disable_device(pdev); | 1655 | pci_disable_device(pdev); |
1621 | } | 1656 | } |
@@ -1655,7 +1690,7 @@ int ngene_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
1655 | 1690 | ||
1656 | dev->pci_dev = pci_dev; | 1691 | dev->pci_dev = pci_dev; |
1657 | dev->card_info = (struct ngene_info *)id->driver_data; | 1692 | dev->card_info = (struct ngene_info *)id->driver_data; |
1658 | printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name); | 1693 | dev_info(&pci_dev->dev, "Found %s\n", dev->card_info->name); |
1659 | 1694 | ||
1660 | pci_set_drvdata(pci_dev, dev); | 1695 | pci_set_drvdata(pci_dev, dev); |
1661 | 1696 | ||
diff --git a/drivers/media/pci/ngene/ngene-dvb.c b/drivers/media/pci/ngene/ngene-dvb.c index 03fc218a45e9..fee89b9ed9c1 100644 --- a/drivers/media/pci/ngene/ngene-dvb.c +++ b/drivers/media/pci/ngene/ngene-dvb.c | |||
@@ -38,6 +38,9 @@ | |||
38 | 38 | ||
39 | #include "ngene.h" | 39 | #include "ngene.h" |
40 | 40 | ||
41 | static int ci_tsfix = 1; | ||
42 | module_param(ci_tsfix, int, 0444); | ||
43 | MODULE_PARM_DESC(ci_tsfix, "Detect and fix TS buffer offset shifs in conjunction with CI expansions (default: 1/enabled)"); | ||
41 | 44 | ||
42 | /****************************************************************************/ | 45 | /****************************************************************************/ |
43 | /* COMMAND API interface ****************************************************/ | 46 | /* COMMAND API interface ****************************************************/ |
@@ -84,18 +87,41 @@ static ssize_t ts_read(struct file *file, char __user *buf, | |||
84 | return count; | 87 | return count; |
85 | } | 88 | } |
86 | 89 | ||
90 | static __poll_t ts_poll(struct file *file, poll_table *wait) | ||
91 | { | ||
92 | struct dvb_device *dvbdev = file->private_data; | ||
93 | struct ngene_channel *chan = dvbdev->priv; | ||
94 | struct ngene *dev = chan->dev; | ||
95 | struct dvb_ringbuffer *rbuf = &dev->tsin_rbuf; | ||
96 | struct dvb_ringbuffer *wbuf = &dev->tsout_rbuf; | ||
97 | __poll_t mask = 0; | ||
98 | |||
99 | poll_wait(file, &rbuf->queue, wait); | ||
100 | poll_wait(file, &wbuf->queue, wait); | ||
101 | |||
102 | if (!dvb_ringbuffer_empty(rbuf)) | ||
103 | mask |= EPOLLIN | EPOLLRDNORM; | ||
104 | if (dvb_ringbuffer_free(wbuf) >= 188) | ||
105 | mask |= EPOLLOUT | EPOLLWRNORM; | ||
106 | |||
107 | return mask; | ||
108 | } | ||
109 | |||
87 | static const struct file_operations ci_fops = { | 110 | static const struct file_operations ci_fops = { |
88 | .owner = THIS_MODULE, | 111 | .owner = THIS_MODULE, |
89 | .read = ts_read, | 112 | .read = ts_read, |
90 | .write = ts_write, | 113 | .write = ts_write, |
91 | .open = dvb_generic_open, | 114 | .open = dvb_generic_open, |
92 | .release = dvb_generic_release, | 115 | .release = dvb_generic_release, |
116 | .poll = ts_poll, | ||
117 | .mmap = NULL, | ||
93 | }; | 118 | }; |
94 | 119 | ||
95 | struct dvb_device ngene_dvbdev_ci = { | 120 | struct dvb_device ngene_dvbdev_ci = { |
96 | .readers = -1, | 121 | .priv = NULL, |
97 | .writers = -1, | 122 | .readers = 1, |
98 | .users = -1, | 123 | .writers = 1, |
124 | .users = 2, | ||
99 | .fops = &ci_fops, | 125 | .fops = &ci_fops, |
100 | }; | 126 | }; |
101 | 127 | ||
@@ -116,47 +142,118 @@ static void swap_buffer(u32 *p, u32 len) | |||
116 | /* start of filler packet */ | 142 | /* start of filler packet */ |
117 | static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER }; | 143 | static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER }; |
118 | 144 | ||
119 | /* #define DEBUG_CI_XFER */ | 145 | static int tsin_find_offset(void *buf, u32 len) |
120 | #ifdef DEBUG_CI_XFER | 146 | { |
121 | static u32 ok; | 147 | int i, l; |
122 | static u32 overflow; | 148 | |
123 | static u32 stripped; | 149 | l = len - sizeof(fill_ts); |
124 | #endif | 150 | if (l <= 0) |
151 | return -1; | ||
152 | |||
153 | for (i = 0; i < l; i++) { | ||
154 | if (((char *)buf)[i] == 0x47) { | ||
155 | if (!memcmp(buf + i, fill_ts, sizeof(fill_ts))) | ||
156 | return i % 188; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | return -1; | ||
161 | } | ||
162 | |||
163 | static inline void tsin_copy_stripped(struct ngene *dev, void *buf) | ||
164 | { | ||
165 | if (memcmp(buf, fill_ts, sizeof(fill_ts)) != 0) { | ||
166 | if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) { | ||
167 | dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188); | ||
168 | wake_up(&dev->tsin_rbuf.queue); | ||
169 | } | ||
170 | } | ||
171 | } | ||
125 | 172 | ||
126 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | 173 | void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) |
127 | { | 174 | { |
128 | struct ngene_channel *chan = priv; | 175 | struct ngene_channel *chan = priv; |
129 | struct ngene *dev = chan->dev; | 176 | struct ngene *dev = chan->dev; |
130 | 177 | int tsoff; | |
131 | 178 | ||
132 | if (flags & DF_SWAP32) | 179 | if (flags & DF_SWAP32) |
133 | swap_buffer(buf, len); | 180 | swap_buffer(buf, len); |
134 | 181 | ||
135 | if (dev->ci.en && chan->number == 2) { | 182 | if (dev->ci.en && chan->number == 2) { |
183 | /* blindly copy buffers if ci_tsfix is disabled */ | ||
184 | if (!ci_tsfix) { | ||
185 | while (len >= 188) { | ||
186 | tsin_copy_stripped(dev, buf); | ||
187 | |||
188 | buf += 188; | ||
189 | len -= 188; | ||
190 | } | ||
191 | return NULL; | ||
192 | } | ||
193 | |||
194 | /* ci_tsfix = 1 */ | ||
195 | |||
196 | /* | ||
197 | * since the remainder of the TS packet which got cut off | ||
198 | * in the previous tsin_exchange() run is at the beginning | ||
199 | * of the new TS buffer, append this to the temp buffer and | ||
200 | * send it to the DVB ringbuffer afterwards. | ||
201 | */ | ||
202 | if (chan->tsin_offset) { | ||
203 | memcpy(&chan->tsin_buffer[(188 - chan->tsin_offset)], | ||
204 | buf, chan->tsin_offset); | ||
205 | tsin_copy_stripped(dev, &chan->tsin_buffer); | ||
206 | |||
207 | buf += chan->tsin_offset; | ||
208 | len -= chan->tsin_offset; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * copy TS packets to the DVB ringbuffer and detect new offset | ||
213 | * shifts by checking for a valid TS SYNC byte | ||
214 | */ | ||
136 | while (len >= 188) { | 215 | while (len >= 188) { |
137 | if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) { | 216 | if (*((char *)buf) != 0x47) { |
138 | if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) { | 217 | /* |
139 | dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188); | 218 | * no SYNC header, find new offset shift |
140 | wake_up(&dev->tsin_rbuf.queue); | 219 | * (max. 188 bytes, tsoff will be mod 188) |
141 | #ifdef DEBUG_CI_XFER | 220 | */ |
142 | ok++; | 221 | tsoff = tsin_find_offset(buf, len); |
143 | #endif | 222 | if (tsoff > 0) { |
223 | chan->tsin_offset += tsoff; | ||
224 | chan->tsin_offset %= 188; | ||
225 | |||
226 | buf += tsoff; | ||
227 | len -= tsoff; | ||
228 | |||
229 | dev_info(&dev->pci_dev->dev, | ||
230 | "%s(): tsin_offset shift by %d on channel %d\n", | ||
231 | __func__, tsoff, | ||
232 | chan->number); | ||
233 | |||
234 | /* | ||
235 | * offset corrected. re-check remaining | ||
236 | * len for a full TS frame, break and | ||
237 | * skip to fragment handling if < 188. | ||
238 | */ | ||
239 | if (len < 188) | ||
240 | break; | ||
144 | } | 241 | } |
145 | #ifdef DEBUG_CI_XFER | ||
146 | else | ||
147 | overflow++; | ||
148 | #endif | ||
149 | } | 242 | } |
150 | #ifdef DEBUG_CI_XFER | ||
151 | else | ||
152 | stripped++; | ||
153 | 243 | ||
154 | if (ok % 100 == 0 && overflow) | 244 | tsin_copy_stripped(dev, buf); |
155 | printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped); | 245 | |
156 | #endif | ||
157 | buf += 188; | 246 | buf += 188; |
158 | len -= 188; | 247 | len -= 188; |
159 | } | 248 | } |
249 | |||
250 | /* | ||
251 | * if a fragment is left, copy to temp buffer. The remainder | ||
252 | * will be appended in the next tsin_exchange() iteration. | ||
253 | */ | ||
254 | if (len > 0 && len < 188) | ||
255 | memcpy(&chan->tsin_buffer, buf, len); | ||
256 | |||
160 | return NULL; | 257 | return NULL; |
161 | } | 258 | } |
162 | 259 | ||
diff --git a/drivers/media/pci/ngene/ngene-i2c.c b/drivers/media/pci/ngene/ngene-i2c.c index 3004947f300b..092d46c2a3a9 100644 --- a/drivers/media/pci/ngene/ngene-i2c.c +++ b/drivers/media/pci/ngene/ngene-i2c.c | |||
@@ -147,7 +147,7 @@ done: | |||
147 | 147 | ||
148 | static u32 ngene_i2c_functionality(struct i2c_adapter *adap) | 148 | static u32 ngene_i2c_functionality(struct i2c_adapter *adap) |
149 | { | 149 | { |
150 | return I2C_FUNC_SMBUS_EMUL; | 150 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
151 | } | 151 | } |
152 | 152 | ||
153 | static const struct i2c_algorithm ngene_i2c_algo = { | 153 | static const struct i2c_algorithm ngene_i2c_algo = { |
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h index 02dbd18f92d0..01d9f1b58fcb 100644 --- a/drivers/media/pci/ngene/ngene.h +++ b/drivers/media/pci/ngene/ngene.h | |||
@@ -51,6 +51,22 @@ | |||
51 | #define VIDEO_CAP_MPEG4 512 | 51 | #define VIDEO_CAP_MPEG4 512 |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #define DEMOD_TYPE_STV090X 0 | ||
55 | #define DEMOD_TYPE_DRXK 1 | ||
56 | #define DEMOD_TYPE_STV0367 2 | ||
57 | |||
58 | #define DEMOD_TYPE_XO2 32 | ||
59 | #define DEMOD_TYPE_STV0910 (DEMOD_TYPE_XO2 + 0) | ||
60 | #define DEMOD_TYPE_SONY_CT2 (DEMOD_TYPE_XO2 + 1) | ||
61 | #define DEMOD_TYPE_SONY_ISDBT (DEMOD_TYPE_XO2 + 2) | ||
62 | #define DEMOD_TYPE_SONY_C2T2 (DEMOD_TYPE_XO2 + 3) | ||
63 | #define DEMOD_TYPE_ST_ATSC (DEMOD_TYPE_XO2 + 4) | ||
64 | #define DEMOD_TYPE_SONY_C2T2I (DEMOD_TYPE_XO2 + 5) | ||
65 | |||
66 | #define NGENE_XO2_TYPE_NONE 0 | ||
67 | #define NGENE_XO2_TYPE_DUOFLEX 1 | ||
68 | #define NGENE_XO2_TYPE_CI 2 | ||
69 | |||
54 | enum STREAM { | 70 | enum STREAM { |
55 | STREAM_VIDEOIN1 = 0, /* ITU656 or TS Input */ | 71 | STREAM_VIDEOIN1 = 0, /* ITU656 or TS Input */ |
56 | STREAM_VIDEOIN2, | 72 | STREAM_VIDEOIN2, |
@@ -630,6 +646,8 @@ struct ngene_vopen { | |||
630 | struct ngene_channel { | 646 | struct ngene_channel { |
631 | struct device device; | 647 | struct device device; |
632 | struct i2c_adapter i2c_adapter; | 648 | struct i2c_adapter i2c_adapter; |
649 | struct i2c_client *i2c_client[1]; | ||
650 | int i2c_client_fe; | ||
633 | 651 | ||
634 | struct ngene *dev; | 652 | struct ngene *dev; |
635 | int number; | 653 | int number; |
@@ -714,6 +732,9 @@ struct ngene_channel { | |||
714 | #endif | 732 | #endif |
715 | 733 | ||
716 | int running; | 734 | int running; |
735 | |||
736 | int tsin_offset; | ||
737 | u8 tsin_buffer[188]; | ||
717 | }; | 738 | }; |
718 | 739 | ||
719 | 740 | ||
@@ -891,6 +912,9 @@ int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); | |||
891 | void set_transfer(struct ngene_channel *chan, int state); | 912 | void set_transfer(struct ngene_channel *chan, int state); |
892 | void FillTSBuffer(void *Buffer, int Length, u32 Flags); | 913 | void FillTSBuffer(void *Buffer, int Length, u32 Flags); |
893 | 914 | ||
915 | /* Provided by ngene-cards.c */ | ||
916 | int ngene_port_has_cxd2099(struct i2c_adapter *i2c, u8 *type); | ||
917 | |||
894 | /* Provided by ngene-i2c.c */ | 918 | /* Provided by ngene-i2c.c */ |
895 | int ngene_i2c_init(struct ngene *dev, int dev_nr); | 919 | int ngene_i2c_init(struct ngene *dev, int dev_nr); |
896 | 920 | ||
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index c59b69f1af9d..72311445d13d 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c | |||
@@ -273,9 +273,8 @@ static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages) | |||
273 | return -ENOMEM; | 273 | return -ENOMEM; |
274 | } | 274 | } |
275 | 275 | ||
276 | pr_debug("vmalloc is at addr 0x%08lx, size=%d\n", | 276 | pr_debug("vmalloc is at addr %p, size=%d\n", |
277 | (unsigned long)dma->vaddr, | 277 | dma->vaddr, nr_pages << PAGE_SHIFT); |
278 | nr_pages << PAGE_SHIFT); | ||
279 | 278 | ||
280 | memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); | 279 | memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); |
281 | dma->nr_pages = nr_pages; | 280 | dma->nr_pages = nr_pages; |
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index a7a63d608dde..3025d38ddb2b 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c | |||
@@ -1195,7 +1195,7 @@ static struct s5h1411_config kworld_s5h1411_config = { | |||
1195 | .inversion = S5H1411_INVERSION_ON, | 1195 | .inversion = S5H1411_INVERSION_ON, |
1196 | .status_mode = S5H1411_DEMODLOCKING, | 1196 | .status_mode = S5H1411_DEMODLOCKING, |
1197 | .mpeg_timing = | 1197 | .mpeg_timing = |
1198 | S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 1198 | S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
1199 | }; | 1199 | }; |
1200 | 1200 | ||
1201 | 1201 | ||
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 33ee8322895e..0e28c5021ac4 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c | |||
@@ -115,7 +115,7 @@ static int build_key(struct saa7134_dev *dev) | |||
115 | static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_proto *protocol, | 115 | static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_proto *protocol, |
116 | u32 *scancode, u8 *toggle) | 116 | u32 *scancode, u8 *toggle) |
117 | { | 117 | { |
118 | int gpio; | 118 | int gpio, rc; |
119 | int attempt = 0; | 119 | int attempt = 0; |
120 | unsigned char b; | 120 | unsigned char b; |
121 | 121 | ||
@@ -153,8 +153,11 @@ static int get_key_flydvb_trio(struct IR_i2c *ir, enum rc_proto *protocol, | |||
153 | attempt); | 153 | attempt); |
154 | return -EIO; | 154 | return -EIO; |
155 | } | 155 | } |
156 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 156 | rc = i2c_master_recv(ir->c, &b, 1); |
157 | if (rc != 1) { | ||
157 | ir_dbg(ir, "read error\n"); | 158 | ir_dbg(ir, "read error\n"); |
159 | if (rc < 0) | ||
160 | return rc; | ||
158 | return -EIO; | 161 | return -EIO; |
159 | } | 162 | } |
160 | 163 | ||
@@ -169,7 +172,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, | |||
169 | u32 *scancode, u8 *toggle) | 172 | u32 *scancode, u8 *toggle) |
170 | { | 173 | { |
171 | unsigned char b; | 174 | unsigned char b; |
172 | int gpio; | 175 | int gpio, rc; |
173 | 176 | ||
174 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ | 177 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ |
175 | struct saa7134_dev *dev = ir->c->adapter->algo_data; | 178 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
@@ -193,8 +196,11 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, | |||
193 | 196 | ||
194 | /* GPIO says there is a button press. Get it. */ | 197 | /* GPIO says there is a button press. Get it. */ |
195 | 198 | ||
196 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 199 | rc = i2c_master_recv(ir->c, &b, 1); |
200 | if (rc != 1) { | ||
197 | ir_dbg(ir, "read error\n"); | 201 | ir_dbg(ir, "read error\n"); |
202 | if (rc < 0) | ||
203 | return rc; | ||
198 | return -EIO; | 204 | return -EIO; |
199 | } | 205 | } |
200 | 206 | ||
@@ -218,6 +224,7 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_proto *protocol, | |||
218 | { | 224 | { |
219 | unsigned char b; | 225 | unsigned char b; |
220 | unsigned int gpio; | 226 | unsigned int gpio; |
227 | int rc; | ||
221 | 228 | ||
222 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ | 229 | /* <dev> is needed to access GPIO. Used by the saa_readl macro. */ |
223 | struct saa7134_dev *dev = ir->c->adapter->algo_data; | 230 | struct saa7134_dev *dev = ir->c->adapter->algo_data; |
@@ -241,8 +248,11 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_proto *protocol, | |||
241 | 248 | ||
242 | /* GPIO says there is a button press. Get it. */ | 249 | /* GPIO says there is a button press. Get it. */ |
243 | 250 | ||
244 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 251 | rc = i2c_master_recv(ir->c, &b, 1); |
252 | if (rc != 1) { | ||
245 | ir_dbg(ir, "read error\n"); | 253 | ir_dbg(ir, "read error\n"); |
254 | if (rc < 0) | ||
255 | return rc; | ||
246 | return -EIO; | 256 | return -EIO; |
247 | } | 257 | } |
248 | 258 | ||
@@ -263,11 +273,15 @@ static int get_key_kworld_pc150u(struct IR_i2c *ir, enum rc_proto *protocol, | |||
263 | static int get_key_purpletv(struct IR_i2c *ir, enum rc_proto *protocol, | 273 | static int get_key_purpletv(struct IR_i2c *ir, enum rc_proto *protocol, |
264 | u32 *scancode, u8 *toggle) | 274 | u32 *scancode, u8 *toggle) |
265 | { | 275 | { |
276 | int rc; | ||
266 | unsigned char b; | 277 | unsigned char b; |
267 | 278 | ||
268 | /* poll IR chip */ | 279 | /* poll IR chip */ |
269 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | 280 | rc = i2c_master_recv(ir->c, &b, 1); |
281 | if (rc != 1) { | ||
270 | ir_dbg(ir, "read error\n"); | 282 | ir_dbg(ir, "read error\n"); |
283 | if (rc < 0) | ||
284 | return rc; | ||
271 | return -EIO; | 285 | return -EIO; |
272 | } | 286 | } |
273 | 287 | ||
@@ -288,11 +302,17 @@ static int get_key_purpletv(struct IR_i2c *ir, enum rc_proto *protocol, | |||
288 | static int get_key_hvr1110(struct IR_i2c *ir, enum rc_proto *protocol, | 302 | static int get_key_hvr1110(struct IR_i2c *ir, enum rc_proto *protocol, |
289 | u32 *scancode, u8 *toggle) | 303 | u32 *scancode, u8 *toggle) |
290 | { | 304 | { |
305 | int rc; | ||
291 | unsigned char buf[5]; | 306 | unsigned char buf[5]; |
292 | 307 | ||
293 | /* poll IR chip */ | 308 | /* poll IR chip */ |
294 | if (5 != i2c_master_recv(ir->c, buf, 5)) | 309 | rc = i2c_master_recv(ir->c, buf, 5); |
310 | if (rc != 5) { | ||
311 | ir_dbg(ir, "read error\n"); | ||
312 | if (rc < 0) | ||
313 | return rc; | ||
295 | return -EIO; | 314 | return -EIO; |
315 | } | ||
296 | 316 | ||
297 | /* Check if some key were pressed */ | 317 | /* Check if some key were pressed */ |
298 | if (!(buf[0] & 0x80)) | 318 | if (!(buf[0] & 0x80)) |
@@ -319,6 +339,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, enum rc_proto *protocol, | |||
319 | static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_proto *protocol, | 339 | static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_proto *protocol, |
320 | u32 *scancode, u8 *toggle) | 340 | u32 *scancode, u8 *toggle) |
321 | { | 341 | { |
342 | int rc; | ||
322 | unsigned char data[12]; | 343 | unsigned char data[12]; |
323 | u32 gpio; | 344 | u32 gpio; |
324 | 345 | ||
@@ -335,8 +356,11 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_proto *protocol, | |||
335 | 356 | ||
336 | ir->c->addr = 0x5a >> 1; | 357 | ir->c->addr = 0x5a >> 1; |
337 | 358 | ||
338 | if (12 != i2c_master_recv(ir->c, data, 12)) { | 359 | rc = i2c_master_recv(ir->c, data, 12); |
360 | if (rc != 12) { | ||
339 | ir_dbg(ir, "read error\n"); | 361 | ir_dbg(ir, "read error\n"); |
362 | if (rc < 0) | ||
363 | return rc; | ||
340 | return -EIO; | 364 | return -EIO; |
341 | } | 365 | } |
342 | 366 | ||
@@ -356,12 +380,16 @@ static int get_key_pinnacle(struct IR_i2c *ir, enum rc_proto *protocol, | |||
356 | u32 *scancode, u8 *toggle, int parity_offset, | 380 | u32 *scancode, u8 *toggle, int parity_offset, |
357 | int marker, int code_modulo) | 381 | int marker, int code_modulo) |
358 | { | 382 | { |
383 | int rc; | ||
359 | unsigned char b[4]; | 384 | unsigned char b[4]; |
360 | unsigned int start = 0,parity = 0,code = 0; | 385 | unsigned int start = 0,parity = 0,code = 0; |
361 | 386 | ||
362 | /* poll IR chip */ | 387 | /* poll IR chip */ |
363 | if (4 != i2c_master_recv(ir->c, b, 4)) { | 388 | rc = i2c_master_recv(ir->c, b, 4); |
389 | if (rc != 4) { | ||
364 | ir_dbg(ir, "read error\n"); | 390 | ir_dbg(ir, "read error\n"); |
391 | if (rc < 0) | ||
392 | return rc; | ||
365 | return -EIO; | 393 | return -EIO; |
366 | } | 394 | } |
367 | 395 | ||
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 1ca6a32ad10e..4f1091a11e91 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c | |||
@@ -1200,7 +1200,7 @@ static int video_release(struct file *file) | |||
1200 | saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); | 1200 | saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0); |
1201 | saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); | 1201 | saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0); |
1202 | 1202 | ||
1203 | saa_call_all(dev, core, s_power, 0); | 1203 | saa_call_all(dev, tuner, standby); |
1204 | if (vdev->vfl_type == VFL_TYPE_RADIO) | 1204 | if (vdev->vfl_type == VFL_TYPE_RADIO) |
1205 | saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); | 1205 | saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); |
1206 | mutex_unlock(&dev->lock); | 1206 | mutex_unlock(&dev->lock); |
diff --git a/drivers/media/pci/saa7164/saa7164-dvb.c b/drivers/media/pci/saa7164/saa7164-dvb.c index e76d3bafe2ce..4f9f03c3b252 100644 --- a/drivers/media/pci/saa7164/saa7164-dvb.c +++ b/drivers/media/pci/saa7164/saa7164-dvb.c | |||
@@ -78,7 +78,7 @@ static struct s5h1411_config hauppauge_s5h1411_config = { | |||
78 | .vsb_if = S5H1411_IF_3250, | 78 | .vsb_if = S5H1411_IF_3250, |
79 | .inversion = S5H1411_INVERSION_ON, | 79 | .inversion = S5H1411_INVERSION_ON, |
80 | .status_mode = S5H1411_DEMODLOCKING, | 80 | .status_mode = S5H1411_DEMODLOCKING, |
81 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 81 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static struct lgdt3306a_config hauppauge_hvr2255a_config = { | 84 | static struct lgdt3306a_config hauppauge_hvr2255a_config = { |
diff --git a/drivers/media/pci/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c index 81be1b8df758..2ac33b5cc454 100644 --- a/drivers/media/pci/solo6x10/solo6x10-g723.c +++ b/drivers/media/pci/solo6x10/solo6x10-g723.c | |||
@@ -223,9 +223,9 @@ static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) | |||
223 | return idx * G723_FRAMES_PER_PAGE; | 223 | return idx * G723_FRAMES_PER_PAGE; |
224 | } | 224 | } |
225 | 225 | ||
226 | static int __snd_solo_pcm_copy(struct snd_pcm_substream *ss, | 226 | static int snd_solo_pcm_copy_user(struct snd_pcm_substream *ss, int channel, |
227 | unsigned long pos, void *dst, | 227 | unsigned long pos, void __user *dst, |
228 | unsigned long count, bool in_kernel) | 228 | unsigned long count) |
229 | { | 229 | { |
230 | struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); | 230 | struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); |
231 | struct solo_dev *solo_dev = solo_pcm->solo_dev; | 231 | struct solo_dev *solo_dev = solo_pcm->solo_dev; |
@@ -242,10 +242,7 @@ static int __snd_solo_pcm_copy(struct snd_pcm_substream *ss, | |||
242 | if (err) | 242 | if (err) |
243 | return err; | 243 | return err; |
244 | 244 | ||
245 | if (in_kernel) | 245 | if (copy_to_user(dst, solo_pcm->g723_buf, G723_PERIOD_BYTES)) |
246 | memcpy(dst, solo_pcm->g723_buf, G723_PERIOD_BYTES); | ||
247 | else if (copy_to_user((void __user *)dst, | ||
248 | solo_pcm->g723_buf, G723_PERIOD_BYTES)) | ||
249 | return -EFAULT; | 246 | return -EFAULT; |
250 | dst += G723_PERIOD_BYTES; | 247 | dst += G723_PERIOD_BYTES; |
251 | } | 248 | } |
@@ -253,18 +250,30 @@ static int __snd_solo_pcm_copy(struct snd_pcm_substream *ss, | |||
253 | return 0; | 250 | return 0; |
254 | } | 251 | } |
255 | 252 | ||
256 | static int snd_solo_pcm_copy_user(struct snd_pcm_substream *ss, int channel, | ||
257 | unsigned long pos, void __user *dst, | ||
258 | unsigned long count) | ||
259 | { | ||
260 | return __snd_solo_pcm_copy(ss, pos, (void *)dst, count, false); | ||
261 | } | ||
262 | |||
263 | static int snd_solo_pcm_copy_kernel(struct snd_pcm_substream *ss, int channel, | 253 | static int snd_solo_pcm_copy_kernel(struct snd_pcm_substream *ss, int channel, |
264 | unsigned long pos, void *dst, | 254 | unsigned long pos, void *dst, |
265 | unsigned long count) | 255 | unsigned long count) |
266 | { | 256 | { |
267 | return __snd_solo_pcm_copy(ss, pos, dst, count, true); | 257 | struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss); |
258 | struct solo_dev *solo_dev = solo_pcm->solo_dev; | ||
259 | int err, i; | ||
260 | |||
261 | for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) { | ||
262 | int page = (pos / G723_FRAMES_PER_PAGE) + i; | ||
263 | |||
264 | err = solo_p2m_dma_t(solo_dev, 0, solo_pcm->g723_dma, | ||
265 | SOLO_G723_EXT_ADDR(solo_dev) + | ||
266 | (page * G723_PERIOD_BLOCK) + | ||
267 | (ss->number * G723_PERIOD_BYTES), | ||
268 | G723_PERIOD_BYTES, 0, 0); | ||
269 | if (err) | ||
270 | return err; | ||
271 | |||
272 | memcpy(dst, solo_pcm->g723_buf, G723_PERIOD_BYTES); | ||
273 | dst += G723_PERIOD_BYTES; | ||
274 | } | ||
275 | |||
276 | return 0; | ||
268 | } | 277 | } |
269 | 278 | ||
270 | static const struct snd_pcm_ops snd_solo_pcm_ops = { | 279 | static const struct snd_pcm_ops snd_solo_pcm_ops = { |
diff --git a/drivers/media/pci/solo6x10/solo6x10-p2m.c b/drivers/media/pci/solo6x10/solo6x10-p2m.c index 8c8484674d2f..46c30430e30b 100644 --- a/drivers/media/pci/solo6x10/solo6x10-p2m.c +++ b/drivers/media/pci/solo6x10/solo6x10-p2m.c | |||
@@ -69,14 +69,11 @@ int solo_p2m_dma_desc(struct solo_dev *solo_dev, | |||
69 | unsigned int timeout; | 69 | unsigned int timeout; |
70 | unsigned int config = 0; | 70 | unsigned int config = 0; |
71 | int ret = 0; | 71 | int ret = 0; |
72 | int p2m_id = 0; | 72 | unsigned int p2m_id = 0; |
73 | 73 | ||
74 | /* Get next ID. According to Softlogic, 6110 has problems on !=0 P2M */ | 74 | /* Get next ID. According to Softlogic, 6110 has problems on !=0 P2M */ |
75 | if (solo_dev->type != SOLO_DEV_6110 && multi_p2m) { | 75 | if (solo_dev->type != SOLO_DEV_6110 && multi_p2m) |
76 | p2m_id = atomic_inc_return(&solo_dev->p2m_count) % SOLO_NR_P2M; | 76 | p2m_id = atomic_inc_return(&solo_dev->p2m_count) % SOLO_NR_P2M; |
77 | if (p2m_id < 0) | ||
78 | p2m_id = -p2m_id; | ||
79 | } | ||
80 | 77 | ||
81 | p2m_dev = &solo_dev->p2m_dev[p2m_id]; | 78 | p2m_dev = &solo_dev->p2m_dev[p2m_id]; |
82 | 79 | ||
diff --git a/drivers/media/pci/ttpci/ttpci-eeprom.c b/drivers/media/pci/ttpci/ttpci-eeprom.c index 9534f29c1ffd..78c7a6589be5 100644 --- a/drivers/media/pci/ttpci/ttpci-eeprom.c +++ b/drivers/media/pci/ttpci/ttpci-eeprom.c | |||
@@ -138,7 +138,7 @@ static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encode | |||
138 | 138 | ||
139 | int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac) | 139 | int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac) |
140 | { | 140 | { |
141 | int ret, i; | 141 | int ret; |
142 | u8 encodedMAC[20]; | 142 | u8 encodedMAC[20]; |
143 | u8 decodedMAC[6]; | 143 | u8 decodedMAC[6]; |
144 | 144 | ||
@@ -153,11 +153,8 @@ int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac) | |||
153 | ret = getmac_tt(decodedMAC, encodedMAC); | 153 | ret = getmac_tt(decodedMAC, encodedMAC); |
154 | if( ret != 0 ) { | 154 | if( ret != 0 ) { |
155 | dprintk("adapter failed MAC signature check\n"); | 155 | dprintk("adapter failed MAC signature check\n"); |
156 | dprintk("encoded MAC from EEPROM was " ); | 156 | dprintk("encoded MAC from EEPROM was %*phC", |
157 | for(i=0; i<19; i++) { | 157 | (int)sizeof(encodedMAC), &encodedMAC); |
158 | dprintk( "%.2x:", encodedMAC[i]); | ||
159 | } | ||
160 | dprintk("%.2x\n", encodedMAC[19]); | ||
161 | eth_zero_addr(proposed_mac); | 158 | eth_zero_addr(proposed_mac); |
162 | return ret; | 159 | return ret; |
163 | } | 160 | } |
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index 8d4e7d930a66..14f9c0e26a1c 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c | |||
@@ -241,8 +241,8 @@ static int v4l_fbuffer_alloc(struct zoran_fh *fh) | |||
241 | SetPageReserved(virt_to_page(mem + off)); | 241 | SetPageReserved(virt_to_page(mem + off)); |
242 | dprintk(4, | 242 | dprintk(4, |
243 | KERN_INFO | 243 | KERN_INFO |
244 | "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", | 244 | "%s: %s - V4L frame %d mem %p (bus: 0x%llx)\n", |
245 | ZR_DEVNAME(zr), __func__, i, (unsigned long) mem, | 245 | ZR_DEVNAME(zr), __func__, i, mem, |
246 | (unsigned long long)virt_to_bus(mem)); | 246 | (unsigned long long)virt_to_bus(mem)); |
247 | } | 247 | } |
248 | 248 | ||
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 6df9ec377482..c7a1cf8a1b01 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
@@ -122,6 +122,15 @@ config VIDEO_STM32_DCMI | |||
122 | To compile this driver as a module, choose M here: the module | 122 | To compile this driver as a module, choose M here: the module |
123 | will be called stm32-dcmi. | 123 | will be called stm32-dcmi. |
124 | 124 | ||
125 | config VIDEO_RENESAS_CEU | ||
126 | tristate "Renesas Capture Engine Unit (CEU) driver" | ||
127 | depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA | ||
128 | depends on ARCH_SHMOBILE || ARCH_R7S72100 || COMPILE_TEST | ||
129 | select VIDEOBUF2_DMA_CONTIG | ||
130 | select V4L2_FWNODE | ||
131 | ---help--- | ||
132 | This is a v4l2 driver for the Renesas CEU Interface | ||
133 | |||
125 | source "drivers/media/platform/soc_camera/Kconfig" | 134 | source "drivers/media/platform/soc_camera/Kconfig" |
126 | source "drivers/media/platform/exynos4-is/Kconfig" | 135 | source "drivers/media/platform/exynos4-is/Kconfig" |
127 | source "drivers/media/platform/am437x/Kconfig" | 136 | source "drivers/media/platform/am437x/Kconfig" |
@@ -560,7 +569,7 @@ config CEC_GPIO | |||
560 | 569 | ||
561 | config VIDEO_SAMSUNG_S5P_CEC | 570 | config VIDEO_SAMSUNG_S5P_CEC |
562 | tristate "Samsung S5P CEC driver" | 571 | tristate "Samsung S5P CEC driver" |
563 | depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST | 572 | depends on ARCH_EXYNOS || COMPILE_TEST |
564 | select CEC_CORE | 573 | select CEC_CORE |
565 | select CEC_NOTIFIER | 574 | select CEC_NOTIFIER |
566 | ---help--- | 575 | ---help--- |
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index db96a3cb18dd..932515df4477 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o | |||
58 | obj-$(CONFIG_SOC_CAMERA) += soc_camera/ | 58 | obj-$(CONFIG_SOC_CAMERA) += soc_camera/ |
59 | 59 | ||
60 | obj-$(CONFIG_VIDEO_RCAR_DRIF) += rcar_drif.o | 60 | obj-$(CONFIG_VIDEO_RCAR_DRIF) += rcar_drif.o |
61 | obj-$(CONFIG_VIDEO_RENESAS_CEU) += renesas-ceu.o | ||
61 | obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o | 62 | obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o |
62 | obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o | 63 | obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o |
63 | obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o | 64 | obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o |
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index 34676409ca08..d89e14524d42 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c | |||
@@ -335,7 +335,7 @@ static struct isc_format formats_list[] = { | |||
335 | }, | 335 | }, |
336 | }; | 336 | }; |
337 | 337 | ||
338 | struct fmt_config fmt_configs_list[] = { | 338 | static struct fmt_config fmt_configs_list[] = { |
339 | { | 339 | { |
340 | .fourcc = V4L2_PIX_FMT_SBGGR8, | 340 | .fourcc = V4L2_PIX_FMT_SBGGR8, |
341 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 341 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
@@ -1417,20 +1417,14 @@ static int isc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | |||
1417 | { | 1417 | { |
1418 | struct isc_device *isc = video_drvdata(file); | 1418 | struct isc_device *isc = video_drvdata(file); |
1419 | 1419 | ||
1420 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1420 | return v4l2_g_parm_cap(video_devdata(file), isc->current_subdev->sd, a); |
1421 | return -EINVAL; | ||
1422 | |||
1423 | return v4l2_subdev_call(isc->current_subdev->sd, video, g_parm, a); | ||
1424 | } | 1421 | } |
1425 | 1422 | ||
1426 | static int isc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | 1423 | static int isc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) |
1427 | { | 1424 | { |
1428 | struct isc_device *isc = video_drvdata(file); | 1425 | struct isc_device *isc = video_drvdata(file); |
1429 | 1426 | ||
1430 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1427 | return v4l2_s_parm_cap(video_devdata(file), isc->current_subdev->sd, a); |
1431 | return -EINVAL; | ||
1432 | |||
1433 | return v4l2_subdev_call(isc->current_subdev->sd, video, s_parm, a); | ||
1434 | } | 1428 | } |
1435 | 1429 | ||
1436 | static int isc_enum_framesizes(struct file *file, void *fh, | 1430 | static int isc_enum_framesizes(struct file *file, void *fh, |
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index 9958918e2449..e5be21a31640 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c | |||
@@ -689,22 +689,14 @@ static int isi_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | |||
689 | { | 689 | { |
690 | struct atmel_isi *isi = video_drvdata(file); | 690 | struct atmel_isi *isi = video_drvdata(file); |
691 | 691 | ||
692 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 692 | return v4l2_g_parm_cap(video_devdata(file), isi->entity.subdev, a); |
693 | return -EINVAL; | ||
694 | |||
695 | a->parm.capture.readbuffers = 2; | ||
696 | return v4l2_subdev_call(isi->entity.subdev, video, g_parm, a); | ||
697 | } | 693 | } |
698 | 694 | ||
699 | static int isi_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | 695 | static int isi_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) |
700 | { | 696 | { |
701 | struct atmel_isi *isi = video_drvdata(file); | 697 | struct atmel_isi *isi = video_drvdata(file); |
702 | 698 | ||
703 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 699 | return v4l2_s_parm_cap(video_devdata(file), isi->entity.subdev, a); |
704 | return -EINVAL; | ||
705 | |||
706 | a->parm.capture.readbuffers = 2; | ||
707 | return v4l2_subdev_call(isi->entity.subdev, video, s_parm, a); | ||
708 | } | 700 | } |
709 | 701 | ||
710 | static int isi_enum_framesizes(struct file *file, void *fh, | 702 | static int isi_enum_framesizes(struct file *file, void *fh, |
diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c b/drivers/media/platform/cec-gpio/cec-gpio.c index 5debdf08fbe7..f1f28cf5c751 100644 --- a/drivers/media/platform/cec-gpio/cec-gpio.c +++ b/drivers/media/platform/cec-gpio/cec-gpio.c | |||
@@ -1,18 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 3 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
3 | * | ||
4 | * This program is free software; you may redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
9 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
10 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
11 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
12 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
15 | * SOFTWARE. | ||
16 | */ | 4 | */ |
17 | 5 | ||
18 | #include <linux/module.h> | 6 | #include <linux/module.h> |
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 9fe113cb901f..68ed2a564ad1 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c | |||
@@ -68,8 +68,9 @@ static void coda_command_async(struct coda_ctx *ctx, int cmd) | |||
68 | { | 68 | { |
69 | struct coda_dev *dev = ctx->dev; | 69 | struct coda_dev *dev = ctx->dev; |
70 | 70 | ||
71 | if (dev->devtype->product == CODA_960 || | 71 | if (dev->devtype->product == CODA_HX4 || |
72 | dev->devtype->product == CODA_7541) { | 72 | dev->devtype->product == CODA_7541 || |
73 | dev->devtype->product == CODA_960) { | ||
73 | /* Restore context related registers to CODA */ | 74 | /* Restore context related registers to CODA */ |
74 | coda_write(dev, ctx->bit_stream_param, | 75 | coda_write(dev, ctx->bit_stream_param, |
75 | CODA_REG_BIT_BIT_STREAM_PARAM); | 76 | CODA_REG_BIT_BIT_STREAM_PARAM); |
@@ -506,7 +507,8 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, | |||
506 | goto err; | 507 | goto err; |
507 | } | 508 | } |
508 | 509 | ||
509 | if (!ctx->psbuf.vaddr && dev->devtype->product == CODA_7541) { | 510 | if (!ctx->psbuf.vaddr && (dev->devtype->product == CODA_HX4 || |
511 | dev->devtype->product == CODA_7541)) { | ||
510 | ret = coda_alloc_context_buf(ctx, &ctx->psbuf, | 512 | ret = coda_alloc_context_buf(ctx, &ctx->psbuf, |
511 | CODA7_PS_BUF_SIZE, "psbuf"); | 513 | CODA7_PS_BUF_SIZE, "psbuf"); |
512 | if (ret < 0) | 514 | if (ret < 0) |
@@ -594,6 +596,7 @@ static void coda_setup_iram(struct coda_ctx *ctx) | |||
594 | int dbk_bits; | 596 | int dbk_bits; |
595 | int bit_bits; | 597 | int bit_bits; |
596 | int ip_bits; | 598 | int ip_bits; |
599 | int me_bits; | ||
597 | 600 | ||
598 | memset(iram_info, 0, sizeof(*iram_info)); | 601 | memset(iram_info, 0, sizeof(*iram_info)); |
599 | iram_info->next_paddr = dev->iram.paddr; | 602 | iram_info->next_paddr = dev->iram.paddr; |
@@ -603,15 +606,23 @@ static void coda_setup_iram(struct coda_ctx *ctx) | |||
603 | return; | 606 | return; |
604 | 607 | ||
605 | switch (dev->devtype->product) { | 608 | switch (dev->devtype->product) { |
609 | case CODA_HX4: | ||
610 | dbk_bits = CODA7_USE_HOST_DBK_ENABLE; | ||
611 | bit_bits = CODA7_USE_HOST_BIT_ENABLE; | ||
612 | ip_bits = CODA7_USE_HOST_IP_ENABLE; | ||
613 | me_bits = CODA7_USE_HOST_ME_ENABLE; | ||
614 | break; | ||
606 | case CODA_7541: | 615 | case CODA_7541: |
607 | dbk_bits = CODA7_USE_HOST_DBK_ENABLE | CODA7_USE_DBK_ENABLE; | 616 | dbk_bits = CODA7_USE_HOST_DBK_ENABLE | CODA7_USE_DBK_ENABLE; |
608 | bit_bits = CODA7_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE; | 617 | bit_bits = CODA7_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE; |
609 | ip_bits = CODA7_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE; | 618 | ip_bits = CODA7_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE; |
619 | me_bits = CODA7_USE_HOST_ME_ENABLE | CODA7_USE_ME_ENABLE; | ||
610 | break; | 620 | break; |
611 | case CODA_960: | 621 | case CODA_960: |
612 | dbk_bits = CODA9_USE_HOST_DBK_ENABLE | CODA9_USE_DBK_ENABLE; | 622 | dbk_bits = CODA9_USE_HOST_DBK_ENABLE | CODA9_USE_DBK_ENABLE; |
613 | bit_bits = CODA9_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE; | 623 | bit_bits = CODA9_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE; |
614 | ip_bits = CODA9_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE; | 624 | ip_bits = CODA9_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE; |
625 | me_bits = 0; | ||
615 | break; | 626 | break; |
616 | default: /* CODA_DX6 */ | 627 | default: /* CODA_DX6 */ |
617 | return; | 628 | return; |
@@ -626,7 +637,8 @@ static void coda_setup_iram(struct coda_ctx *ctx) | |||
626 | w64 = mb_width * 64; | 637 | w64 = mb_width * 64; |
627 | 638 | ||
628 | /* Prioritize in case IRAM is too small for everything */ | 639 | /* Prioritize in case IRAM is too small for everything */ |
629 | if (dev->devtype->product == CODA_7541) { | 640 | if (dev->devtype->product == CODA_HX4 || |
641 | dev->devtype->product == CODA_7541) { | ||
630 | iram_info->search_ram_size = round_up(mb_width * 16 * | 642 | iram_info->search_ram_size = round_up(mb_width * 16 * |
631 | 36 + 2048, 1024); | 643 | 36 + 2048, 1024); |
632 | iram_info->search_ram_paddr = coda_iram_alloc(iram_info, | 644 | iram_info->search_ram_paddr = coda_iram_alloc(iram_info, |
@@ -635,8 +647,7 @@ static void coda_setup_iram(struct coda_ctx *ctx) | |||
635 | pr_err("IRAM is smaller than the search ram size\n"); | 647 | pr_err("IRAM is smaller than the search ram size\n"); |
636 | goto out; | 648 | goto out; |
637 | } | 649 | } |
638 | iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE | | 650 | iram_info->axi_sram_use |= me_bits; |
639 | CODA7_USE_ME_ENABLE; | ||
640 | } | 651 | } |
641 | 652 | ||
642 | /* Only H.264BP and H.263P3 are considered */ | 653 | /* Only H.264BP and H.263P3 are considered */ |
@@ -688,7 +699,8 @@ out: | |||
688 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, | 699 | v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, |
689 | "IRAM smaller than needed\n"); | 700 | "IRAM smaller than needed\n"); |
690 | 701 | ||
691 | if (dev->devtype->product == CODA_7541) { | 702 | if (dev->devtype->product == CODA_HX4 || |
703 | dev->devtype->product == CODA_7541) { | ||
692 | /* TODO - Enabling these causes picture errors on CODA7541 */ | 704 | /* TODO - Enabling these causes picture errors on CODA7541 */ |
693 | if (ctx->inst_type == CODA_INST_DECODER) { | 705 | if (ctx->inst_type == CODA_INST_DECODER) { |
694 | /* fw 1.4.50 */ | 706 | /* fw 1.4.50 */ |
@@ -706,6 +718,7 @@ out: | |||
706 | 718 | ||
707 | static u32 coda_supported_firmwares[] = { | 719 | static u32 coda_supported_firmwares[] = { |
708 | CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5), | 720 | CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5), |
721 | CODA_FIRMWARE_VERNUM(CODA_HX4, 1, 4, 50), | ||
709 | CODA_FIRMWARE_VERNUM(CODA_7541, 1, 4, 50), | 722 | CODA_FIRMWARE_VERNUM(CODA_7541, 1, 4, 50), |
710 | CODA_FIRMWARE_VERNUM(CODA_960, 2, 1, 5), | 723 | CODA_FIRMWARE_VERNUM(CODA_960, 2, 1, 5), |
711 | CODA_FIRMWARE_VERNUM(CODA_960, 2, 3, 10), | 724 | CODA_FIRMWARE_VERNUM(CODA_960, 2, 3, 10), |
@@ -890,6 +903,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) | |||
890 | case CODA_960: | 903 | case CODA_960: |
891 | coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN); | 904 | coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN); |
892 | /* fallthrough */ | 905 | /* fallthrough */ |
906 | case CODA_HX4: | ||
893 | case CODA_7541: | 907 | case CODA_7541: |
894 | coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN | | 908 | coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN | |
895 | CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL); | 909 | CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL); |
@@ -919,6 +933,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) | |||
919 | value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) | 933 | value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) |
920 | << CODA_PICHEIGHT_OFFSET; | 934 | << CODA_PICHEIGHT_OFFSET; |
921 | break; | 935 | break; |
936 | case CODA_HX4: | ||
922 | case CODA_7541: | 937 | case CODA_7541: |
923 | if (dst_fourcc == V4L2_PIX_FMT_H264) { | 938 | if (dst_fourcc == V4L2_PIX_FMT_H264) { |
924 | value = (round_up(q_data_src->width, 16) & | 939 | value = (round_up(q_data_src->width, 16) & |
@@ -1086,6 +1101,7 @@ static int coda_start_encoding(struct coda_ctx *ctx) | |||
1086 | value = FMO_SLICE_SAVE_BUF_SIZE << 7; | 1101 | value = FMO_SLICE_SAVE_BUF_SIZE << 7; |
1087 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); | 1102 | coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO); |
1088 | break; | 1103 | break; |
1104 | case CODA_HX4: | ||
1089 | case CODA_7541: | 1105 | case CODA_7541: |
1090 | coda_write(dev, ctx->iram_info.search_ram_paddr, | 1106 | coda_write(dev, ctx->iram_info.search_ram_paddr, |
1091 | CODA7_CMD_ENC_SEQ_SEARCH_BASE); | 1107 | CODA7_CMD_ENC_SEQ_SEARCH_BASE); |
@@ -1131,7 +1147,8 @@ static int coda_start_encoding(struct coda_ctx *ctx) | |||
1131 | coda_write(dev, num_fb, CODA_CMD_SET_FRAME_BUF_NUM); | 1147 | coda_write(dev, num_fb, CODA_CMD_SET_FRAME_BUF_NUM); |
1132 | coda_write(dev, stride, CODA_CMD_SET_FRAME_BUF_STRIDE); | 1148 | coda_write(dev, stride, CODA_CMD_SET_FRAME_BUF_STRIDE); |
1133 | 1149 | ||
1134 | if (dev->devtype->product == CODA_7541) { | 1150 | if (dev->devtype->product == CODA_HX4 || |
1151 | dev->devtype->product == CODA_7541) { | ||
1135 | coda_write(dev, q_data_src->bytesperline, | 1152 | coda_write(dev, q_data_src->bytesperline, |
1136 | CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE); | 1153 | CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE); |
1137 | } | 1154 | } |
@@ -1570,7 +1587,8 @@ static bool coda_reorder_enable(struct coda_ctx *ctx) | |||
1570 | struct coda_dev *dev = ctx->dev; | 1587 | struct coda_dev *dev = ctx->dev; |
1571 | int profile, level; | 1588 | int profile, level; |
1572 | 1589 | ||
1573 | if (dev->devtype->product != CODA_7541 && | 1590 | if (dev->devtype->product != CODA_HX4 && |
1591 | dev->devtype->product != CODA_7541 && | ||
1574 | dev->devtype->product != CODA_960) | 1592 | dev->devtype->product != CODA_960) |
1575 | return false; | 1593 | return false; |
1576 | 1594 | ||
@@ -1664,7 +1682,8 @@ static int __coda_start_decoding(struct coda_ctx *ctx) | |||
1664 | CODA_CMD_DEC_SEQ_MP4_ASP_CLASS); | 1682 | CODA_CMD_DEC_SEQ_MP4_ASP_CLASS); |
1665 | } | 1683 | } |
1666 | if (src_fourcc == V4L2_PIX_FMT_H264) { | 1684 | if (src_fourcc == V4L2_PIX_FMT_H264) { |
1667 | if (dev->devtype->product == CODA_7541) { | 1685 | if (dev->devtype->product == CODA_HX4 || |
1686 | dev->devtype->product == CODA_7541) { | ||
1668 | coda_write(dev, ctx->psbuf.paddr, | 1687 | coda_write(dev, ctx->psbuf.paddr, |
1669 | CODA_CMD_DEC_SEQ_PS_BB_START); | 1688 | CODA_CMD_DEC_SEQ_PS_BB_START); |
1670 | coda_write(dev, (CODA7_PS_BUF_SIZE / 1024), | 1689 | coda_write(dev, (CODA7_PS_BUF_SIZE / 1024), |
@@ -1791,7 +1810,8 @@ static int __coda_start_decoding(struct coda_ctx *ctx) | |||
1791 | CODA_CMD_SET_FRAME_SLICE_BB_SIZE); | 1810 | CODA_CMD_SET_FRAME_SLICE_BB_SIZE); |
1792 | } | 1811 | } |
1793 | 1812 | ||
1794 | if (dev->devtype->product == CODA_7541) { | 1813 | if (dev->devtype->product == CODA_HX4 || |
1814 | dev->devtype->product == CODA_7541) { | ||
1795 | int max_mb_x = 1920 / 16; | 1815 | int max_mb_x = 1920 / 16; |
1796 | int max_mb_y = 1088 / 16; | 1816 | int max_mb_y = 1088 / 16; |
1797 | int max_mb_num = max_mb_x * max_mb_y; | 1817 | int max_mb_num = max_mb_x * max_mb_y; |
@@ -1909,6 +1929,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx) | |||
1909 | switch (dev->devtype->product) { | 1929 | switch (dev->devtype->product) { |
1910 | case CODA_DX6: | 1930 | case CODA_DX6: |
1911 | /* TBD */ | 1931 | /* TBD */ |
1932 | case CODA_HX4: | ||
1912 | case CODA_7541: | 1933 | case CODA_7541: |
1913 | coda_write(dev, CODA_PRE_SCAN_EN, CODA_CMD_DEC_PIC_OPTION); | 1934 | coda_write(dev, CODA_PRE_SCAN_EN, CODA_CMD_DEC_PIC_OPTION); |
1914 | break; | 1935 | break; |
@@ -2049,7 +2070,8 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
2049 | v4l2_err(&dev->v4l2_dev, | 2070 | v4l2_err(&dev->v4l2_dev, |
2050 | "errors in %d macroblocks\n", err_mb); | 2071 | "errors in %d macroblocks\n", err_mb); |
2051 | 2072 | ||
2052 | if (dev->devtype->product == CODA_7541) { | 2073 | if (dev->devtype->product == CODA_HX4 || |
2074 | dev->devtype->product == CODA_7541) { | ||
2053 | val = coda_read(dev, CODA_RET_DEC_PIC_OPTION); | 2075 | val = coda_read(dev, CODA_RET_DEC_PIC_OPTION); |
2054 | if (val == 0) { | 2076 | if (val == 0) { |
2055 | /* not enough bitstream data */ | 2077 | /* not enough bitstream data */ |
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index e8a7554a61d2..04e35d70ce2e 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c | |||
@@ -128,7 +128,8 @@ void coda_write_base(struct coda_ctx *ctx, struct coda_q_data *q_data, | |||
128 | /* | 128 | /* |
129 | * Arrays of codecs supported by each given version of Coda: | 129 | * Arrays of codecs supported by each given version of Coda: |
130 | * i.MX27 -> codadx6 | 130 | * i.MX27 -> codadx6 |
131 | * i.MX5x -> coda7 | 131 | * i.MX51 -> codahx4 |
132 | * i.MX53 -> coda7 | ||
132 | * i.MX6 -> coda960 | 133 | * i.MX6 -> coda960 |
133 | * Use V4L2_PIX_FMT_YUV420 as placeholder for all supported YUV 4:2:0 variants | 134 | * Use V4L2_PIX_FMT_YUV420 as placeholder for all supported YUV 4:2:0 variants |
134 | */ | 135 | */ |
@@ -137,6 +138,13 @@ static const struct coda_codec codadx6_codecs[] = { | |||
137 | CODA_CODEC(CODADX6_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 720, 576), | 138 | CODA_CODEC(CODADX6_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 720, 576), |
138 | }; | 139 | }; |
139 | 140 | ||
141 | static const struct coda_codec codahx4_codecs[] = { | ||
142 | CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 720, 576), | ||
143 | CODA_CODEC(CODA7_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1088), | ||
144 | CODA_CODEC(CODA7_MODE_DECODE_MP2, V4L2_PIX_FMT_MPEG2, V4L2_PIX_FMT_YUV420, 1920, 1088), | ||
145 | CODA_CODEC(CODA7_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1280, 720), | ||
146 | }; | ||
147 | |||
140 | static const struct coda_codec coda7_codecs[] = { | 148 | static const struct coda_codec coda7_codecs[] = { |
141 | CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1280, 720), | 149 | CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1280, 720), |
142 | CODA_CODEC(CODA7_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1280, 720), | 150 | CODA_CODEC(CODA7_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1280, 720), |
@@ -234,6 +242,11 @@ static const struct coda_video_device *codadx6_video_devices[] = { | |||
234 | &coda_bit_encoder, | 242 | &coda_bit_encoder, |
235 | }; | 243 | }; |
236 | 244 | ||
245 | static const struct coda_video_device *codahx4_video_devices[] = { | ||
246 | &coda_bit_encoder, | ||
247 | &coda_bit_decoder, | ||
248 | }; | ||
249 | |||
237 | static const struct coda_video_device *coda7_video_devices[] = { | 250 | static const struct coda_video_device *coda7_video_devices[] = { |
238 | &coda_bit_jpeg_encoder, | 251 | &coda_bit_jpeg_encoder, |
239 | &coda_bit_jpeg_decoder, | 252 | &coda_bit_jpeg_decoder, |
@@ -332,6 +345,8 @@ const char *coda_product_name(int product) | |||
332 | switch (product) { | 345 | switch (product) { |
333 | case CODA_DX6: | 346 | case CODA_DX6: |
334 | return "CodaDx6"; | 347 | return "CodaDx6"; |
348 | case CODA_HX4: | ||
349 | return "CodaHx4"; | ||
335 | case CODA_7541: | 350 | case CODA_7541: |
336 | return "CODA7541"; | 351 | return "CODA7541"; |
337 | case CODA_960: | 352 | case CODA_960: |
@@ -1775,7 +1790,8 @@ static void coda_encode_ctrls(struct coda_ctx *ctx) | |||
1775 | V4L2_CID_MPEG_VIDEO_H264_PROFILE, | 1790 | V4L2_CID_MPEG_VIDEO_H264_PROFILE, |
1776 | V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 0x0, | 1791 | V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 0x0, |
1777 | V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); | 1792 | V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); |
1778 | if (ctx->dev->devtype->product == CODA_7541) { | 1793 | if (ctx->dev->devtype->product == CODA_HX4 || |
1794 | ctx->dev->devtype->product == CODA_7541) { | ||
1779 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, | 1795 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, |
1780 | V4L2_CID_MPEG_VIDEO_H264_LEVEL, | 1796 | V4L2_CID_MPEG_VIDEO_H264_LEVEL, |
1781 | V4L2_MPEG_VIDEO_H264_LEVEL_3_1, | 1797 | V4L2_MPEG_VIDEO_H264_LEVEL_3_1, |
@@ -1803,7 +1819,8 @@ static void coda_encode_ctrls(struct coda_ctx *ctx) | |||
1803 | V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, | 1819 | V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, |
1804 | V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, 0x0, | 1820 | V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, 0x0, |
1805 | V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); | 1821 | V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); |
1806 | if (ctx->dev->devtype->product == CODA_7541 || | 1822 | if (ctx->dev->devtype->product == CODA_HX4 || |
1823 | ctx->dev->devtype->product == CODA_7541 || | ||
1807 | ctx->dev->devtype->product == CODA_960) { | 1824 | ctx->dev->devtype->product == CODA_960) { |
1808 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, | 1825 | v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, |
1809 | V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, | 1826 | V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, |
@@ -2004,6 +2021,7 @@ static int coda_open(struct file *file) | |||
2004 | if (enable_bwb || ctx->inst_type == CODA_INST_ENCODER) | 2021 | if (enable_bwb || ctx->inst_type == CODA_INST_ENCODER) |
2005 | ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB; | 2022 | ctx->frame_mem_ctrl = CODA9_FRAME_ENABLE_BWB; |
2006 | /* fallthrough */ | 2023 | /* fallthrough */ |
2024 | case CODA_HX4: | ||
2007 | case CODA_7541: | 2025 | case CODA_7541: |
2008 | ctx->reg_idx = 0; | 2026 | ctx->reg_idx = 0; |
2009 | break; | 2027 | break; |
@@ -2182,7 +2200,8 @@ static int coda_hw_init(struct coda_dev *dev) | |||
2182 | 2200 | ||
2183 | /* Tell the BIT where to find everything it needs */ | 2201 | /* Tell the BIT where to find everything it needs */ |
2184 | if (dev->devtype->product == CODA_960 || | 2202 | if (dev->devtype->product == CODA_960 || |
2185 | dev->devtype->product == CODA_7541) { | 2203 | dev->devtype->product == CODA_7541 || |
2204 | dev->devtype->product == CODA_HX4) { | ||
2186 | coda_write(dev, dev->tempbuf.paddr, | 2205 | coda_write(dev, dev->tempbuf.paddr, |
2187 | CODA_REG_BIT_TEMP_BUF_ADDR); | 2206 | CODA_REG_BIT_TEMP_BUF_ADDR); |
2188 | coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); | 2207 | coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM); |
@@ -2387,6 +2406,7 @@ put_pm: | |||
2387 | 2406 | ||
2388 | enum coda_platform { | 2407 | enum coda_platform { |
2389 | CODA_IMX27, | 2408 | CODA_IMX27, |
2409 | CODA_IMX51, | ||
2390 | CODA_IMX53, | 2410 | CODA_IMX53, |
2391 | CODA_IMX6Q, | 2411 | CODA_IMX6Q, |
2392 | CODA_IMX6DL, | 2412 | CODA_IMX6DL, |
@@ -2407,6 +2427,21 @@ static const struct coda_devtype coda_devdata[] = { | |||
2407 | .workbuf_size = 288 * 1024 + FMO_SLICE_SAVE_BUF_SIZE * 8 * 1024, | 2427 | .workbuf_size = 288 * 1024 + FMO_SLICE_SAVE_BUF_SIZE * 8 * 1024, |
2408 | .iram_size = 0xb000, | 2428 | .iram_size = 0xb000, |
2409 | }, | 2429 | }, |
2430 | [CODA_IMX51] = { | ||
2431 | .firmware = { | ||
2432 | "vpu_fw_imx51.bin", | ||
2433 | "vpu/vpu_fw_imx51.bin", | ||
2434 | "v4l-codahx4-imx51.bin" | ||
2435 | }, | ||
2436 | .product = CODA_HX4, | ||
2437 | .codecs = codahx4_codecs, | ||
2438 | .num_codecs = ARRAY_SIZE(codahx4_codecs), | ||
2439 | .vdevs = codahx4_video_devices, | ||
2440 | .num_vdevs = ARRAY_SIZE(codahx4_video_devices), | ||
2441 | .workbuf_size = 128 * 1024, | ||
2442 | .tempbuf_size = 304 * 1024, | ||
2443 | .iram_size = 0x14000, | ||
2444 | }, | ||
2410 | [CODA_IMX53] = { | 2445 | [CODA_IMX53] = { |
2411 | .firmware = { | 2446 | .firmware = { |
2412 | "vpu_fw_imx53.bin", | 2447 | "vpu_fw_imx53.bin", |
@@ -2463,6 +2498,7 @@ MODULE_DEVICE_TABLE(platform, coda_platform_ids); | |||
2463 | #ifdef CONFIG_OF | 2498 | #ifdef CONFIG_OF |
2464 | static const struct of_device_id coda_dt_ids[] = { | 2499 | static const struct of_device_id coda_dt_ids[] = { |
2465 | { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] }, | 2500 | { .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] }, |
2501 | { .compatible = "fsl,imx51-vpu", .data = &coda_devdata[CODA_IMX51] }, | ||
2466 | { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] }, | 2502 | { .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] }, |
2467 | { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] }, | 2503 | { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] }, |
2468 | { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] }, | 2504 | { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] }, |
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h index c5f504d8cf67..c70cfab2433f 100644 --- a/drivers/media/platform/coda/coda.h +++ b/drivers/media/platform/coda/coda.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #include "coda_regs.h" | 29 | #include "coda_regs.h" |
30 | 30 | ||
31 | #define CODA_MAX_FRAMEBUFFERS 17 | 31 | #define CODA_MAX_FRAMEBUFFERS 19 |
32 | #define FMO_SLICE_SAVE_BUF_SIZE (32) | 32 | #define FMO_SLICE_SAVE_BUF_SIZE (32) |
33 | 33 | ||
34 | enum { | 34 | enum { |
@@ -43,6 +43,7 @@ enum coda_inst_type { | |||
43 | 43 | ||
44 | enum coda_product { | 44 | enum coda_product { |
45 | CODA_DX6 = 0xf001, | 45 | CODA_DX6 = 0xf001, |
46 | CODA_HX4 = 0xf00a, | ||
46 | CODA_7541 = 0xf012, | 47 | CODA_7541 = 0xf012, |
47 | CODA_960 = 0xf020, | 48 | CODA_960 = 0xf020, |
48 | }; | 49 | }; |
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c index b73886519f4f..19cf6853411e 100644 --- a/drivers/media/platform/davinci/vpss.c +++ b/drivers/media/platform/davinci/vpss.c | |||
@@ -116,7 +116,7 @@ struct vpss_hw_ops { | |||
116 | struct vpss_oper_config { | 116 | struct vpss_oper_config { |
117 | __iomem void *vpss_regs_base0; | 117 | __iomem void *vpss_regs_base0; |
118 | __iomem void *vpss_regs_base1; | 118 | __iomem void *vpss_regs_base1; |
119 | resource_size_t *vpss_regs_base2; | 119 | __iomem void *vpss_regs_base2; |
120 | enum vpss_platform_type platform; | 120 | enum vpss_platform_type platform; |
121 | spinlock_t vpss_lock; | 121 | spinlock_t vpss_lock; |
122 | struct vpss_hw_ops hw_ops; | 122 | struct vpss_hw_ops hw_ops; |
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index ed9302caa004..a3cdac188190 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c | |||
@@ -670,10 +670,13 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx, | |||
670 | return; | 670 | return; |
671 | } | 671 | } |
672 | if (target == V4L2_SEL_TGT_COMPOSE) { | 672 | if (target == V4L2_SEL_TGT_COMPOSE) { |
673 | u32 tmp_min_h = ffs(sink->width) - 3; | ||
674 | u32 tmp_min_v = ffs(sink->height) - 1; | ||
675 | |||
673 | if (ctx->rotation != 90 && ctx->rotation != 270) | 676 | if (ctx->rotation != 90 && ctx->rotation != 270) |
674 | align_h = 1; | 677 | align_h = 1; |
675 | max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3)); | 678 | max_sc_h = min(SCALER_MAX_HRATIO, 1 << tmp_min_h); |
676 | max_sc_v = min(SCALER_MAX_VRATIO, 1 << (ffs(sink->height) - 1)); | 679 | max_sc_v = min(SCALER_MAX_VRATIO, 1 << tmp_min_v); |
677 | min_sz = var->min_out_pixsize; | 680 | min_sz = var->min_out_pixsize; |
678 | } else { | 681 | } else { |
679 | u32 depth = fimc_get_format_depth(sink->fmt); | 682 | u32 depth = fimc_get_format_depth(sink->fmt); |
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c index cfe4406a83ff..e0e291066037 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-regs.c +++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c | |||
@@ -159,7 +159,7 @@ void fimc_is_hw_load_setfile(struct fimc_is *is) | |||
159 | 159 | ||
160 | int fimc_is_hw_change_mode(struct fimc_is *is) | 160 | int fimc_is_hw_change_mode(struct fimc_is *is) |
161 | { | 161 | { |
162 | const u8 cmd[] = { | 162 | static const u8 cmd[] = { |
163 | HIC_PREVIEW_STILL, HIC_PREVIEW_VIDEO, | 163 | HIC_PREVIEW_STILL, HIC_PREVIEW_VIDEO, |
164 | HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO, | 164 | HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO, |
165 | }; | 165 | }; |
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 7b7250b1cff8..80670eeee142 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c | |||
@@ -1443,24 +1443,24 @@ static int mcam_vidioc_s_input(struct file *filp, void *priv, unsigned int i) | |||
1443 | * the level which controls the number of read buffers. | 1443 | * the level which controls the number of read buffers. |
1444 | */ | 1444 | */ |
1445 | static int mcam_vidioc_g_parm(struct file *filp, void *priv, | 1445 | static int mcam_vidioc_g_parm(struct file *filp, void *priv, |
1446 | struct v4l2_streamparm *parms) | 1446 | struct v4l2_streamparm *a) |
1447 | { | 1447 | { |
1448 | struct mcam_camera *cam = video_drvdata(filp); | 1448 | struct mcam_camera *cam = video_drvdata(filp); |
1449 | int ret; | 1449 | int ret; |
1450 | 1450 | ||
1451 | ret = sensor_call(cam, video, g_parm, parms); | 1451 | ret = v4l2_g_parm_cap(video_devdata(filp), cam->sensor, a); |
1452 | parms->parm.capture.readbuffers = n_dma_bufs; | 1452 | a->parm.capture.readbuffers = n_dma_bufs; |
1453 | return ret; | 1453 | return ret; |
1454 | } | 1454 | } |
1455 | 1455 | ||
1456 | static int mcam_vidioc_s_parm(struct file *filp, void *priv, | 1456 | static int mcam_vidioc_s_parm(struct file *filp, void *priv, |
1457 | struct v4l2_streamparm *parms) | 1457 | struct v4l2_streamparm *a) |
1458 | { | 1458 | { |
1459 | struct mcam_camera *cam = video_drvdata(filp); | 1459 | struct mcam_camera *cam = video_drvdata(filp); |
1460 | int ret; | 1460 | int ret; |
1461 | 1461 | ||
1462 | ret = sensor_call(cam, video, s_parm, parms); | 1462 | ret = v4l2_s_parm_cap(video_devdata(filp), cam->sensor, a); |
1463 | parms->parm.capture.readbuffers = n_dma_bufs; | 1463 | a->parm.capture.readbuffers = n_dma_bufs; |
1464 | return ret; | 1464 | return ret; |
1465 | } | 1465 | } |
1466 | 1466 | ||
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 843510979ad8..86f0a7134365 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | |||
@@ -1224,6 +1224,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) | |||
1224 | ctx->dpb_size = dpbsize; | 1224 | ctx->dpb_size = dpbsize; |
1225 | ctx->state = MTK_STATE_HEADER; | 1225 | ctx->state = MTK_STATE_HEADER; |
1226 | mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size); | 1226 | mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size); |
1227 | |||
1228 | mtk_vdec_queue_res_chg_event(ctx); | ||
1227 | } | 1229 | } |
1228 | 1230 | ||
1229 | static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) | 1231 | static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) |
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index 123c2b26a933..1d8508237220 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c | |||
@@ -236,7 +236,6 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, | |||
236 | struct dma_async_tx_descriptor *tx; | 236 | struct dma_async_tx_descriptor *tx; |
237 | enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; | 237 | enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; |
238 | struct dma_chan *chan = vout->vrfb_dma_tx.chan; | 238 | struct dma_chan *chan = vout->vrfb_dma_tx.chan; |
239 | struct dma_device *dmadev = chan->device; | ||
240 | struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; | 239 | struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; |
241 | dma_cookie_t cookie; | 240 | dma_cookie_t cookie; |
242 | enum dma_status status; | 241 | enum dma_status status; |
@@ -271,7 +270,7 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, | |||
271 | xt->dst_sgl = true; | 270 | xt->dst_sgl = true; |
272 | xt->dst_inc = true; | 271 | xt->dst_inc = true; |
273 | 272 | ||
274 | tx = dmadev->device_prep_interleaved_dma(chan, xt, flags); | 273 | tx = dmaengine_prep_interleaved_dma(chan, xt, flags); |
275 | if (tx == NULL) { | 274 | if (tx == NULL) { |
276 | pr_err("%s: DMA interleaved prep error\n", __func__); | 275 | pr_err("%s: DMA interleaved prep error\n", __func__); |
277 | return -EINVAL; | 276 | return -EINVAL; |
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c b/drivers/media/platform/qcom/venus/hfi_msgs.c index a681ae5381d6..90c93d9603dc 100644 --- a/drivers/media/platform/qcom/venus/hfi_msgs.c +++ b/drivers/media/platform/qcom/venus/hfi_msgs.c | |||
@@ -659,10 +659,10 @@ static u32 init_done_read_prop(struct venus_core *core, struct venus_inst *inst, | |||
659 | prop->buffer_type == HFI_BUFFER_OUTPUT2) { | 659 | prop->buffer_type == HFI_BUFFER_OUTPUT2) { |
660 | switch (prop->data[i]) { | 660 | switch (prop->data[i]) { |
661 | case HFI_BUFFER_MODE_STATIC: | 661 | case HFI_BUFFER_MODE_STATIC: |
662 | inst->cap_bufs_mode_static = 1; | 662 | inst->cap_bufs_mode_static = true; |
663 | break; | 663 | break; |
664 | case HFI_BUFFER_MODE_DYNAMIC: | 664 | case HFI_BUFFER_MODE_DYNAMIC: |
665 | inst->cap_bufs_mode_dynamic = 1; | 665 | inst->cap_bufs_mode_dynamic = true; |
666 | break; | 666 | break; |
667 | default: | 667 | default: |
668 | break; | 668 | break; |
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 23fdff7a7370..4a40e6ad1be7 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c | |||
@@ -168,12 +168,8 @@ static int rvin_setup(struct rvin_dev *vin) | |||
168 | break; | 168 | break; |
169 | case V4L2_FIELD_ALTERNATE: | 169 | case V4L2_FIELD_ALTERNATE: |
170 | case V4L2_FIELD_NONE: | 170 | case V4L2_FIELD_NONE: |
171 | if (vin->continuous) { | 171 | vnmc = VNMC_IM_ODD_EVEN; |
172 | vnmc = VNMC_IM_ODD_EVEN; | 172 | progressive = true; |
173 | progressive = true; | ||
174 | } else { | ||
175 | vnmc = VNMC_IM_ODD; | ||
176 | } | ||
177 | break; | 173 | break; |
178 | default: | 174 | default: |
179 | vnmc = VNMC_IM_ODD; | 175 | vnmc = VNMC_IM_ODD; |
@@ -298,14 +294,6 @@ static bool rvin_capture_active(struct rvin_dev *vin) | |||
298 | return rvin_read(vin, VNMS_REG) & VNMS_CA; | 294 | return rvin_read(vin, VNMS_REG) & VNMS_CA; |
299 | } | 295 | } |
300 | 296 | ||
301 | static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms) | ||
302 | { | ||
303 | if (vin->continuous) | ||
304 | return (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT; | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) | 297 | static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) |
310 | { | 298 | { |
311 | if (vin->format.field == V4L2_FIELD_ALTERNATE) { | 299 | if (vin->format.field == V4L2_FIELD_ALTERNATE) { |
@@ -344,76 +332,47 @@ static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) | |||
344 | rvin_write(vin, offset, VNMB_REG(slot)); | 332 | rvin_write(vin, offset, VNMB_REG(slot)); |
345 | } | 333 | } |
346 | 334 | ||
347 | /* Moves a buffer from the queue to the HW slots */ | 335 | /* |
348 | static bool rvin_fill_hw_slot(struct rvin_dev *vin, int slot) | 336 | * Moves a buffer from the queue to the HW slot. If no buffer is |
337 | * available use the scratch buffer. The scratch buffer is never | ||
338 | * returned to userspace, its only function is to enable the capture | ||
339 | * loop to keep running. | ||
340 | */ | ||
341 | static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot) | ||
349 | { | 342 | { |
350 | struct rvin_buffer *buf; | 343 | struct rvin_buffer *buf; |
351 | struct vb2_v4l2_buffer *vbuf; | 344 | struct vb2_v4l2_buffer *vbuf; |
352 | dma_addr_t phys_addr_top; | 345 | dma_addr_t phys_addr; |
353 | |||
354 | if (vin->queue_buf[slot] != NULL) | ||
355 | return true; | ||
356 | 346 | ||
357 | if (list_empty(&vin->buf_list)) | 347 | /* A already populated slot shall never be overwritten. */ |
358 | return false; | 348 | if (WARN_ON(vin->queue_buf[slot] != NULL)) |
349 | return; | ||
359 | 350 | ||
360 | vin_dbg(vin, "Filling HW slot: %d\n", slot); | 351 | vin_dbg(vin, "Filling HW slot: %d\n", slot); |
361 | 352 | ||
362 | /* Keep track of buffer we give to HW */ | 353 | if (list_empty(&vin->buf_list)) { |
363 | buf = list_entry(vin->buf_list.next, struct rvin_buffer, list); | 354 | vin->queue_buf[slot] = NULL; |
364 | vbuf = &buf->vb; | 355 | phys_addr = vin->scratch_phys; |
365 | list_del_init(to_buf_list(vbuf)); | 356 | } else { |
366 | vin->queue_buf[slot] = vbuf; | 357 | /* Keep track of buffer we give to HW */ |
367 | 358 | buf = list_entry(vin->buf_list.next, struct rvin_buffer, list); | |
368 | /* Setup DMA */ | 359 | vbuf = &buf->vb; |
369 | phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); | 360 | list_del_init(to_buf_list(vbuf)); |
370 | rvin_set_slot_addr(vin, slot, phys_addr_top); | 361 | vin->queue_buf[slot] = vbuf; |
371 | 362 | ||
372 | return true; | 363 | /* Setup DMA */ |
373 | } | 364 | phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); |
374 | 365 | } | |
375 | static bool rvin_fill_hw(struct rvin_dev *vin) | ||
376 | { | ||
377 | int slot, limit; | ||
378 | |||
379 | limit = vin->continuous ? HW_BUFFER_NUM : 1; | ||
380 | |||
381 | for (slot = 0; slot < limit; slot++) | ||
382 | if (!rvin_fill_hw_slot(vin, slot)) | ||
383 | return false; | ||
384 | return true; | ||
385 | } | ||
386 | |||
387 | static void rvin_capture_on(struct rvin_dev *vin) | ||
388 | { | ||
389 | vin_dbg(vin, "Capture on in %s mode\n", | ||
390 | vin->continuous ? "continuous" : "single"); | ||
391 | 366 | ||
392 | if (vin->continuous) | 367 | rvin_set_slot_addr(vin, slot, phys_addr); |
393 | /* Continuous Frame Capture Mode */ | ||
394 | rvin_write(vin, VNFC_C_FRAME, VNFC_REG); | ||
395 | else | ||
396 | /* Single Frame Capture Mode */ | ||
397 | rvin_write(vin, VNFC_S_FRAME, VNFC_REG); | ||
398 | } | 368 | } |
399 | 369 | ||
400 | static int rvin_capture_start(struct rvin_dev *vin) | 370 | static int rvin_capture_start(struct rvin_dev *vin) |
401 | { | 371 | { |
402 | struct rvin_buffer *buf, *node; | 372 | int slot, ret; |
403 | int bufs, ret; | ||
404 | |||
405 | /* Count number of free buffers */ | ||
406 | bufs = 0; | ||
407 | list_for_each_entry_safe(buf, node, &vin->buf_list, list) | ||
408 | bufs++; | ||
409 | 373 | ||
410 | /* Continuous capture requires more buffers then there are HW slots */ | 374 | for (slot = 0; slot < HW_BUFFER_NUM; slot++) |
411 | vin->continuous = bufs > HW_BUFFER_NUM; | 375 | rvin_fill_hw_slot(vin, slot); |
412 | |||
413 | if (!rvin_fill_hw(vin)) { | ||
414 | vin_err(vin, "HW not ready to start, not enough buffers available\n"); | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | 376 | ||
418 | rvin_crop_scale_comp(vin); | 377 | rvin_crop_scale_comp(vin); |
419 | 378 | ||
@@ -421,7 +380,10 @@ static int rvin_capture_start(struct rvin_dev *vin) | |||
421 | if (ret) | 380 | if (ret) |
422 | return ret; | 381 | return ret; |
423 | 382 | ||
424 | rvin_capture_on(vin); | 383 | vin_dbg(vin, "Starting to capture\n"); |
384 | |||
385 | /* Continuous Frame Capture Mode */ | ||
386 | rvin_write(vin, VNFC_C_FRAME, VNFC_REG); | ||
425 | 387 | ||
426 | vin->state = RUNNING; | 388 | vin->state = RUNNING; |
427 | 389 | ||
@@ -904,7 +866,7 @@ static irqreturn_t rvin_irq(int irq, void *data) | |||
904 | struct rvin_dev *vin = data; | 866 | struct rvin_dev *vin = data; |
905 | u32 int_status, vnms; | 867 | u32 int_status, vnms; |
906 | int slot; | 868 | int slot; |
907 | unsigned int i, sequence, handled = 0; | 869 | unsigned int handled = 0; |
908 | unsigned long flags; | 870 | unsigned long flags; |
909 | 871 | ||
910 | spin_lock_irqsave(&vin->qlock, flags); | 872 | spin_lock_irqsave(&vin->qlock, flags); |
@@ -930,65 +892,25 @@ static irqreturn_t rvin_irq(int irq, void *data) | |||
930 | 892 | ||
931 | /* Prepare for capture and update state */ | 893 | /* Prepare for capture and update state */ |
932 | vnms = rvin_read(vin, VNMS_REG); | 894 | vnms = rvin_read(vin, VNMS_REG); |
933 | slot = rvin_get_active_slot(vin, vnms); | 895 | slot = (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT; |
934 | sequence = vin->sequence++; | ||
935 | |||
936 | vin_dbg(vin, "IRQ %02d: %d\tbuf0: %c buf1: %c buf2: %c\tmore: %d\n", | ||
937 | sequence, slot, | ||
938 | slot == 0 ? 'x' : vin->queue_buf[0] != NULL ? '1' : '0', | ||
939 | slot == 1 ? 'x' : vin->queue_buf[1] != NULL ? '1' : '0', | ||
940 | slot == 2 ? 'x' : vin->queue_buf[2] != NULL ? '1' : '0', | ||
941 | !list_empty(&vin->buf_list)); | ||
942 | |||
943 | /* HW have written to a slot that is not prepared we are in trouble */ | ||
944 | if (WARN_ON((vin->queue_buf[slot] == NULL))) | ||
945 | goto done; | ||
946 | 896 | ||
947 | /* Capture frame */ | 897 | /* Capture frame */ |
948 | vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms); | 898 | if (vin->queue_buf[slot]) { |
949 | vin->queue_buf[slot]->sequence = sequence; | 899 | vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms); |
950 | vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); | 900 | vin->queue_buf[slot]->sequence = vin->sequence; |
951 | vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE); | 901 | vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); |
952 | vin->queue_buf[slot] = NULL; | 902 | vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, |
953 | 903 | VB2_BUF_STATE_DONE); | |
954 | /* Prepare for next frame */ | 904 | vin->queue_buf[slot] = NULL; |
955 | if (!rvin_fill_hw(vin)) { | ||
956 | |||
957 | /* | ||
958 | * Can't supply HW with new buffers fast enough. Halt | ||
959 | * capture until more buffers are available. | ||
960 | */ | ||
961 | vin->state = STALLED; | ||
962 | |||
963 | /* | ||
964 | * The continuous capturing requires an explicit stop | ||
965 | * operation when there is no buffer to be set into | ||
966 | * the VnMBm registers. | ||
967 | */ | ||
968 | if (vin->continuous) { | ||
969 | rvin_capture_stop(vin); | ||
970 | vin_dbg(vin, "IRQ %02d: hw not ready stop\n", sequence); | ||
971 | |||
972 | /* Maybe we can continue in single capture mode */ | ||
973 | for (i = 0; i < HW_BUFFER_NUM; i++) { | ||
974 | if (vin->queue_buf[i]) { | ||
975 | list_add(to_buf_list(vin->queue_buf[i]), | ||
976 | &vin->buf_list); | ||
977 | vin->queue_buf[i] = NULL; | ||
978 | } | ||
979 | } | ||
980 | |||
981 | if (!list_empty(&vin->buf_list)) | ||
982 | rvin_capture_start(vin); | ||
983 | } | ||
984 | } else { | 905 | } else { |
985 | /* | 906 | /* Scratch buffer was used, dropping frame. */ |
986 | * The single capturing requires an explicit capture | 907 | vin_dbg(vin, "Dropping frame %u\n", vin->sequence); |
987 | * operation to fetch the next frame. | ||
988 | */ | ||
989 | if (!vin->continuous) | ||
990 | rvin_capture_on(vin); | ||
991 | } | 908 | } |
909 | |||
910 | vin->sequence++; | ||
911 | |||
912 | /* Prepare for next frame */ | ||
913 | rvin_fill_hw_slot(vin, slot); | ||
992 | done: | 914 | done: |
993 | spin_unlock_irqrestore(&vin->qlock, flags); | 915 | spin_unlock_irqrestore(&vin->qlock, flags); |
994 | 916 | ||
@@ -1059,13 +981,6 @@ static void rvin_buffer_queue(struct vb2_buffer *vb) | |||
1059 | 981 | ||
1060 | list_add_tail(to_buf_list(vbuf), &vin->buf_list); | 982 | list_add_tail(to_buf_list(vbuf), &vin->buf_list); |
1061 | 983 | ||
1062 | /* | ||
1063 | * If capture is stalled add buffer to HW and restart | ||
1064 | * capturing if HW is ready to continue. | ||
1065 | */ | ||
1066 | if (vin->state == STALLED) | ||
1067 | rvin_capture_start(vin); | ||
1068 | |||
1069 | spin_unlock_irqrestore(&vin->qlock, flags); | 984 | spin_unlock_irqrestore(&vin->qlock, flags); |
1070 | } | 985 | } |
1071 | 986 | ||
@@ -1076,6 +991,17 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
1076 | unsigned long flags; | 991 | unsigned long flags; |
1077 | int ret; | 992 | int ret; |
1078 | 993 | ||
994 | /* Allocate scratch buffer. */ | ||
995 | vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage, | ||
996 | &vin->scratch_phys, GFP_KERNEL); | ||
997 | if (!vin->scratch) { | ||
998 | spin_lock_irqsave(&vin->qlock, flags); | ||
999 | return_all_buffers(vin, VB2_BUF_STATE_QUEUED); | ||
1000 | spin_unlock_irqrestore(&vin->qlock, flags); | ||
1001 | vin_err(vin, "Failed to allocate scratch buffer\n"); | ||
1002 | return -ENOMEM; | ||
1003 | } | ||
1004 | |||
1079 | sd = vin_to_source(vin); | 1005 | sd = vin_to_source(vin); |
1080 | v4l2_subdev_call(sd, video, s_stream, 1); | 1006 | v4l2_subdev_call(sd, video, s_stream, 1); |
1081 | 1007 | ||
@@ -1091,6 +1017,10 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
1091 | 1017 | ||
1092 | spin_unlock_irqrestore(&vin->qlock, flags); | 1018 | spin_unlock_irqrestore(&vin->qlock, flags); |
1093 | 1019 | ||
1020 | if (ret) | ||
1021 | dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, | ||
1022 | vin->scratch_phys); | ||
1023 | |||
1094 | return ret; | 1024 | return ret; |
1095 | } | 1025 | } |
1096 | 1026 | ||
@@ -1141,6 +1071,10 @@ static void rvin_stop_streaming(struct vb2_queue *vq) | |||
1141 | 1071 | ||
1142 | /* disable interrupts */ | 1072 | /* disable interrupts */ |
1143 | rvin_disable_interrupts(vin); | 1073 | rvin_disable_interrupts(vin); |
1074 | |||
1075 | /* Free scratch buffer. */ | ||
1076 | dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, | ||
1077 | vin->scratch_phys); | ||
1144 | } | 1078 | } |
1145 | 1079 | ||
1146 | static const struct vb2_ops rvin_qops = { | 1080 | static const struct vb2_ops rvin_qops = { |
@@ -1189,7 +1123,7 @@ int rvin_dma_probe(struct rvin_dev *vin, int irq) | |||
1189 | q->ops = &rvin_qops; | 1123 | q->ops = &rvin_qops; |
1190 | q->mem_ops = &vb2_dma_contig_memops; | 1124 | q->mem_ops = &vb2_dma_contig_memops; |
1191 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | 1125 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
1192 | q->min_buffers_needed = 1; | 1126 | q->min_buffers_needed = 4; |
1193 | q->dev = vin->dev; | 1127 | q->dev = vin->dev; |
1194 | 1128 | ||
1195 | ret = vb2_queue_init(q); | 1129 | ret = vb2_queue_init(q); |
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 5382078143fb..95897127cc41 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h | |||
@@ -38,13 +38,11 @@ enum chip_id { | |||
38 | /** | 38 | /** |
39 | * STOPPED - No operation in progress | 39 | * STOPPED - No operation in progress |
40 | * RUNNING - Operation in progress have buffers | 40 | * RUNNING - Operation in progress have buffers |
41 | * STALLED - No operation in progress have no buffers | ||
42 | * STOPPING - Stopping operation | 41 | * STOPPING - Stopping operation |
43 | */ | 42 | */ |
44 | enum rvin_dma_state { | 43 | enum rvin_dma_state { |
45 | STOPPED = 0, | 44 | STOPPED = 0, |
46 | RUNNING, | 45 | RUNNING, |
47 | STALLED, | ||
48 | STOPPING, | 46 | STOPPING, |
49 | }; | 47 | }; |
50 | 48 | ||
@@ -102,12 +100,13 @@ struct rvin_graph_entity { | |||
102 | * | 100 | * |
103 | * @lock: protects @queue | 101 | * @lock: protects @queue |
104 | * @queue: vb2 buffers queue | 102 | * @queue: vb2 buffers queue |
103 | * @scratch: cpu address for scratch buffer | ||
104 | * @scratch_phys: physical address of the scratch buffer | ||
105 | * | 105 | * |
106 | * @qlock: protects @queue_buf, @buf_list, @continuous, @sequence | 106 | * @qlock: protects @queue_buf, @buf_list, @sequence |
107 | * @state | 107 | * @state |
108 | * @queue_buf: Keeps track of buffers given to HW slot | 108 | * @queue_buf: Keeps track of buffers given to HW slot |
109 | * @buf_list: list of queued buffers | 109 | * @buf_list: list of queued buffers |
110 | * @continuous: tracks if active operation is continuous or single mode | ||
111 | * @sequence: V4L2 buffers sequence number | 110 | * @sequence: V4L2 buffers sequence number |
112 | * @state: keeps track of operation state | 111 | * @state: keeps track of operation state |
113 | * | 112 | * |
@@ -130,11 +129,12 @@ struct rvin_dev { | |||
130 | 129 | ||
131 | struct mutex lock; | 130 | struct mutex lock; |
132 | struct vb2_queue queue; | 131 | struct vb2_queue queue; |
132 | void *scratch; | ||
133 | dma_addr_t scratch_phys; | ||
133 | 134 | ||
134 | spinlock_t qlock; | 135 | spinlock_t qlock; |
135 | struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM]; | 136 | struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM]; |
136 | struct list_head buf_list; | 137 | struct list_head buf_list; |
137 | bool continuous; | ||
138 | unsigned int sequence; | 138 | unsigned int sequence; |
139 | enum rvin_dma_state state; | 139 | enum rvin_dma_state state; |
140 | 140 | ||
diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c index b2e080ef5391..dc7e280c91b4 100644 --- a/drivers/media/platform/rcar_drif.c +++ b/drivers/media/platform/rcar_drif.c | |||
@@ -274,7 +274,7 @@ static int rcar_drif_alloc_dmachannels(struct rcar_drif_sdr *sdr) | |||
274 | { | 274 | { |
275 | struct dma_slave_config dma_cfg; | 275 | struct dma_slave_config dma_cfg; |
276 | unsigned int i; | 276 | unsigned int i; |
277 | int ret = -ENODEV; | 277 | int ret; |
278 | 278 | ||
279 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { | 279 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
280 | struct rcar_drif *ch = sdr->ch[i]; | 280 | struct rcar_drif *ch = sdr->ch[i]; |
@@ -282,6 +282,7 @@ static int rcar_drif_alloc_dmachannels(struct rcar_drif_sdr *sdr) | |||
282 | ch->dmach = dma_request_slave_channel(&ch->pdev->dev, "rx"); | 282 | ch->dmach = dma_request_slave_channel(&ch->pdev->dev, "rx"); |
283 | if (!ch->dmach) { | 283 | if (!ch->dmach) { |
284 | rdrif_err(sdr, "ch%u: dma channel req failed\n", i); | 284 | rdrif_err(sdr, "ch%u: dma channel req failed\n", i); |
285 | ret = -ENODEV; | ||
285 | goto dmach_error; | 286 | goto dmach_error; |
286 | } | 287 | } |
287 | 288 | ||
diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c new file mode 100644 index 000000000000..6599dba5ab84 --- /dev/null +++ b/drivers/media/platform/renesas-ceu.c | |||
@@ -0,0 +1,1677 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * V4L2 Driver for Renesas Capture Engine Unit (CEU) interface | ||
4 | * Copyright (C) 2017-2018 Jacopo Mondi <jacopo+renesas@jmondi.org> | ||
5 | * | ||
6 | * Based on soc-camera driver "soc_camera/sh_mobile_ceu_camera.c" | ||
7 | * Copyright (C) 2008 Magnus Damm | ||
8 | * | ||
9 | * Based on V4L2 Driver for PXA camera host - "pxa_camera.c", | ||
10 | * Copyright (C) 2006, Sascha Hauer, Pengutronix | ||
11 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/of_device.h> | ||
26 | #include <linux/of_graph.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/pm_runtime.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/time.h> | ||
31 | #include <linux/videodev2.h> | ||
32 | |||
33 | #include <media/v4l2-async.h> | ||
34 | #include <media/v4l2-common.h> | ||
35 | #include <media/v4l2-ctrls.h> | ||
36 | #include <media/v4l2-dev.h> | ||
37 | #include <media/v4l2-device.h> | ||
38 | #include <media/v4l2-event.h> | ||
39 | #include <media/v4l2-fwnode.h> | ||
40 | #include <media/v4l2-image-sizes.h> | ||
41 | #include <media/v4l2-ioctl.h> | ||
42 | #include <media/v4l2-mediabus.h> | ||
43 | #include <media/videobuf2-dma-contig.h> | ||
44 | |||
45 | #include <media/drv-intf/renesas-ceu.h> | ||
46 | |||
47 | #define DRIVER_NAME "renesas-ceu" | ||
48 | |||
49 | /* CEU registers offsets and masks. */ | ||
50 | #define CEU_CAPSR 0x00 /* Capture start register */ | ||
51 | #define CEU_CAPCR 0x04 /* Capture control register */ | ||
52 | #define CEU_CAMCR 0x08 /* Capture interface control register */ | ||
53 | #define CEU_CAMOR 0x10 /* Capture interface offset register */ | ||
54 | #define CEU_CAPWR 0x14 /* Capture interface width register */ | ||
55 | #define CEU_CAIFR 0x18 /* Capture interface input format register */ | ||
56 | #define CEU_CRCNTR 0x28 /* CEU register control register */ | ||
57 | #define CEU_CRCMPR 0x2c /* CEU register forcible control register */ | ||
58 | #define CEU_CFLCR 0x30 /* Capture filter control register */ | ||
59 | #define CEU_CFSZR 0x34 /* Capture filter size clip register */ | ||
60 | #define CEU_CDWDR 0x38 /* Capture destination width register */ | ||
61 | #define CEU_CDAYR 0x3c /* Capture data address Y register */ | ||
62 | #define CEU_CDACR 0x40 /* Capture data address C register */ | ||
63 | #define CEU_CFWCR 0x5c /* Firewall operation control register */ | ||
64 | #define CEU_CDOCR 0x64 /* Capture data output control register */ | ||
65 | #define CEU_CEIER 0x70 /* Capture event interrupt enable register */ | ||
66 | #define CEU_CETCR 0x74 /* Capture event flag clear register */ | ||
67 | #define CEU_CSTSR 0x7c /* Capture status register */ | ||
68 | #define CEU_CSRTR 0x80 /* Capture software reset register */ | ||
69 | |||
70 | /* Data synchronous fetch mode. */ | ||
71 | #define CEU_CAMCR_JPEG BIT(4) | ||
72 | |||
73 | /* Input components ordering: CEU_CAMCR.DTARY field. */ | ||
74 | #define CEU_CAMCR_DTARY_8_UYVY (0x00 << 8) | ||
75 | #define CEU_CAMCR_DTARY_8_VYUY (0x01 << 8) | ||
76 | #define CEU_CAMCR_DTARY_8_YUYV (0x02 << 8) | ||
77 | #define CEU_CAMCR_DTARY_8_YVYU (0x03 << 8) | ||
78 | /* TODO: input components ordering for 16 bits input. */ | ||
79 | |||
80 | /* Bus transfer MTU. */ | ||
81 | #define CEU_CAPCR_BUS_WIDTH256 (0x3 << 20) | ||
82 | |||
83 | /* Bus width configuration. */ | ||
84 | #define CEU_CAMCR_DTIF_16BITS BIT(12) | ||
85 | |||
86 | /* No downsampling to planar YUV420 in image fetch mode. */ | ||
87 | #define CEU_CDOCR_NO_DOWSAMPLE BIT(4) | ||
88 | |||
89 | /* Swap all input data in 8-bit, 16-bits and 32-bits units (Figure 46.45). */ | ||
90 | #define CEU_CDOCR_SWAP_ENDIANNESS (7) | ||
91 | |||
92 | /* Capture reset and enable bits. */ | ||
93 | #define CEU_CAPSR_CPKIL BIT(16) | ||
94 | #define CEU_CAPSR_CE BIT(0) | ||
95 | |||
96 | /* CEU operating flag bit. */ | ||
97 | #define CEU_CAPCR_CTNCP BIT(16) | ||
98 | #define CEU_CSTRST_CPTON BIT(0) | ||
99 | |||
100 | /* Platform specific IRQ source flags. */ | ||
101 | #define CEU_CETCR_ALL_IRQS_RZ 0x397f313 | ||
102 | #define CEU_CETCR_ALL_IRQS_SH4 0x3d7f313 | ||
103 | |||
104 | /* Prohibited register access interrupt bit. */ | ||
105 | #define CEU_CETCR_IGRW BIT(4) | ||
106 | /* One-frame capture end interrupt. */ | ||
107 | #define CEU_CEIER_CPE BIT(0) | ||
108 | /* VBP error. */ | ||
109 | #define CEU_CEIER_VBP BIT(20) | ||
110 | #define CEU_CEIER_MASK (CEU_CEIER_CPE | CEU_CEIER_VBP) | ||
111 | |||
112 | #define CEU_MAX_WIDTH 2560 | ||
113 | #define CEU_MAX_HEIGHT 1920 | ||
114 | #define CEU_MAX_BPL 8188 | ||
115 | #define CEU_W_MAX(w) ((w) < CEU_MAX_WIDTH ? (w) : CEU_MAX_WIDTH) | ||
116 | #define CEU_H_MAX(h) ((h) < CEU_MAX_HEIGHT ? (h) : CEU_MAX_HEIGHT) | ||
117 | |||
118 | /* | ||
119 | * ceu_bus_fmt - describe a 8-bits yuyv format the sensor can produce | ||
120 | * | ||
121 | * @mbus_code: bus format code | ||
122 | * @fmt_order: CEU_CAMCR.DTARY ordering of input components (Y, Cb, Cr) | ||
123 | * @fmt_order_swap: swapped CEU_CAMCR.DTARY ordering of input components | ||
124 | * (Y, Cr, Cb) | ||
125 | * @swapped: does Cr appear before Cb? | ||
126 | * @bps: number of bits sent over bus for each sample | ||
127 | * @bpp: number of bits per pixels unit | ||
128 | */ | ||
129 | struct ceu_mbus_fmt { | ||
130 | u32 mbus_code; | ||
131 | u32 fmt_order; | ||
132 | u32 fmt_order_swap; | ||
133 | bool swapped; | ||
134 | u8 bps; | ||
135 | u8 bpp; | ||
136 | }; | ||
137 | |||
138 | /* | ||
139 | * ceu_buffer - Link vb2 buffer to the list of available buffers. | ||
140 | */ | ||
141 | struct ceu_buffer { | ||
142 | struct vb2_v4l2_buffer vb; | ||
143 | struct list_head queue; | ||
144 | }; | ||
145 | |||
146 | static inline struct ceu_buffer *vb2_to_ceu(struct vb2_v4l2_buffer *vbuf) | ||
147 | { | ||
148 | return container_of(vbuf, struct ceu_buffer, vb); | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * ceu_subdev - Wraps v4l2 sub-device and provides async subdevice. | ||
153 | */ | ||
154 | struct ceu_subdev { | ||
155 | struct v4l2_subdev *v4l2_sd; | ||
156 | struct v4l2_async_subdev asd; | ||
157 | |||
158 | /* per-subdevice mbus configuration options */ | ||
159 | unsigned int mbus_flags; | ||
160 | struct ceu_mbus_fmt mbus_fmt; | ||
161 | }; | ||
162 | |||
163 | static struct ceu_subdev *to_ceu_subdev(struct v4l2_async_subdev *asd) | ||
164 | { | ||
165 | return container_of(asd, struct ceu_subdev, asd); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * ceu_device - CEU device instance | ||
170 | */ | ||
171 | struct ceu_device { | ||
172 | struct device *dev; | ||
173 | struct video_device vdev; | ||
174 | struct v4l2_device v4l2_dev; | ||
175 | |||
176 | /* subdevices descriptors */ | ||
177 | struct ceu_subdev *subdevs; | ||
178 | /* the subdevice currently in use */ | ||
179 | struct ceu_subdev *sd; | ||
180 | unsigned int sd_index; | ||
181 | unsigned int num_sd; | ||
182 | |||
183 | /* platform specific mask with all IRQ sources flagged */ | ||
184 | u32 irq_mask; | ||
185 | |||
186 | /* currently configured field and pixel format */ | ||
187 | enum v4l2_field field; | ||
188 | struct v4l2_pix_format_mplane v4l2_pix; | ||
189 | |||
190 | /* async subdev notification helpers */ | ||
191 | struct v4l2_async_notifier notifier; | ||
192 | /* pointers to "struct ceu_subdevice -> asd" */ | ||
193 | struct v4l2_async_subdev **asds; | ||
194 | |||
195 | /* vb2 queue, capture buffer list and active buffer pointer */ | ||
196 | struct vb2_queue vb2_vq; | ||
197 | struct list_head capture; | ||
198 | struct vb2_v4l2_buffer *active; | ||
199 | unsigned int sequence; | ||
200 | |||
201 | /* mlock - lock access to interface reset and vb2 queue */ | ||
202 | struct mutex mlock; | ||
203 | |||
204 | /* lock - lock access to capture buffer queue and active buffer */ | ||
205 | spinlock_t lock; | ||
206 | |||
207 | /* base - CEU memory base address */ | ||
208 | void __iomem *base; | ||
209 | }; | ||
210 | |||
211 | static inline struct ceu_device *v4l2_to_ceu(struct v4l2_device *v4l2_dev) | ||
212 | { | ||
213 | return container_of(v4l2_dev, struct ceu_device, v4l2_dev); | ||
214 | } | ||
215 | |||
216 | /* --- CEU memory output formats --- */ | ||
217 | |||
218 | /* | ||
219 | * ceu_fmt - describe a memory output format supported by CEU interface. | ||
220 | * | ||
221 | * @fourcc: memory layout fourcc format code | ||
222 | * @bpp: number of bits for each pixel stored in memory | ||
223 | */ | ||
224 | struct ceu_fmt { | ||
225 | u32 fourcc; | ||
226 | u32 bpp; | ||
227 | }; | ||
228 | |||
229 | /* | ||
230 | * ceu_format_list - List of supported memory output formats | ||
231 | * | ||
232 | * If sensor provides any YUYV bus format, all the following planar memory | ||
233 | * formats are available thanks to CEU re-ordering and sub-sampling | ||
234 | * capabilities. | ||
235 | */ | ||
236 | static const struct ceu_fmt ceu_fmt_list[] = { | ||
237 | { | ||
238 | .fourcc = V4L2_PIX_FMT_NV16, | ||
239 | .bpp = 16, | ||
240 | }, | ||
241 | { | ||
242 | .fourcc = V4L2_PIX_FMT_NV61, | ||
243 | .bpp = 16, | ||
244 | }, | ||
245 | { | ||
246 | .fourcc = V4L2_PIX_FMT_NV12, | ||
247 | .bpp = 12, | ||
248 | }, | ||
249 | { | ||
250 | .fourcc = V4L2_PIX_FMT_NV21, | ||
251 | .bpp = 12, | ||
252 | }, | ||
253 | { | ||
254 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
255 | .bpp = 16, | ||
256 | }, | ||
257 | }; | ||
258 | |||
259 | static const struct ceu_fmt *get_ceu_fmt_from_fourcc(unsigned int fourcc) | ||
260 | { | ||
261 | const struct ceu_fmt *fmt = &ceu_fmt_list[0]; | ||
262 | unsigned int i; | ||
263 | |||
264 | for (i = 0; i < ARRAY_SIZE(ceu_fmt_list); i++, fmt++) | ||
265 | if (fmt->fourcc == fourcc) | ||
266 | return fmt; | ||
267 | |||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | static bool ceu_fmt_mplane(struct v4l2_pix_format_mplane *pix) | ||
272 | { | ||
273 | switch (pix->pixelformat) { | ||
274 | case V4L2_PIX_FMT_YUYV: | ||
275 | return false; | ||
276 | case V4L2_PIX_FMT_NV16: | ||
277 | case V4L2_PIX_FMT_NV61: | ||
278 | case V4L2_PIX_FMT_NV12: | ||
279 | case V4L2_PIX_FMT_NV21: | ||
280 | return true; | ||
281 | default: | ||
282 | return false; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | /* --- CEU HW operations --- */ | ||
287 | |||
288 | static void ceu_write(struct ceu_device *priv, unsigned int reg_offs, u32 data) | ||
289 | { | ||
290 | iowrite32(data, priv->base + reg_offs); | ||
291 | } | ||
292 | |||
293 | static u32 ceu_read(struct ceu_device *priv, unsigned int reg_offs) | ||
294 | { | ||
295 | return ioread32(priv->base + reg_offs); | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * ceu_soft_reset() - Software reset the CEU interface. | ||
300 | * @ceu_device: CEU device. | ||
301 | * | ||
302 | * Returns 0 for success, -EIO for error. | ||
303 | */ | ||
304 | static int ceu_soft_reset(struct ceu_device *ceudev) | ||
305 | { | ||
306 | unsigned int i; | ||
307 | |||
308 | ceu_write(ceudev, CEU_CAPSR, CEU_CAPSR_CPKIL); | ||
309 | |||
310 | for (i = 0; i < 100; i++) { | ||
311 | if (!(ceu_read(ceudev, CEU_CSTSR) & CEU_CSTRST_CPTON)) | ||
312 | break; | ||
313 | udelay(1); | ||
314 | } | ||
315 | |||
316 | if (i == 100) { | ||
317 | dev_err(ceudev->dev, "soft reset time out\n"); | ||
318 | return -EIO; | ||
319 | } | ||
320 | |||
321 | for (i = 0; i < 100; i++) { | ||
322 | if (!(ceu_read(ceudev, CEU_CAPSR) & CEU_CAPSR_CPKIL)) | ||
323 | return 0; | ||
324 | udelay(1); | ||
325 | } | ||
326 | |||
327 | /* If we get here, CEU has not reset properly. */ | ||
328 | return -EIO; | ||
329 | } | ||
330 | |||
331 | /* --- CEU Capture Operations --- */ | ||
332 | |||
333 | /* | ||
334 | * ceu_hw_config() - Configure CEU interface registers. | ||
335 | */ | ||
336 | static int ceu_hw_config(struct ceu_device *ceudev) | ||
337 | { | ||
338 | u32 camcr, cdocr, cfzsr, cdwdr, capwr; | ||
339 | struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; | ||
340 | struct ceu_subdev *ceu_sd = ceudev->sd; | ||
341 | struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; | ||
342 | unsigned int mbus_flags = ceu_sd->mbus_flags; | ||
343 | |||
344 | /* Start configuring CEU registers */ | ||
345 | ceu_write(ceudev, CEU_CAIFR, 0); | ||
346 | ceu_write(ceudev, CEU_CFWCR, 0); | ||
347 | ceu_write(ceudev, CEU_CRCNTR, 0); | ||
348 | ceu_write(ceudev, CEU_CRCMPR, 0); | ||
349 | |||
350 | /* Set the frame capture period for both image capture and data sync. */ | ||
351 | capwr = (pix->height << 16) | pix->width * mbus_fmt->bpp / 8; | ||
352 | |||
353 | /* | ||
354 | * Swap input data endianness by default. | ||
355 | * In data fetch mode bytes are received in chunks of 8 bytes. | ||
356 | * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first) | ||
357 | * The data is however by default written to memory in reverse order: | ||
358 | * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte) | ||
359 | * | ||
360 | * Use CEU_CDOCR[2:0] to swap data ordering. | ||
361 | */ | ||
362 | cdocr = CEU_CDOCR_SWAP_ENDIANNESS; | ||
363 | |||
364 | /* | ||
365 | * Configure CAMCR and CDOCR: | ||
366 | * match input components ordering with memory output format and | ||
367 | * handle downsampling to YUV420. | ||
368 | * | ||
369 | * If the memory output planar format is 'swapped' (Cr before Cb) and | ||
370 | * input format is not, use the swapped version of CAMCR.DTARY. | ||
371 | * | ||
372 | * If the memory output planar format is not 'swapped' (Cb before Cr) | ||
373 | * and input format is, use the swapped version of CAMCR.DTARY. | ||
374 | * | ||
375 | * CEU by default downsample to planar YUV420 (CDCOR[4] = 0). | ||
376 | * If output is planar YUV422 set CDOCR[4] = 1 | ||
377 | * | ||
378 | * No downsample for data fetch sync mode. | ||
379 | */ | ||
380 | switch (pix->pixelformat) { | ||
381 | /* Data fetch sync mode */ | ||
382 | case V4L2_PIX_FMT_YUYV: | ||
383 | /* TODO: handle YUYV permutations through DTARY bits. */ | ||
384 | camcr = CEU_CAMCR_JPEG; | ||
385 | cdocr |= CEU_CDOCR_NO_DOWSAMPLE; | ||
386 | cfzsr = (pix->height << 16) | pix->width; | ||
387 | cdwdr = pix->plane_fmt[0].bytesperline; | ||
388 | break; | ||
389 | |||
390 | /* Non-swapped planar image capture mode. */ | ||
391 | case V4L2_PIX_FMT_NV16: | ||
392 | cdocr |= CEU_CDOCR_NO_DOWSAMPLE; | ||
393 | /* fall-through */ | ||
394 | case V4L2_PIX_FMT_NV12: | ||
395 | if (mbus_fmt->swapped) | ||
396 | camcr = mbus_fmt->fmt_order_swap; | ||
397 | else | ||
398 | camcr = mbus_fmt->fmt_order; | ||
399 | |||
400 | cfzsr = (pix->height << 16) | pix->width; | ||
401 | cdwdr = pix->width; | ||
402 | break; | ||
403 | |||
404 | /* Swapped planar image capture mode. */ | ||
405 | case V4L2_PIX_FMT_NV61: | ||
406 | cdocr |= CEU_CDOCR_NO_DOWSAMPLE; | ||
407 | /* fall-through */ | ||
408 | case V4L2_PIX_FMT_NV21: | ||
409 | if (mbus_fmt->swapped) | ||
410 | camcr = mbus_fmt->fmt_order; | ||
411 | else | ||
412 | camcr = mbus_fmt->fmt_order_swap; | ||
413 | |||
414 | cfzsr = (pix->height << 16) | pix->width; | ||
415 | cdwdr = pix->width; | ||
416 | break; | ||
417 | |||
418 | default: | ||
419 | return -EINVAL; | ||
420 | } | ||
421 | |||
422 | camcr |= mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; | ||
423 | camcr |= mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; | ||
424 | |||
425 | /* TODO: handle 16 bit bus width with DTIF bit in CAMCR */ | ||
426 | ceu_write(ceudev, CEU_CAMCR, camcr); | ||
427 | ceu_write(ceudev, CEU_CDOCR, cdocr); | ||
428 | ceu_write(ceudev, CEU_CAPCR, CEU_CAPCR_BUS_WIDTH256); | ||
429 | |||
430 | /* | ||
431 | * TODO: make CAMOR offsets configurable. | ||
432 | * CAMOR wants to know the number of blanks between a VS/HS signal | ||
433 | * and valid data. This value should actually come from the sensor... | ||
434 | */ | ||
435 | ceu_write(ceudev, CEU_CAMOR, 0); | ||
436 | |||
437 | /* TODO: 16 bit bus width require re-calculation of cdwdr and cfzsr */ | ||
438 | ceu_write(ceudev, CEU_CAPWR, capwr); | ||
439 | ceu_write(ceudev, CEU_CFSZR, cfzsr); | ||
440 | ceu_write(ceudev, CEU_CDWDR, cdwdr); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* | ||
446 | * ceu_capture() - Trigger start of a capture sequence. | ||
447 | * | ||
448 | * Program the CEU DMA registers with addresses where to transfer image data. | ||
449 | */ | ||
450 | static int ceu_capture(struct ceu_device *ceudev) | ||
451 | { | ||
452 | struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; | ||
453 | dma_addr_t phys_addr_top; | ||
454 | |||
455 | phys_addr_top = | ||
456 | vb2_dma_contig_plane_dma_addr(&ceudev->active->vb2_buf, 0); | ||
457 | ceu_write(ceudev, CEU_CDAYR, phys_addr_top); | ||
458 | |||
459 | /* Ignore CbCr plane for non multi-planar image formats. */ | ||
460 | if (ceu_fmt_mplane(pix)) { | ||
461 | phys_addr_top = | ||
462 | vb2_dma_contig_plane_dma_addr(&ceudev->active->vb2_buf, | ||
463 | 1); | ||
464 | ceu_write(ceudev, CEU_CDACR, phys_addr_top); | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Trigger new capture start: once for each frame, as we work in | ||
469 | * one-frame capture mode. | ||
470 | */ | ||
471 | ceu_write(ceudev, CEU_CAPSR, CEU_CAPSR_CE); | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static irqreturn_t ceu_irq(int irq, void *data) | ||
477 | { | ||
478 | struct ceu_device *ceudev = data; | ||
479 | struct vb2_v4l2_buffer *vbuf; | ||
480 | struct ceu_buffer *buf; | ||
481 | u32 status; | ||
482 | |||
483 | /* Clean interrupt status. */ | ||
484 | status = ceu_read(ceudev, CEU_CETCR); | ||
485 | ceu_write(ceudev, CEU_CETCR, ~ceudev->irq_mask); | ||
486 | |||
487 | /* Unexpected interrupt. */ | ||
488 | if (!(status & CEU_CEIER_MASK)) | ||
489 | return IRQ_NONE; | ||
490 | |||
491 | spin_lock(&ceudev->lock); | ||
492 | |||
493 | /* Stale interrupt from a released buffer, ignore it. */ | ||
494 | vbuf = ceudev->active; | ||
495 | if (!vbuf) { | ||
496 | spin_unlock(&ceudev->lock); | ||
497 | return IRQ_HANDLED; | ||
498 | } | ||
499 | |||
500 | /* | ||
501 | * When a VBP interrupt occurs, no capture end interrupt will occur | ||
502 | * and the image of that frame is not captured correctly. | ||
503 | */ | ||
504 | if (status & CEU_CEIER_VBP) { | ||
505 | dev_err(ceudev->dev, "VBP interrupt: abort capture\n"); | ||
506 | goto error_irq_out; | ||
507 | } | ||
508 | |||
509 | /* Prepare to return the 'previous' buffer. */ | ||
510 | vbuf->vb2_buf.timestamp = ktime_get_ns(); | ||
511 | vbuf->sequence = ceudev->sequence++; | ||
512 | vbuf->field = ceudev->field; | ||
513 | |||
514 | /* Prepare a new 'active' buffer and trigger a new capture. */ | ||
515 | if (!list_empty(&ceudev->capture)) { | ||
516 | buf = list_first_entry(&ceudev->capture, struct ceu_buffer, | ||
517 | queue); | ||
518 | list_del(&buf->queue); | ||
519 | ceudev->active = &buf->vb; | ||
520 | |||
521 | ceu_capture(ceudev); | ||
522 | } | ||
523 | |||
524 | /* Return the 'previous' buffer. */ | ||
525 | vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); | ||
526 | |||
527 | spin_unlock(&ceudev->lock); | ||
528 | |||
529 | return IRQ_HANDLED; | ||
530 | |||
531 | error_irq_out: | ||
532 | /* Return the 'previous' buffer and all queued ones. */ | ||
533 | vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR); | ||
534 | |||
535 | list_for_each_entry(buf, &ceudev->capture, queue) | ||
536 | vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); | ||
537 | |||
538 | spin_unlock(&ceudev->lock); | ||
539 | |||
540 | return IRQ_HANDLED; | ||
541 | } | ||
542 | |||
543 | /* --- CEU Videobuf2 operations --- */ | ||
544 | |||
545 | static void ceu_update_plane_sizes(struct v4l2_plane_pix_format *plane, | ||
546 | unsigned int bpl, unsigned int szimage) | ||
547 | { | ||
548 | memset(plane, 0, sizeof(*plane)); | ||
549 | |||
550 | plane->sizeimage = szimage; | ||
551 | if (plane->bytesperline < bpl || plane->bytesperline > CEU_MAX_BPL) | ||
552 | plane->bytesperline = bpl; | ||
553 | } | ||
554 | |||
555 | /* | ||
556 | * ceu_calc_plane_sizes() - Fill per-plane 'struct v4l2_plane_pix_format' | ||
557 | * information according to the currently configured | ||
558 | * pixel format. | ||
559 | * @ceu_device: CEU device. | ||
560 | * @ceu_fmt: Active image format. | ||
561 | * @pix: Pixel format information (store line width and image sizes) | ||
562 | */ | ||
563 | static void ceu_calc_plane_sizes(struct ceu_device *ceudev, | ||
564 | const struct ceu_fmt *ceu_fmt, | ||
565 | struct v4l2_pix_format_mplane *pix) | ||
566 | { | ||
567 | unsigned int bpl, szimage; | ||
568 | |||
569 | switch (pix->pixelformat) { | ||
570 | case V4L2_PIX_FMT_YUYV: | ||
571 | pix->num_planes = 1; | ||
572 | bpl = pix->width * ceu_fmt->bpp / 8; | ||
573 | szimage = pix->height * bpl; | ||
574 | ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); | ||
575 | break; | ||
576 | |||
577 | case V4L2_PIX_FMT_NV12: | ||
578 | case V4L2_PIX_FMT_NV21: | ||
579 | pix->num_planes = 2; | ||
580 | bpl = pix->width; | ||
581 | szimage = pix->height * pix->width; | ||
582 | ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); | ||
583 | ceu_update_plane_sizes(&pix->plane_fmt[1], bpl, szimage / 2); | ||
584 | break; | ||
585 | |||
586 | case V4L2_PIX_FMT_NV16: | ||
587 | case V4L2_PIX_FMT_NV61: | ||
588 | default: | ||
589 | pix->num_planes = 2; | ||
590 | bpl = pix->width; | ||
591 | szimage = pix->height * pix->width; | ||
592 | ceu_update_plane_sizes(&pix->plane_fmt[0], bpl, szimage); | ||
593 | ceu_update_plane_sizes(&pix->plane_fmt[1], bpl, szimage); | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | /* | ||
599 | * ceu_vb2_setup() - is called to check whether the driver can accept the | ||
600 | * requested number of buffers and to fill in plane sizes | ||
601 | * for the current frame format, if required. | ||
602 | */ | ||
603 | static int ceu_vb2_setup(struct vb2_queue *vq, unsigned int *count, | ||
604 | unsigned int *num_planes, unsigned int sizes[], | ||
605 | struct device *alloc_devs[]) | ||
606 | { | ||
607 | struct ceu_device *ceudev = vb2_get_drv_priv(vq); | ||
608 | struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; | ||
609 | unsigned int i; | ||
610 | |||
611 | /* num_planes is set: just check plane sizes. */ | ||
612 | if (*num_planes) { | ||
613 | for (i = 0; i < pix->num_planes; i++) | ||
614 | if (sizes[i] < pix->plane_fmt[i].sizeimage) | ||
615 | return -EINVAL; | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | /* num_planes not set: called from REQBUFS, just set plane sizes. */ | ||
621 | *num_planes = pix->num_planes; | ||
622 | for (i = 0; i < pix->num_planes; i++) | ||
623 | sizes[i] = pix->plane_fmt[i].sizeimage; | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static void ceu_vb2_queue(struct vb2_buffer *vb) | ||
629 | { | ||
630 | struct ceu_device *ceudev = vb2_get_drv_priv(vb->vb2_queue); | ||
631 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | ||
632 | struct ceu_buffer *buf = vb2_to_ceu(vbuf); | ||
633 | unsigned long irqflags; | ||
634 | |||
635 | spin_lock_irqsave(&ceudev->lock, irqflags); | ||
636 | list_add_tail(&buf->queue, &ceudev->capture); | ||
637 | spin_unlock_irqrestore(&ceudev->lock, irqflags); | ||
638 | } | ||
639 | |||
640 | static int ceu_vb2_prepare(struct vb2_buffer *vb) | ||
641 | { | ||
642 | struct ceu_device *ceudev = vb2_get_drv_priv(vb->vb2_queue); | ||
643 | struct v4l2_pix_format_mplane *pix = &ceudev->v4l2_pix; | ||
644 | unsigned int i; | ||
645 | |||
646 | for (i = 0; i < pix->num_planes; i++) { | ||
647 | if (vb2_plane_size(vb, i) < pix->plane_fmt[i].sizeimage) { | ||
648 | dev_err(ceudev->dev, | ||
649 | "Plane size too small (%lu < %u)\n", | ||
650 | vb2_plane_size(vb, i), | ||
651 | pix->plane_fmt[i].sizeimage); | ||
652 | return -EINVAL; | ||
653 | } | ||
654 | |||
655 | vb2_set_plane_payload(vb, i, pix->plane_fmt[i].sizeimage); | ||
656 | } | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int ceu_start_streaming(struct vb2_queue *vq, unsigned int count) | ||
662 | { | ||
663 | struct ceu_device *ceudev = vb2_get_drv_priv(vq); | ||
664 | struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; | ||
665 | struct ceu_buffer *buf; | ||
666 | unsigned long irqflags; | ||
667 | int ret; | ||
668 | |||
669 | /* Program the CEU interface according to the CEU image format. */ | ||
670 | ret = ceu_hw_config(ceudev); | ||
671 | if (ret) | ||
672 | goto error_return_bufs; | ||
673 | |||
674 | ret = v4l2_subdev_call(v4l2_sd, video, s_stream, 1); | ||
675 | if (ret && ret != -ENOIOCTLCMD) { | ||
676 | dev_dbg(ceudev->dev, | ||
677 | "Subdevice failed to start streaming: %d\n", ret); | ||
678 | goto error_return_bufs; | ||
679 | } | ||
680 | |||
681 | spin_lock_irqsave(&ceudev->lock, irqflags); | ||
682 | ceudev->sequence = 0; | ||
683 | |||
684 | /* Grab the first available buffer and trigger the first capture. */ | ||
685 | buf = list_first_entry(&ceudev->capture, struct ceu_buffer, | ||
686 | queue); | ||
687 | if (!buf) { | ||
688 | spin_unlock_irqrestore(&ceudev->lock, irqflags); | ||
689 | dev_dbg(ceudev->dev, | ||
690 | "No buffer available for capture.\n"); | ||
691 | goto error_stop_sensor; | ||
692 | } | ||
693 | |||
694 | list_del(&buf->queue); | ||
695 | ceudev->active = &buf->vb; | ||
696 | |||
697 | /* Clean and program interrupts for first capture. */ | ||
698 | ceu_write(ceudev, CEU_CETCR, ~ceudev->irq_mask); | ||
699 | ceu_write(ceudev, CEU_CEIER, CEU_CEIER_MASK); | ||
700 | |||
701 | ceu_capture(ceudev); | ||
702 | |||
703 | spin_unlock_irqrestore(&ceudev->lock, irqflags); | ||
704 | |||
705 | return 0; | ||
706 | |||
707 | error_stop_sensor: | ||
708 | v4l2_subdev_call(v4l2_sd, video, s_stream, 0); | ||
709 | |||
710 | error_return_bufs: | ||
711 | spin_lock_irqsave(&ceudev->lock, irqflags); | ||
712 | list_for_each_entry(buf, &ceudev->capture, queue) | ||
713 | vb2_buffer_done(&ceudev->active->vb2_buf, | ||
714 | VB2_BUF_STATE_QUEUED); | ||
715 | ceudev->active = NULL; | ||
716 | spin_unlock_irqrestore(&ceudev->lock, irqflags); | ||
717 | |||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | static void ceu_stop_streaming(struct vb2_queue *vq) | ||
722 | { | ||
723 | struct ceu_device *ceudev = vb2_get_drv_priv(vq); | ||
724 | struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; | ||
725 | struct ceu_buffer *buf; | ||
726 | unsigned long irqflags; | ||
727 | |||
728 | /* Clean and disable interrupt sources. */ | ||
729 | ceu_write(ceudev, CEU_CETCR, | ||
730 | ceu_read(ceudev, CEU_CETCR) & ceudev->irq_mask); | ||
731 | ceu_write(ceudev, CEU_CEIER, CEU_CEIER_MASK); | ||
732 | |||
733 | v4l2_subdev_call(v4l2_sd, video, s_stream, 0); | ||
734 | |||
735 | spin_lock_irqsave(&ceudev->lock, irqflags); | ||
736 | if (ceudev->active) { | ||
737 | vb2_buffer_done(&ceudev->active->vb2_buf, | ||
738 | VB2_BUF_STATE_ERROR); | ||
739 | ceudev->active = NULL; | ||
740 | } | ||
741 | |||
742 | /* Release all queued buffers. */ | ||
743 | list_for_each_entry(buf, &ceudev->capture, queue) | ||
744 | vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); | ||
745 | INIT_LIST_HEAD(&ceudev->capture); | ||
746 | |||
747 | spin_unlock_irqrestore(&ceudev->lock, irqflags); | ||
748 | |||
749 | ceu_soft_reset(ceudev); | ||
750 | } | ||
751 | |||
752 | static const struct vb2_ops ceu_vb2_ops = { | ||
753 | .queue_setup = ceu_vb2_setup, | ||
754 | .buf_queue = ceu_vb2_queue, | ||
755 | .buf_prepare = ceu_vb2_prepare, | ||
756 | .wait_prepare = vb2_ops_wait_prepare, | ||
757 | .wait_finish = vb2_ops_wait_finish, | ||
758 | .start_streaming = ceu_start_streaming, | ||
759 | .stop_streaming = ceu_stop_streaming, | ||
760 | }; | ||
761 | |||
762 | /* --- CEU image formats handling --- */ | ||
763 | |||
764 | /* | ||
765 | * ceu_try_fmt() - test format on CEU and sensor | ||
766 | * @ceudev: The CEU device. | ||
767 | * @v4l2_fmt: format to test. | ||
768 | * | ||
769 | * Returns 0 for success, < 0 for errors. | ||
770 | */ | ||
771 | static int ceu_try_fmt(struct ceu_device *ceudev, struct v4l2_format *v4l2_fmt) | ||
772 | { | ||
773 | struct ceu_subdev *ceu_sd = ceudev->sd; | ||
774 | struct v4l2_pix_format_mplane *pix = &v4l2_fmt->fmt.pix_mp; | ||
775 | struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; | ||
776 | struct v4l2_subdev_pad_config pad_cfg; | ||
777 | const struct ceu_fmt *ceu_fmt; | ||
778 | int ret; | ||
779 | |||
780 | struct v4l2_subdev_format sd_format = { | ||
781 | .which = V4L2_SUBDEV_FORMAT_TRY, | ||
782 | }; | ||
783 | |||
784 | switch (pix->pixelformat) { | ||
785 | case V4L2_PIX_FMT_YUYV: | ||
786 | case V4L2_PIX_FMT_NV16: | ||
787 | case V4L2_PIX_FMT_NV61: | ||
788 | case V4L2_PIX_FMT_NV12: | ||
789 | case V4L2_PIX_FMT_NV21: | ||
790 | break; | ||
791 | |||
792 | default: | ||
793 | pix->pixelformat = V4L2_PIX_FMT_NV16; | ||
794 | break; | ||
795 | } | ||
796 | |||
797 | ceu_fmt = get_ceu_fmt_from_fourcc(pix->pixelformat); | ||
798 | |||
799 | /* CFSZR requires height and width to be 4-pixel aligned. */ | ||
800 | v4l_bound_align_image(&pix->width, 2, CEU_MAX_WIDTH, 4, | ||
801 | &pix->height, 4, CEU_MAX_HEIGHT, 4, 0); | ||
802 | |||
803 | /* | ||
804 | * Set format on sensor sub device: bus format used to produce memory | ||
805 | * format is selected at initialization time. | ||
806 | */ | ||
807 | v4l2_fill_mbus_format_mplane(&sd_format.format, pix); | ||
808 | ret = v4l2_subdev_call(v4l2_sd, pad, set_fmt, &pad_cfg, &sd_format); | ||
809 | if (ret) | ||
810 | return ret; | ||
811 | |||
812 | /* Apply size returned by sensor as the CEU can't scale. */ | ||
813 | v4l2_fill_pix_format_mplane(pix, &sd_format.format); | ||
814 | |||
815 | /* Calculate per-plane sizes based on image format. */ | ||
816 | ceu_calc_plane_sizes(ceudev, ceu_fmt, pix); | ||
817 | |||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * ceu_set_fmt() - Apply the supplied format to both sensor and CEU | ||
823 | */ | ||
824 | static int ceu_set_fmt(struct ceu_device *ceudev, struct v4l2_format *v4l2_fmt) | ||
825 | { | ||
826 | struct ceu_subdev *ceu_sd = ceudev->sd; | ||
827 | struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; | ||
828 | int ret; | ||
829 | |||
830 | struct v4l2_subdev_format format = { | ||
831 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
832 | }; | ||
833 | |||
834 | ret = ceu_try_fmt(ceudev, v4l2_fmt); | ||
835 | if (ret) | ||
836 | return ret; | ||
837 | |||
838 | v4l2_fill_mbus_format_mplane(&format.format, &v4l2_fmt->fmt.pix_mp); | ||
839 | ret = v4l2_subdev_call(v4l2_sd, pad, set_fmt, NULL, &format); | ||
840 | if (ret) | ||
841 | return ret; | ||
842 | |||
843 | ceudev->v4l2_pix = v4l2_fmt->fmt.pix_mp; | ||
844 | ceudev->field = V4L2_FIELD_NONE; | ||
845 | |||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | /* | ||
850 | * ceu_set_default_fmt() - Apply default NV16 memory output format with VGA | ||
851 | * sizes. | ||
852 | */ | ||
853 | static int ceu_set_default_fmt(struct ceu_device *ceudev) | ||
854 | { | ||
855 | int ret; | ||
856 | |||
857 | struct v4l2_format v4l2_fmt = { | ||
858 | .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, | ||
859 | .fmt.pix_mp = { | ||
860 | .width = VGA_WIDTH, | ||
861 | .height = VGA_HEIGHT, | ||
862 | .field = V4L2_FIELD_NONE, | ||
863 | .pixelformat = V4L2_PIX_FMT_NV16, | ||
864 | .num_planes = 2, | ||
865 | .plane_fmt = { | ||
866 | [0] = { | ||
867 | .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2, | ||
868 | .bytesperline = VGA_WIDTH * 2, | ||
869 | }, | ||
870 | [1] = { | ||
871 | .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2, | ||
872 | .bytesperline = VGA_WIDTH * 2, | ||
873 | }, | ||
874 | }, | ||
875 | }, | ||
876 | }; | ||
877 | |||
878 | ret = ceu_try_fmt(ceudev, &v4l2_fmt); | ||
879 | if (ret) | ||
880 | return ret; | ||
881 | |||
882 | ceudev->v4l2_pix = v4l2_fmt.fmt.pix_mp; | ||
883 | ceudev->field = V4L2_FIELD_NONE; | ||
884 | |||
885 | return 0; | ||
886 | } | ||
887 | |||
888 | /* | ||
889 | * ceu_init_mbus_fmt() - Query sensor for supported formats and initialize | ||
890 | * CEU media bus format used to produce memory formats. | ||
891 | * | ||
892 | * Find out if sensor can produce a permutation of 8-bits YUYV bus format. | ||
893 | * From a single 8-bits YUYV bus format the CEU can produce several memory | ||
894 | * output formats: | ||
895 | * - NV[12|21|16|61] through image fetch mode; | ||
896 | * - YUYV422 if sensor provides YUYV422 | ||
897 | * | ||
898 | * TODO: Other YUYV422 permutations through data fetch sync mode and DTARY | ||
899 | * TODO: Binary data (eg. JPEG) and raw formats through data fetch sync mode | ||
900 | */ | ||
901 | static int ceu_init_mbus_fmt(struct ceu_device *ceudev) | ||
902 | { | ||
903 | struct ceu_subdev *ceu_sd = ceudev->sd; | ||
904 | struct ceu_mbus_fmt *mbus_fmt = &ceu_sd->mbus_fmt; | ||
905 | struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; | ||
906 | bool yuyv_bus_fmt = false; | ||
907 | |||
908 | struct v4l2_subdev_mbus_code_enum sd_mbus_fmt = { | ||
909 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
910 | .index = 0, | ||
911 | }; | ||
912 | |||
913 | /* Find out if sensor can produce any permutation of 8-bits YUYV422. */ | ||
914 | while (!yuyv_bus_fmt && | ||
915 | !v4l2_subdev_call(v4l2_sd, pad, enum_mbus_code, | ||
916 | NULL, &sd_mbus_fmt)) { | ||
917 | switch (sd_mbus_fmt.code) { | ||
918 | case MEDIA_BUS_FMT_YUYV8_2X8: | ||
919 | case MEDIA_BUS_FMT_YVYU8_2X8: | ||
920 | case MEDIA_BUS_FMT_UYVY8_2X8: | ||
921 | case MEDIA_BUS_FMT_VYUY8_2X8: | ||
922 | yuyv_bus_fmt = true; | ||
923 | break; | ||
924 | default: | ||
925 | /* | ||
926 | * Only support 8-bits YUYV bus formats at the moment; | ||
927 | * | ||
928 | * TODO: add support for binary formats (data sync | ||
929 | * fetch mode). | ||
930 | */ | ||
931 | break; | ||
932 | } | ||
933 | |||
934 | sd_mbus_fmt.index++; | ||
935 | } | ||
936 | |||
937 | if (!yuyv_bus_fmt) | ||
938 | return -ENXIO; | ||
939 | |||
940 | /* | ||
941 | * Save the first encountered YUYV format as "mbus_fmt" and use it | ||
942 | * to output all planar YUV422 and YUV420 (NV*) formats to memory as | ||
943 | * well as for data synch fetch mode (YUYV - YVYU etc. ). | ||
944 | */ | ||
945 | mbus_fmt->mbus_code = sd_mbus_fmt.code; | ||
946 | mbus_fmt->bps = 8; | ||
947 | |||
948 | /* Annotate the selected bus format components ordering. */ | ||
949 | switch (sd_mbus_fmt.code) { | ||
950 | case MEDIA_BUS_FMT_YUYV8_2X8: | ||
951 | mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YUYV; | ||
952 | mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YVYU; | ||
953 | mbus_fmt->swapped = false; | ||
954 | mbus_fmt->bpp = 16; | ||
955 | break; | ||
956 | |||
957 | case MEDIA_BUS_FMT_YVYU8_2X8: | ||
958 | mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_YVYU; | ||
959 | mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_YUYV; | ||
960 | mbus_fmt->swapped = true; | ||
961 | mbus_fmt->bpp = 16; | ||
962 | break; | ||
963 | |||
964 | case MEDIA_BUS_FMT_UYVY8_2X8: | ||
965 | mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_UYVY; | ||
966 | mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_VYUY; | ||
967 | mbus_fmt->swapped = false; | ||
968 | mbus_fmt->bpp = 16; | ||
969 | break; | ||
970 | |||
971 | case MEDIA_BUS_FMT_VYUY8_2X8: | ||
972 | mbus_fmt->fmt_order = CEU_CAMCR_DTARY_8_VYUY; | ||
973 | mbus_fmt->fmt_order_swap = CEU_CAMCR_DTARY_8_UYVY; | ||
974 | mbus_fmt->swapped = true; | ||
975 | mbus_fmt->bpp = 16; | ||
976 | break; | ||
977 | } | ||
978 | |||
979 | return 0; | ||
980 | } | ||
981 | |||
982 | /* --- Runtime PM Handlers --- */ | ||
983 | |||
984 | /* | ||
985 | * ceu_runtime_resume() - soft-reset the interface and turn sensor power on. | ||
986 | */ | ||
987 | static int __maybe_unused ceu_runtime_resume(struct device *dev) | ||
988 | { | ||
989 | struct ceu_device *ceudev = dev_get_drvdata(dev); | ||
990 | struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; | ||
991 | |||
992 | v4l2_subdev_call(v4l2_sd, core, s_power, 1); | ||
993 | |||
994 | ceu_soft_reset(ceudev); | ||
995 | |||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | /* | ||
1000 | * ceu_runtime_suspend() - disable capture and interrupts and soft-reset. | ||
1001 | * Turn sensor power off. | ||
1002 | */ | ||
1003 | static int __maybe_unused ceu_runtime_suspend(struct device *dev) | ||
1004 | { | ||
1005 | struct ceu_device *ceudev = dev_get_drvdata(dev); | ||
1006 | struct v4l2_subdev *v4l2_sd = ceudev->sd->v4l2_sd; | ||
1007 | |||
1008 | v4l2_subdev_call(v4l2_sd, core, s_power, 0); | ||
1009 | |||
1010 | ceu_write(ceudev, CEU_CEIER, 0); | ||
1011 | ceu_soft_reset(ceudev); | ||
1012 | |||
1013 | return 0; | ||
1014 | } | ||
1015 | |||
1016 | /* --- File Operations --- */ | ||
1017 | |||
1018 | static int ceu_open(struct file *file) | ||
1019 | { | ||
1020 | struct ceu_device *ceudev = video_drvdata(file); | ||
1021 | int ret; | ||
1022 | |||
1023 | ret = v4l2_fh_open(file); | ||
1024 | if (ret) | ||
1025 | return ret; | ||
1026 | |||
1027 | mutex_lock(&ceudev->mlock); | ||
1028 | /* Causes soft-reset and sensor power on on first open */ | ||
1029 | pm_runtime_get_sync(ceudev->dev); | ||
1030 | mutex_unlock(&ceudev->mlock); | ||
1031 | |||
1032 | return 0; | ||
1033 | } | ||
1034 | |||
1035 | static int ceu_release(struct file *file) | ||
1036 | { | ||
1037 | struct ceu_device *ceudev = video_drvdata(file); | ||
1038 | |||
1039 | vb2_fop_release(file); | ||
1040 | |||
1041 | mutex_lock(&ceudev->mlock); | ||
1042 | /* Causes soft-reset and sensor power down on last close */ | ||
1043 | pm_runtime_put(ceudev->dev); | ||
1044 | mutex_unlock(&ceudev->mlock); | ||
1045 | |||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | static const struct v4l2_file_operations ceu_fops = { | ||
1050 | .owner = THIS_MODULE, | ||
1051 | .open = ceu_open, | ||
1052 | .release = ceu_release, | ||
1053 | .unlocked_ioctl = video_ioctl2, | ||
1054 | .mmap = vb2_fop_mmap, | ||
1055 | .poll = vb2_fop_poll, | ||
1056 | }; | ||
1057 | |||
1058 | /* --- Video Device IOCTLs --- */ | ||
1059 | |||
1060 | static int ceu_querycap(struct file *file, void *priv, | ||
1061 | struct v4l2_capability *cap) | ||
1062 | { | ||
1063 | struct ceu_device *ceudev = video_drvdata(file); | ||
1064 | |||
1065 | strlcpy(cap->card, "Renesas CEU", sizeof(cap->card)); | ||
1066 | strlcpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); | ||
1067 | snprintf(cap->bus_info, sizeof(cap->bus_info), | ||
1068 | "platform:renesas-ceu-%s", dev_name(ceudev->dev)); | ||
1069 | |||
1070 | return 0; | ||
1071 | } | ||
1072 | |||
1073 | static int ceu_enum_fmt_vid_cap(struct file *file, void *priv, | ||
1074 | struct v4l2_fmtdesc *f) | ||
1075 | { | ||
1076 | const struct ceu_fmt *fmt; | ||
1077 | |||
1078 | if (f->index >= ARRAY_SIZE(ceu_fmt_list)) | ||
1079 | return -EINVAL; | ||
1080 | |||
1081 | fmt = &ceu_fmt_list[f->index]; | ||
1082 | f->pixelformat = fmt->fourcc; | ||
1083 | |||
1084 | return 0; | ||
1085 | } | ||
1086 | |||
1087 | static int ceu_try_fmt_vid_cap(struct file *file, void *priv, | ||
1088 | struct v4l2_format *f) | ||
1089 | { | ||
1090 | struct ceu_device *ceudev = video_drvdata(file); | ||
1091 | |||
1092 | return ceu_try_fmt(ceudev, f); | ||
1093 | } | ||
1094 | |||
1095 | static int ceu_s_fmt_vid_cap(struct file *file, void *priv, | ||
1096 | struct v4l2_format *f) | ||
1097 | { | ||
1098 | struct ceu_device *ceudev = video_drvdata(file); | ||
1099 | |||
1100 | if (vb2_is_streaming(&ceudev->vb2_vq)) | ||
1101 | return -EBUSY; | ||
1102 | |||
1103 | return ceu_set_fmt(ceudev, f); | ||
1104 | } | ||
1105 | |||
1106 | static int ceu_g_fmt_vid_cap(struct file *file, void *priv, | ||
1107 | struct v4l2_format *f) | ||
1108 | { | ||
1109 | struct ceu_device *ceudev = video_drvdata(file); | ||
1110 | |||
1111 | f->fmt.pix_mp = ceudev->v4l2_pix; | ||
1112 | |||
1113 | return 0; | ||
1114 | } | ||
1115 | |||
1116 | static int ceu_enum_input(struct file *file, void *priv, | ||
1117 | struct v4l2_input *inp) | ||
1118 | { | ||
1119 | struct ceu_device *ceudev = video_drvdata(file); | ||
1120 | struct ceu_subdev *ceusd; | ||
1121 | |||
1122 | if (inp->index >= ceudev->num_sd) | ||
1123 | return -EINVAL; | ||
1124 | |||
1125 | ceusd = &ceudev->subdevs[inp->index]; | ||
1126 | |||
1127 | inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
1128 | inp->std = 0; | ||
1129 | snprintf(inp->name, sizeof(inp->name), "Camera%u: %s", | ||
1130 | inp->index, ceusd->v4l2_sd->name); | ||
1131 | |||
1132 | return 0; | ||
1133 | } | ||
1134 | |||
1135 | static int ceu_g_input(struct file *file, void *priv, unsigned int *i) | ||
1136 | { | ||
1137 | struct ceu_device *ceudev = video_drvdata(file); | ||
1138 | |||
1139 | *i = ceudev->sd_index; | ||
1140 | |||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | static int ceu_s_input(struct file *file, void *priv, unsigned int i) | ||
1145 | { | ||
1146 | struct ceu_device *ceudev = video_drvdata(file); | ||
1147 | struct ceu_subdev *ceu_sd_old; | ||
1148 | int ret; | ||
1149 | |||
1150 | if (i >= ceudev->num_sd) | ||
1151 | return -EINVAL; | ||
1152 | |||
1153 | if (vb2_is_streaming(&ceudev->vb2_vq)) | ||
1154 | return -EBUSY; | ||
1155 | |||
1156 | if (i == ceudev->sd_index) | ||
1157 | return 0; | ||
1158 | |||
1159 | ceu_sd_old = ceudev->sd; | ||
1160 | ceudev->sd = &ceudev->subdevs[i]; | ||
1161 | |||
1162 | /* | ||
1163 | * Make sure we can generate output image formats and apply | ||
1164 | * default one. | ||
1165 | */ | ||
1166 | ret = ceu_init_mbus_fmt(ceudev); | ||
1167 | if (ret) { | ||
1168 | ceudev->sd = ceu_sd_old; | ||
1169 | return -EINVAL; | ||
1170 | } | ||
1171 | |||
1172 | ret = ceu_set_default_fmt(ceudev); | ||
1173 | if (ret) { | ||
1174 | ceudev->sd = ceu_sd_old; | ||
1175 | return -EINVAL; | ||
1176 | } | ||
1177 | |||
1178 | /* Now that we're sure we can use the sensor, power off the old one. */ | ||
1179 | v4l2_subdev_call(ceu_sd_old->v4l2_sd, core, s_power, 0); | ||
1180 | v4l2_subdev_call(ceudev->sd->v4l2_sd, core, s_power, 1); | ||
1181 | |||
1182 | ceudev->sd_index = i; | ||
1183 | |||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | static int ceu_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | ||
1188 | { | ||
1189 | struct ceu_device *ceudev = video_drvdata(file); | ||
1190 | |||
1191 | return v4l2_g_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); | ||
1192 | } | ||
1193 | |||
1194 | static int ceu_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) | ||
1195 | { | ||
1196 | struct ceu_device *ceudev = video_drvdata(file); | ||
1197 | |||
1198 | return v4l2_s_parm_cap(video_devdata(file), ceudev->sd->v4l2_sd, a); | ||
1199 | } | ||
1200 | |||
1201 | static int ceu_enum_framesizes(struct file *file, void *fh, | ||
1202 | struct v4l2_frmsizeenum *fsize) | ||
1203 | { | ||
1204 | struct ceu_device *ceudev = video_drvdata(file); | ||
1205 | struct ceu_subdev *ceu_sd = ceudev->sd; | ||
1206 | const struct ceu_fmt *ceu_fmt; | ||
1207 | struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; | ||
1208 | int ret; | ||
1209 | |||
1210 | struct v4l2_subdev_frame_size_enum fse = { | ||
1211 | .code = ceu_sd->mbus_fmt.mbus_code, | ||
1212 | .index = fsize->index, | ||
1213 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1214 | }; | ||
1215 | |||
1216 | /* Just check if user supplied pixel format is supported. */ | ||
1217 | ceu_fmt = get_ceu_fmt_from_fourcc(fsize->pixel_format); | ||
1218 | if (!ceu_fmt) | ||
1219 | return -EINVAL; | ||
1220 | |||
1221 | ret = v4l2_subdev_call(v4l2_sd, pad, enum_frame_size, | ||
1222 | NULL, &fse); | ||
1223 | if (ret) | ||
1224 | return ret; | ||
1225 | |||
1226 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
1227 | fsize->discrete.width = CEU_W_MAX(fse.max_width); | ||
1228 | fsize->discrete.height = CEU_H_MAX(fse.max_height); | ||
1229 | |||
1230 | return 0; | ||
1231 | } | ||
1232 | |||
1233 | static int ceu_enum_frameintervals(struct file *file, void *fh, | ||
1234 | struct v4l2_frmivalenum *fival) | ||
1235 | { | ||
1236 | struct ceu_device *ceudev = video_drvdata(file); | ||
1237 | struct ceu_subdev *ceu_sd = ceudev->sd; | ||
1238 | const struct ceu_fmt *ceu_fmt; | ||
1239 | struct v4l2_subdev *v4l2_sd = ceu_sd->v4l2_sd; | ||
1240 | int ret; | ||
1241 | |||
1242 | struct v4l2_subdev_frame_interval_enum fie = { | ||
1243 | .code = ceu_sd->mbus_fmt.mbus_code, | ||
1244 | .index = fival->index, | ||
1245 | .width = fival->width, | ||
1246 | .height = fival->height, | ||
1247 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | ||
1248 | }; | ||
1249 | |||
1250 | /* Just check if user supplied pixel format is supported. */ | ||
1251 | ceu_fmt = get_ceu_fmt_from_fourcc(fival->pixel_format); | ||
1252 | if (!ceu_fmt) | ||
1253 | return -EINVAL; | ||
1254 | |||
1255 | ret = v4l2_subdev_call(v4l2_sd, pad, enum_frame_interval, NULL, | ||
1256 | &fie); | ||
1257 | if (ret) | ||
1258 | return ret; | ||
1259 | |||
1260 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1261 | fival->discrete = fie.interval; | ||
1262 | |||
1263 | return 0; | ||
1264 | } | ||
1265 | |||
1266 | static const struct v4l2_ioctl_ops ceu_ioctl_ops = { | ||
1267 | .vidioc_querycap = ceu_querycap, | ||
1268 | |||
1269 | .vidioc_enum_fmt_vid_cap_mplane = ceu_enum_fmt_vid_cap, | ||
1270 | .vidioc_try_fmt_vid_cap_mplane = ceu_try_fmt_vid_cap, | ||
1271 | .vidioc_s_fmt_vid_cap_mplane = ceu_s_fmt_vid_cap, | ||
1272 | .vidioc_g_fmt_vid_cap_mplane = ceu_g_fmt_vid_cap, | ||
1273 | |||
1274 | .vidioc_enum_input = ceu_enum_input, | ||
1275 | .vidioc_g_input = ceu_g_input, | ||
1276 | .vidioc_s_input = ceu_s_input, | ||
1277 | |||
1278 | .vidioc_reqbufs = vb2_ioctl_reqbufs, | ||
1279 | .vidioc_querybuf = vb2_ioctl_querybuf, | ||
1280 | .vidioc_qbuf = vb2_ioctl_qbuf, | ||
1281 | .vidioc_expbuf = vb2_ioctl_expbuf, | ||
1282 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | ||
1283 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | ||
1284 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, | ||
1285 | .vidioc_streamon = vb2_ioctl_streamon, | ||
1286 | .vidioc_streamoff = vb2_ioctl_streamoff, | ||
1287 | |||
1288 | .vidioc_g_parm = ceu_g_parm, | ||
1289 | .vidioc_s_parm = ceu_s_parm, | ||
1290 | .vidioc_enum_framesizes = ceu_enum_framesizes, | ||
1291 | .vidioc_enum_frameintervals = ceu_enum_frameintervals, | ||
1292 | |||
1293 | .vidioc_log_status = v4l2_ctrl_log_status, | ||
1294 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
1295 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1296 | }; | ||
1297 | |||
1298 | /* | ||
1299 | * ceu_vdev_release() - release CEU video device memory when last reference | ||
1300 | * to this driver is closed | ||
1301 | */ | ||
1302 | static void ceu_vdev_release(struct video_device *vdev) | ||
1303 | { | ||
1304 | struct ceu_device *ceudev = video_get_drvdata(vdev); | ||
1305 | |||
1306 | kfree(ceudev); | ||
1307 | } | ||
1308 | |||
1309 | static int ceu_notify_bound(struct v4l2_async_notifier *notifier, | ||
1310 | struct v4l2_subdev *v4l2_sd, | ||
1311 | struct v4l2_async_subdev *asd) | ||
1312 | { | ||
1313 | struct v4l2_device *v4l2_dev = notifier->v4l2_dev; | ||
1314 | struct ceu_device *ceudev = v4l2_to_ceu(v4l2_dev); | ||
1315 | struct ceu_subdev *ceu_sd = to_ceu_subdev(asd); | ||
1316 | |||
1317 | ceu_sd->v4l2_sd = v4l2_sd; | ||
1318 | ceudev->num_sd++; | ||
1319 | |||
1320 | return 0; | ||
1321 | } | ||
1322 | |||
1323 | static int ceu_notify_complete(struct v4l2_async_notifier *notifier) | ||
1324 | { | ||
1325 | struct v4l2_device *v4l2_dev = notifier->v4l2_dev; | ||
1326 | struct ceu_device *ceudev = v4l2_to_ceu(v4l2_dev); | ||
1327 | struct video_device *vdev = &ceudev->vdev; | ||
1328 | struct vb2_queue *q = &ceudev->vb2_vq; | ||
1329 | struct v4l2_subdev *v4l2_sd; | ||
1330 | int ret; | ||
1331 | |||
1332 | /* Initialize vb2 queue. */ | ||
1333 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | ||
1334 | q->io_modes = VB2_MMAP | VB2_DMABUF; | ||
1335 | q->drv_priv = ceudev; | ||
1336 | q->ops = &ceu_vb2_ops; | ||
1337 | q->mem_ops = &vb2_dma_contig_memops; | ||
1338 | q->buf_struct_size = sizeof(struct ceu_buffer); | ||
1339 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1340 | q->min_buffers_needed = 2; | ||
1341 | q->lock = &ceudev->mlock; | ||
1342 | q->dev = ceudev->v4l2_dev.dev; | ||
1343 | |||
1344 | ret = vb2_queue_init(q); | ||
1345 | if (ret) | ||
1346 | return ret; | ||
1347 | |||
1348 | /* | ||
1349 | * Make sure at least one sensor is primary and use it to initialize | ||
1350 | * ceu formats. | ||
1351 | */ | ||
1352 | if (!ceudev->sd) { | ||
1353 | ceudev->sd = &ceudev->subdevs[0]; | ||
1354 | ceudev->sd_index = 0; | ||
1355 | } | ||
1356 | |||
1357 | v4l2_sd = ceudev->sd->v4l2_sd; | ||
1358 | |||
1359 | ret = ceu_init_mbus_fmt(ceudev); | ||
1360 | if (ret) | ||
1361 | return ret; | ||
1362 | |||
1363 | ret = ceu_set_default_fmt(ceudev); | ||
1364 | if (ret) | ||
1365 | return ret; | ||
1366 | |||
1367 | /* Register the video device. */ | ||
1368 | strncpy(vdev->name, DRIVER_NAME, strlen(DRIVER_NAME)); | ||
1369 | vdev->v4l2_dev = v4l2_dev; | ||
1370 | vdev->lock = &ceudev->mlock; | ||
1371 | vdev->queue = &ceudev->vb2_vq; | ||
1372 | vdev->ctrl_handler = v4l2_sd->ctrl_handler; | ||
1373 | vdev->fops = &ceu_fops; | ||
1374 | vdev->ioctl_ops = &ceu_ioctl_ops; | ||
1375 | vdev->release = ceu_vdev_release; | ||
1376 | vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | | ||
1377 | V4L2_CAP_STREAMING; | ||
1378 | video_set_drvdata(vdev, ceudev); | ||
1379 | |||
1380 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); | ||
1381 | if (ret < 0) { | ||
1382 | v4l2_err(vdev->v4l2_dev, | ||
1383 | "video_register_device failed: %d\n", ret); | ||
1384 | return ret; | ||
1385 | } | ||
1386 | |||
1387 | return 0; | ||
1388 | } | ||
1389 | |||
1390 | static const struct v4l2_async_notifier_operations ceu_notify_ops = { | ||
1391 | .bound = ceu_notify_bound, | ||
1392 | .complete = ceu_notify_complete, | ||
1393 | }; | ||
1394 | |||
1395 | /* | ||
1396 | * ceu_init_async_subdevs() - Initialize CEU subdevices and async_subdevs in | ||
1397 | * ceu device. Both DT and platform data parsing use | ||
1398 | * this routine. | ||
1399 | * | ||
1400 | * Returns 0 for success, -ENOMEM for failure. | ||
1401 | */ | ||
1402 | static int ceu_init_async_subdevs(struct ceu_device *ceudev, unsigned int n_sd) | ||
1403 | { | ||
1404 | /* Reserve memory for 'n_sd' ceu_subdev descriptors. */ | ||
1405 | ceudev->subdevs = devm_kcalloc(ceudev->dev, n_sd, | ||
1406 | sizeof(*ceudev->subdevs), GFP_KERNEL); | ||
1407 | if (!ceudev->subdevs) | ||
1408 | return -ENOMEM; | ||
1409 | |||
1410 | /* | ||
1411 | * Reserve memory for 'n_sd' pointers to async_subdevices. | ||
1412 | * ceudev->asds members will point to &ceu_subdev.asd | ||
1413 | */ | ||
1414 | ceudev->asds = devm_kcalloc(ceudev->dev, n_sd, | ||
1415 | sizeof(*ceudev->asds), GFP_KERNEL); | ||
1416 | if (!ceudev->asds) | ||
1417 | return -ENOMEM; | ||
1418 | |||
1419 | ceudev->sd = NULL; | ||
1420 | ceudev->sd_index = 0; | ||
1421 | ceudev->num_sd = 0; | ||
1422 | |||
1423 | return 0; | ||
1424 | } | ||
1425 | |||
1426 | /* | ||
1427 | * ceu_parse_platform_data() - Initialize async_subdevices using platform | ||
1428 | * device provided data. | ||
1429 | */ | ||
1430 | static int ceu_parse_platform_data(struct ceu_device *ceudev, | ||
1431 | const struct ceu_platform_data *pdata) | ||
1432 | { | ||
1433 | const struct ceu_async_subdev *async_sd; | ||
1434 | struct ceu_subdev *ceu_sd; | ||
1435 | unsigned int i; | ||
1436 | int ret; | ||
1437 | |||
1438 | if (pdata->num_subdevs == 0) | ||
1439 | return -ENODEV; | ||
1440 | |||
1441 | ret = ceu_init_async_subdevs(ceudev, pdata->num_subdevs); | ||
1442 | if (ret) | ||
1443 | return ret; | ||
1444 | |||
1445 | for (i = 0; i < pdata->num_subdevs; i++) { | ||
1446 | /* Setup the ceu subdevice and the async subdevice. */ | ||
1447 | async_sd = &pdata->subdevs[i]; | ||
1448 | ceu_sd = &ceudev->subdevs[i]; | ||
1449 | |||
1450 | INIT_LIST_HEAD(&ceu_sd->asd.list); | ||
1451 | |||
1452 | ceu_sd->mbus_flags = async_sd->flags; | ||
1453 | ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_I2C; | ||
1454 | ceu_sd->asd.match.i2c.adapter_id = async_sd->i2c_adapter_id; | ||
1455 | ceu_sd->asd.match.i2c.address = async_sd->i2c_address; | ||
1456 | |||
1457 | ceudev->asds[i] = &ceu_sd->asd; | ||
1458 | } | ||
1459 | |||
1460 | return pdata->num_subdevs; | ||
1461 | } | ||
1462 | |||
1463 | /* | ||
1464 | * ceu_parse_dt() - Initialize async_subdevs parsing device tree graph. | ||
1465 | */ | ||
1466 | static int ceu_parse_dt(struct ceu_device *ceudev) | ||
1467 | { | ||
1468 | struct device_node *of = ceudev->dev->of_node; | ||
1469 | struct v4l2_fwnode_endpoint fw_ep; | ||
1470 | struct ceu_subdev *ceu_sd; | ||
1471 | struct device_node *ep; | ||
1472 | unsigned int i; | ||
1473 | int num_ep; | ||
1474 | int ret; | ||
1475 | |||
1476 | num_ep = of_graph_get_endpoint_count(of); | ||
1477 | if (!num_ep) | ||
1478 | return -ENODEV; | ||
1479 | |||
1480 | ret = ceu_init_async_subdevs(ceudev, num_ep); | ||
1481 | if (ret) | ||
1482 | return ret; | ||
1483 | |||
1484 | for (i = 0; i < num_ep; i++) { | ||
1485 | ep = of_graph_get_endpoint_by_regs(of, 0, i); | ||
1486 | if (!ep) { | ||
1487 | dev_err(ceudev->dev, | ||
1488 | "No subdevice connected on endpoint %u.\n", i); | ||
1489 | ret = -ENODEV; | ||
1490 | goto error_put_node; | ||
1491 | } | ||
1492 | |||
1493 | ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &fw_ep); | ||
1494 | if (ret) { | ||
1495 | dev_err(ceudev->dev, | ||
1496 | "Unable to parse endpoint #%u.\n", i); | ||
1497 | goto error_put_node; | ||
1498 | } | ||
1499 | |||
1500 | if (fw_ep.bus_type != V4L2_MBUS_PARALLEL) { | ||
1501 | dev_err(ceudev->dev, | ||
1502 | "Only parallel input supported.\n"); | ||
1503 | ret = -EINVAL; | ||
1504 | goto error_put_node; | ||
1505 | } | ||
1506 | |||
1507 | /* Setup the ceu subdevice and the async subdevice. */ | ||
1508 | ceu_sd = &ceudev->subdevs[i]; | ||
1509 | INIT_LIST_HEAD(&ceu_sd->asd.list); | ||
1510 | |||
1511 | ceu_sd->mbus_flags = fw_ep.bus.parallel.flags; | ||
1512 | ceu_sd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; | ||
1513 | ceu_sd->asd.match.fwnode = | ||
1514 | fwnode_graph_get_remote_port_parent( | ||
1515 | of_fwnode_handle(ep)); | ||
1516 | |||
1517 | ceudev->asds[i] = &ceu_sd->asd; | ||
1518 | of_node_put(ep); | ||
1519 | } | ||
1520 | |||
1521 | return num_ep; | ||
1522 | |||
1523 | error_put_node: | ||
1524 | of_node_put(ep); | ||
1525 | return ret; | ||
1526 | } | ||
1527 | |||
1528 | /* | ||
1529 | * struct ceu_data - Platform specific CEU data | ||
1530 | * @irq_mask: CETCR mask with all interrupt sources enabled. The mask differs | ||
1531 | * between SH4 and RZ platforms. | ||
1532 | */ | ||
1533 | struct ceu_data { | ||
1534 | u32 irq_mask; | ||
1535 | }; | ||
1536 | |||
1537 | static const struct ceu_data ceu_data_rz = { | ||
1538 | .irq_mask = CEU_CETCR_ALL_IRQS_RZ, | ||
1539 | }; | ||
1540 | |||
1541 | static const struct ceu_data ceu_data_sh4 = { | ||
1542 | .irq_mask = CEU_CETCR_ALL_IRQS_SH4, | ||
1543 | }; | ||
1544 | |||
1545 | #if IS_ENABLED(CONFIG_OF) | ||
1546 | static const struct of_device_id ceu_of_match[] = { | ||
1547 | { .compatible = "renesas,r7s72100-ceu", .data = &ceu_data_rz }, | ||
1548 | { } | ||
1549 | }; | ||
1550 | MODULE_DEVICE_TABLE(of, ceu_of_match); | ||
1551 | #endif | ||
1552 | |||
1553 | static int ceu_probe(struct platform_device *pdev) | ||
1554 | { | ||
1555 | struct device *dev = &pdev->dev; | ||
1556 | const struct ceu_data *ceu_data; | ||
1557 | struct ceu_device *ceudev; | ||
1558 | struct resource *res; | ||
1559 | unsigned int irq; | ||
1560 | int num_subdevs; | ||
1561 | int ret; | ||
1562 | |||
1563 | ceudev = kzalloc(sizeof(*ceudev), GFP_KERNEL); | ||
1564 | if (!ceudev) | ||
1565 | return -ENOMEM; | ||
1566 | |||
1567 | platform_set_drvdata(pdev, ceudev); | ||
1568 | ceudev->dev = dev; | ||
1569 | |||
1570 | INIT_LIST_HEAD(&ceudev->capture); | ||
1571 | spin_lock_init(&ceudev->lock); | ||
1572 | mutex_init(&ceudev->mlock); | ||
1573 | |||
1574 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1575 | ceudev->base = devm_ioremap_resource(dev, res); | ||
1576 | if (IS_ERR(ceudev->base)) { | ||
1577 | ret = PTR_ERR(ceudev->base); | ||
1578 | goto error_free_ceudev; | ||
1579 | } | ||
1580 | |||
1581 | ret = platform_get_irq(pdev, 0); | ||
1582 | if (ret < 0) { | ||
1583 | dev_err(dev, "Failed to get irq: %d\n", ret); | ||
1584 | goto error_free_ceudev; | ||
1585 | } | ||
1586 | irq = ret; | ||
1587 | |||
1588 | ret = devm_request_irq(dev, irq, ceu_irq, | ||
1589 | 0, dev_name(dev), ceudev); | ||
1590 | if (ret) { | ||
1591 | dev_err(&pdev->dev, "Unable to request CEU interrupt.\n"); | ||
1592 | goto error_free_ceudev; | ||
1593 | } | ||
1594 | |||
1595 | pm_runtime_enable(dev); | ||
1596 | |||
1597 | ret = v4l2_device_register(dev, &ceudev->v4l2_dev); | ||
1598 | if (ret) | ||
1599 | goto error_pm_disable; | ||
1600 | |||
1601 | if (IS_ENABLED(CONFIG_OF) && dev->of_node) { | ||
1602 | ceu_data = of_match_device(ceu_of_match, dev)->data; | ||
1603 | num_subdevs = ceu_parse_dt(ceudev); | ||
1604 | } else if (dev->platform_data) { | ||
1605 | /* Assume SH4 if booting with platform data. */ | ||
1606 | ceu_data = &ceu_data_sh4; | ||
1607 | num_subdevs = ceu_parse_platform_data(ceudev, | ||
1608 | dev->platform_data); | ||
1609 | } else { | ||
1610 | num_subdevs = -EINVAL; | ||
1611 | } | ||
1612 | |||
1613 | if (num_subdevs < 0) { | ||
1614 | ret = num_subdevs; | ||
1615 | goto error_v4l2_unregister; | ||
1616 | } | ||
1617 | ceudev->irq_mask = ceu_data->irq_mask; | ||
1618 | |||
1619 | ceudev->notifier.v4l2_dev = &ceudev->v4l2_dev; | ||
1620 | ceudev->notifier.subdevs = ceudev->asds; | ||
1621 | ceudev->notifier.num_subdevs = num_subdevs; | ||
1622 | ceudev->notifier.ops = &ceu_notify_ops; | ||
1623 | ret = v4l2_async_notifier_register(&ceudev->v4l2_dev, | ||
1624 | &ceudev->notifier); | ||
1625 | if (ret) | ||
1626 | goto error_v4l2_unregister; | ||
1627 | |||
1628 | dev_info(dev, "Renesas Capture Engine Unit %s\n", dev_name(dev)); | ||
1629 | |||
1630 | return 0; | ||
1631 | |||
1632 | error_v4l2_unregister: | ||
1633 | v4l2_device_unregister(&ceudev->v4l2_dev); | ||
1634 | error_pm_disable: | ||
1635 | pm_runtime_disable(dev); | ||
1636 | error_free_ceudev: | ||
1637 | kfree(ceudev); | ||
1638 | |||
1639 | return ret; | ||
1640 | } | ||
1641 | |||
1642 | static int ceu_remove(struct platform_device *pdev) | ||
1643 | { | ||
1644 | struct ceu_device *ceudev = platform_get_drvdata(pdev); | ||
1645 | |||
1646 | pm_runtime_disable(ceudev->dev); | ||
1647 | |||
1648 | v4l2_async_notifier_unregister(&ceudev->notifier); | ||
1649 | |||
1650 | v4l2_device_unregister(&ceudev->v4l2_dev); | ||
1651 | |||
1652 | video_unregister_device(&ceudev->vdev); | ||
1653 | |||
1654 | return 0; | ||
1655 | } | ||
1656 | |||
1657 | static const struct dev_pm_ops ceu_pm_ops = { | ||
1658 | SET_RUNTIME_PM_OPS(ceu_runtime_suspend, | ||
1659 | ceu_runtime_resume, | ||
1660 | NULL) | ||
1661 | }; | ||
1662 | |||
1663 | static struct platform_driver ceu_driver = { | ||
1664 | .driver = { | ||
1665 | .name = DRIVER_NAME, | ||
1666 | .pm = &ceu_pm_ops, | ||
1667 | .of_match_table = of_match_ptr(ceu_of_match), | ||
1668 | }, | ||
1669 | .probe = ceu_probe, | ||
1670 | .remove = ceu_remove, | ||
1671 | }; | ||
1672 | |||
1673 | module_platform_driver(ceu_driver); | ||
1674 | |||
1675 | MODULE_DESCRIPTION("Renesas CEU camera driver"); | ||
1676 | MODULE_AUTHOR("Jacopo Mondi <jacopo+renesas@jmondi.org>"); | ||
1677 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c index 49cacc7a48d1..fa1ba98c96dc 100644 --- a/drivers/media/platform/rockchip/rga/rga-buf.c +++ b/drivers/media/platform/rockchip/rga/rga-buf.c | |||
@@ -140,7 +140,8 @@ void rga_buf_map(struct vb2_buffer *vb) | |||
140 | address = sg_phys(sgl); | 140 | address = sg_phys(sgl); |
141 | 141 | ||
142 | for (p = 0; p < len; p++) { | 142 | for (p = 0; p < len; p++) { |
143 | dma_addr_t phys = address + (p << PAGE_SHIFT); | 143 | dma_addr_t phys = address + |
144 | ((dma_addr_t)p << PAGE_SHIFT); | ||
144 | 145 | ||
145 | pages[mapped_size + p] = phys; | 146 | pages[mapped_size + p] = phys; |
146 | } | 147 | } |
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 89296de9cf4a..d508a8ba6f89 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c | |||
@@ -207,7 +207,7 @@ static int rga_setup_ctrls(struct rga_ctx *ctx) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | struct rga_fmt formats[] = { | 210 | static struct rga_fmt formats[] = { |
211 | { | 211 | { |
212 | .fourcc = V4L2_PIX_FMT_ARGB32, | 212 | .fourcc = V4L2_PIX_FMT_ARGB32, |
213 | .color_swap = RGA_COLOR_RB_SWAP, | 213 | .color_swap = RGA_COLOR_RB_SWAP, |
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 437395a61065..9ab8e7ee2e1e 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c | |||
@@ -1256,16 +1256,17 @@ static void __camif_subdev_try_format(struct camif_dev *camif, | |||
1256 | { | 1256 | { |
1257 | const struct s3c_camif_variant *variant = camif->variant; | 1257 | const struct s3c_camif_variant *variant = camif->variant; |
1258 | const struct vp_pix_limits *pix_lim; | 1258 | const struct vp_pix_limits *pix_lim; |
1259 | int i = ARRAY_SIZE(camif_mbus_formats); | 1259 | unsigned int i; |
1260 | 1260 | ||
1261 | /* FIXME: constraints against codec or preview path ? */ | 1261 | /* FIXME: constraints against codec or preview path ? */ |
1262 | pix_lim = &variant->vp_pix_limits[VP_CODEC]; | 1262 | pix_lim = &variant->vp_pix_limits[VP_CODEC]; |
1263 | 1263 | ||
1264 | while (i-- >= 0) | 1264 | for (i = 0; i < ARRAY_SIZE(camif_mbus_formats); i++) |
1265 | if (camif_mbus_formats[i] == mf->code) | 1265 | if (camif_mbus_formats[i] == mf->code) |
1266 | break; | 1266 | break; |
1267 | 1267 | ||
1268 | mf->code = camif_mbus_formats[i]; | 1268 | if (i == ARRAY_SIZE(camif_mbus_formats)) |
1269 | mf->code = camif_mbus_formats[0]; | ||
1269 | 1270 | ||
1270 | if (pad == CAMIF_SD_PAD_SINK) { | 1271 | if (pad == CAMIF_SD_PAD_SINK) { |
1271 | v4l_bound_align_image(&mf->width, 8, CAMIF_MAX_PIX_WIDTH, | 1272 | v4l_bound_align_image(&mf->width, 8, CAMIF_MAX_PIX_WIDTH, |
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v10.h b/drivers/media/platform/s5p-mfc/regs-mfc-v10.h new file mode 100644 index 000000000000..fadd9139b489 --- /dev/null +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v10.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * | ||
4 | * Copyright (c) 2017 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com/ | ||
6 | * | ||
7 | * Register definition file for Samsung MFC V10.x Interface (FIMV) driver | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef _REGS_MFC_V10_H | ||
12 | #define _REGS_MFC_V10_H | ||
13 | |||
14 | #include <linux/sizes.h> | ||
15 | #include "regs-mfc-v8.h" | ||
16 | |||
17 | /* MFCv10 register definitions*/ | ||
18 | #define S5P_FIMV_MFC_CLOCK_OFF_V10 0x7120 | ||
19 | #define S5P_FIMV_MFC_STATE_V10 0x7124 | ||
20 | #define S5P_FIMV_D_STATIC_BUFFER_ADDR_V10 0xF570 | ||
21 | #define S5P_FIMV_D_STATIC_BUFFER_SIZE_V10 0xF574 | ||
22 | #define S5P_FIMV_E_NUM_T_LAYER_V10 0xFBAC | ||
23 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER0_V10 0xFBB0 | ||
24 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER1_V10 0xFBB4 | ||
25 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER2_V10 0xFBB8 | ||
26 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER3_V10 0xFBBC | ||
27 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER4_V10 0xFBC0 | ||
28 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER5_V10 0xFBC4 | ||
29 | #define S5P_FIMV_E_HIERARCHICAL_QP_LAYER6_V10 0xFBC8 | ||
30 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0_V10 0xFD18 | ||
31 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER1_V10 0xFD1C | ||
32 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER2_V10 0xFD20 | ||
33 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER3_V10 0xFD24 | ||
34 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER4_V10 0xFD28 | ||
35 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER5_V10 0xFD2C | ||
36 | #define S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER6_V10 0xFD30 | ||
37 | #define S5P_FIMV_E_HEVC_OPTIONS_V10 0xFDD4 | ||
38 | #define S5P_FIMV_E_HEVC_REFRESH_PERIOD_V10 0xFDD8 | ||
39 | #define S5P_FIMV_E_HEVC_CHROMA_QP_OFFSET_V10 0xFDDC | ||
40 | #define S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2_V10 0xFDE0 | ||
41 | #define S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2_V10 0xFDE4 | ||
42 | #define S5P_FIMV_E_HEVC_NAL_CONTROL_V10 0xFDE8 | ||
43 | |||
44 | /* MFCv10 Context buffer sizes */ | ||
45 | #define MFC_CTX_BUF_SIZE_V10 (30 * SZ_1K) | ||
46 | #define MFC_H264_DEC_CTX_BUF_SIZE_V10 (2 * SZ_1M) | ||
47 | #define MFC_OTHER_DEC_CTX_BUF_SIZE_V10 (20 * SZ_1K) | ||
48 | #define MFC_H264_ENC_CTX_BUF_SIZE_V10 (100 * SZ_1K) | ||
49 | #define MFC_HEVC_ENC_CTX_BUF_SIZE_V10 (30 * SZ_1K) | ||
50 | #define MFC_OTHER_ENC_CTX_BUF_SIZE_V10 (15 * SZ_1K) | ||
51 | |||
52 | /* MFCv10 variant defines */ | ||
53 | #define MAX_FW_SIZE_V10 (SZ_1M) | ||
54 | #define MAX_CPB_SIZE_V10 (3 * SZ_1M) | ||
55 | #define MFC_VERSION_V10 0xA0 | ||
56 | #define MFC_NUM_PORTS_V10 1 | ||
57 | |||
58 | /* MFCv10 codec defines*/ | ||
59 | #define S5P_FIMV_CODEC_HEVC_DEC 17 | ||
60 | #define S5P_FIMV_CODEC_VP9_DEC 18 | ||
61 | #define S5P_FIMV_CODEC_HEVC_ENC 26 | ||
62 | |||
63 | /* Decoder buffer size for MFC v10 */ | ||
64 | #define DEC_VP9_STATIC_BUFFER_SIZE 20480 | ||
65 | |||
66 | /* Encoder buffer size for MFC v10.0 */ | ||
67 | #define ENC_V100_BASE_SIZE(x, y) \ | ||
68 | (((x + 3) * (y + 3) * 8) \ | ||
69 | + ((y * 64) + 1280) * DIV_ROUND_UP(x, 8)) | ||
70 | |||
71 | #define ENC_V100_H264_ME_SIZE(x, y) \ | ||
72 | (ENC_V100_BASE_SIZE(x, y) \ | ||
73 | + (DIV_ROUND_UP(x * y, 64) * 32)) | ||
74 | |||
75 | #define ENC_V100_MPEG4_ME_SIZE(x, y) \ | ||
76 | (ENC_V100_BASE_SIZE(x, y) \ | ||
77 | + (DIV_ROUND_UP(x * y, 128) * 16)) | ||
78 | |||
79 | #define ENC_V100_VP8_ME_SIZE(x, y) \ | ||
80 | ENC_V100_BASE_SIZE(x, y) | ||
81 | |||
82 | #define ENC_V100_HEVC_ME_SIZE(x, y) \ | ||
83 | (((x + 3) * (y + 3) * 32) \ | ||
84 | + ((y * 128) + 1280) * DIV_ROUND_UP(x, 4)) | ||
85 | |||
86 | #endif /*_REGS_MFC_V10_H*/ | ||
87 | |||
diff --git a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h index 75f5f7511d72..bd639ae71023 100644 --- a/drivers/media/platform/s5p-mfc/regs-mfc-v8.h +++ b/drivers/media/platform/s5p-mfc/regs-mfc-v8.h | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | /* Additional registers for v8 */ | 18 | /* Additional registers for v8 */ |
19 | #define S5P_FIMV_D_MVC_NUM_VIEWS_V8 0xf104 | 19 | #define S5P_FIMV_D_MVC_NUM_VIEWS_V8 0xf104 |
20 | #define S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8 0xf108 | ||
20 | #define S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8 0xf144 | 21 | #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_SECOND_PLANE_DPB_SIZE_V8 0xf148 |
22 | #define S5P_FIMV_D_MV_BUFFER_SIZE_V8 0xf150 | 23 | #define S5P_FIMV_D_MV_BUFFER_SIZE_V8 0xf150 |
@@ -84,6 +85,7 @@ | |||
84 | 85 | ||
85 | #define S5P_FIMV_E_VBV_BUFFER_SIZE_V8 0xf78c | 86 | #define S5P_FIMV_E_VBV_BUFFER_SIZE_V8 0xf78c |
86 | #define S5P_FIMV_E_VBV_INIT_DELAY_V8 0xf790 | 87 | #define S5P_FIMV_E_VBV_INIT_DELAY_V8 0xf790 |
88 | #define S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE_V8 0xf894 | ||
87 | 89 | ||
88 | #define S5P_FIMV_E_ASPECT_RATIO_V8 0xfb4c | 90 | #define S5P_FIMV_E_ASPECT_RATIO_V8 0xfb4c |
89 | #define S5P_FIMV_E_EXTENDED_SAR_V8 0xfb50 | 91 | #define S5P_FIMV_E_EXTENDED_SAR_V8 0xfb50 |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index d5b94fc0040e..a80251ed3143 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c | |||
@@ -526,6 +526,8 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, | |||
526 | dev); | 526 | dev); |
527 | ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count, | 527 | ctx->mv_count = s5p_mfc_hw_call(dev->mfc_ops, get_mv_count, |
528 | dev); | 528 | dev); |
529 | ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops, | ||
530 | get_min_scratch_buf_size, dev); | ||
529 | if (ctx->img_width == 0 || ctx->img_height == 0) | 531 | if (ctx->img_width == 0 || ctx->img_height == 0) |
530 | ctx->state = MFCINST_ERROR; | 532 | ctx->state = MFCINST_ERROR; |
531 | else | 533 | else |
@@ -1607,6 +1609,29 @@ static struct s5p_mfc_variant mfc_drvdata_v8_5433 = { | |||
1607 | .num_clocks = 3, | 1609 | .num_clocks = 3, |
1608 | }; | 1610 | }; |
1609 | 1611 | ||
1612 | static struct s5p_mfc_buf_size_v6 mfc_buf_size_v10 = { | ||
1613 | .dev_ctx = MFC_CTX_BUF_SIZE_V10, | ||
1614 | .h264_dec_ctx = MFC_H264_DEC_CTX_BUF_SIZE_V10, | ||
1615 | .other_dec_ctx = MFC_OTHER_DEC_CTX_BUF_SIZE_V10, | ||
1616 | .h264_enc_ctx = MFC_H264_ENC_CTX_BUF_SIZE_V10, | ||
1617 | .hevc_enc_ctx = MFC_HEVC_ENC_CTX_BUF_SIZE_V10, | ||
1618 | .other_enc_ctx = MFC_OTHER_ENC_CTX_BUF_SIZE_V10, | ||
1619 | }; | ||
1620 | |||
1621 | static struct s5p_mfc_buf_size buf_size_v10 = { | ||
1622 | .fw = MAX_FW_SIZE_V10, | ||
1623 | .cpb = MAX_CPB_SIZE_V10, | ||
1624 | .priv = &mfc_buf_size_v10, | ||
1625 | }; | ||
1626 | |||
1627 | static struct s5p_mfc_variant mfc_drvdata_v10 = { | ||
1628 | .version = MFC_VERSION_V10, | ||
1629 | .version_bit = MFC_V10_BIT, | ||
1630 | .port_num = MFC_NUM_PORTS_V10, | ||
1631 | .buf_size = &buf_size_v10, | ||
1632 | .fw_name[0] = "s5p-mfc-v10.fw", | ||
1633 | }; | ||
1634 | |||
1610 | static const struct of_device_id exynos_mfc_match[] = { | 1635 | static const struct of_device_id exynos_mfc_match[] = { |
1611 | { | 1636 | { |
1612 | .compatible = "samsung,mfc-v5", | 1637 | .compatible = "samsung,mfc-v5", |
@@ -1623,6 +1648,9 @@ static const struct of_device_id exynos_mfc_match[] = { | |||
1623 | }, { | 1648 | }, { |
1624 | .compatible = "samsung,exynos5433-mfc", | 1649 | .compatible = "samsung,exynos5433-mfc", |
1625 | .data = &mfc_drvdata_v8_5433, | 1650 | .data = &mfc_drvdata_v8_5433, |
1651 | }, { | ||
1652 | .compatible = "samsung,mfc-v10", | ||
1653 | .data = &mfc_drvdata_v10, | ||
1626 | }, | 1654 | }, |
1627 | {}, | 1655 | {}, |
1628 | }; | 1656 | }; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c index b1b149151d2d..7521fceb68f1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_cmd_v6.c | |||
@@ -101,6 +101,12 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) | |||
101 | case S5P_MFC_CODEC_VP8_DEC: | 101 | case S5P_MFC_CODEC_VP8_DEC: |
102 | codec_type = S5P_FIMV_CODEC_VP8_DEC_V6; | 102 | codec_type = S5P_FIMV_CODEC_VP8_DEC_V6; |
103 | break; | 103 | break; |
104 | case S5P_MFC_CODEC_HEVC_DEC: | ||
105 | codec_type = S5P_FIMV_CODEC_HEVC_DEC; | ||
106 | break; | ||
107 | case S5P_MFC_CODEC_VP9_DEC: | ||
108 | codec_type = S5P_FIMV_CODEC_VP9_DEC; | ||
109 | break; | ||
104 | case S5P_MFC_CODEC_H264_ENC: | 110 | case S5P_MFC_CODEC_H264_ENC: |
105 | codec_type = S5P_FIMV_CODEC_H264_ENC_V6; | 111 | codec_type = S5P_FIMV_CODEC_H264_ENC_V6; |
106 | break; | 112 | break; |
@@ -116,6 +122,9 @@ static int s5p_mfc_open_inst_cmd_v6(struct s5p_mfc_ctx *ctx) | |||
116 | case S5P_MFC_CODEC_VP8_ENC: | 122 | case S5P_MFC_CODEC_VP8_ENC: |
117 | codec_type = S5P_FIMV_CODEC_VP8_ENC_V7; | 123 | codec_type = S5P_FIMV_CODEC_VP8_ENC_V7; |
118 | break; | 124 | break; |
125 | case S5P_MFC_CODEC_HEVC_ENC: | ||
126 | codec_type = S5P_FIMV_CODEC_HEVC_ENC; | ||
127 | break; | ||
119 | default: | 128 | default: |
120 | codec_type = S5P_FIMV_CODEC_NONE_V6; | 129 | codec_type = S5P_FIMV_CODEC_NONE_V6; |
121 | } | 130 | } |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 76119a8cc477..20442a9b9f7a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <media/v4l2-ioctl.h> | 23 | #include <media/v4l2-ioctl.h> |
24 | #include <media/videobuf2-v4l2.h> | 24 | #include <media/videobuf2-v4l2.h> |
25 | #include "regs-mfc.h" | 25 | #include "regs-mfc.h" |
26 | #include "regs-mfc-v8.h" | 26 | #include "regs-mfc-v10.h" |
27 | 27 | ||
28 | #define S5P_MFC_NAME "s5p-mfc" | 28 | #define S5P_MFC_NAME "s5p-mfc" |
29 | 29 | ||
@@ -61,7 +61,7 @@ | |||
61 | #define MFC_ENC_CAP_PLANE_COUNT 1 | 61 | #define MFC_ENC_CAP_PLANE_COUNT 1 |
62 | #define MFC_ENC_OUT_PLANE_COUNT 2 | 62 | #define MFC_ENC_OUT_PLANE_COUNT 2 |
63 | #define STUFF_BYTE 4 | 63 | #define STUFF_BYTE 4 |
64 | #define MFC_MAX_CTRLS 77 | 64 | #define MFC_MAX_CTRLS 128 |
65 | 65 | ||
66 | #define S5P_MFC_CODEC_NONE -1 | 66 | #define S5P_MFC_CODEC_NONE -1 |
67 | #define S5P_MFC_CODEC_H264_DEC 0 | 67 | #define S5P_MFC_CODEC_H264_DEC 0 |
@@ -72,12 +72,15 @@ | |||
72 | #define S5P_MFC_CODEC_H263_DEC 5 | 72 | #define S5P_MFC_CODEC_H263_DEC 5 |
73 | #define S5P_MFC_CODEC_VC1RCV_DEC 6 | 73 | #define S5P_MFC_CODEC_VC1RCV_DEC 6 |
74 | #define S5P_MFC_CODEC_VP8_DEC 7 | 74 | #define S5P_MFC_CODEC_VP8_DEC 7 |
75 | #define S5P_MFC_CODEC_HEVC_DEC 17 | ||
76 | #define S5P_MFC_CODEC_VP9_DEC 18 | ||
75 | 77 | ||
76 | #define S5P_MFC_CODEC_H264_ENC 20 | 78 | #define S5P_MFC_CODEC_H264_ENC 20 |
77 | #define S5P_MFC_CODEC_H264_MVC_ENC 21 | 79 | #define S5P_MFC_CODEC_H264_MVC_ENC 21 |
78 | #define S5P_MFC_CODEC_MPEG4_ENC 22 | 80 | #define S5P_MFC_CODEC_MPEG4_ENC 22 |
79 | #define S5P_MFC_CODEC_H263_ENC 23 | 81 | #define S5P_MFC_CODEC_H263_ENC 23 |
80 | #define S5P_MFC_CODEC_VP8_ENC 24 | 82 | #define S5P_MFC_CODEC_VP8_ENC 24 |
83 | #define S5P_MFC_CODEC_HEVC_ENC 26 | ||
81 | 84 | ||
82 | #define S5P_MFC_R2H_CMD_EMPTY 0 | 85 | #define S5P_MFC_R2H_CMD_EMPTY 0 |
83 | #define S5P_MFC_R2H_CMD_SYS_INIT_RET 1 | 86 | #define S5P_MFC_R2H_CMD_SYS_INIT_RET 1 |
@@ -213,6 +216,7 @@ struct s5p_mfc_buf_size_v6 { | |||
213 | unsigned int h264_dec_ctx; | 216 | unsigned int h264_dec_ctx; |
214 | unsigned int other_dec_ctx; | 217 | unsigned int other_dec_ctx; |
215 | unsigned int h264_enc_ctx; | 218 | unsigned int h264_enc_ctx; |
219 | unsigned int hevc_enc_ctx; | ||
216 | unsigned int other_enc_ctx; | 220 | unsigned int other_enc_ctx; |
217 | }; | 221 | }; |
218 | 222 | ||
@@ -430,6 +434,55 @@ struct s5p_mfc_vp8_enc_params { | |||
430 | u8 profile; | 434 | u8 profile; |
431 | }; | 435 | }; |
432 | 436 | ||
437 | struct s5p_mfc_hevc_enc_params { | ||
438 | enum v4l2_mpeg_video_hevc_profile profile; | ||
439 | int level; | ||
440 | enum v4l2_mpeg_video_h264_level level_v4l2; | ||
441 | u8 tier; | ||
442 | u32 rc_framerate; | ||
443 | u8 rc_min_qp; | ||
444 | u8 rc_max_qp; | ||
445 | u8 rc_lcu_dark; | ||
446 | u8 rc_lcu_smooth; | ||
447 | u8 rc_lcu_static; | ||
448 | u8 rc_lcu_activity; | ||
449 | u8 rc_frame_qp; | ||
450 | u8 rc_p_frame_qp; | ||
451 | u8 rc_b_frame_qp; | ||
452 | u8 max_partition_depth; | ||
453 | u8 num_refs_for_p; | ||
454 | u8 refreshtype; | ||
455 | u16 refreshperiod; | ||
456 | s32 lf_beta_offset_div2; | ||
457 | s32 lf_tc_offset_div2; | ||
458 | u8 loopfilter; | ||
459 | u8 loopfilter_disable; | ||
460 | u8 loopfilter_across; | ||
461 | u8 nal_control_length_filed; | ||
462 | u8 nal_control_user_ref; | ||
463 | u8 nal_control_store_ref; | ||
464 | u8 const_intra_period_enable; | ||
465 | u8 lossless_cu_enable; | ||
466 | u8 wavefront_enable; | ||
467 | u8 enable_ltr; | ||
468 | u8 hier_qp_enable; | ||
469 | enum v4l2_mpeg_video_hevc_hier_coding_type hier_qp_type; | ||
470 | u8 num_hier_layer; | ||
471 | u8 hier_qp_layer[7]; | ||
472 | u32 hier_bit_layer[7]; | ||
473 | u8 sign_data_hiding; | ||
474 | u8 general_pb_enable; | ||
475 | u8 temporal_id_enable; | ||
476 | u8 strong_intra_smooth; | ||
477 | u8 intra_pu_split_disable; | ||
478 | u8 tmv_prediction_disable; | ||
479 | u8 max_num_merge_mv; | ||
480 | u8 eco_mode_enable; | ||
481 | u8 encoding_nostartcode_enable; | ||
482 | u8 size_of_length_field; | ||
483 | u8 prepend_sps_pps_to_idr; | ||
484 | }; | ||
485 | |||
433 | /** | 486 | /** |
434 | * struct s5p_mfc_enc_params - general encoding parameters | 487 | * struct s5p_mfc_enc_params - general encoding parameters |
435 | */ | 488 | */ |
@@ -467,6 +520,7 @@ struct s5p_mfc_enc_params { | |||
467 | struct s5p_mfc_h264_enc_params h264; | 520 | struct s5p_mfc_h264_enc_params h264; |
468 | struct s5p_mfc_mpeg4_enc_params mpeg4; | 521 | struct s5p_mfc_mpeg4_enc_params mpeg4; |
469 | struct s5p_mfc_vp8_enc_params vp8; | 522 | struct s5p_mfc_vp8_enc_params vp8; |
523 | struct s5p_mfc_hevc_enc_params hevc; | ||
470 | } codec; | 524 | } codec; |
471 | 525 | ||
472 | }; | 526 | }; |
@@ -714,12 +768,20 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq); | |||
714 | #define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0) | 768 | #define IS_TWOPORT(dev) (dev->variant->port_num == 2 ? 1 : 0) |
715 | #define IS_MFCV6_PLUS(dev) (dev->variant->version >= 0x60 ? 1 : 0) | 769 | #define IS_MFCV6_PLUS(dev) (dev->variant->version >= 0x60 ? 1 : 0) |
716 | #define IS_MFCV7_PLUS(dev) (dev->variant->version >= 0x70 ? 1 : 0) | 770 | #define IS_MFCV7_PLUS(dev) (dev->variant->version >= 0x70 ? 1 : 0) |
717 | #define IS_MFCV8(dev) (dev->variant->version >= 0x80 ? 1 : 0) | 771 | #define IS_MFCV8_PLUS(dev) (dev->variant->version >= 0x80 ? 1 : 0) |
772 | #define IS_MFCV10(dev) (dev->variant->version >= 0xA0 ? 1 : 0) | ||
773 | #define FW_HAS_E_MIN_SCRATCH_BUF(dev) (IS_MFCV10(dev)) | ||
718 | 774 | ||
719 | #define MFC_V5_BIT BIT(0) | 775 | #define MFC_V5_BIT BIT(0) |
720 | #define MFC_V6_BIT BIT(1) | 776 | #define MFC_V6_BIT BIT(1) |
721 | #define MFC_V7_BIT BIT(2) | 777 | #define MFC_V7_BIT BIT(2) |
722 | #define MFC_V8_BIT BIT(3) | 778 | #define MFC_V8_BIT BIT(3) |
779 | #define MFC_V10_BIT BIT(5) | ||
723 | 780 | ||
781 | #define MFC_V5PLUS_BITS (MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | \ | ||
782 | MFC_V8_BIT | MFC_V10_BIT) | ||
783 | #define MFC_V6PLUS_BITS (MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT | \ | ||
784 | MFC_V10_BIT) | ||
785 | #define MFC_V7PLUS_BITS (MFC_V7_BIT | MFC_V8_BIT | MFC_V10_BIT) | ||
724 | 786 | ||
725 | #endif /* S5P_MFC_COMMON_H_ */ | 787 | #endif /* S5P_MFC_COMMON_H_ */ |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index f95cd76af537..ee7b15b335e0 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | |||
@@ -62,7 +62,7 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev) | |||
62 | if (!dev->variant->fw_name[i]) | 62 | if (!dev->variant->fw_name[i]) |
63 | continue; | 63 | continue; |
64 | err = request_firmware((const struct firmware **)&fw_blob, | 64 | err = request_firmware((const struct firmware **)&fw_blob, |
65 | dev->variant->fw_name[i], dev->v4l2_dev.dev); | 65 | dev->variant->fw_name[i], &dev->plat_dev->dev); |
66 | if (!err) { | 66 | if (!err) { |
67 | dev->fw_ver = (enum s5p_mfc_fw_ver) i; | 67 | dev->fw_ver = (enum s5p_mfc_fw_ver) i; |
68 | break; | 68 | break; |
@@ -239,6 +239,10 @@ int s5p_mfc_init_hw(struct s5p_mfc_dev *dev) | |||
239 | } | 239 | } |
240 | else | 240 | else |
241 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); | 241 | mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET); |
242 | |||
243 | if (IS_MFCV10(dev)) | ||
244 | mfc_write(dev, 0x0, S5P_FIMV_MFC_CLOCK_OFF_V10); | ||
245 | |||
242 | mfc_debug(2, "Will now wait for completion of firmware transfer\n"); | 246 | mfc_debug(2, "Will now wait for completion of firmware transfer\n"); |
243 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { | 247 | if (s5p_mfc_wait_for_done_dev(dev, S5P_MFC_R2H_CMD_FW_STATUS_RET)) { |
244 | mfc_err("Failed to load firmware\n"); | 248 | mfc_err("Failed to load firmware\n"); |
@@ -399,7 +403,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev) | |||
399 | s5p_mfc_clear_cmds(dev); | 403 | s5p_mfc_clear_cmds(dev); |
400 | s5p_mfc_clean_dev_int_flags(dev); | 404 | s5p_mfc_clean_dev_int_flags(dev); |
401 | /* 3. Send MFC wakeup command and wait for completion*/ | 405 | /* 3. Send MFC wakeup command and wait for completion*/ |
402 | if (IS_MFCV8(dev)) | 406 | if (IS_MFCV8_PLUS(dev)) |
403 | ret = s5p_mfc_v8_wait_wakeup(dev); | 407 | ret = s5p_mfc_v8_wait_wakeup(dev); |
404 | else | 408 | else |
405 | ret = s5p_mfc_wait_wakeup(dev); | 409 | ret = s5p_mfc_wait_wakeup(dev); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 8937b0af7cb3..5cf4d9921264 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
@@ -54,7 +54,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
54 | .codec_mode = S5P_MFC_CODEC_NONE, | 54 | .codec_mode = S5P_MFC_CODEC_NONE, |
55 | .type = MFC_FMT_RAW, | 55 | .type = MFC_FMT_RAW, |
56 | .num_planes = 2, | 56 | .num_planes = 2, |
57 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | 57 | .versions = MFC_V6PLUS_BITS, |
58 | }, | 58 | }, |
59 | { | 59 | { |
60 | .name = "4:2:0 2 Planes Y/CrCb", | 60 | .name = "4:2:0 2 Planes Y/CrCb", |
@@ -62,7 +62,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
62 | .codec_mode = S5P_MFC_CODEC_NONE, | 62 | .codec_mode = S5P_MFC_CODEC_NONE, |
63 | .type = MFC_FMT_RAW, | 63 | .type = MFC_FMT_RAW, |
64 | .num_planes = 2, | 64 | .num_planes = 2, |
65 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | 65 | .versions = MFC_V6PLUS_BITS, |
66 | }, | 66 | }, |
67 | { | 67 | { |
68 | .name = "H264 Encoded Stream", | 68 | .name = "H264 Encoded Stream", |
@@ -70,8 +70,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
70 | .codec_mode = S5P_MFC_CODEC_H264_DEC, | 70 | .codec_mode = S5P_MFC_CODEC_H264_DEC, |
71 | .type = MFC_FMT_DEC, | 71 | .type = MFC_FMT_DEC, |
72 | .num_planes = 1, | 72 | .num_planes = 1, |
73 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 73 | .versions = MFC_V5PLUS_BITS, |
74 | MFC_V8_BIT, | ||
75 | }, | 74 | }, |
76 | { | 75 | { |
77 | .name = "H264/MVC Encoded Stream", | 76 | .name = "H264/MVC Encoded Stream", |
@@ -79,7 +78,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
79 | .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC, | 78 | .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC, |
80 | .type = MFC_FMT_DEC, | 79 | .type = MFC_FMT_DEC, |
81 | .num_planes = 1, | 80 | .num_planes = 1, |
82 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | 81 | .versions = MFC_V6PLUS_BITS, |
83 | }, | 82 | }, |
84 | { | 83 | { |
85 | .name = "H263 Encoded Stream", | 84 | .name = "H263 Encoded Stream", |
@@ -87,8 +86,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
87 | .codec_mode = S5P_MFC_CODEC_H263_DEC, | 86 | .codec_mode = S5P_MFC_CODEC_H263_DEC, |
88 | .type = MFC_FMT_DEC, | 87 | .type = MFC_FMT_DEC, |
89 | .num_planes = 1, | 88 | .num_planes = 1, |
90 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 89 | .versions = MFC_V5PLUS_BITS, |
91 | MFC_V8_BIT, | ||
92 | }, | 90 | }, |
93 | { | 91 | { |
94 | .name = "MPEG1 Encoded Stream", | 92 | .name = "MPEG1 Encoded Stream", |
@@ -96,8 +94,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
96 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, | 94 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, |
97 | .type = MFC_FMT_DEC, | 95 | .type = MFC_FMT_DEC, |
98 | .num_planes = 1, | 96 | .num_planes = 1, |
99 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 97 | .versions = MFC_V5PLUS_BITS, |
100 | MFC_V8_BIT, | ||
101 | }, | 98 | }, |
102 | { | 99 | { |
103 | .name = "MPEG2 Encoded Stream", | 100 | .name = "MPEG2 Encoded Stream", |
@@ -105,8 +102,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
105 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, | 102 | .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, |
106 | .type = MFC_FMT_DEC, | 103 | .type = MFC_FMT_DEC, |
107 | .num_planes = 1, | 104 | .num_planes = 1, |
108 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 105 | .versions = MFC_V5PLUS_BITS, |
109 | MFC_V8_BIT, | ||
110 | }, | 106 | }, |
111 | { | 107 | { |
112 | .name = "MPEG4 Encoded Stream", | 108 | .name = "MPEG4 Encoded Stream", |
@@ -114,8 +110,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
114 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, | 110 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, |
115 | .type = MFC_FMT_DEC, | 111 | .type = MFC_FMT_DEC, |
116 | .num_planes = 1, | 112 | .num_planes = 1, |
117 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 113 | .versions = MFC_V5PLUS_BITS, |
118 | MFC_V8_BIT, | ||
119 | }, | 114 | }, |
120 | { | 115 | { |
121 | .name = "XviD Encoded Stream", | 116 | .name = "XviD Encoded Stream", |
@@ -123,8 +118,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
123 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, | 118 | .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, |
124 | .type = MFC_FMT_DEC, | 119 | .type = MFC_FMT_DEC, |
125 | .num_planes = 1, | 120 | .num_planes = 1, |
126 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 121 | .versions = MFC_V5PLUS_BITS, |
127 | MFC_V8_BIT, | ||
128 | }, | 122 | }, |
129 | { | 123 | { |
130 | .name = "VC1 Encoded Stream", | 124 | .name = "VC1 Encoded Stream", |
@@ -132,8 +126,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
132 | .codec_mode = S5P_MFC_CODEC_VC1_DEC, | 126 | .codec_mode = S5P_MFC_CODEC_VC1_DEC, |
133 | .type = MFC_FMT_DEC, | 127 | .type = MFC_FMT_DEC, |
134 | .num_planes = 1, | 128 | .num_planes = 1, |
135 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 129 | .versions = MFC_V5PLUS_BITS, |
136 | MFC_V8_BIT, | ||
137 | }, | 130 | }, |
138 | { | 131 | { |
139 | .name = "VC1 RCV Encoded Stream", | 132 | .name = "VC1 RCV Encoded Stream", |
@@ -141,8 +134,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
141 | .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC, | 134 | .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC, |
142 | .type = MFC_FMT_DEC, | 135 | .type = MFC_FMT_DEC, |
143 | .num_planes = 1, | 136 | .num_planes = 1, |
144 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 137 | .versions = MFC_V5PLUS_BITS, |
145 | MFC_V8_BIT, | ||
146 | }, | 138 | }, |
147 | { | 139 | { |
148 | .name = "VP8 Encoded Stream", | 140 | .name = "VP8 Encoded Stream", |
@@ -150,7 +142,21 @@ static struct s5p_mfc_fmt formats[] = { | |||
150 | .codec_mode = S5P_MFC_CODEC_VP8_DEC, | 142 | .codec_mode = S5P_MFC_CODEC_VP8_DEC, |
151 | .type = MFC_FMT_DEC, | 143 | .type = MFC_FMT_DEC, |
152 | .num_planes = 1, | 144 | .num_planes = 1, |
153 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | 145 | .versions = MFC_V6PLUS_BITS, |
146 | }, | ||
147 | { | ||
148 | .fourcc = V4L2_PIX_FMT_HEVC, | ||
149 | .codec_mode = S5P_FIMV_CODEC_HEVC_DEC, | ||
150 | .type = MFC_FMT_DEC, | ||
151 | .num_planes = 1, | ||
152 | .versions = MFC_V10_BIT, | ||
153 | }, | ||
154 | { | ||
155 | .fourcc = V4L2_PIX_FMT_VP9, | ||
156 | .codec_mode = S5P_FIMV_CODEC_VP9_DEC, | ||
157 | .type = MFC_FMT_DEC, | ||
158 | .num_planes = 1, | ||
159 | .versions = MFC_V10_BIT, | ||
154 | }, | 160 | }, |
155 | }; | 161 | }; |
156 | 162 | ||
@@ -1177,7 +1183,7 @@ void s5p_mfc_dec_init(struct s5p_mfc_ctx *ctx) | |||
1177 | struct v4l2_format f; | 1183 | struct v4l2_format f; |
1178 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; | 1184 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; |
1179 | ctx->src_fmt = find_format(&f, MFC_FMT_DEC); | 1185 | ctx->src_fmt = find_format(&f, MFC_FMT_DEC); |
1180 | if (IS_MFCV8(ctx->dev)) | 1186 | if (IS_MFCV8_PLUS(ctx->dev)) |
1181 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; | 1187 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; |
1182 | else if (IS_MFCV6_PLUS(ctx->dev)) | 1188 | else if (IS_MFCV6_PLUS(ctx->dev)) |
1183 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; | 1189 | f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12MT_16X16; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 0d5d465561be..5c0462ca9993 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
@@ -57,8 +57,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
57 | .codec_mode = S5P_MFC_CODEC_NONE, | 57 | .codec_mode = S5P_MFC_CODEC_NONE, |
58 | .type = MFC_FMT_RAW, | 58 | .type = MFC_FMT_RAW, |
59 | .num_planes = 2, | 59 | .num_planes = 2, |
60 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 60 | .versions = MFC_V5PLUS_BITS, |
61 | MFC_V8_BIT, | ||
62 | }, | 61 | }, |
63 | { | 62 | { |
64 | .name = "4:2:0 2 Planes Y/CrCb", | 63 | .name = "4:2:0 2 Planes Y/CrCb", |
@@ -66,7 +65,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
66 | .codec_mode = S5P_MFC_CODEC_NONE, | 65 | .codec_mode = S5P_MFC_CODEC_NONE, |
67 | .type = MFC_FMT_RAW, | 66 | .type = MFC_FMT_RAW, |
68 | .num_planes = 2, | 67 | .num_planes = 2, |
69 | .versions = MFC_V6_BIT | MFC_V7_BIT | MFC_V8_BIT, | 68 | .versions = MFC_V6PLUS_BITS, |
70 | }, | 69 | }, |
71 | { | 70 | { |
72 | .name = "H264 Encoded Stream", | 71 | .name = "H264 Encoded Stream", |
@@ -74,8 +73,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
74 | .codec_mode = S5P_MFC_CODEC_H264_ENC, | 73 | .codec_mode = S5P_MFC_CODEC_H264_ENC, |
75 | .type = MFC_FMT_ENC, | 74 | .type = MFC_FMT_ENC, |
76 | .num_planes = 1, | 75 | .num_planes = 1, |
77 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 76 | .versions = MFC_V5PLUS_BITS, |
78 | MFC_V8_BIT, | ||
79 | }, | 77 | }, |
80 | { | 78 | { |
81 | .name = "MPEG4 Encoded Stream", | 79 | .name = "MPEG4 Encoded Stream", |
@@ -83,8 +81,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
83 | .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, | 81 | .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, |
84 | .type = MFC_FMT_ENC, | 82 | .type = MFC_FMT_ENC, |
85 | .num_planes = 1, | 83 | .num_planes = 1, |
86 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 84 | .versions = MFC_V5PLUS_BITS, |
87 | MFC_V8_BIT, | ||
88 | }, | 85 | }, |
89 | { | 86 | { |
90 | .name = "H263 Encoded Stream", | 87 | .name = "H263 Encoded Stream", |
@@ -92,8 +89,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
92 | .codec_mode = S5P_MFC_CODEC_H263_ENC, | 89 | .codec_mode = S5P_MFC_CODEC_H263_ENC, |
93 | .type = MFC_FMT_ENC, | 90 | .type = MFC_FMT_ENC, |
94 | .num_planes = 1, | 91 | .num_planes = 1, |
95 | .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | | 92 | .versions = MFC_V5PLUS_BITS, |
96 | MFC_V8_BIT, | ||
97 | }, | 93 | }, |
98 | { | 94 | { |
99 | .name = "VP8 Encoded Stream", | 95 | .name = "VP8 Encoded Stream", |
@@ -101,7 +97,14 @@ static struct s5p_mfc_fmt formats[] = { | |||
101 | .codec_mode = S5P_MFC_CODEC_VP8_ENC, | 97 | .codec_mode = S5P_MFC_CODEC_VP8_ENC, |
102 | .type = MFC_FMT_ENC, | 98 | .type = MFC_FMT_ENC, |
103 | .num_planes = 1, | 99 | .num_planes = 1, |
104 | .versions = MFC_V7_BIT | MFC_V8_BIT, | 100 | .versions = MFC_V7PLUS_BITS, |
101 | }, | ||
102 | { | ||
103 | .fourcc = V4L2_PIX_FMT_HEVC, | ||
104 | .codec_mode = S5P_FIMV_CODEC_HEVC_ENC, | ||
105 | .type = MFC_FMT_ENC, | ||
106 | .num_planes = 1, | ||
107 | .versions = MFC_V10_BIT, | ||
105 | }, | 108 | }, |
106 | }; | 109 | }; |
107 | 110 | ||
@@ -697,6 +700,368 @@ static struct mfc_control controls[] = { | |||
697 | .default_value = 0, | 700 | .default_value = 0, |
698 | }, | 701 | }, |
699 | { | 702 | { |
703 | .id = V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, | ||
704 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
705 | .name = "HEVC I Frame QP Value", | ||
706 | .minimum = 0, | ||
707 | .maximum = 51, | ||
708 | .step = 1, | ||
709 | .default_value = 0, | ||
710 | }, | ||
711 | { | ||
712 | .id = V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, | ||
713 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
714 | .name = "HEVC P Frame QP Value", | ||
715 | .minimum = 0, | ||
716 | .maximum = 51, | ||
717 | .step = 1, | ||
718 | .default_value = 0, | ||
719 | }, | ||
720 | { | ||
721 | .id = V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP, | ||
722 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
723 | .minimum = 0, | ||
724 | .maximum = 51, | ||
725 | .step = 1, | ||
726 | .default_value = 0, | ||
727 | }, | ||
728 | { | ||
729 | .id = V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, | ||
730 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
731 | .minimum = 0, | ||
732 | .maximum = 51, | ||
733 | .step = 1, | ||
734 | .default_value = 0, | ||
735 | }, | ||
736 | { | ||
737 | .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP, | ||
738 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
739 | .minimum = 0, | ||
740 | .maximum = 51, | ||
741 | .step = 1, | ||
742 | .default_value = 0, | ||
743 | }, | ||
744 | { | ||
745 | .id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, | ||
746 | .type = V4L2_CTRL_TYPE_MENU, | ||
747 | .minimum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, | ||
748 | .maximum = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, | ||
749 | .step = 1, | ||
750 | .default_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, | ||
751 | }, | ||
752 | { | ||
753 | .id = V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, | ||
754 | .type = V4L2_CTRL_TYPE_MENU, | ||
755 | .minimum = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, | ||
756 | .maximum = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, | ||
757 | .step = 1, | ||
758 | .default_value = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, | ||
759 | }, | ||
760 | { | ||
761 | .id = V4L2_CID_MPEG_VIDEO_HEVC_TIER, | ||
762 | .type = V4L2_CTRL_TYPE_MENU, | ||
763 | .minimum = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, | ||
764 | .maximum = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, | ||
765 | .step = 1, | ||
766 | .default_value = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, | ||
767 | }, | ||
768 | { | ||
769 | .id = V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION, | ||
770 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
771 | .minimum = 1, | ||
772 | .maximum = (1 << 16) - 1, | ||
773 | .step = 1, | ||
774 | .default_value = 1, | ||
775 | }, | ||
776 | { | ||
777 | .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH, | ||
778 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
779 | .minimum = 0, | ||
780 | .maximum = 1, | ||
781 | .step = 1, | ||
782 | .default_value = 0, | ||
783 | }, | ||
784 | { | ||
785 | .id = V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES, | ||
786 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
787 | .minimum = 1, | ||
788 | .maximum = 2, | ||
789 | .step = 1, | ||
790 | .default_value = 1, | ||
791 | }, | ||
792 | { | ||
793 | .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE, | ||
794 | .type = V4L2_CTRL_TYPE_MENU, | ||
795 | .minimum = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE, | ||
796 | .maximum = V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR, | ||
797 | .step = 1, | ||
798 | .default_value = V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE, | ||
799 | }, | ||
800 | { | ||
801 | .id = V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED, | ||
802 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
803 | .minimum = 0, | ||
804 | .maximum = 1, | ||
805 | .step = 1, | ||
806 | .default_value = 0, | ||
807 | }, | ||
808 | { | ||
809 | .id = V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU, | ||
810 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
811 | .minimum = 0, | ||
812 | .maximum = 1, | ||
813 | .step = 1, | ||
814 | .default_value = 0, | ||
815 | }, | ||
816 | { | ||
817 | .id = V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT, | ||
818 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
819 | .minimum = 0, | ||
820 | .maximum = 1, | ||
821 | .step = 1, | ||
822 | .default_value = 0, | ||
823 | }, | ||
824 | { | ||
825 | .id = V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE, | ||
826 | .type = V4L2_CTRL_TYPE_MENU, | ||
827 | .minimum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED, | ||
828 | .maximum = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY, | ||
829 | .step = 1, | ||
830 | .default_value = V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED, | ||
831 | }, | ||
832 | { | ||
833 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP, | ||
834 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
835 | .minimum = 0, | ||
836 | .maximum = 1, | ||
837 | .step = 1, | ||
838 | .default_value = 0, | ||
839 | }, | ||
840 | { | ||
841 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE, | ||
842 | .type = V4L2_CTRL_TYPE_MENU, | ||
843 | .minimum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B, | ||
844 | .maximum = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P, | ||
845 | .step = 1, | ||
846 | .default_value = V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B, | ||
847 | }, | ||
848 | { | ||
849 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER, | ||
850 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
851 | .minimum = 0, | ||
852 | .maximum = 6, | ||
853 | .step = 1, | ||
854 | .default_value = 0, | ||
855 | }, | ||
856 | { | ||
857 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP, | ||
858 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
859 | .minimum = 0, | ||
860 | .maximum = 51, | ||
861 | .step = 1, | ||
862 | .default_value = 0, | ||
863 | }, | ||
864 | { | ||
865 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP, | ||
866 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
867 | .minimum = 0, | ||
868 | .maximum = 51, | ||
869 | .step = 1, | ||
870 | .default_value = 0, | ||
871 | }, | ||
872 | { | ||
873 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP, | ||
874 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
875 | .minimum = 0, | ||
876 | .maximum = 51, | ||
877 | .step = 1, | ||
878 | .default_value = 0, | ||
879 | }, | ||
880 | { | ||
881 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP, | ||
882 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
883 | .minimum = 0, | ||
884 | .maximum = 51, | ||
885 | .step = 1, | ||
886 | .default_value = 0, | ||
887 | }, | ||
888 | { | ||
889 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP, | ||
890 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
891 | .minimum = 0, | ||
892 | .maximum = 51, | ||
893 | .step = 1, | ||
894 | .default_value = 0, | ||
895 | }, | ||
896 | { | ||
897 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP, | ||
898 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
899 | .minimum = 0, | ||
900 | .maximum = 51, | ||
901 | .step = 1, | ||
902 | .default_value = 0, | ||
903 | }, | ||
904 | { | ||
905 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP, | ||
906 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
907 | .minimum = 0, | ||
908 | .maximum = 51, | ||
909 | .step = 1, | ||
910 | .default_value = 0, | ||
911 | }, | ||
912 | { | ||
913 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR, | ||
914 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
915 | .minimum = INT_MIN, | ||
916 | .maximum = INT_MAX, | ||
917 | .step = 1, | ||
918 | .default_value = 0, | ||
919 | }, | ||
920 | { | ||
921 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR, | ||
922 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
923 | .minimum = INT_MIN, | ||
924 | .maximum = INT_MAX, | ||
925 | .step = 1, | ||
926 | .default_value = 0, | ||
927 | }, | ||
928 | { | ||
929 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR, | ||
930 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
931 | .minimum = INT_MIN, | ||
932 | .maximum = INT_MAX, | ||
933 | .step = 1, | ||
934 | .default_value = 0, | ||
935 | }, | ||
936 | { | ||
937 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR, | ||
938 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
939 | .minimum = INT_MIN, | ||
940 | .maximum = INT_MAX, | ||
941 | .step = 1, | ||
942 | .default_value = 0, | ||
943 | }, | ||
944 | { | ||
945 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR, | ||
946 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
947 | .minimum = INT_MIN, | ||
948 | .maximum = INT_MAX, | ||
949 | .step = 1, | ||
950 | .default_value = 0, | ||
951 | }, | ||
952 | { | ||
953 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR, | ||
954 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
955 | .minimum = INT_MIN, | ||
956 | .maximum = INT_MAX, | ||
957 | .step = 1, | ||
958 | .default_value = 0, | ||
959 | }, | ||
960 | { | ||
961 | .id = V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR, | ||
962 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
963 | .minimum = INT_MIN, | ||
964 | .maximum = INT_MAX, | ||
965 | .step = 1, | ||
966 | .default_value = 0, | ||
967 | }, | ||
968 | { | ||
969 | .id = V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB, | ||
970 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
971 | .minimum = 0, | ||
972 | .maximum = 1, | ||
973 | .step = 1, | ||
974 | .default_value = 0, | ||
975 | }, | ||
976 | { | ||
977 | .id = V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID, | ||
978 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
979 | .minimum = 0, | ||
980 | .maximum = 1, | ||
981 | .step = 1, | ||
982 | .default_value = 0, | ||
983 | }, | ||
984 | { | ||
985 | .id = V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING, | ||
986 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
987 | .minimum = 0, | ||
988 | .maximum = 1, | ||
989 | .step = 1, | ||
990 | .default_value = 0, | ||
991 | }, | ||
992 | { | ||
993 | .id = V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT, | ||
994 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
995 | .minimum = 0, | ||
996 | .maximum = 1, | ||
997 | .step = 1, | ||
998 | .default_value = 0, | ||
999 | }, | ||
1000 | { | ||
1001 | .id = V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION, | ||
1002 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1003 | .minimum = 0, | ||
1004 | .maximum = 1, | ||
1005 | .step = 1, | ||
1006 | .default_value = 0, | ||
1007 | }, | ||
1008 | { | ||
1009 | .id = V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1, | ||
1010 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1011 | .minimum = 0, | ||
1012 | .maximum = 4, | ||
1013 | .step = 1, | ||
1014 | .default_value = 0, | ||
1015 | }, | ||
1016 | { | ||
1017 | .id = V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE, | ||
1018 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1019 | .minimum = 0, | ||
1020 | .maximum = 1, | ||
1021 | .step = 1, | ||
1022 | .default_value = 0, | ||
1023 | }, | ||
1024 | { | ||
1025 | .id = V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD, | ||
1026 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1027 | .minimum = 0, | ||
1028 | .maximum = (1 << 16) - 1, | ||
1029 | .step = 1, | ||
1030 | .default_value = 0, | ||
1031 | }, | ||
1032 | { | ||
1033 | .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2, | ||
1034 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1035 | .minimum = -6, | ||
1036 | .maximum = 6, | ||
1037 | .step = 1, | ||
1038 | .default_value = 0, | ||
1039 | }, | ||
1040 | { | ||
1041 | .id = V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2, | ||
1042 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1043 | .minimum = -6, | ||
1044 | .maximum = 6, | ||
1045 | .step = 1, | ||
1046 | .default_value = 0, | ||
1047 | }, | ||
1048 | { | ||
1049 | .id = V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD, | ||
1050 | .type = V4L2_CTRL_TYPE_MENU, | ||
1051 | .minimum = V4L2_MPEG_VIDEO_HEVC_SIZE_0, | ||
1052 | .maximum = V4L2_MPEG_VIDEO_HEVC_SIZE_4, | ||
1053 | .step = 1, | ||
1054 | .default_value = V4L2_MPEG_VIDEO_HEVC_SIZE_0, | ||
1055 | }, | ||
1056 | { | ||
1057 | .id = V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR, | ||
1058 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1059 | .minimum = 0, | ||
1060 | .maximum = 1, | ||
1061 | .step = 1, | ||
1062 | .default_value = 0, | ||
1063 | }, | ||
1064 | { | ||
700 | .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, | 1065 | .id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, |
701 | .type = V4L2_CTRL_TYPE_INTEGER, | 1066 | .type = V4L2_CTRL_TYPE_INTEGER, |
702 | .name = "Minimum number of output bufs", | 1067 | .name = "Minimum number of output bufs", |
@@ -817,6 +1182,11 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) | |||
817 | get_enc_dpb_count, dev); | 1182 | get_enc_dpb_count, dev); |
818 | if (ctx->pb_count < enc_pb_count) | 1183 | if (ctx->pb_count < enc_pb_count) |
819 | ctx->pb_count = enc_pb_count; | 1184 | ctx->pb_count = enc_pb_count; |
1185 | if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) { | ||
1186 | ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops, | ||
1187 | get_e_min_scratch_buf_size, dev); | ||
1188 | ctx->bank1.size += ctx->scratch_buf_size; | ||
1189 | } | ||
820 | ctx->state = MFCINST_HEAD_PRODUCED; | 1190 | ctx->state = MFCINST_HEAD_PRODUCED; |
821 | } | 1191 | } |
822 | 1192 | ||
@@ -850,7 +1220,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) | |||
850 | { | 1220 | { |
851 | struct s5p_mfc_dev *dev = ctx->dev; | 1221 | struct s5p_mfc_dev *dev = ctx->dev; |
852 | struct s5p_mfc_buf *mb_entry; | 1222 | struct s5p_mfc_buf *mb_entry; |
853 | unsigned long enc_y_addr, enc_c_addr; | 1223 | unsigned long enc_y_addr = 0, enc_c_addr = 0; |
854 | unsigned long mb_y_addr, mb_c_addr; | 1224 | unsigned long mb_y_addr, mb_c_addr; |
855 | int slice_type; | 1225 | int slice_type; |
856 | unsigned int strm_size; | 1226 | unsigned int strm_size; |
@@ -1358,6 +1728,26 @@ static inline int mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl) | |||
1358 | return t[lvl]; | 1728 | return t[lvl]; |
1359 | } | 1729 | } |
1360 | 1730 | ||
1731 | static inline int hevc_level(enum v4l2_mpeg_video_hevc_level lvl) | ||
1732 | { | ||
1733 | static unsigned int t[] = { | ||
1734 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_1 */ 10, | ||
1735 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2 */ 20, | ||
1736 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 */ 21, | ||
1737 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3 */ 30, | ||
1738 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 */ 31, | ||
1739 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4 */ 40, | ||
1740 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 */ 41, | ||
1741 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5 */ 50, | ||
1742 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 */ 51, | ||
1743 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 */ 52, | ||
1744 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6 */ 60, | ||
1745 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 */ 61, | ||
1746 | /* V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 */ 62, | ||
1747 | }; | ||
1748 | return t[lvl]; | ||
1749 | } | ||
1750 | |||
1361 | static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar) | 1751 | static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar) |
1362 | { | 1752 | { |
1363 | static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = { | 1753 | static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = { |
@@ -1383,6 +1773,42 @@ static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar) | |||
1383 | return t[sar]; | 1773 | return t[sar]; |
1384 | } | 1774 | } |
1385 | 1775 | ||
1776 | /* | ||
1777 | * Update range of all HEVC quantization parameter controls that depend on the | ||
1778 | * V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP, V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP controls. | ||
1779 | */ | ||
1780 | static void __enc_update_hevc_qp_ctrls_range(struct s5p_mfc_ctx *ctx, | ||
1781 | int min, int max) | ||
1782 | { | ||
1783 | static const int __hevc_qp_ctrls[] = { | ||
1784 | V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP, | ||
1785 | V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP, | ||
1786 | V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP, | ||
1787 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP, | ||
1788 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP, | ||
1789 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP, | ||
1790 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP, | ||
1791 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP, | ||
1792 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP, | ||
1793 | V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP, | ||
1794 | }; | ||
1795 | struct v4l2_ctrl *ctrl = NULL; | ||
1796 | int i, j; | ||
1797 | |||
1798 | for (i = 0; i < ARRAY_SIZE(__hevc_qp_ctrls); i++) { | ||
1799 | for (j = 0; j < ARRAY_SIZE(ctx->ctrls); j++) { | ||
1800 | if (ctx->ctrls[j]->id == __hevc_qp_ctrls[i]) { | ||
1801 | ctrl = ctx->ctrls[j]; | ||
1802 | break; | ||
1803 | } | ||
1804 | } | ||
1805 | if (WARN_ON(!ctrl)) | ||
1806 | break; | ||
1807 | |||
1808 | __v4l2_ctrl_modify_range(ctrl, min, max, ctrl->step, min); | ||
1809 | } | ||
1810 | } | ||
1811 | |||
1386 | static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) | 1812 | static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) |
1387 | { | 1813 | { |
1388 | struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl); | 1814 | struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl); |
@@ -1634,6 +2060,157 @@ static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1634 | case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: | 2060 | case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: |
1635 | p->codec.vp8.profile = ctrl->val; | 2061 | p->codec.vp8.profile = ctrl->val; |
1636 | break; | 2062 | break; |
2063 | case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: | ||
2064 | p->codec.hevc.rc_frame_qp = ctrl->val; | ||
2065 | break; | ||
2066 | case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: | ||
2067 | p->codec.hevc.rc_p_frame_qp = ctrl->val; | ||
2068 | break; | ||
2069 | case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: | ||
2070 | p->codec.hevc.rc_b_frame_qp = ctrl->val; | ||
2071 | break; | ||
2072 | case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: | ||
2073 | p->codec.hevc.rc_framerate = ctrl->val; | ||
2074 | break; | ||
2075 | case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: | ||
2076 | p->codec.hevc.rc_min_qp = ctrl->val; | ||
2077 | __enc_update_hevc_qp_ctrls_range(ctx, ctrl->val, | ||
2078 | p->codec.hevc.rc_max_qp); | ||
2079 | break; | ||
2080 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: | ||
2081 | p->codec.hevc.rc_max_qp = ctrl->val; | ||
2082 | __enc_update_hevc_qp_ctrls_range(ctx, p->codec.hevc.rc_min_qp, | ||
2083 | ctrl->val); | ||
2084 | break; | ||
2085 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: | ||
2086 | p->codec.hevc.level_v4l2 = ctrl->val; | ||
2087 | p->codec.hevc.level = hevc_level(ctrl->val); | ||
2088 | break; | ||
2089 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: | ||
2090 | switch (ctrl->val) { | ||
2091 | case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: | ||
2092 | p->codec.hevc.profile = | ||
2093 | V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN; | ||
2094 | break; | ||
2095 | case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: | ||
2096 | p->codec.hevc.profile = | ||
2097 | V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE; | ||
2098 | break; | ||
2099 | default: | ||
2100 | ret = -EINVAL; | ||
2101 | } | ||
2102 | break; | ||
2103 | case V4L2_CID_MPEG_VIDEO_HEVC_TIER: | ||
2104 | p->codec.hevc.tier = ctrl->val; | ||
2105 | break; | ||
2106 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: | ||
2107 | p->codec.hevc.max_partition_depth = ctrl->val; | ||
2108 | break; | ||
2109 | case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: | ||
2110 | p->codec.hevc.num_refs_for_p = ctrl->val; | ||
2111 | break; | ||
2112 | case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: | ||
2113 | p->codec.hevc.refreshtype = ctrl->val; | ||
2114 | break; | ||
2115 | case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: | ||
2116 | p->codec.hevc.const_intra_period_enable = ctrl->val; | ||
2117 | break; | ||
2118 | case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: | ||
2119 | p->codec.hevc.lossless_cu_enable = ctrl->val; | ||
2120 | break; | ||
2121 | case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: | ||
2122 | p->codec.hevc.wavefront_enable = ctrl->val; | ||
2123 | break; | ||
2124 | case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: | ||
2125 | p->codec.hevc.loopfilter = ctrl->val; | ||
2126 | break; | ||
2127 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: | ||
2128 | p->codec.hevc.hier_qp_enable = ctrl->val; | ||
2129 | break; | ||
2130 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: | ||
2131 | p->codec.hevc.hier_qp_type = ctrl->val; | ||
2132 | break; | ||
2133 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: | ||
2134 | p->codec.hevc.num_hier_layer = ctrl->val; | ||
2135 | break; | ||
2136 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: | ||
2137 | p->codec.hevc.hier_qp_layer[0] = ctrl->val; | ||
2138 | break; | ||
2139 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: | ||
2140 | p->codec.hevc.hier_qp_layer[1] = ctrl->val; | ||
2141 | break; | ||
2142 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: | ||
2143 | p->codec.hevc.hier_qp_layer[2] = ctrl->val; | ||
2144 | break; | ||
2145 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: | ||
2146 | p->codec.hevc.hier_qp_layer[3] = ctrl->val; | ||
2147 | break; | ||
2148 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: | ||
2149 | p->codec.hevc.hier_qp_layer[4] = ctrl->val; | ||
2150 | break; | ||
2151 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: | ||
2152 | p->codec.hevc.hier_qp_layer[5] = ctrl->val; | ||
2153 | break; | ||
2154 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: | ||
2155 | p->codec.hevc.hier_qp_layer[6] = ctrl->val; | ||
2156 | break; | ||
2157 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: | ||
2158 | p->codec.hevc.hier_bit_layer[0] = ctrl->val; | ||
2159 | break; | ||
2160 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: | ||
2161 | p->codec.hevc.hier_bit_layer[1] = ctrl->val; | ||
2162 | break; | ||
2163 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: | ||
2164 | p->codec.hevc.hier_bit_layer[2] = ctrl->val; | ||
2165 | break; | ||
2166 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: | ||
2167 | p->codec.hevc.hier_bit_layer[3] = ctrl->val; | ||
2168 | break; | ||
2169 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: | ||
2170 | p->codec.hevc.hier_bit_layer[4] = ctrl->val; | ||
2171 | break; | ||
2172 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: | ||
2173 | p->codec.hevc.hier_bit_layer[5] = ctrl->val; | ||
2174 | break; | ||
2175 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: | ||
2176 | p->codec.hevc.hier_bit_layer[6] = ctrl->val; | ||
2177 | break; | ||
2178 | case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: | ||
2179 | p->codec.hevc.general_pb_enable = ctrl->val; | ||
2180 | break; | ||
2181 | case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: | ||
2182 | p->codec.hevc.temporal_id_enable = ctrl->val; | ||
2183 | break; | ||
2184 | case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: | ||
2185 | p->codec.hevc.strong_intra_smooth = ctrl->val; | ||
2186 | break; | ||
2187 | case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: | ||
2188 | p->codec.hevc.intra_pu_split_disable = ctrl->val; | ||
2189 | break; | ||
2190 | case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: | ||
2191 | p->codec.hevc.tmv_prediction_disable = !ctrl->val; | ||
2192 | break; | ||
2193 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: | ||
2194 | p->codec.hevc.max_num_merge_mv = ctrl->val; | ||
2195 | break; | ||
2196 | case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: | ||
2197 | p->codec.hevc.encoding_nostartcode_enable = ctrl->val; | ||
2198 | break; | ||
2199 | case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: | ||
2200 | p->codec.hevc.refreshperiod = ctrl->val; | ||
2201 | break; | ||
2202 | case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: | ||
2203 | p->codec.hevc.lf_beta_offset_div2 = ctrl->val; | ||
2204 | break; | ||
2205 | case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: | ||
2206 | p->codec.hevc.lf_tc_offset_div2 = ctrl->val; | ||
2207 | break; | ||
2208 | case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: | ||
2209 | p->codec.hevc.size_of_length_field = ctrl->val; | ||
2210 | break; | ||
2211 | case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: | ||
2212 | p->codec.hevc.prepend_sps_pps_to_idr = ctrl->val; | ||
2213 | break; | ||
1637 | default: | 2214 | default: |
1638 | v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", | 2215 | v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", |
1639 | ctrl->id, ctrl->val); | 2216 | ctrl->id, ctrl->val); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h index 16d553fcff08..8c295f0f9740 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h | |||
@@ -169,6 +169,9 @@ struct s5p_mfc_regs { | |||
169 | void __iomem *d_decoded_third_addr;/* only v7 */ | 169 | void __iomem *d_decoded_third_addr;/* only v7 */ |
170 | void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */ | 170 | void __iomem *d_used_dpb_flag_upper;/* v7 and v8 */ |
171 | void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */ | 171 | void __iomem *d_used_dpb_flag_lower;/* v7 and v8 */ |
172 | void __iomem *d_min_scratch_buffer_size; /* v10 */ | ||
173 | void __iomem *d_static_buffer_addr; /* v10 */ | ||
174 | void __iomem *d_static_buffer_size; /* v10 */ | ||
172 | 175 | ||
173 | /* encoder registers */ | 176 | /* encoder registers */ |
174 | void __iomem *e_frame_width; | 177 | void __iomem *e_frame_width; |
@@ -268,6 +271,15 @@ struct s5p_mfc_regs { | |||
268 | void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */ | 271 | void __iomem *e_vp8_hierarchical_qp_layer0;/* v7 and v8 */ |
269 | void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */ | 272 | void __iomem *e_vp8_hierarchical_qp_layer1;/* v7 and v8 */ |
270 | void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */ | 273 | void __iomem *e_vp8_hierarchical_qp_layer2;/* v7 and v8 */ |
274 | void __iomem *e_min_scratch_buffer_size; /* v10 */ | ||
275 | void __iomem *e_num_t_layer; /* v10 */ | ||
276 | void __iomem *e_hier_qp_layer0; /* v10 */ | ||
277 | void __iomem *e_hier_bit_rate_layer0; /* v10 */ | ||
278 | void __iomem *e_hevc_options; /* v10 */ | ||
279 | void __iomem *e_hevc_refresh_period; /* v10 */ | ||
280 | void __iomem *e_hevc_lf_beta_offset_div2; /* v10 */ | ||
281 | void __iomem *e_hevc_lf_tc_offset_div2; /* v10 */ | ||
282 | void __iomem *e_hevc_nal_control; /* v10 */ | ||
271 | }; | 283 | }; |
272 | 284 | ||
273 | struct s5p_mfc_hw_ops { | 285 | struct s5p_mfc_hw_ops { |
@@ -311,6 +323,8 @@ struct s5p_mfc_hw_ops { | |||
311 | unsigned int (*get_pic_type_bot)(struct s5p_mfc_ctx *ctx); | 323 | unsigned int (*get_pic_type_bot)(struct s5p_mfc_ctx *ctx); |
312 | unsigned int (*get_crop_info_h)(struct s5p_mfc_ctx *ctx); | 324 | unsigned int (*get_crop_info_h)(struct s5p_mfc_ctx *ctx); |
313 | unsigned int (*get_crop_info_v)(struct s5p_mfc_ctx *ctx); | 325 | unsigned int (*get_crop_info_v)(struct s5p_mfc_ctx *ctx); |
326 | int (*get_min_scratch_buf_size)(struct s5p_mfc_dev *dev); | ||
327 | int (*get_e_min_scratch_buf_size)(struct s5p_mfc_dev *dev); | ||
314 | }; | 328 | }; |
315 | 329 | ||
316 | void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); | 330 | void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 88dbb9c341ec..7c629be43205 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | |||
@@ -64,6 +64,7 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
64 | { | 64 | { |
65 | struct s5p_mfc_dev *dev = ctx->dev; | 65 | struct s5p_mfc_dev *dev = ctx->dev; |
66 | unsigned int mb_width, mb_height; | 66 | unsigned int mb_width, mb_height; |
67 | unsigned int lcu_width = 0, lcu_height = 0; | ||
67 | int ret; | 68 | int ret; |
68 | 69 | ||
69 | mb_width = MB_WIDTH(ctx->img_width); | 70 | mb_width = MB_WIDTH(ctx->img_width); |
@@ -74,7 +75,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
74 | ctx->luma_size, ctx->chroma_size, ctx->mv_size); | 75 | ctx->luma_size, ctx->chroma_size, ctx->mv_size); |
75 | mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count); | 76 | mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count); |
76 | } else if (ctx->type == MFCINST_ENCODER) { | 77 | } else if (ctx->type == MFCINST_ENCODER) { |
77 | if (IS_MFCV8(dev)) | 78 | if (IS_MFCV10(dev)) { |
79 | ctx->tmv_buffer_size = 0; | ||
80 | } else if (IS_MFCV8_PLUS(dev)) | ||
78 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * | 81 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * |
79 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height), | 82 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height), |
80 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); | 83 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); |
@@ -82,14 +85,37 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
82 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * | 85 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * |
83 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height), | 86 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height), |
84 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); | 87 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); |
85 | 88 | if (IS_MFCV10(dev)) { | |
86 | ctx->luma_dpb_size = ALIGN((mb_width * mb_height) * | 89 | lcu_width = S5P_MFC_LCU_WIDTH(ctx->img_width); |
87 | S5P_FIMV_LUMA_MB_TO_PIXEL_V6, | 90 | lcu_height = S5P_MFC_LCU_HEIGHT(ctx->img_height); |
88 | S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6); | 91 | if (ctx->codec_mode != S5P_FIMV_CODEC_HEVC_ENC) { |
89 | ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * | 92 | ctx->luma_dpb_size = |
90 | S5P_FIMV_CHROMA_MB_TO_PIXEL_V6, | 93 | ALIGN((mb_width * 16), 64) |
91 | S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6); | 94 | * ALIGN((mb_height * 16), 32) |
92 | if (IS_MFCV8(dev)) | 95 | + 64; |
96 | ctx->chroma_dpb_size = | ||
97 | ALIGN((mb_width * 16), 64) | ||
98 | * (mb_height * 8) | ||
99 | + 64; | ||
100 | } else { | ||
101 | ctx->luma_dpb_size = | ||
102 | ALIGN((lcu_width * 32), 64) | ||
103 | * ALIGN((lcu_height * 32), 32) | ||
104 | + 64; | ||
105 | ctx->chroma_dpb_size = | ||
106 | ALIGN((lcu_width * 32), 64) | ||
107 | * (lcu_height * 16) | ||
108 | + 64; | ||
109 | } | ||
110 | } else { | ||
111 | ctx->luma_dpb_size = ALIGN((mb_width * mb_height) * | ||
112 | S5P_FIMV_LUMA_MB_TO_PIXEL_V6, | ||
113 | S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6); | ||
114 | ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * | ||
115 | S5P_FIMV_CHROMA_MB_TO_PIXEL_V6, | ||
116 | S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6); | ||
117 | } | ||
118 | if (IS_MFCV8_PLUS(dev)) | ||
93 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V8( | 119 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V8( |
94 | ctx->img_width, ctx->img_height, | 120 | ctx->img_width, ctx->img_height, |
95 | mb_width, mb_height), | 121 | mb_width, mb_height), |
@@ -110,7 +136,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
110 | switch (ctx->codec_mode) { | 136 | switch (ctx->codec_mode) { |
111 | case S5P_MFC_CODEC_H264_DEC: | 137 | case S5P_MFC_CODEC_H264_DEC: |
112 | case S5P_MFC_CODEC_H264_MVC_DEC: | 138 | case S5P_MFC_CODEC_H264_MVC_DEC: |
113 | if (IS_MFCV8(dev)) | 139 | if (IS_MFCV10(dev)) |
140 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
141 | else if (IS_MFCV8_PLUS(dev)) | ||
114 | ctx->scratch_buf_size = | 142 | ctx->scratch_buf_size = |
115 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V8( | 143 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V8( |
116 | mb_width, | 144 | mb_width, |
@@ -127,7 +155,9 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
127 | (ctx->mv_count * ctx->mv_size); | 155 | (ctx->mv_count * ctx->mv_size); |
128 | break; | 156 | break; |
129 | case S5P_MFC_CODEC_MPEG4_DEC: | 157 | case S5P_MFC_CODEC_MPEG4_DEC: |
130 | if (IS_MFCV7_PLUS(dev)) { | 158 | if (IS_MFCV10(dev)) |
159 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
160 | else if (IS_MFCV7_PLUS(dev)) { | ||
131 | ctx->scratch_buf_size = | 161 | ctx->scratch_buf_size = |
132 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V7( | 162 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V7( |
133 | mb_width, | 163 | mb_width, |
@@ -145,10 +175,14 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
145 | break; | 175 | break; |
146 | case S5P_MFC_CODEC_VC1RCV_DEC: | 176 | case S5P_MFC_CODEC_VC1RCV_DEC: |
147 | case S5P_MFC_CODEC_VC1_DEC: | 177 | case S5P_MFC_CODEC_VC1_DEC: |
148 | ctx->scratch_buf_size = | 178 | if (IS_MFCV10(dev)) |
149 | S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6( | 179 | mfc_debug(2, "Use min scratch buffer size\n"); |
150 | mb_width, | 180 | else |
151 | mb_height); | 181 | ctx->scratch_buf_size = |
182 | S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6( | ||
183 | mb_width, | ||
184 | mb_height); | ||
185 | |||
152 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 186 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
153 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 187 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
154 | ctx->bank1.size = ctx->scratch_buf_size; | 188 | ctx->bank1.size = ctx->scratch_buf_size; |
@@ -158,16 +192,21 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
158 | ctx->bank2.size = 0; | 192 | ctx->bank2.size = 0; |
159 | break; | 193 | break; |
160 | case S5P_MFC_CODEC_H263_DEC: | 194 | case S5P_MFC_CODEC_H263_DEC: |
161 | ctx->scratch_buf_size = | 195 | if (IS_MFCV10(dev)) |
162 | S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6( | 196 | mfc_debug(2, "Use min scratch buffer size\n"); |
163 | mb_width, | 197 | else |
164 | mb_height); | 198 | ctx->scratch_buf_size = |
199 | S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6( | ||
200 | mb_width, | ||
201 | mb_height); | ||
165 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 202 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
166 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 203 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
167 | ctx->bank1.size = ctx->scratch_buf_size; | 204 | ctx->bank1.size = ctx->scratch_buf_size; |
168 | break; | 205 | break; |
169 | case S5P_MFC_CODEC_VP8_DEC: | 206 | case S5P_MFC_CODEC_VP8_DEC: |
170 | if (IS_MFCV8(dev)) | 207 | if (IS_MFCV10(dev)) |
208 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
209 | else if (IS_MFCV8_PLUS(dev)) | ||
171 | ctx->scratch_buf_size = | 210 | ctx->scratch_buf_size = |
172 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V8( | 211 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V8( |
173 | mb_width, | 212 | mb_width, |
@@ -181,8 +220,24 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
181 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 220 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
182 | ctx->bank1.size = ctx->scratch_buf_size; | 221 | ctx->bank1.size = ctx->scratch_buf_size; |
183 | break; | 222 | break; |
223 | case S5P_MFC_CODEC_HEVC_DEC: | ||
224 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
225 | ctx->bank1.size = | ||
226 | ctx->scratch_buf_size + | ||
227 | (ctx->mv_count * ctx->mv_size); | ||
228 | break; | ||
229 | case S5P_MFC_CODEC_VP9_DEC: | ||
230 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
231 | ctx->bank1.size = | ||
232 | ctx->scratch_buf_size + | ||
233 | DEC_VP9_STATIC_BUFFER_SIZE; | ||
234 | break; | ||
184 | case S5P_MFC_CODEC_H264_ENC: | 235 | case S5P_MFC_CODEC_H264_ENC: |
185 | if (IS_MFCV8(dev)) | 236 | if (IS_MFCV10(dev)) { |
237 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
238 | ctx->me_buffer_size = | ||
239 | ALIGN(ENC_V100_H264_ME_SIZE(mb_width, mb_height), 16); | ||
240 | } else if (IS_MFCV8_PLUS(dev)) | ||
186 | ctx->scratch_buf_size = | 241 | ctx->scratch_buf_size = |
187 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V8( | 242 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V8( |
188 | mb_width, | 243 | mb_width, |
@@ -202,10 +257,16 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
202 | break; | 257 | break; |
203 | case S5P_MFC_CODEC_MPEG4_ENC: | 258 | case S5P_MFC_CODEC_MPEG4_ENC: |
204 | case S5P_MFC_CODEC_H263_ENC: | 259 | case S5P_MFC_CODEC_H263_ENC: |
205 | ctx->scratch_buf_size = | 260 | if (IS_MFCV10(dev)) { |
206 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6( | 261 | mfc_debug(2, "Use min scratch buffer size\n"); |
207 | mb_width, | 262 | ctx->me_buffer_size = |
208 | mb_height); | 263 | ALIGN(ENC_V100_MPEG4_ME_SIZE(mb_width, |
264 | mb_height), 16); | ||
265 | } else | ||
266 | ctx->scratch_buf_size = | ||
267 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6( | ||
268 | mb_width, | ||
269 | mb_height); | ||
209 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | 270 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
210 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | 271 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
211 | ctx->bank1.size = | 272 | ctx->bank1.size = |
@@ -215,7 +276,12 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
215 | ctx->bank2.size = 0; | 276 | ctx->bank2.size = 0; |
216 | break; | 277 | break; |
217 | case S5P_MFC_CODEC_VP8_ENC: | 278 | case S5P_MFC_CODEC_VP8_ENC: |
218 | if (IS_MFCV8(dev)) | 279 | if (IS_MFCV10(dev)) { |
280 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
281 | ctx->me_buffer_size = | ||
282 | ALIGN(ENC_V100_VP8_ME_SIZE(mb_width, mb_height), | ||
283 | 16); | ||
284 | } else if (IS_MFCV8_PLUS(dev)) | ||
219 | ctx->scratch_buf_size = | 285 | ctx->scratch_buf_size = |
220 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V8( | 286 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V8( |
221 | mb_width, | 287 | mb_width, |
@@ -233,6 +299,17 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) | |||
233 | ctx->chroma_dpb_size + ctx->me_buffer_size)); | 299 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
234 | ctx->bank2.size = 0; | 300 | ctx->bank2.size = 0; |
235 | break; | 301 | break; |
302 | case S5P_MFC_CODEC_HEVC_ENC: | ||
303 | mfc_debug(2, "Use min scratch buffer size\n"); | ||
304 | ctx->me_buffer_size = | ||
305 | ALIGN(ENC_V100_HEVC_ME_SIZE(lcu_width, lcu_height), 16); | ||
306 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, 256); | ||
307 | ctx->bank1.size = | ||
308 | ctx->scratch_buf_size + ctx->tmv_buffer_size + | ||
309 | (ctx->pb_count * (ctx->luma_dpb_size + | ||
310 | ctx->chroma_dpb_size + ctx->me_buffer_size)); | ||
311 | ctx->bank2.size = 0; | ||
312 | break; | ||
236 | default: | 313 | default: |
237 | break; | 314 | break; |
238 | } | 315 | } |
@@ -267,6 +344,7 @@ static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
267 | switch (ctx->codec_mode) { | 344 | switch (ctx->codec_mode) { |
268 | case S5P_MFC_CODEC_H264_DEC: | 345 | case S5P_MFC_CODEC_H264_DEC: |
269 | case S5P_MFC_CODEC_H264_MVC_DEC: | 346 | case S5P_MFC_CODEC_H264_MVC_DEC: |
347 | case S5P_MFC_CODEC_HEVC_DEC: | ||
270 | ctx->ctx.size = buf_size->h264_dec_ctx; | 348 | ctx->ctx.size = buf_size->h264_dec_ctx; |
271 | break; | 349 | break; |
272 | case S5P_MFC_CODEC_MPEG4_DEC: | 350 | case S5P_MFC_CODEC_MPEG4_DEC: |
@@ -275,11 +353,15 @@ static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
275 | case S5P_MFC_CODEC_VC1_DEC: | 353 | case S5P_MFC_CODEC_VC1_DEC: |
276 | case S5P_MFC_CODEC_MPEG2_DEC: | 354 | case S5P_MFC_CODEC_MPEG2_DEC: |
277 | case S5P_MFC_CODEC_VP8_DEC: | 355 | case S5P_MFC_CODEC_VP8_DEC: |
356 | case S5P_MFC_CODEC_VP9_DEC: | ||
278 | ctx->ctx.size = buf_size->other_dec_ctx; | 357 | ctx->ctx.size = buf_size->other_dec_ctx; |
279 | break; | 358 | break; |
280 | case S5P_MFC_CODEC_H264_ENC: | 359 | case S5P_MFC_CODEC_H264_ENC: |
281 | ctx->ctx.size = buf_size->h264_enc_ctx; | 360 | ctx->ctx.size = buf_size->h264_enc_ctx; |
282 | break; | 361 | break; |
362 | case S5P_MFC_CODEC_HEVC_ENC: | ||
363 | ctx->ctx.size = buf_size->hevc_enc_ctx; | ||
364 | break; | ||
283 | case S5P_MFC_CODEC_MPEG4_ENC: | 365 | case S5P_MFC_CODEC_MPEG4_ENC: |
284 | case S5P_MFC_CODEC_H263_ENC: | 366 | case S5P_MFC_CODEC_H263_ENC: |
285 | case S5P_MFC_CODEC_VP8_ENC: | 367 | case S5P_MFC_CODEC_VP8_ENC: |
@@ -356,6 +438,7 @@ static int calc_plane(int width, int height) | |||
356 | 438 | ||
357 | static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) | 439 | static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) |
358 | { | 440 | { |
441 | struct s5p_mfc_dev *dev = ctx->dev; | ||
359 | ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6); | 442 | ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6); |
360 | ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6); | 443 | ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6); |
361 | mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n" | 444 | mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n" |
@@ -364,7 +447,7 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) | |||
364 | 447 | ||
365 | ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height); | 448 | ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height); |
366 | ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1)); | 449 | ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1)); |
367 | if (IS_MFCV8(ctx->dev)) { | 450 | if (IS_MFCV8_PLUS(ctx->dev)) { |
368 | /* MFCv8 needs additional 64 bytes for luma,chroma dpb*/ | 451 | /* MFCv8 needs additional 64 bytes for luma,chroma dpb*/ |
369 | ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; | 452 | ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; |
370 | ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; | 453 | ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; |
@@ -372,9 +455,17 @@ static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) | |||
372 | 455 | ||
373 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || | 456 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
374 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { | 457 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { |
375 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width, | 458 | if (IS_MFCV10(dev)) { |
459 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V10(ctx->img_width, | ||
460 | ctx->img_height); | ||
461 | } else { | ||
462 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width, | ||
463 | ctx->img_height); | ||
464 | } | ||
465 | } else if (ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) { | ||
466 | ctx->mv_size = s5p_mfc_dec_hevc_mv_size(ctx->img_width, | ||
376 | ctx->img_height); | 467 | ctx->img_height); |
377 | ctx->mv_size = ALIGN(ctx->mv_size, 16); | 468 | ctx->mv_size = ALIGN(ctx->mv_size, 32); |
378 | } else { | 469 | } else { |
379 | ctx->mv_size = 0; | 470 | ctx->mv_size = 0; |
380 | } | 471 | } |
@@ -445,7 +536,7 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
445 | writel(buf_addr1, mfc_regs->d_scratch_buffer_addr); | 536 | writel(buf_addr1, mfc_regs->d_scratch_buffer_addr); |
446 | writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size); | 537 | writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size); |
447 | 538 | ||
448 | if (IS_MFCV8(dev)) { | 539 | if (IS_MFCV8_PLUS(dev)) { |
449 | writel(ctx->img_width, | 540 | writel(ctx->img_width, |
450 | mfc_regs->d_first_plane_dpb_stride_size); | 541 | mfc_regs->d_first_plane_dpb_stride_size); |
451 | writel(ctx->img_width, | 542 | writel(ctx->img_width, |
@@ -456,7 +547,8 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
456 | buf_size1 -= ctx->scratch_buf_size; | 547 | buf_size1 -= ctx->scratch_buf_size; |
457 | 548 | ||
458 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || | 549 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || |
459 | ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){ | 550 | ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC || |
551 | ctx->codec_mode == S5P_FIMV_CODEC_HEVC_DEC) { | ||
460 | writel(ctx->mv_size, mfc_regs->d_mv_buffer_size); | 552 | writel(ctx->mv_size, mfc_regs->d_mv_buffer_size); |
461 | writel(ctx->mv_count, mfc_regs->d_num_mv); | 553 | writel(ctx->mv_count, mfc_regs->d_num_mv); |
462 | } | 554 | } |
@@ -479,7 +571,8 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
479 | mfc_regs->d_second_plane_dpb + i * 4); | 571 | mfc_regs->d_second_plane_dpb + i * 4); |
480 | } | 572 | } |
481 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || | 573 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
482 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { | 574 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC || |
575 | ctx->codec_mode == S5P_MFC_CODEC_HEVC_DEC) { | ||
483 | for (i = 0; i < ctx->mv_count; i++) { | 576 | for (i = 0; i < ctx->mv_count; i++) { |
484 | /* To test alignment */ | 577 | /* To test alignment */ |
485 | align_gap = buf_addr1; | 578 | align_gap = buf_addr1; |
@@ -494,6 +587,13 @@ static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
494 | buf_size1 -= frame_size_mv; | 587 | buf_size1 -= frame_size_mv; |
495 | } | 588 | } |
496 | } | 589 | } |
590 | if (ctx->codec_mode == S5P_FIMV_CODEC_VP9_DEC) { | ||
591 | writel(buf_addr1, mfc_regs->d_static_buffer_addr); | ||
592 | writel(DEC_VP9_STATIC_BUFFER_SIZE, | ||
593 | mfc_regs->d_static_buffer_size); | ||
594 | buf_addr1 += DEC_VP9_STATIC_BUFFER_SIZE; | ||
595 | buf_size1 -= DEC_VP9_STATIC_BUFFER_SIZE; | ||
596 | } | ||
497 | 597 | ||
498 | mfc_debug(2, "Buf1: %zx, buf_size1: %d (frames %d)\n", | 598 | mfc_debug(2, "Buf1: %zx, buf_size1: %d (frames %d)\n", |
499 | buf_addr1, buf_size1, ctx->total_dpb_count); | 599 | buf_addr1, buf_size1, ctx->total_dpb_count); |
@@ -571,15 +671,34 @@ static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) | |||
571 | 671 | ||
572 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); | 672 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); |
573 | 673 | ||
574 | for (i = 0; i < ctx->pb_count; i++) { | 674 | if (IS_MFCV10(dev)) { |
575 | writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i)); | 675 | /* start address of per buffer is aligned */ |
576 | buf_addr1 += ctx->luma_dpb_size; | 676 | for (i = 0; i < ctx->pb_count; i++) { |
577 | writel(buf_addr1, mfc_regs->e_chroma_dpb + (4 * i)); | 677 | writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i)); |
578 | buf_addr1 += ctx->chroma_dpb_size; | 678 | buf_addr1 += ctx->luma_dpb_size; |
579 | writel(buf_addr1, mfc_regs->e_me_buffer + (4 * i)); | 679 | buf_size1 -= ctx->luma_dpb_size; |
580 | buf_addr1 += ctx->me_buffer_size; | 680 | } |
581 | buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size + | 681 | for (i = 0; i < ctx->pb_count; i++) { |
582 | ctx->me_buffer_size); | 682 | writel(buf_addr1, mfc_regs->e_chroma_dpb + (4 * i)); |
683 | buf_addr1 += ctx->chroma_dpb_size; | ||
684 | buf_size1 -= ctx->chroma_dpb_size; | ||
685 | } | ||
686 | for (i = 0; i < ctx->pb_count; i++) { | ||
687 | writel(buf_addr1, mfc_regs->e_me_buffer + (4 * i)); | ||
688 | buf_addr1 += ctx->me_buffer_size; | ||
689 | buf_size1 -= ctx->me_buffer_size; | ||
690 | } | ||
691 | } else { | ||
692 | for (i = 0; i < ctx->pb_count; i++) { | ||
693 | writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i)); | ||
694 | buf_addr1 += ctx->luma_dpb_size; | ||
695 | writel(buf_addr1, mfc_regs->e_chroma_dpb + (4 * i)); | ||
696 | buf_addr1 += ctx->chroma_dpb_size; | ||
697 | writel(buf_addr1, mfc_regs->e_me_buffer + (4 * i)); | ||
698 | buf_addr1 += ctx->me_buffer_size; | ||
699 | buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size | ||
700 | + ctx->me_buffer_size); | ||
701 | } | ||
583 | } | 702 | } |
584 | 703 | ||
585 | writel(buf_addr1, mfc_regs->e_scratch_buffer_addr); | 704 | writel(buf_addr1, mfc_regs->e_scratch_buffer_addr); |
@@ -1321,6 +1440,162 @@ static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) | |||
1321 | return 0; | 1440 | return 0; |
1322 | } | 1441 | } |
1323 | 1442 | ||
1443 | static int s5p_mfc_set_enc_params_hevc(struct s5p_mfc_ctx *ctx) | ||
1444 | { | ||
1445 | struct s5p_mfc_dev *dev = ctx->dev; | ||
1446 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; | ||
1447 | struct s5p_mfc_enc_params *p = &ctx->enc_params; | ||
1448 | struct s5p_mfc_hevc_enc_params *p_hevc = &p->codec.hevc; | ||
1449 | unsigned int reg = 0; | ||
1450 | int i; | ||
1451 | |||
1452 | mfc_debug_enter(); | ||
1453 | |||
1454 | s5p_mfc_set_enc_params(ctx); | ||
1455 | |||
1456 | /* pictype : number of B */ | ||
1457 | reg = readl(mfc_regs->e_gop_config); | ||
1458 | /* num_b_frame - 0 ~ 2 */ | ||
1459 | reg &= ~(0x3 << 16); | ||
1460 | reg |= (p->num_b_frame << 16); | ||
1461 | writel(reg, mfc_regs->e_gop_config); | ||
1462 | |||
1463 | /* UHD encoding case */ | ||
1464 | if ((ctx->img_width == 3840) && (ctx->img_height == 2160)) { | ||
1465 | p_hevc->level = 51; | ||
1466 | p_hevc->tier = 0; | ||
1467 | /* this tier can be changed */ | ||
1468 | } | ||
1469 | |||
1470 | /* tier & level */ | ||
1471 | reg = 0; | ||
1472 | /* profile */ | ||
1473 | reg |= p_hevc->profile & 0x3; | ||
1474 | /* level */ | ||
1475 | reg &= ~(0xFF << 8); | ||
1476 | reg |= (p_hevc->level << 8); | ||
1477 | /* tier - 0 ~ 1 */ | ||
1478 | reg |= (p_hevc->tier << 16); | ||
1479 | writel(reg, mfc_regs->e_picture_profile); | ||
1480 | |||
1481 | switch (p_hevc->loopfilter) { | ||
1482 | case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED: | ||
1483 | p_hevc->loopfilter_disable = 1; | ||
1484 | break; | ||
1485 | case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED: | ||
1486 | p_hevc->loopfilter_disable = 0; | ||
1487 | p_hevc->loopfilter_across = 1; | ||
1488 | break; | ||
1489 | case V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: | ||
1490 | p_hevc->loopfilter_disable = 0; | ||
1491 | p_hevc->loopfilter_across = 0; | ||
1492 | break; | ||
1493 | } | ||
1494 | |||
1495 | /* max partition depth */ | ||
1496 | reg = 0; | ||
1497 | reg |= (p_hevc->max_partition_depth & 0x1); | ||
1498 | reg |= (p_hevc->num_refs_for_p-1) << 2; | ||
1499 | reg |= (p_hevc->refreshtype & 0x3) << 3; | ||
1500 | reg |= (p_hevc->const_intra_period_enable & 0x1) << 5; | ||
1501 | reg |= (p_hevc->lossless_cu_enable & 0x1) << 6; | ||
1502 | reg |= (p_hevc->wavefront_enable & 0x1) << 7; | ||
1503 | reg |= (p_hevc->loopfilter_disable & 0x1) << 8; | ||
1504 | reg |= (p_hevc->loopfilter_across & 0x1) << 9; | ||
1505 | reg |= (p_hevc->enable_ltr & 0x1) << 10; | ||
1506 | reg |= (p_hevc->hier_qp_enable & 0x1) << 11; | ||
1507 | reg |= (p_hevc->general_pb_enable & 0x1) << 13; | ||
1508 | reg |= (p_hevc->temporal_id_enable & 0x1) << 14; | ||
1509 | reg |= (p_hevc->strong_intra_smooth & 0x1) << 15; | ||
1510 | reg |= (p_hevc->intra_pu_split_disable & 0x1) << 16; | ||
1511 | reg |= (p_hevc->tmv_prediction_disable & 0x1) << 17; | ||
1512 | reg |= (p_hevc->max_num_merge_mv & 0x7) << 18; | ||
1513 | reg |= (p_hevc->encoding_nostartcode_enable & 0x1) << 23; | ||
1514 | reg |= (p_hevc->prepend_sps_pps_to_idr << 26); | ||
1515 | |||
1516 | writel(reg, mfc_regs->e_hevc_options); | ||
1517 | /* refresh period */ | ||
1518 | if (p_hevc->refreshtype) { | ||
1519 | reg = 0; | ||
1520 | reg |= (p_hevc->refreshperiod & 0xFFFF); | ||
1521 | writel(reg, mfc_regs->e_hevc_refresh_period); | ||
1522 | } | ||
1523 | /* loop filter setting */ | ||
1524 | if (!(p_hevc->loopfilter_disable & 0x1)) { | ||
1525 | reg = 0; | ||
1526 | reg |= (p_hevc->lf_beta_offset_div2); | ||
1527 | writel(reg, mfc_regs->e_hevc_lf_beta_offset_div2); | ||
1528 | reg = 0; | ||
1529 | reg |= (p_hevc->lf_tc_offset_div2); | ||
1530 | writel(reg, mfc_regs->e_hevc_lf_tc_offset_div2); | ||
1531 | } | ||
1532 | /* hier qp enable */ | ||
1533 | if (p_hevc->num_hier_layer) { | ||
1534 | reg = 0; | ||
1535 | reg |= (p_hevc->hier_qp_type & 0x1) << 0x3; | ||
1536 | reg |= p_hevc->num_hier_layer & 0x7; | ||
1537 | writel(reg, mfc_regs->e_num_t_layer); | ||
1538 | /* QP value for each layer */ | ||
1539 | if (p_hevc->hier_qp_enable) { | ||
1540 | for (i = 0; i < 7; i++) | ||
1541 | writel(p_hevc->hier_qp_layer[i], | ||
1542 | mfc_regs->e_hier_qp_layer0 + i * 4); | ||
1543 | } | ||
1544 | if (p->rc_frame) { | ||
1545 | for (i = 0; i < 7; i++) | ||
1546 | writel(p_hevc->hier_bit_layer[i], | ||
1547 | mfc_regs->e_hier_bit_rate_layer0 | ||
1548 | + i * 4); | ||
1549 | } | ||
1550 | } | ||
1551 | |||
1552 | /* rate control config. */ | ||
1553 | reg = readl(mfc_regs->e_rc_config); | ||
1554 | /* macroblock level rate control */ | ||
1555 | reg &= ~(0x1 << 8); | ||
1556 | reg |= (p->rc_mb << 8); | ||
1557 | writel(reg, mfc_regs->e_rc_config); | ||
1558 | /* frame QP */ | ||
1559 | reg &= ~(0xFF); | ||
1560 | reg |= p_hevc->rc_frame_qp; | ||
1561 | writel(reg, mfc_regs->e_rc_config); | ||
1562 | |||
1563 | /* frame rate */ | ||
1564 | if (p->rc_frame) { | ||
1565 | reg = 0; | ||
1566 | reg &= ~(0xFFFF << 16); | ||
1567 | reg |= ((p_hevc->rc_framerate) << 16); | ||
1568 | reg &= ~(0xFFFF); | ||
1569 | reg |= FRAME_DELTA_DEFAULT; | ||
1570 | writel(reg, mfc_regs->e_rc_frame_rate); | ||
1571 | } | ||
1572 | |||
1573 | /* max & min value of QP */ | ||
1574 | reg = 0; | ||
1575 | /* max QP */ | ||
1576 | reg &= ~(0xFF << 8); | ||
1577 | reg |= (p_hevc->rc_max_qp << 8); | ||
1578 | /* min QP */ | ||
1579 | reg &= ~(0xFF); | ||
1580 | reg |= p_hevc->rc_min_qp; | ||
1581 | writel(reg, mfc_regs->e_rc_qp_bound); | ||
1582 | |||
1583 | writel(0x0, mfc_regs->e_fixed_picture_qp); | ||
1584 | if (!p->rc_frame && !p->rc_mb) { | ||
1585 | reg = 0; | ||
1586 | reg &= ~(0xFF << 16); | ||
1587 | reg |= (p_hevc->rc_b_frame_qp << 16); | ||
1588 | reg &= ~(0xFF << 8); | ||
1589 | reg |= (p_hevc->rc_p_frame_qp << 8); | ||
1590 | reg &= ~(0xFF); | ||
1591 | reg |= p_hevc->rc_frame_qp; | ||
1592 | writel(reg, mfc_regs->e_fixed_picture_qp); | ||
1593 | } | ||
1594 | mfc_debug_leave(); | ||
1595 | |||
1596 | return 0; | ||
1597 | } | ||
1598 | |||
1324 | /* Initialize decoding */ | 1599 | /* Initialize decoding */ |
1325 | static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) | 1600 | static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) |
1326 | { | 1601 | { |
@@ -1440,6 +1715,8 @@ static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) | |||
1440 | s5p_mfc_set_enc_params_h263(ctx); | 1715 | s5p_mfc_set_enc_params_h263(ctx); |
1441 | else if (ctx->codec_mode == S5P_MFC_CODEC_VP8_ENC) | 1716 | else if (ctx->codec_mode == S5P_MFC_CODEC_VP8_ENC) |
1442 | s5p_mfc_set_enc_params_vp8(ctx); | 1717 | s5p_mfc_set_enc_params_vp8(ctx); |
1718 | else if (ctx->codec_mode == S5P_FIMV_CODEC_HEVC_ENC) | ||
1719 | s5p_mfc_set_enc_params_hevc(ctx); | ||
1443 | else { | 1720 | else { |
1444 | mfc_err("Unknown codec for encoding (%x).\n", | 1721 | mfc_err("Unknown codec for encoding (%x).\n", |
1445 | ctx->codec_mode); | 1722 | ctx->codec_mode); |
@@ -1895,6 +2172,16 @@ static int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) | |||
1895 | return readl(dev->mfc_regs->d_min_num_mv); | 2172 | return readl(dev->mfc_regs->d_min_num_mv); |
1896 | } | 2173 | } |
1897 | 2174 | ||
2175 | static int s5p_mfc_get_min_scratch_buf_size(struct s5p_mfc_dev *dev) | ||
2176 | { | ||
2177 | return readl(dev->mfc_regs->d_min_scratch_buffer_size); | ||
2178 | } | ||
2179 | |||
2180 | static int s5p_mfc_get_e_min_scratch_buf_size(struct s5p_mfc_dev *dev) | ||
2181 | { | ||
2182 | return readl(dev->mfc_regs->e_min_scratch_buffer_size); | ||
2183 | } | ||
2184 | |||
1898 | static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) | 2185 | static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) |
1899 | { | 2186 | { |
1900 | return readl(dev->mfc_regs->ret_instance_id); | 2187 | return readl(dev->mfc_regs->ret_instance_id); |
@@ -2109,7 +2396,7 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) | |||
2109 | S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7); | 2396 | S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7); |
2110 | R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7); | 2397 | R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7); |
2111 | 2398 | ||
2112 | if (!IS_MFCV8(dev)) | 2399 | if (!IS_MFCV8_PLUS(dev)) |
2113 | goto done; | 2400 | goto done; |
2114 | 2401 | ||
2115 | /* Initialize registers used in MFC v8 only. | 2402 | /* Initialize registers used in MFC v8 only. |
@@ -2153,6 +2440,7 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) | |||
2153 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V8); | 2440 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V8); |
2154 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V8); | 2441 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V8); |
2155 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V8); | 2442 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V8); |
2443 | R(d_min_scratch_buffer_size, S5P_FIMV_D_MIN_SCRATCH_BUFFER_SIZE_V8); | ||
2156 | 2444 | ||
2157 | /* encoder registers */ | 2445 | /* encoder registers */ |
2158 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V8); | 2446 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V8); |
@@ -2168,6 +2456,29 @@ const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) | |||
2168 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V8); | 2456 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V8); |
2169 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V8); | 2457 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V8); |
2170 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8); | 2458 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8); |
2459 | R(e_min_scratch_buffer_size, S5P_FIMV_E_MIN_SCRATCH_BUFFER_SIZE_V8); | ||
2460 | |||
2461 | if (!IS_MFCV10(dev)) | ||
2462 | goto done; | ||
2463 | |||
2464 | /* Initialize registers used in MFC v10 only. | ||
2465 | * Also, over-write the registers which have | ||
2466 | * a different offset for MFC v10. | ||
2467 | */ | ||
2468 | |||
2469 | /* decoder registers */ | ||
2470 | R(d_static_buffer_addr, S5P_FIMV_D_STATIC_BUFFER_ADDR_V10); | ||
2471 | R(d_static_buffer_size, S5P_FIMV_D_STATIC_BUFFER_SIZE_V10); | ||
2472 | |||
2473 | /* encoder registers */ | ||
2474 | R(e_num_t_layer, S5P_FIMV_E_NUM_T_LAYER_V10); | ||
2475 | R(e_hier_qp_layer0, S5P_FIMV_E_HIERARCHICAL_QP_LAYER0_V10); | ||
2476 | R(e_hier_bit_rate_layer0, S5P_FIMV_E_HIERARCHICAL_BIT_RATE_LAYER0_V10); | ||
2477 | R(e_hevc_options, S5P_FIMV_E_HEVC_OPTIONS_V10); | ||
2478 | R(e_hevc_refresh_period, S5P_FIMV_E_HEVC_REFRESH_PERIOD_V10); | ||
2479 | R(e_hevc_lf_beta_offset_div2, S5P_FIMV_E_HEVC_LF_BETA_OFFSET_DIV2_V10); | ||
2480 | R(e_hevc_lf_tc_offset_div2, S5P_FIMV_E_HEVC_LF_TC_OFFSET_DIV2_V10); | ||
2481 | R(e_hevc_nal_control, S5P_FIMV_E_HEVC_NAL_CONTROL_V10); | ||
2171 | 2482 | ||
2172 | done: | 2483 | done: |
2173 | return &mfc_regs; | 2484 | return &mfc_regs; |
@@ -2216,6 +2527,8 @@ static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = { | |||
2216 | .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v6, | 2527 | .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v6, |
2217 | .get_crop_info_h = s5p_mfc_get_crop_info_h_v6, | 2528 | .get_crop_info_h = s5p_mfc_get_crop_info_h_v6, |
2218 | .get_crop_info_v = s5p_mfc_get_crop_info_v_v6, | 2529 | .get_crop_info_v = s5p_mfc_get_crop_info_v_v6, |
2530 | .get_min_scratch_buf_size = s5p_mfc_get_min_scratch_buf_size, | ||
2531 | .get_e_min_scratch_buf_size = s5p_mfc_get_e_min_scratch_buf_size, | ||
2219 | }; | 2532 | }; |
2220 | 2533 | ||
2221 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void) | 2534 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void) |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h index 80558484bb40..f013b291ae5b 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.h | |||
@@ -24,6 +24,13 @@ | |||
24 | #define MB_HEIGHT(y_size) DIV_ROUND_UP(y_size, 16) | 24 | #define MB_HEIGHT(y_size) DIV_ROUND_UP(y_size, 16) |
25 | #define S5P_MFC_DEC_MV_SIZE_V6(x, y) (MB_WIDTH(x) * \ | 25 | #define S5P_MFC_DEC_MV_SIZE_V6(x, y) (MB_WIDTH(x) * \ |
26 | (((MB_HEIGHT(y)+1)/2)*2) * 64 + 128) | 26 | (((MB_HEIGHT(y)+1)/2)*2) * 64 + 128) |
27 | #define S5P_MFC_DEC_MV_SIZE_V10(x, y) (MB_WIDTH(x) * \ | ||
28 | (((MB_HEIGHT(y)+1)/2)*2) * 64 + 512) | ||
29 | #define S5P_MFC_LCU_WIDTH(x_size) DIV_ROUND_UP(x_size, 32) | ||
30 | #define S5P_MFC_LCU_HEIGHT(y_size) DIV_ROUND_UP(y_size, 32) | ||
31 | |||
32 | #define s5p_mfc_dec_hevc_mv_size(x, y) \ | ||
33 | (DIV_ROUND_UP(x, 64) * DIV_ROUND_UP(y, 64) * 256 + 512) | ||
27 | 34 | ||
28 | /* Definition */ | 35 | /* Definition */ |
29 | #define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1) | 36 | #define ENC_MULTI_SLICE_MB_MAX ((1 << 30) - 1) |
@@ -39,6 +46,14 @@ | |||
39 | #define ENC_MPEG4_VOP_TIME_RES_MAX ((1 << 16) - 1) | 46 | #define ENC_MPEG4_VOP_TIME_RES_MAX ((1 << 16) - 1) |
40 | #define FRAME_DELTA_H264_H263 1 | 47 | #define FRAME_DELTA_H264_H263 1 |
41 | #define TIGHT_CBR_MAX 10 | 48 | #define TIGHT_CBR_MAX 10 |
49 | #define ENC_HEVC_RC_FRAME_RATE_MAX ((1 << 16) - 1) | ||
50 | #define ENC_HEVC_QP_INDEX_MIN -12 | ||
51 | #define ENC_HEVC_QP_INDEX_MAX 12 | ||
52 | #define ENC_HEVC_LOOP_FILTER_MIN -12 | ||
53 | #define ENC_HEVC_LOOP_FILTER_MAX 12 | ||
54 | #define ENC_HEVC_LEVEL_MAX 62 | ||
55 | |||
56 | #define FRAME_DELTA_DEFAULT 1 | ||
42 | 57 | ||
43 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void); | 58 | 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); | 59 | const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev); |
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index 976ea0bb5b6c..1a0cde017fdf 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c | |||
@@ -520,8 +520,8 @@ static void sh_veu_colour_offset(struct sh_veu_dev *veu, struct sh_veu_vfmt *vfm | |||
520 | /* dst_left and dst_top validity will be verified in CROP / COMPOSE */ | 520 | /* dst_left and dst_top validity will be verified in CROP / COMPOSE */ |
521 | unsigned int left = vfmt->frame.left & ~0x03; | 521 | unsigned int left = vfmt->frame.left & ~0x03; |
522 | unsigned int top = vfmt->frame.top; | 522 | unsigned int top = vfmt->frame.top; |
523 | dma_addr_t offset = ((left * veu->vfmt_out.fmt->depth) >> 3) + | 523 | dma_addr_t offset = (dma_addr_t)top * veu->vfmt_out.bytesperline + |
524 | top * veu->vfmt_out.bytesperline; | 524 | (((dma_addr_t)left * veu->vfmt_out.fmt->depth) >> 3); |
525 | unsigned int y_line; | 525 | unsigned int y_line; |
526 | 526 | ||
527 | vfmt->offset_y = offset; | 527 | vfmt->offset_y = offset; |
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index c86dd2fdab84..69f0d8e80bd8 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c | |||
@@ -787,7 +787,7 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) | |||
787 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 787 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
788 | int err; | 788 | int err; |
789 | 789 | ||
790 | dev_dbg(icd->pdev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); | 790 | dev_dbg(icd->pdev, "mmap called, vma=%p\n", vma); |
791 | 791 | ||
792 | if (icd->streamer != file) | 792 | if (icd->streamer != file) |
793 | return -EBUSY; | 793 | return -EBUSY; |
@@ -1788,17 +1788,19 @@ static int default_s_selection(struct soc_camera_device *icd, | |||
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | static int default_g_parm(struct soc_camera_device *icd, | 1790 | static int default_g_parm(struct soc_camera_device *icd, |
1791 | struct v4l2_streamparm *parm) | 1791 | struct v4l2_streamparm *a) |
1792 | { | 1792 | { |
1793 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1793 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1794 | return v4l2_subdev_call(sd, video, g_parm, parm); | 1794 | |
1795 | return v4l2_g_parm_cap(icd->vdev, sd, a); | ||
1795 | } | 1796 | } |
1796 | 1797 | ||
1797 | static int default_s_parm(struct soc_camera_device *icd, | 1798 | static int default_s_parm(struct soc_camera_device *icd, |
1798 | struct v4l2_streamparm *parm) | 1799 | struct v4l2_streamparm *a) |
1799 | { | 1800 | { |
1800 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | 1801 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
1801 | return v4l2_subdev_call(sd, video, s_parm, parm); | 1802 | |
1803 | return v4l2_s_parm_cap(icd->vdev, sd, a); | ||
1802 | } | 1804 | } |
1803 | 1805 | ||
1804 | static int default_enum_framesizes(struct soc_camera_device *icd, | 1806 | static int default_enum_framesizes(struct soc_camera_device *icd, |
diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c index 0e5aa17bdd40..7c496bc1cf38 100644 --- a/drivers/media/platform/stm32/stm32-cec.c +++ b/drivers/media/platform/stm32/stm32-cec.c | |||
@@ -1,11 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * STM32 CEC driver | 3 | * STM32 CEC driver |
3 | * Copyright (C) STMicroelectronics SA 2017 | 4 | * Copyright (C) STMicroelectronics SA 2017 |
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | 6 | */ |
10 | 7 | ||
11 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 9460b3080dca..2e1933d872ee 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Driver for STM32 Digital Camera Memory Interface | 3 | * Driver for STM32 Digital Camera Memory Interface |
3 | * | 4 | * |
@@ -5,7 +6,6 @@ | |||
5 | * Authors: Yannick Fertre <yannick.fertre@st.com> | 6 | * Authors: Yannick Fertre <yannick.fertre@st.com> |
6 | * Hugues Fruchet <hugues.fruchet@st.com> | 7 | * Hugues Fruchet <hugues.fruchet@st.com> |
7 | * for STMicroelectronics. | 8 | * for STMicroelectronics. |
8 | * License terms: GNU General Public License (GPL), version 2 | ||
9 | * | 9 | * |
10 | * This driver is based on atmel_isi.c | 10 | * This driver is based on atmel_isi.c |
11 | * | 11 | * |
@@ -93,6 +93,11 @@ enum state { | |||
93 | #define MIN_HEIGHT 16U | 93 | #define MIN_HEIGHT 16U |
94 | #define MAX_HEIGHT 2048U | 94 | #define MAX_HEIGHT 2048U |
95 | 95 | ||
96 | #define MIN_JPEG_WIDTH 16U | ||
97 | #define MAX_JPEG_WIDTH 2592U | ||
98 | #define MIN_JPEG_HEIGHT 16U | ||
99 | #define MAX_JPEG_HEIGHT 2592U | ||
100 | |||
96 | #define TIMEOUT_MS 1000 | 101 | #define TIMEOUT_MS 1000 |
97 | 102 | ||
98 | struct dcmi_graph_entity { | 103 | struct dcmi_graph_entity { |
@@ -160,6 +165,7 @@ struct stm32_dcmi { | |||
160 | dma_cookie_t dma_cookie; | 165 | dma_cookie_t dma_cookie; |
161 | u32 misr; | 166 | u32 misr; |
162 | int errors_count; | 167 | int errors_count; |
168 | int overrun_count; | ||
163 | int buffers_count; | 169 | int buffers_count; |
164 | }; | 170 | }; |
165 | 171 | ||
@@ -190,14 +196,67 @@ static inline void reg_clear(void __iomem *base, u32 reg, u32 mask) | |||
190 | 196 | ||
191 | static int dcmi_start_capture(struct stm32_dcmi *dcmi); | 197 | static int dcmi_start_capture(struct stm32_dcmi *dcmi); |
192 | 198 | ||
199 | static void dcmi_buffer_done(struct stm32_dcmi *dcmi, | ||
200 | struct dcmi_buf *buf, | ||
201 | size_t bytesused, | ||
202 | int err) | ||
203 | { | ||
204 | struct vb2_v4l2_buffer *vbuf; | ||
205 | |||
206 | if (!buf) | ||
207 | return; | ||
208 | |||
209 | vbuf = &buf->vb; | ||
210 | |||
211 | vbuf->sequence = dcmi->sequence++; | ||
212 | vbuf->field = V4L2_FIELD_NONE; | ||
213 | vbuf->vb2_buf.timestamp = ktime_get_ns(); | ||
214 | vb2_set_plane_payload(&vbuf->vb2_buf, 0, bytesused); | ||
215 | vb2_buffer_done(&vbuf->vb2_buf, | ||
216 | err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); | ||
217 | dev_dbg(dcmi->dev, "buffer[%d] done seq=%d, bytesused=%zu\n", | ||
218 | vbuf->vb2_buf.index, vbuf->sequence, bytesused); | ||
219 | |||
220 | dcmi->buffers_count++; | ||
221 | dcmi->active = NULL; | ||
222 | } | ||
223 | |||
224 | static int dcmi_restart_capture(struct stm32_dcmi *dcmi) | ||
225 | { | ||
226 | spin_lock_irq(&dcmi->irqlock); | ||
227 | |||
228 | if (dcmi->state != RUNNING) { | ||
229 | spin_unlock_irq(&dcmi->irqlock); | ||
230 | return -EINVAL; | ||
231 | } | ||
232 | |||
233 | /* Restart a new DMA transfer with next buffer */ | ||
234 | if (list_empty(&dcmi->buffers)) { | ||
235 | dev_err(dcmi->dev, "%s: No more buffer queued, cannot capture buffer\n", | ||
236 | __func__); | ||
237 | dcmi->errors_count++; | ||
238 | dcmi->active = NULL; | ||
239 | |||
240 | spin_unlock_irq(&dcmi->irqlock); | ||
241 | return -EINVAL; | ||
242 | } | ||
243 | |||
244 | dcmi->active = list_entry(dcmi->buffers.next, | ||
245 | struct dcmi_buf, list); | ||
246 | list_del_init(&dcmi->active->list); | ||
247 | |||
248 | spin_unlock_irq(&dcmi->irqlock); | ||
249 | |||
250 | return dcmi_start_capture(dcmi); | ||
251 | } | ||
252 | |||
193 | static void dcmi_dma_callback(void *param) | 253 | static void dcmi_dma_callback(void *param) |
194 | { | 254 | { |
195 | struct stm32_dcmi *dcmi = (struct stm32_dcmi *)param; | 255 | struct stm32_dcmi *dcmi = (struct stm32_dcmi *)param; |
196 | struct dma_chan *chan = dcmi->dma_chan; | 256 | struct dma_chan *chan = dcmi->dma_chan; |
197 | struct dma_tx_state state; | 257 | struct dma_tx_state state; |
198 | enum dma_status status; | 258 | enum dma_status status; |
199 | 259 | struct dcmi_buf *buf = dcmi->active; | |
200 | spin_lock(&dcmi->irqlock); | ||
201 | 260 | ||
202 | /* Check DMA status */ | 261 | /* Check DMA status */ |
203 | status = dmaengine_tx_status(chan, dcmi->dma_cookie, &state); | 262 | status = dmaengine_tx_status(chan, dcmi->dma_cookie, &state); |
@@ -215,58 +274,18 @@ static void dcmi_dma_callback(void *param) | |||
215 | case DMA_COMPLETE: | 274 | case DMA_COMPLETE: |
216 | dev_dbg(dcmi->dev, "%s: Received DMA_COMPLETE\n", __func__); | 275 | dev_dbg(dcmi->dev, "%s: Received DMA_COMPLETE\n", __func__); |
217 | 276 | ||
218 | if (dcmi->active) { | 277 | /* Return buffer to V4L2 */ |
219 | struct dcmi_buf *buf = dcmi->active; | 278 | dcmi_buffer_done(dcmi, buf, buf->size, 0); |
220 | struct vb2_v4l2_buffer *vbuf = &dcmi->active->vb; | ||
221 | |||
222 | vbuf->sequence = dcmi->sequence++; | ||
223 | vbuf->field = V4L2_FIELD_NONE; | ||
224 | vbuf->vb2_buf.timestamp = ktime_get_ns(); | ||
225 | vb2_set_plane_payload(&vbuf->vb2_buf, 0, buf->size); | ||
226 | vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); | ||
227 | dev_dbg(dcmi->dev, "buffer[%d] done seq=%d\n", | ||
228 | vbuf->vb2_buf.index, vbuf->sequence); | ||
229 | |||
230 | dcmi->buffers_count++; | ||
231 | dcmi->active = NULL; | ||
232 | } | ||
233 | |||
234 | /* Restart a new DMA transfer with next buffer */ | ||
235 | if (dcmi->state == RUNNING) { | ||
236 | if (list_empty(&dcmi->buffers)) { | ||
237 | dev_err(dcmi->dev, "%s: No more buffer queued, cannot capture buffer", | ||
238 | __func__); | ||
239 | dcmi->errors_count++; | ||
240 | dcmi->active = NULL; | ||
241 | |||
242 | spin_unlock(&dcmi->irqlock); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | dcmi->active = list_entry(dcmi->buffers.next, | ||
247 | struct dcmi_buf, list); | ||
248 | |||
249 | list_del_init(&dcmi->active->list); | ||
250 | |||
251 | if (dcmi_start_capture(dcmi)) { | ||
252 | dev_err(dcmi->dev, "%s: Cannot restart capture on DMA complete", | ||
253 | __func__); | ||
254 | |||
255 | spin_unlock(&dcmi->irqlock); | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | /* Enable capture */ | ||
260 | reg_set(dcmi->regs, DCMI_CR, CR_CAPTURE); | ||
261 | } | ||
262 | 279 | ||
280 | /* Restart capture */ | ||
281 | if (dcmi_restart_capture(dcmi)) | ||
282 | dev_err(dcmi->dev, "%s: Cannot restart capture on DMA complete\n", | ||
283 | __func__); | ||
263 | break; | 284 | break; |
264 | default: | 285 | default: |
265 | dev_err(dcmi->dev, "%s: Received unknown status\n", __func__); | 286 | dev_err(dcmi->dev, "%s: Received unknown status\n", __func__); |
266 | break; | 287 | break; |
267 | } | 288 | } |
268 | |||
269 | spin_unlock(&dcmi->irqlock); | ||
270 | } | 289 | } |
271 | 290 | ||
272 | static int dcmi_start_dma(struct stm32_dcmi *dcmi, | 291 | static int dcmi_start_dma(struct stm32_dcmi *dcmi, |
@@ -359,11 +378,57 @@ static void dcmi_set_crop(struct stm32_dcmi *dcmi) | |||
359 | reg_set(dcmi->regs, DCMI_CR, CR_CROP); | 378 | reg_set(dcmi->regs, DCMI_CR, CR_CROP); |
360 | } | 379 | } |
361 | 380 | ||
381 | static void dcmi_process_jpeg(struct stm32_dcmi *dcmi) | ||
382 | { | ||
383 | struct dma_tx_state state; | ||
384 | enum dma_status status; | ||
385 | struct dma_chan *chan = dcmi->dma_chan; | ||
386 | struct dcmi_buf *buf = dcmi->active; | ||
387 | |||
388 | if (!buf) | ||
389 | return; | ||
390 | |||
391 | /* | ||
392 | * Because of variable JPEG buffer size sent by sensor, | ||
393 | * DMA transfer never completes due to transfer size | ||
394 | * never reached. | ||
395 | * In order to ensure that all the JPEG data are transferred | ||
396 | * in active buffer memory, DMA is drained. | ||
397 | * Then DMA tx status gives the amount of data transferred | ||
398 | * to memory, which is then returned to V4L2 through the active | ||
399 | * buffer payload. | ||
400 | */ | ||
401 | |||
402 | /* Drain DMA */ | ||
403 | dmaengine_synchronize(chan); | ||
404 | |||
405 | /* Get DMA residue to get JPEG size */ | ||
406 | status = dmaengine_tx_status(chan, dcmi->dma_cookie, &state); | ||
407 | if (status != DMA_ERROR && state.residue < buf->size) { | ||
408 | /* Return JPEG buffer to V4L2 with received JPEG buffer size */ | ||
409 | dcmi_buffer_done(dcmi, buf, buf->size - state.residue, 0); | ||
410 | } else { | ||
411 | dcmi->errors_count++; | ||
412 | dev_err(dcmi->dev, "%s: Cannot get JPEG size from DMA\n", | ||
413 | __func__); | ||
414 | /* Return JPEG buffer to V4L2 in ERROR state */ | ||
415 | dcmi_buffer_done(dcmi, buf, 0, -EIO); | ||
416 | } | ||
417 | |||
418 | /* Abort DMA operation */ | ||
419 | dmaengine_terminate_all(dcmi->dma_chan); | ||
420 | |||
421 | /* Restart capture */ | ||
422 | if (dcmi_restart_capture(dcmi)) | ||
423 | dev_err(dcmi->dev, "%s: Cannot restart capture on JPEG received\n", | ||
424 | __func__); | ||
425 | } | ||
426 | |||
362 | static irqreturn_t dcmi_irq_thread(int irq, void *arg) | 427 | static irqreturn_t dcmi_irq_thread(int irq, void *arg) |
363 | { | 428 | { |
364 | struct stm32_dcmi *dcmi = arg; | 429 | struct stm32_dcmi *dcmi = arg; |
365 | 430 | ||
366 | spin_lock(&dcmi->irqlock); | 431 | spin_lock_irq(&dcmi->irqlock); |
367 | 432 | ||
368 | /* Stop capture is required */ | 433 | /* Stop capture is required */ |
369 | if (dcmi->state == STOPPING) { | 434 | if (dcmi->state == STOPPING) { |
@@ -373,50 +438,41 @@ static irqreturn_t dcmi_irq_thread(int irq, void *arg) | |||
373 | 438 | ||
374 | complete(&dcmi->complete); | 439 | complete(&dcmi->complete); |
375 | 440 | ||
376 | spin_unlock(&dcmi->irqlock); | 441 | spin_unlock_irq(&dcmi->irqlock); |
377 | return IRQ_HANDLED; | 442 | return IRQ_HANDLED; |
378 | } | 443 | } |
379 | 444 | ||
380 | if ((dcmi->misr & IT_OVR) || (dcmi->misr & IT_ERR)) { | 445 | if ((dcmi->misr & IT_OVR) || (dcmi->misr & IT_ERR)) { |
381 | /* | ||
382 | * An overflow or an error has been detected, | ||
383 | * stop current DMA transfert & restart it | ||
384 | */ | ||
385 | dev_warn(dcmi->dev, "%s: Overflow or error detected\n", | ||
386 | __func__); | ||
387 | |||
388 | dcmi->errors_count++; | 446 | dcmi->errors_count++; |
389 | dmaengine_terminate_all(dcmi->dma_chan); | 447 | if (dcmi->misr & IT_OVR) |
390 | 448 | dcmi->overrun_count++; | |
391 | reg_set(dcmi->regs, DCMI_ICR, IT_FRAME | IT_OVR | IT_ERR); | 449 | } |
392 | |||
393 | dev_dbg(dcmi->dev, "Restarting capture after DCMI error\n"); | ||
394 | |||
395 | if (dcmi_start_capture(dcmi)) { | ||
396 | dev_err(dcmi->dev, "%s: Cannot restart capture on overflow or error\n", | ||
397 | __func__); | ||
398 | 450 | ||
399 | spin_unlock(&dcmi->irqlock); | 451 | if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG && |
400 | return IRQ_HANDLED; | 452 | dcmi->misr & IT_FRAME) { |
401 | } | 453 | /* JPEG received */ |
454 | spin_unlock_irq(&dcmi->irqlock); | ||
455 | dcmi_process_jpeg(dcmi); | ||
456 | return IRQ_HANDLED; | ||
402 | } | 457 | } |
403 | 458 | ||
404 | spin_unlock(&dcmi->irqlock); | 459 | spin_unlock_irq(&dcmi->irqlock); |
405 | return IRQ_HANDLED; | 460 | return IRQ_HANDLED; |
406 | } | 461 | } |
407 | 462 | ||
408 | static irqreturn_t dcmi_irq_callback(int irq, void *arg) | 463 | static irqreturn_t dcmi_irq_callback(int irq, void *arg) |
409 | { | 464 | { |
410 | struct stm32_dcmi *dcmi = arg; | 465 | struct stm32_dcmi *dcmi = arg; |
466 | unsigned long flags; | ||
411 | 467 | ||
412 | spin_lock(&dcmi->irqlock); | 468 | spin_lock_irqsave(&dcmi->irqlock, flags); |
413 | 469 | ||
414 | dcmi->misr = reg_read(dcmi->regs, DCMI_MIS); | 470 | dcmi->misr = reg_read(dcmi->regs, DCMI_MIS); |
415 | 471 | ||
416 | /* Clear interrupt */ | 472 | /* Clear interrupt */ |
417 | reg_set(dcmi->regs, DCMI_ICR, IT_FRAME | IT_OVR | IT_ERR); | 473 | reg_set(dcmi->regs, DCMI_ICR, IT_FRAME | IT_OVR | IT_ERR); |
418 | 474 | ||
419 | spin_unlock(&dcmi->irqlock); | 475 | spin_unlock_irqrestore(&dcmi->irqlock, flags); |
420 | 476 | ||
421 | return IRQ_WAKE_THREAD; | 477 | return IRQ_WAKE_THREAD; |
422 | } | 478 | } |
@@ -483,7 +539,7 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb) | |||
483 | 539 | ||
484 | vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size); | 540 | vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size); |
485 | 541 | ||
486 | dev_dbg(dcmi->dev, "buffer[%d] phy=0x%pad size=%zu\n", | 542 | dev_dbg(dcmi->dev, "buffer[%d] phy=%pad size=%zu\n", |
487 | vb->index, &buf->paddr, buf->size); | 543 | vb->index, &buf->paddr, buf->size); |
488 | } | 544 | } |
489 | 545 | ||
@@ -495,29 +551,24 @@ static void dcmi_buf_queue(struct vb2_buffer *vb) | |||
495 | struct stm32_dcmi *dcmi = vb2_get_drv_priv(vb->vb2_queue); | 551 | struct stm32_dcmi *dcmi = vb2_get_drv_priv(vb->vb2_queue); |
496 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | 552 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
497 | struct dcmi_buf *buf = container_of(vbuf, struct dcmi_buf, vb); | 553 | struct dcmi_buf *buf = container_of(vbuf, struct dcmi_buf, vb); |
498 | unsigned long flags = 0; | ||
499 | 554 | ||
500 | spin_lock_irqsave(&dcmi->irqlock, flags); | 555 | spin_lock_irq(&dcmi->irqlock); |
501 | 556 | ||
502 | if ((dcmi->state == RUNNING) && (!dcmi->active)) { | 557 | if (dcmi->state == RUNNING && !dcmi->active) { |
503 | dcmi->active = buf; | 558 | dcmi->active = buf; |
504 | 559 | ||
505 | dev_dbg(dcmi->dev, "Starting capture on buffer[%d] queued\n", | 560 | dev_dbg(dcmi->dev, "Starting capture on buffer[%d] queued\n", |
506 | buf->vb.vb2_buf.index); | 561 | buf->vb.vb2_buf.index); |
507 | 562 | ||
508 | if (dcmi_start_capture(dcmi)) { | 563 | spin_unlock_irq(&dcmi->irqlock); |
564 | if (dcmi_start_capture(dcmi)) | ||
509 | dev_err(dcmi->dev, "%s: Cannot restart capture on overflow or error\n", | 565 | dev_err(dcmi->dev, "%s: Cannot restart capture on overflow or error\n", |
510 | __func__); | 566 | __func__); |
511 | |||
512 | spin_unlock_irqrestore(&dcmi->irqlock, flags); | ||
513 | return; | ||
514 | } | ||
515 | } else { | 567 | } else { |
516 | /* Enqueue to video buffers list */ | 568 | /* Enqueue to video buffers list */ |
517 | list_add_tail(&buf->list, &dcmi->buffers); | 569 | list_add_tail(&buf->list, &dcmi->buffers); |
570 | spin_unlock_irq(&dcmi->irqlock); | ||
518 | } | 571 | } |
519 | |||
520 | spin_unlock_irqrestore(&dcmi->irqlock, flags); | ||
521 | } | 572 | } |
522 | 573 | ||
523 | static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) | 574 | static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) |
@@ -529,7 +580,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
529 | 580 | ||
530 | ret = clk_enable(dcmi->mclk); | 581 | ret = clk_enable(dcmi->mclk); |
531 | if (ret) { | 582 | if (ret) { |
532 | dev_err(dcmi->dev, "%s: Failed to start streaming, cannot enable clock", | 583 | dev_err(dcmi->dev, "%s: Failed to start streaming, cannot enable clock\n", |
533 | __func__); | 584 | __func__); |
534 | goto err_release_buffers; | 585 | goto err_release_buffers; |
535 | } | 586 | } |
@@ -578,6 +629,10 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
578 | if (dcmi->do_crop) | 629 | if (dcmi->do_crop) |
579 | dcmi_set_crop(dcmi); | 630 | dcmi_set_crop(dcmi); |
580 | 631 | ||
632 | /* Enable jpeg capture */ | ||
633 | if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG) | ||
634 | reg_set(dcmi->regs, DCMI_CR, CR_CM);/* Snapshot mode */ | ||
635 | |||
581 | /* Enable dcmi */ | 636 | /* Enable dcmi */ |
582 | reg_set(dcmi->regs, DCMI_CR, CR_ENABLE); | 637 | reg_set(dcmi->regs, DCMI_CR, CR_ENABLE); |
583 | 638 | ||
@@ -585,6 +640,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
585 | 640 | ||
586 | dcmi->sequence = 0; | 641 | dcmi->sequence = 0; |
587 | dcmi->errors_count = 0; | 642 | dcmi->errors_count = 0; |
643 | dcmi->overrun_count = 0; | ||
588 | dcmi->buffers_count = 0; | 644 | dcmi->buffers_count = 0; |
589 | dcmi->active = NULL; | 645 | dcmi->active = NULL; |
590 | 646 | ||
@@ -603,20 +659,17 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
603 | 659 | ||
604 | dev_dbg(dcmi->dev, "Start streaming, starting capture\n"); | 660 | dev_dbg(dcmi->dev, "Start streaming, starting capture\n"); |
605 | 661 | ||
662 | spin_unlock_irq(&dcmi->irqlock); | ||
606 | ret = dcmi_start_capture(dcmi); | 663 | ret = dcmi_start_capture(dcmi); |
607 | if (ret) { | 664 | if (ret) { |
608 | dev_err(dcmi->dev, "%s: Start streaming failed, cannot start capture", | 665 | dev_err(dcmi->dev, "%s: Start streaming failed, cannot start capture\n", |
609 | __func__); | 666 | __func__); |
610 | |||
611 | spin_unlock_irq(&dcmi->irqlock); | ||
612 | goto err_subdev_streamoff; | 667 | goto err_subdev_streamoff; |
613 | } | 668 | } |
614 | 669 | ||
615 | /* Enable interruptions */ | 670 | /* Enable interruptions */ |
616 | reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR); | 671 | reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR); |
617 | 672 | ||
618 | spin_unlock_irq(&dcmi->irqlock); | ||
619 | |||
620 | return 0; | 673 | return 0; |
621 | 674 | ||
622 | err_subdev_streamoff: | 675 | err_subdev_streamoff: |
@@ -656,9 +709,12 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) | |||
656 | /* Disable stream on the sub device */ | 709 | /* Disable stream on the sub device */ |
657 | ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0); | 710 | ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0); |
658 | if (ret && ret != -ENOIOCTLCMD) | 711 | if (ret && ret != -ENOIOCTLCMD) |
659 | dev_err(dcmi->dev, "stream off failed in subdev\n"); | 712 | dev_err(dcmi->dev, "%s: Failed to stop streaming, subdev streamoff error (%d)\n", |
713 | __func__, ret); | ||
660 | 714 | ||
715 | spin_lock_irq(&dcmi->irqlock); | ||
661 | dcmi->state = STOPPING; | 716 | dcmi->state = STOPPING; |
717 | spin_unlock_irq(&dcmi->irqlock); | ||
662 | 718 | ||
663 | timeout = wait_for_completion_interruptible_timeout(&dcmi->complete, | 719 | timeout = wait_for_completion_interruptible_timeout(&dcmi->complete, |
664 | time_ms); | 720 | time_ms); |
@@ -672,7 +728,8 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) | |||
672 | reg_clear(dcmi->regs, DCMI_CR, CR_ENABLE); | 728 | reg_clear(dcmi->regs, DCMI_CR, CR_ENABLE); |
673 | 729 | ||
674 | if (!timeout) { | 730 | if (!timeout) { |
675 | dev_err(dcmi->dev, "Timeout during stop streaming\n"); | 731 | dev_err(dcmi->dev, "%s: Timeout during stop streaming\n", |
732 | __func__); | ||
676 | dcmi->state = STOPPED; | 733 | dcmi->state = STOPPED; |
677 | } | 734 | } |
678 | 735 | ||
@@ -694,8 +751,13 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) | |||
694 | 751 | ||
695 | clk_disable(dcmi->mclk); | 752 | clk_disable(dcmi->mclk); |
696 | 753 | ||
697 | dev_dbg(dcmi->dev, "Stop streaming, errors=%d buffers=%d\n", | 754 | if (dcmi->errors_count) |
698 | dcmi->errors_count, dcmi->buffers_count); | 755 | dev_warn(dcmi->dev, "Some errors found while streaming: errors=%d (overrun=%d), buffers=%d\n", |
756 | dcmi->errors_count, dcmi->overrun_count, | ||
757 | dcmi->buffers_count); | ||
758 | dev_dbg(dcmi->dev, "Stop streaming, errors=%d (overrun=%d), buffers=%d\n", | ||
759 | dcmi->errors_count, dcmi->overrun_count, | ||
760 | dcmi->buffers_count); | ||
699 | } | 761 | } |
700 | 762 | ||
701 | static const struct vb2_ops dcmi_video_qops = { | 763 | static const struct vb2_ops dcmi_video_qops = { |
@@ -749,7 +811,7 @@ static void __find_outer_frame_size(struct stm32_dcmi *dcmi, | |||
749 | int h_err = (fsize->height - pix->height); | 811 | int h_err = (fsize->height - pix->height); |
750 | int err = w_err + h_err; | 812 | int err = w_err + h_err; |
751 | 813 | ||
752 | if ((w_err >= 0) && (h_err >= 0) && (err < min_err)) { | 814 | if (w_err >= 0 && h_err >= 0 && err < min_err) { |
753 | min_err = err; | 815 | min_err = err; |
754 | match = fsize; | 816 | match = fsize; |
755 | } | 817 | } |
@@ -771,6 +833,7 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, | |||
771 | struct v4l2_subdev_format format = { | 833 | struct v4l2_subdev_format format = { |
772 | .which = V4L2_SUBDEV_FORMAT_TRY, | 834 | .which = V4L2_SUBDEV_FORMAT_TRY, |
773 | }; | 835 | }; |
836 | bool do_crop; | ||
774 | int ret; | 837 | int ret; |
775 | 838 | ||
776 | sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); | 839 | sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); |
@@ -780,10 +843,19 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, | |||
780 | } | 843 | } |
781 | 844 | ||
782 | /* Limit to hardware capabilities */ | 845 | /* Limit to hardware capabilities */ |
783 | pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); | 846 | if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { |
784 | pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT); | 847 | pix->width = clamp(pix->width, MIN_JPEG_WIDTH, MAX_JPEG_WIDTH); |
848 | pix->height = | ||
849 | clamp(pix->height, MIN_JPEG_HEIGHT, MAX_JPEG_HEIGHT); | ||
850 | } else { | ||
851 | pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); | ||
852 | pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT); | ||
853 | } | ||
785 | 854 | ||
786 | if (dcmi->do_crop && dcmi->num_of_sd_framesizes) { | 855 | /* No crop if JPEG is requested */ |
856 | do_crop = dcmi->do_crop && (pix->pixelformat != V4L2_PIX_FMT_JPEG); | ||
857 | |||
858 | if (do_crop && dcmi->num_of_sd_framesizes) { | ||
787 | struct dcmi_framesize outer_sd_fsize; | 859 | struct dcmi_framesize outer_sd_fsize; |
788 | /* | 860 | /* |
789 | * If crop is requested and sensor have discrete frame sizes, | 861 | * If crop is requested and sensor have discrete frame sizes, |
@@ -807,7 +879,7 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, | |||
807 | sd_fsize.width = pix->width; | 879 | sd_fsize.width = pix->width; |
808 | sd_fsize.height = pix->height; | 880 | sd_fsize.height = pix->height; |
809 | 881 | ||
810 | if (dcmi->do_crop) { | 882 | if (do_crop) { |
811 | struct v4l2_rect c = dcmi->crop; | 883 | struct v4l2_rect c = dcmi->crop; |
812 | struct v4l2_rect max_rect; | 884 | struct v4l2_rect max_rect; |
813 | 885 | ||
@@ -862,6 +934,10 @@ static int dcmi_set_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f) | |||
862 | if (ret) | 934 | if (ret) |
863 | return ret; | 935 | return ret; |
864 | 936 | ||
937 | /* Disable crop if JPEG is requested */ | ||
938 | if (pix->pixelformat == V4L2_PIX_FMT_JPEG) | ||
939 | dcmi->do_crop = false; | ||
940 | |||
865 | /* pix to mbus format */ | 941 | /* pix to mbus format */ |
866 | v4l2_fill_mbus_format(mf, pix, | 942 | v4l2_fill_mbus_format(mf, pix, |
867 | sd_format->mbus_code); | 943 | sd_format->mbus_code); |
@@ -1084,10 +1160,10 @@ static int dcmi_s_selection(struct file *file, void *priv, | |||
1084 | r.top = clamp_t(s32, r.top, 0, pix.height - r.height); | 1160 | r.top = clamp_t(s32, r.top, 0, pix.height - r.height); |
1085 | r.left = clamp_t(s32, r.left, 0, pix.width - r.width); | 1161 | r.left = clamp_t(s32, r.left, 0, pix.width - r.width); |
1086 | 1162 | ||
1087 | if (!((r.top == dcmi->sd_bounds.top) && | 1163 | if (!(r.top == dcmi->sd_bounds.top && |
1088 | (r.left == dcmi->sd_bounds.left) && | 1164 | r.left == dcmi->sd_bounds.left && |
1089 | (r.width == dcmi->sd_bounds.width) && | 1165 | r.width == dcmi->sd_bounds.width && |
1090 | (r.height == dcmi->sd_bounds.height))) { | 1166 | r.height == dcmi->sd_bounds.height)) { |
1091 | /* Crop if request is different than sensor resolution */ | 1167 | /* Crop if request is different than sensor resolution */ |
1092 | dcmi->do_crop = true; | 1168 | dcmi->do_crop = true; |
1093 | dcmi->crop = r; | 1169 | dcmi->crop = r; |
@@ -1167,6 +1243,22 @@ static int dcmi_enum_framesizes(struct file *file, void *fh, | |||
1167 | return 0; | 1243 | return 0; |
1168 | } | 1244 | } |
1169 | 1245 | ||
1246 | static int dcmi_g_parm(struct file *file, void *priv, | ||
1247 | struct v4l2_streamparm *p) | ||
1248 | { | ||
1249 | struct stm32_dcmi *dcmi = video_drvdata(file); | ||
1250 | |||
1251 | return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.subdev, p); | ||
1252 | } | ||
1253 | |||
1254 | static int dcmi_s_parm(struct file *file, void *priv, | ||
1255 | struct v4l2_streamparm *p) | ||
1256 | { | ||
1257 | struct stm32_dcmi *dcmi = video_drvdata(file); | ||
1258 | |||
1259 | return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.subdev, p); | ||
1260 | } | ||
1261 | |||
1170 | static int dcmi_enum_frameintervals(struct file *file, void *fh, | 1262 | static int dcmi_enum_frameintervals(struct file *file, void *fh, |
1171 | struct v4l2_frmivalenum *fival) | 1263 | struct v4l2_frmivalenum *fival) |
1172 | { | 1264 | { |
@@ -1269,6 +1361,9 @@ static const struct v4l2_ioctl_ops dcmi_ioctl_ops = { | |||
1269 | .vidioc_g_input = dcmi_g_input, | 1361 | .vidioc_g_input = dcmi_g_input, |
1270 | .vidioc_s_input = dcmi_s_input, | 1362 | .vidioc_s_input = dcmi_s_input, |
1271 | 1363 | ||
1364 | .vidioc_g_parm = dcmi_g_parm, | ||
1365 | .vidioc_s_parm = dcmi_s_parm, | ||
1366 | |||
1272 | .vidioc_enum_framesizes = dcmi_enum_framesizes, | 1367 | .vidioc_enum_framesizes = dcmi_enum_framesizes, |
1273 | .vidioc_enum_frameintervals = dcmi_enum_frameintervals, | 1368 | .vidioc_enum_frameintervals = dcmi_enum_frameintervals, |
1274 | 1369 | ||
@@ -1334,6 +1429,10 @@ static const struct dcmi_format dcmi_formats[] = { | |||
1334 | .fourcc = V4L2_PIX_FMT_UYVY, | 1429 | .fourcc = V4L2_PIX_FMT_UYVY, |
1335 | .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, | 1430 | .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, |
1336 | .bpp = 2, | 1431 | .bpp = 2, |
1432 | }, { | ||
1433 | .fourcc = V4L2_PIX_FMT_JPEG, | ||
1434 | .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, | ||
1435 | .bpp = 1, | ||
1337 | }, | 1436 | }, |
1338 | }; | 1437 | }; |
1339 | 1438 | ||
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index f77be9302120..e9a02639554b 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c | |||
@@ -1112,7 +1112,7 @@ static int viacam_g_parm(struct file *filp, void *priv, | |||
1112 | int ret; | 1112 | int ret; |
1113 | 1113 | ||
1114 | mutex_lock(&cam->lock); | 1114 | mutex_lock(&cam->lock); |
1115 | ret = sensor_call(cam, video, g_parm, parm); | 1115 | ret = v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm); |
1116 | mutex_unlock(&cam->lock); | 1116 | mutex_unlock(&cam->lock); |
1117 | parm->parm.capture.readbuffers = cam->n_cap_bufs; | 1117 | parm->parm.capture.readbuffers = cam->n_cap_bufs; |
1118 | return ret; | 1118 | return ret; |
@@ -1125,7 +1125,7 @@ static int viacam_s_parm(struct file *filp, void *priv, | |||
1125 | int ret; | 1125 | int ret; |
1126 | 1126 | ||
1127 | mutex_lock(&cam->lock); | 1127 | mutex_lock(&cam->lock); |
1128 | ret = sensor_call(cam, video, s_parm, parm); | 1128 | ret = v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm); |
1129 | mutex_unlock(&cam->lock); | 1129 | mutex_unlock(&cam->lock); |
1130 | parm->parm.capture.readbuffers = cam->n_cap_bufs; | 1130 | parm->parm.capture.readbuffers = cam->n_cap_bufs; |
1131 | return ret; | 1131 | return ret; |
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index 9d63c84a9876..617415c224fe 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c | |||
@@ -434,7 +434,9 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, | |||
434 | v4l2_set_subdevdata(sd, ved); | 434 | v4l2_set_subdevdata(sd, ved); |
435 | 435 | ||
436 | /* Expose this subdev to user space */ | 436 | /* Expose this subdev to user space */ |
437 | sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; | 437 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
438 | if (sd->ctrl_handler) | ||
439 | sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS; | ||
438 | 440 | ||
439 | /* Initialize the media entity */ | 441 | /* Initialize the media entity */ |
440 | ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads); | 442 | ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads); |
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 4d663e89d33f..6e10b63ba9ec 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c | |||
@@ -533,7 +533,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, | |||
533 | /* Initialize ved and sd */ | 533 | /* Initialize ved and sd */ |
534 | ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev, | 534 | ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev, |
535 | pdata->entity_name, | 535 | pdata->entity_name, |
536 | MEDIA_ENT_F_ATV_DECODER, 2, | 536 | MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2, |
537 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, | 537 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, |
538 | MEDIA_PAD_FL_SOURCE}, | 538 | MEDIA_PAD_FL_SOURCE}, |
539 | &vimc_deb_ops); | 539 | &vimc_deb_ops); |
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index e1602e0bc230..e583ec7a91da 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c | |||
@@ -395,7 +395,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master, | |||
395 | /* Initialize ved and sd */ | 395 | /* Initialize ved and sd */ |
396 | ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev, | 396 | ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev, |
397 | pdata->entity_name, | 397 | pdata->entity_name, |
398 | MEDIA_ENT_F_ATV_DECODER, 2, | 398 | MEDIA_ENT_F_PROC_VIDEO_SCALER, 2, |
399 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, | 399 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, |
400 | MEDIA_PAD_FL_SOURCE}, | 400 | MEDIA_PAD_FL_SOURCE}, |
401 | &vimc_sca_ops); | 401 | &vimc_sca_ops); |
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 457e211514c6..605e2a2d5dd5 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/v4l2-mediabus.h> | 23 | #include <linux/v4l2-mediabus.h> |
24 | #include <linux/vmalloc.h> | 24 | #include <linux/vmalloc.h> |
25 | #include <media/v4l2-ctrls.h> | 25 | #include <media/v4l2-ctrls.h> |
26 | #include <media/v4l2-event.h> | ||
26 | #include <media/v4l2-subdev.h> | 27 | #include <media/v4l2-subdev.h> |
27 | #include <media/tpg/v4l2-tpg.h> | 28 | #include <media/tpg/v4l2-tpg.h> |
28 | 29 | ||
@@ -284,11 +285,18 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) | |||
284 | return 0; | 285 | return 0; |
285 | } | 286 | } |
286 | 287 | ||
288 | static struct v4l2_subdev_core_ops vimc_sen_core_ops = { | ||
289 | .log_status = v4l2_ctrl_subdev_log_status, | ||
290 | .subscribe_event = v4l2_ctrl_subdev_subscribe_event, | ||
291 | .unsubscribe_event = v4l2_event_subdev_unsubscribe, | ||
292 | }; | ||
293 | |||
287 | static const struct v4l2_subdev_video_ops vimc_sen_video_ops = { | 294 | static const struct v4l2_subdev_video_ops vimc_sen_video_ops = { |
288 | .s_stream = vimc_sen_s_stream, | 295 | .s_stream = vimc_sen_s_stream, |
289 | }; | 296 | }; |
290 | 297 | ||
291 | static const struct v4l2_subdev_ops vimc_sen_ops = { | 298 | static const struct v4l2_subdev_ops vimc_sen_ops = { |
299 | .core = &vimc_sen_core_ops, | ||
292 | .pad = &vimc_sen_pad_ops, | 300 | .pad = &vimc_sen_pad_ops, |
293 | .video = &vimc_sen_video_ops, | 301 | .video = &vimc_sen_video_ops, |
294 | }; | 302 | }; |
@@ -378,7 +386,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, | |||
378 | /* Initialize ved and sd */ | 386 | /* Initialize ved and sd */ |
379 | ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, | 387 | ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev, |
380 | pdata->entity_name, | 388 | pdata->entity_name, |
381 | MEDIA_ENT_F_ATV_DECODER, 1, | 389 | MEDIA_ENT_F_CAM_SENSOR, 1, |
382 | (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, | 390 | (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, |
383 | &vimc_sen_ops); | 391 | &vimc_sen_ops); |
384 | if (ret) | 392 | if (ret) |
diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c index b55d278d38a7..71105fa4c5f9 100644 --- a/drivers/media/platform/vivid/vivid-cec.c +++ b/drivers/media/platform/vivid/vivid-cec.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-cec.c - A Virtual Video Test Driver, cec emulation | 3 | * vivid-cec.c - A Virtual Video Test Driver, cec emulation |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <media/cec.h> | 8 | #include <media/cec.h> |
@@ -82,11 +70,18 @@ static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts, | |||
82 | 70 | ||
83 | if (adap == NULL) | 71 | if (adap == NULL) |
84 | return; | 72 | return; |
85 | ts = ktime_sub_us(ts, (CEC_TIM_START_BIT_TOTAL + | 73 | |
86 | len * 10 * CEC_TIM_DATA_BIT_TOTAL)); | 74 | /* |
87 | cec_queue_pin_cec_event(adap, false, ts); | 75 | * Suffix ULL on constant 10 makes the expression |
76 | * CEC_TIM_START_BIT_TOTAL + 10ULL * len * CEC_TIM_DATA_BIT_TOTAL | ||
77 | * to be evaluated using 64-bit unsigned arithmetic (u64), which | ||
78 | * is what ktime_sub_us expects as second argument. | ||
79 | */ | ||
80 | ts = ktime_sub_us(ts, CEC_TIM_START_BIT_TOTAL + | ||
81 | 10ULL * len * CEC_TIM_DATA_BIT_TOTAL); | ||
82 | cec_queue_pin_cec_event(adap, false, false, ts); | ||
88 | ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW); | 83 | ts = ktime_add_us(ts, CEC_TIM_START_BIT_LOW); |
89 | cec_queue_pin_cec_event(adap, true, ts); | 84 | cec_queue_pin_cec_event(adap, true, false, ts); |
90 | ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH); | 85 | ts = ktime_add_us(ts, CEC_TIM_START_BIT_HIGH); |
91 | 86 | ||
92 | for (i = 0; i < 10 * len; i++) { | 87 | for (i = 0; i < 10 * len; i++) { |
@@ -101,12 +96,12 @@ static void vivid_cec_pin_adap_events(struct cec_adapter *adap, ktime_t ts, | |||
101 | bit = cec_msg_is_broadcast(msg) ^ nacked; | 96 | bit = cec_msg_is_broadcast(msg) ^ nacked; |
102 | break; | 97 | break; |
103 | } | 98 | } |
104 | cec_queue_pin_cec_event(adap, false, ts); | 99 | cec_queue_pin_cec_event(adap, false, false, ts); |
105 | if (bit) | 100 | if (bit) |
106 | ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW); | 101 | ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_LOW); |
107 | else | 102 | else |
108 | ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW); | 103 | ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_0_LOW); |
109 | cec_queue_pin_cec_event(adap, true, ts); | 104 | cec_queue_pin_cec_event(adap, true, false, ts); |
110 | if (bit) | 105 | if (bit) |
111 | ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH); | 106 | ts = ktime_add_us(ts, CEC_TIM_DATA_BIT_1_HIGH); |
112 | else | 107 | else |
diff --git a/drivers/media/platform/vivid/vivid-cec.h b/drivers/media/platform/vivid/vivid-cec.h index 3926b1422777..7524ed48a914 100644 --- a/drivers/media/platform/vivid/vivid-cec.h +++ b/drivers/media/platform/vivid/vivid-cec.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-cec.h - A Virtual Video Test Driver, cec emulation | 3 | * vivid-cec.h - A Virtual Video Test Driver, cec emulation |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifdef CONFIG_VIDEO_VIVID_CEC | 8 | #ifdef CONFIG_VIDEO_VIVID_CEC |
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 9f036c5f51b0..82ec216f2ad8 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-core.c - A Virtual Video Test Driver, core initialization | 3 | * vivid-core.c - A Virtual Video Test Driver, core initialization |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index c90e4a0ab94e..477c80a4d44c 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-core.h - core datastructures | 3 | * vivid-core.h - core datastructures |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_CORE_H_ | 8 | #ifndef _VIVID_CORE_H_ |
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 3f9d354827af..6b0bfa091592 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-ctrls.c - control support functions. | 3 | * vivid-ctrls.c - control support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
@@ -1208,6 +1196,7 @@ static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1208 | v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls); | 1196 | v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls); |
1209 | v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls); | 1197 | v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls); |
1210 | v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls); | 1198 | v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls); |
1199 | dev->radio_rx_dev.device_caps = dev->radio_rx_caps; | ||
1211 | break; | 1200 | break; |
1212 | case V4L2_CID_RDS_RECEPTION: | 1201 | case V4L2_CID_RDS_RECEPTION: |
1213 | dev->radio_rx_rds_enabled = ctrl->val; | 1202 | dev->radio_rx_rds_enabled = ctrl->val; |
@@ -1282,6 +1271,7 @@ static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1282 | dev->radio_tx_caps &= ~V4L2_CAP_READWRITE; | 1271 | dev->radio_tx_caps &= ~V4L2_CAP_READWRITE; |
1283 | if (!dev->radio_tx_rds_controls) | 1272 | if (!dev->radio_tx_rds_controls) |
1284 | dev->radio_tx_caps |= V4L2_CAP_READWRITE; | 1273 | dev->radio_tx_caps |= V4L2_CAP_READWRITE; |
1274 | dev->radio_tx_dev.device_caps = dev->radio_tx_caps; | ||
1285 | break; | 1275 | break; |
1286 | case V4L2_CID_RDS_TX_PTY: | 1276 | case V4L2_CID_RDS_TX_PTY: |
1287 | if (dev->radio_rx_rds_controls) | 1277 | if (dev->radio_rx_rds_controls) |
diff --git a/drivers/media/platform/vivid/vivid-ctrls.h b/drivers/media/platform/vivid/vivid-ctrls.h index 9bcca9d56359..6fad5f5d0054 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.h +++ b/drivers/media/platform/vivid/vivid-ctrls.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-ctrls.h - control support functions. | 3 | * vivid-ctrls.h - control support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_CTRLS_H_ | 8 | #ifndef _VIVID_CTRLS_H_ |
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c index 6ca71aabb576..3fdb280c36ca 100644 --- a/drivers/media/platform/vivid/vivid-kthread-cap.c +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-kthread-cap.h - video/vbi capture thread support functions. | 3 | * vivid-kthread-cap.h - video/vbi capture thread support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.h b/drivers/media/platform/vivid/vivid-kthread-cap.h index 5b92fc9a0d04..0f43015306d6 100644 --- a/drivers/media/platform/vivid/vivid-kthread-cap.h +++ b/drivers/media/platform/vivid/vivid-kthread-cap.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-kthread-cap.h - video/vbi capture thread support functions. | 3 | * vivid-kthread-cap.h - video/vbi capture thread support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_KTHREAD_CAP_H_ | 8 | #ifndef _VIVID_KTHREAD_CAP_H_ |
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c index 98eed5889bc1..9981e7548019 100644 --- a/drivers/media/platform/vivid/vivid-kthread-out.c +++ b/drivers/media/platform/vivid/vivid-kthread-out.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-kthread-out.h - video/vbi output thread support functions. | 3 | * vivid-kthread-out.h - video/vbi output thread support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.h b/drivers/media/platform/vivid/vivid-kthread-out.h index 2bf04a17b05d..d5bcf44bbaca 100644 --- a/drivers/media/platform/vivid/vivid-kthread-out.h +++ b/drivers/media/platform/vivid/vivid-kthread-out.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-kthread-out.h - video/vbi output thread support functions. | 3 | * vivid-kthread-out.h - video/vbi output thread support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_KTHREAD_OUT_H_ | 8 | #ifndef _VIVID_KTHREAD_OUT_H_ |
diff --git a/drivers/media/platform/vivid/vivid-osd.c b/drivers/media/platform/vivid/vivid-osd.c index bdc380b14e0c..bbbc1b6938a5 100644 --- a/drivers/media/platform/vivid/vivid-osd.c +++ b/drivers/media/platform/vivid/vivid-osd.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-osd.c - osd support for testing overlays. | 3 | * vivid-osd.c - osd support for testing overlays. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/media/platform/vivid/vivid-osd.h b/drivers/media/platform/vivid/vivid-osd.h index 57c9daa5940a..f9ac1af25dd3 100644 --- a/drivers/media/platform/vivid/vivid-osd.h +++ b/drivers/media/platform/vivid/vivid-osd.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-osd.h - output overlay support functions. | 3 | * vivid-osd.h - output overlay support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_OSD_H_ | 8 | #ifndef _VIVID_OSD_H_ |
diff --git a/drivers/media/platform/vivid/vivid-radio-common.c b/drivers/media/platform/vivid/vivid-radio-common.c index 78c1e920670a..7c8efe38ff5b 100644 --- a/drivers/media/platform/vivid/vivid-radio-common.c +++ b/drivers/media/platform/vivid/vivid-radio-common.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-radio-common.c - common radio rx/tx support functions. | 3 | * vivid-radio-common.c - common radio rx/tx support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-radio-common.h b/drivers/media/platform/vivid/vivid-radio-common.h index 92fe589141b7..30a9900e5b2b 100644 --- a/drivers/media/platform/vivid/vivid-radio-common.h +++ b/drivers/media/platform/vivid/vivid-radio-common.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-radio-common.h - common radio rx/tx support functions. | 3 | * vivid-radio-common.h - common radio rx/tx support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_RADIO_COMMON_H_ | 8 | #ifndef _VIVID_RADIO_COMMON_H_ |
diff --git a/drivers/media/platform/vivid/vivid-radio-rx.c b/drivers/media/platform/vivid/vivid-radio-rx.c index f834f7df8cf9..1f86d7d4f72f 100644 --- a/drivers/media/platform/vivid/vivid-radio-rx.c +++ b/drivers/media/platform/vivid/vivid-radio-rx.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-radio-rx.c - radio receiver support functions. | 3 | * vivid-radio-rx.c - radio receiver support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
@@ -259,7 +247,7 @@ int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
259 | vt->rangehigh = FM_FREQ_RANGE_HIGH; | 247 | vt->rangehigh = FM_FREQ_RANGE_HIGH; |
260 | sig_qual = dev->radio_rx_sig_qual; | 248 | sig_qual = dev->radio_rx_sig_qual; |
261 | vt->signal = abs(sig_qual) > delta ? 0 : | 249 | vt->signal = abs(sig_qual) > delta ? 0 : |
262 | 0xffff - (abs(sig_qual) * 0xffff) / delta; | 250 | 0xffff - ((unsigned)abs(sig_qual) * 0xffff) / delta; |
263 | vt->afc = sig_qual > delta ? 0 : sig_qual; | 251 | vt->afc = sig_qual > delta ? 0 : sig_qual; |
264 | if (abs(sig_qual) > delta) | 252 | if (abs(sig_qual) > delta) |
265 | vt->rxsubchans = 0; | 253 | vt->rxsubchans = 0; |
diff --git a/drivers/media/platform/vivid/vivid-radio-rx.h b/drivers/media/platform/vivid/vivid-radio-rx.h index 2b33edb60942..c9c7849f6f99 100644 --- a/drivers/media/platform/vivid/vivid-radio-rx.h +++ b/drivers/media/platform/vivid/vivid-radio-rx.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-radio-rx.h - radio receiver support functions. | 3 | * vivid-radio-rx.h - radio receiver support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_RADIO_RX_H_ | 8 | #ifndef _VIVID_RADIO_RX_H_ |
diff --git a/drivers/media/platform/vivid/vivid-radio-tx.c b/drivers/media/platform/vivid/vivid-radio-tx.c index 308b13f85dc0..1a3749ba5e7e 100644 --- a/drivers/media/platform/vivid/vivid-radio-tx.c +++ b/drivers/media/platform/vivid/vivid-radio-tx.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-radio-tx.c - radio transmitter support functions. | 3 | * vivid-radio-tx.c - radio transmitter support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-radio-tx.h b/drivers/media/platform/vivid/vivid-radio-tx.h index 3c3343d70cbc..c2bf1e7e634a 100644 --- a/drivers/media/platform/vivid/vivid-radio-tx.h +++ b/drivers/media/platform/vivid/vivid-radio-tx.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-radio-tx.h - radio transmitter support functions. | 3 | * vivid-radio-tx.h - radio transmitter support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_RADIO_TX_H_ | 8 | #ifndef _VIVID_RADIO_TX_H_ |
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.c b/drivers/media/platform/vivid/vivid-rds-gen.c index 996e35e28d37..39ca9a56448c 100644 --- a/drivers/media/platform/vivid/vivid-rds-gen.c +++ b/drivers/media/platform/vivid/vivid-rds-gen.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-rds-gen.c - rds (radio data system) generator support functions. | 3 | * vivid-rds-gen.c - rds (radio data system) generator support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.h b/drivers/media/platform/vivid/vivid-rds-gen.h index e55e3b22b7ca..35ac5742302b 100644 --- a/drivers/media/platform/vivid/vivid-rds-gen.h +++ b/drivers/media/platform/vivid/vivid-rds-gen.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-rds-gen.h - rds (radio data system) generator support functions. | 3 | * vivid-rds-gen.h - rds (radio data system) generator support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_RDS_GEN_H_ | 8 | #ifndef _VIVID_RDS_GEN_H_ |
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c index ebd7b9c4dd83..cfb7cb4d37a8 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.c +++ b/drivers/media/platform/vivid/vivid-sdr-cap.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-sdr-cap.c - software defined radio support functions. | 3 | * vivid-sdr-cap.c - software defined radio support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.h b/drivers/media/platform/vivid/vivid-sdr-cap.h index 43014b2733db..813c9248e5a7 100644 --- a/drivers/media/platform/vivid/vivid-sdr-cap.h +++ b/drivers/media/platform/vivid/vivid-sdr-cap.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-sdr-cap.h - software defined radio support functions. | 3 | * vivid-sdr-cap.h - software defined radio support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_SDR_CAP_H_ | 8 | #ifndef _VIVID_SDR_CAP_H_ |
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.c b/drivers/media/platform/vivid/vivid-vbi-cap.c index d66ef95dd2b5..92a852955173 100644 --- a/drivers/media/platform/vivid/vivid-vbi-cap.c +++ b/drivers/media/platform/vivid/vivid-vbi-cap.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-vbi-cap.c - vbi capture support functions. | 3 | * vivid-vbi-cap.c - vbi capture support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-vbi-cap.h b/drivers/media/platform/vivid/vivid-vbi-cap.h index 2d8ea0bac743..91d2de01381c 100644 --- a/drivers/media/platform/vivid/vivid-vbi-cap.h +++ b/drivers/media/platform/vivid/vivid-vbi-cap.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-vbi-cap.h - vbi capture support functions. | 3 | * vivid-vbi-cap.h - vbi capture support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_VBI_CAP_H_ | 8 | #ifndef _VIVID_VBI_CAP_H_ |
diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.c b/drivers/media/platform/vivid/vivid-vbi-gen.c index 02c79d7cedab..acc98445a1fa 100644 --- a/drivers/media/platform/vivid/vivid-vbi-gen.c +++ b/drivers/media/platform/vivid/vivid-vbi-gen.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-vbi-gen.c - vbi generator support functions. | 3 | * vivid-vbi-gen.c - vbi generator support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.h b/drivers/media/platform/vivid/vivid-vbi-gen.h index 8444abe905ea..2657a7f5571c 100644 --- a/drivers/media/platform/vivid/vivid-vbi-gen.h +++ b/drivers/media/platform/vivid/vivid-vbi-gen.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-vbi-gen.h - vbi generator support functions. | 3 | * vivid-vbi-gen.h - vbi generator support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_VBI_GEN_H_ | 8 | #ifndef _VIVID_VBI_GEN_H_ |
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.c b/drivers/media/platform/vivid/vivid-vbi-out.c index d2989195cf03..69486c130a7e 100644 --- a/drivers/media/platform/vivid/vivid-vbi-out.c +++ b/drivers/media/platform/vivid/vivid-vbi-out.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-vbi-out.c - vbi output support functions. | 3 | * vivid-vbi-out.c - vbi output support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-vbi-out.h b/drivers/media/platform/vivid/vivid-vbi-out.h index 6555ba9d2860..76584940cdaf 100644 --- a/drivers/media/platform/vivid/vivid-vbi-out.h +++ b/drivers/media/platform/vivid/vivid-vbi-out.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-vbi-out.h - vbi output support functions. | 3 | * vivid-vbi-out.h - vbi output support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_VBI_OUT_H_ | 8 | #ifndef _VIVID_VBI_OUT_H_ |
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 0fbbcde19f0d..01c703683657 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-vid-cap.c - video capture support functions. | 3 | * vivid-vid-cap.c - video capture support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
@@ -573,9 +561,8 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, | |||
573 | mp->field = vivid_field_cap(dev, mp->field); | 561 | mp->field = vivid_field_cap(dev, mp->field); |
574 | if (vivid_is_webcam(dev)) { | 562 | if (vivid_is_webcam(dev)) { |
575 | const struct v4l2_frmsize_discrete *sz = | 563 | const struct v4l2_frmsize_discrete *sz = |
576 | v4l2_find_nearest_format(webcam_sizes, | 564 | v4l2_find_nearest_size(webcam_sizes, width, height, |
577 | VIVID_WEBCAM_SIZES, | 565 | mp->width, mp->height); |
578 | mp->width, mp->height); | ||
579 | 566 | ||
580 | w = sz->width; | 567 | w = sz->width; |
581 | h = sz->height; | 568 | h = sz->height; |
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.h b/drivers/media/platform/vivid/vivid-vid-cap.h index 94079815dbc2..47d8b48820df 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.h +++ b/drivers/media/platform/vivid/vivid-vid-cap.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-vid-cap.h - video capture support functions. | 3 | * vivid-vid-cap.h - video capture support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_VID_CAP_H_ | 8 | #ifndef _VIVID_VID_CAP_H_ |
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index a651527d80db..e5914be0e12d 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-vid-common.c - common video support functions. | 3 | * vivid-vid-common.c - common video support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
@@ -874,7 +862,8 @@ int vidioc_g_edid(struct file *file, void *_fh, | |||
874 | return -EINVAL; | 862 | return -EINVAL; |
875 | if (edid->start_block + edid->blocks > dev->edid_blocks) | 863 | if (edid->start_block + edid->blocks > dev->edid_blocks) |
876 | edid->blocks = dev->edid_blocks - edid->start_block; | 864 | edid->blocks = dev->edid_blocks - edid->start_block; |
877 | cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); | 865 | if (adap) |
866 | cec_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); | ||
878 | memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); | 867 | memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); |
879 | return 0; | 868 | return 0; |
880 | } | 869 | } |
diff --git a/drivers/media/platform/vivid/vivid-vid-common.h b/drivers/media/platform/vivid/vivid-vid-common.h index 4b6175eab8a2..29b6c0b40a1b 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.h +++ b/drivers/media/platform/vivid/vivid-vid-common.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-vid-common.h - common video support functions. | 3 | * vivid-vid-common.h - common video support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_VID_COMMON_H_ | 8 | #ifndef _VIVID_VID_COMMON_H_ |
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index 0b1b6218ede8..51fec66d8d45 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c | |||
@@ -1,20 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * vivid-vid-out.c - video output support functions. | 3 | * vivid-vid-out.c - video output support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
diff --git a/drivers/media/platform/vivid/vivid-vid-out.h b/drivers/media/platform/vivid/vivid-vid-out.h index dfa84db184ed..e87aacf843c5 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.h +++ b/drivers/media/platform/vivid/vivid-vid-out.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * vivid-vid-out.h - video output support functions. | 3 | * vivid-vid-out.h - video output support functions. |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _VIVID_VID_OUT_H_ | 8 | #ifndef _VIVID_VID_OUT_H_ |
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 4257451f1bd8..0b86ed01e85d 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c | |||
@@ -509,7 +509,8 @@ static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm) | |||
509 | return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE) | 509 | return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE) |
510 | & VI6_DL_BODY_SIZE_UPD); | 510 | & VI6_DL_BODY_SIZE_UPD); |
511 | else | 511 | else |
512 | return !!(vsp1_read(vsp1, VI6_CMD(dlm->index) & VI6_CMD_UPDHDR)); | 512 | return !!(vsp1_read(vsp1, VI6_CMD(dlm->index)) |
513 | & VI6_CMD_UPDHDR); | ||
513 | } | 514 | } |
514 | 515 | ||
515 | static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl) | 516 | static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl) |
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 7ce69f23f50a..b8fee1834253 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "vsp1_pipe.h" | 27 | #include "vsp1_pipe.h" |
28 | #include "vsp1_rwpf.h" | 28 | #include "vsp1_rwpf.h" |
29 | 29 | ||
30 | #define BRU_NAME(e) (e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS" | ||
30 | 31 | ||
31 | /* ----------------------------------------------------------------------------- | 32 | /* ----------------------------------------------------------------------------- |
32 | * Interrupt Handling | 33 | * Interrupt Handling |
@@ -88,7 +89,6 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, | |||
88 | struct vsp1_entity *next; | 89 | struct vsp1_entity *next; |
89 | struct vsp1_dl_list *dl; | 90 | struct vsp1_dl_list *dl; |
90 | struct v4l2_subdev_format format; | 91 | struct v4l2_subdev_format format; |
91 | const char *bru_name; | ||
92 | unsigned long flags; | 92 | unsigned long flags; |
93 | unsigned int i; | 93 | unsigned int i; |
94 | int ret; | 94 | int ret; |
@@ -99,7 +99,6 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, | |||
99 | drm_pipe = &vsp1->drm->pipe[pipe_index]; | 99 | drm_pipe = &vsp1->drm->pipe[pipe_index]; |
100 | pipe = &drm_pipe->pipe; | 100 | pipe = &drm_pipe->pipe; |
101 | bru = to_bru(&pipe->bru->subdev); | 101 | bru = to_bru(&pipe->bru->subdev); |
102 | bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"; | ||
103 | 102 | ||
104 | if (!cfg) { | 103 | if (!cfg) { |
105 | /* | 104 | /* |
@@ -165,7 +164,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, | |||
165 | 164 | ||
166 | dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", | 165 | dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", |
167 | __func__, format.format.width, format.format.height, | 166 | __func__, format.format.width, format.format.height, |
168 | format.format.code, bru_name, i); | 167 | format.format.code, BRU_NAME(pipe->bru), i); |
169 | } | 168 | } |
170 | 169 | ||
171 | format.pad = pipe->bru->source_pad; | 170 | format.pad = pipe->bru->source_pad; |
@@ -181,7 +180,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, | |||
181 | 180 | ||
182 | dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", | 181 | dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", |
183 | __func__, format.format.width, format.format.height, | 182 | __func__, format.format.width, format.format.height, |
184 | format.format.code, bru_name, i); | 183 | format.format.code, BRU_NAME(pipe->bru), i); |
185 | 184 | ||
186 | format.pad = RWPF_PAD_SINK; | 185 | format.pad = RWPF_PAD_SINK; |
187 | ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL, | 186 | ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL, |
@@ -473,9 +472,9 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1, | |||
473 | if (ret < 0) | 472 | if (ret < 0) |
474 | return ret; | 473 | return ret; |
475 | 474 | ||
476 | dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n", | 475 | dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", |
477 | __func__, format.format.width, format.format.height, | 476 | __func__, format.format.width, format.format.height, |
478 | format.format.code, format.pad); | 477 | format.format.code, BRU_NAME(pipe->bru), format.pad); |
479 | 478 | ||
480 | sel.pad = bru_input; | 479 | sel.pad = bru_input; |
481 | sel.target = V4L2_SEL_TGT_COMPOSE; | 480 | sel.target = V4L2_SEL_TGT_COMPOSE; |
@@ -486,10 +485,9 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1, | |||
486 | if (ret < 0) | 485 | if (ret < 0) |
487 | return ret; | 486 | return ret; |
488 | 487 | ||
489 | dev_dbg(vsp1->dev, | 488 | dev_dbg(vsp1->dev, "%s: set selection (%u,%u)/%ux%u on %s pad %u\n", |
490 | "%s: set selection (%u,%u)/%ux%u on BRU pad %u\n", | ||
491 | __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, | 489 | __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, |
492 | sel.pad); | 490 | BRU_NAME(pipe->bru), sel.pad); |
493 | 491 | ||
494 | return 0; | 492 | return 0; |
495 | } | 493 | } |
@@ -514,12 +512,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) | |||
514 | struct vsp1_entity *entity; | 512 | struct vsp1_entity *entity; |
515 | struct vsp1_entity *next; | 513 | struct vsp1_entity *next; |
516 | struct vsp1_dl_list *dl; | 514 | struct vsp1_dl_list *dl; |
517 | const char *bru_name; | ||
518 | unsigned int i; | 515 | unsigned int i; |
519 | int ret; | 516 | int ret; |
520 | 517 | ||
521 | bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"; | ||
522 | |||
523 | /* Prepare the display list. */ | 518 | /* Prepare the display list. */ |
524 | dl = vsp1_dl_list_get(pipe->output->dlm); | 519 | dl = vsp1_dl_list_get(pipe->output->dlm); |
525 | 520 | ||
@@ -530,6 +525,15 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) | |||
530 | struct vsp1_rwpf *rpf = vsp1->rpf[i]; | 525 | struct vsp1_rwpf *rpf = vsp1->rpf[i]; |
531 | unsigned int j; | 526 | unsigned int j; |
532 | 527 | ||
528 | /* | ||
529 | * Make sure we don't accept more inputs than the hardware can | ||
530 | * handle. This is a temporary fix to avoid display stall, we | ||
531 | * need to instead allocate the BRU or BRS to display pipelines | ||
532 | * dynamically based on the number of planes they each use. | ||
533 | */ | ||
534 | if (pipe->num_inputs >= pipe->bru->source_pad) | ||
535 | pipe->inputs[i] = NULL; | ||
536 | |||
533 | if (!pipe->inputs[i]) | 537 | if (!pipe->inputs[i]) |
534 | continue; | 538 | continue; |
535 | 539 | ||
@@ -561,7 +565,7 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) | |||
561 | rpf->entity.sink_pad = i; | 565 | rpf->entity.sink_pad = i; |
562 | 566 | ||
563 | dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n", | 567 | dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n", |
564 | __func__, rpf->entity.index, bru_name, i); | 568 | __func__, rpf->entity.index, BRU_NAME(pipe->bru), i); |
565 | 569 | ||
566 | ret = vsp1_du_setup_rpf_pipe(vsp1, pipe, rpf, i); | 570 | ret = vsp1_du_setup_rpf_pipe(vsp1, pipe, rpf, i); |
567 | if (ret < 0) | 571 | if (ret < 0) |
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c index e6fa16d7fda8..704920753998 100644 --- a/drivers/media/platform/vsp1/vsp1_lif.c +++ b/drivers/media/platform/vsp1/vsp1_lif.c | |||
@@ -155,6 +155,18 @@ static void lif_configure(struct vsp1_entity *entity, | |||
155 | (obth << VI6_LIF_CTRL_OBTH_SHIFT) | | 155 | (obth << VI6_LIF_CTRL_OBTH_SHIFT) | |
156 | (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) | | 156 | (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) | |
157 | VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN); | 157 | VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN); |
158 | |||
159 | /* | ||
160 | * On R-Car V3M the LIF0 buffer attribute register has to be set to a | ||
161 | * non-default value to guarantee proper operation (otherwise artifacts | ||
162 | * may appear on the output). The value required by the manual is not | ||
163 | * explained but is likely a buffer size or threshold. | ||
164 | */ | ||
165 | if ((entity->vsp1->version & VI6_IP_VERSION_MASK) == | ||
166 | (VI6_IP_VERSION_MODEL_VSPD_V3 | VI6_IP_VERSION_SOC_V3M)) | ||
167 | vsp1_lif_write(lif, dl, VI6_LIF_LBA, | ||
168 | VI6_LIF_LBA_LBA0 | | ||
169 | (1536 << VI6_LIF_LBA_LBA1_SHIFT)); | ||
158 | } | 170 | } |
159 | 171 | ||
160 | static const struct vsp1_entity_operations lif_entity_ops = { | 172 | static const struct vsp1_entity_operations lif_entity_ops = { |
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index 26c4ffad2f46..dae0c1901297 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h | |||
@@ -225,7 +225,7 @@ | |||
225 | #define VI6_RPF_MULT_ALPHA_P_MMD_RATIO (1 << 8) | 225 | #define VI6_RPF_MULT_ALPHA_P_MMD_RATIO (1 << 8) |
226 | #define VI6_RPF_MULT_ALPHA_P_MMD_IMAGE (2 << 8) | 226 | #define VI6_RPF_MULT_ALPHA_P_MMD_IMAGE (2 << 8) |
227 | #define VI6_RPF_MULT_ALPHA_P_MMD_BOTH (3 << 8) | 227 | #define VI6_RPF_MULT_ALPHA_P_MMD_BOTH (3 << 8) |
228 | #define VI6_RPF_MULT_ALPHA_RATIO_MASK (0xff < 0) | 228 | #define VI6_RPF_MULT_ALPHA_RATIO_MASK (0xff << 0) |
229 | #define VI6_RPF_MULT_ALPHA_RATIO_SHIFT 0 | 229 | #define VI6_RPF_MULT_ALPHA_RATIO_SHIFT 0 |
230 | 230 | ||
231 | /* ----------------------------------------------------------------------------- | 231 | /* ----------------------------------------------------------------------------- |
@@ -693,6 +693,11 @@ | |||
693 | #define VI6_LIF_CSBTH_LBTH_MASK (0x7ff << 0) | 693 | #define VI6_LIF_CSBTH_LBTH_MASK (0x7ff << 0) |
694 | #define VI6_LIF_CSBTH_LBTH_SHIFT 0 | 694 | #define VI6_LIF_CSBTH_LBTH_SHIFT 0 |
695 | 695 | ||
696 | #define VI6_LIF_LBA 0x3b0c | ||
697 | #define VI6_LIF_LBA_LBA0 (1 << 31) | ||
698 | #define VI6_LIF_LBA_LBA1_MASK (0xfff << 16) | ||
699 | #define VI6_LIF_LBA_LBA1_SHIFT 16 | ||
700 | |||
696 | /* ----------------------------------------------------------------------------- | 701 | /* ----------------------------------------------------------------------------- |
697 | * Security Control Registers | 702 | * Security Control Registers |
698 | */ | 703 | */ |
@@ -705,6 +710,7 @@ | |||
705 | */ | 710 | */ |
706 | 711 | ||
707 | #define VI6_IP_VERSION 0x3f00 | 712 | #define VI6_IP_VERSION 0x3f00 |
713 | #define VI6_IP_VERSION_MASK (0xffff << 0) | ||
708 | #define VI6_IP_VERSION_MODEL_MASK (0xff << 8) | 714 | #define VI6_IP_VERSION_MODEL_MASK (0xff << 8) |
709 | #define VI6_IP_VERSION_MODEL_VSPS_H2 (0x09 << 8) | 715 | #define VI6_IP_VERSION_MODEL_VSPS_H2 (0x09 << 8) |
710 | #define VI6_IP_VERSION_MODEL_VSPR_H2 (0x0a << 8) | 716 | #define VI6_IP_VERSION_MODEL_VSPR_H2 (0x0a << 8) |
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index dc6c4f985911..0f292c6ba338 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -511,7 +511,7 @@ static int usb_amradio_probe(struct usb_interface *intf, | |||
511 | const struct usb_device_id *id) | 511 | const struct usb_device_id *id) |
512 | { | 512 | { |
513 | struct amradio_device *radio; | 513 | struct amradio_device *radio; |
514 | int retval = 0; | 514 | int retval; |
515 | 515 | ||
516 | radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); | 516 | radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); |
517 | 517 | ||
diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c index 70a2c86774ce..9a5079d64c4a 100644 --- a/drivers/media/radio/radio-raremono.c +++ b/drivers/media/radio/radio-raremono.c | |||
@@ -1,18 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 3 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
3 | * | ||
4 | * This program is free software; you may redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
9 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
10 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
11 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
12 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
15 | * SOFTWARE. | ||
16 | */ | 4 | */ |
17 | 5 | ||
18 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index 58e944591602..8f9f8dfc3497 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c | |||
@@ -671,7 +671,7 @@ fail: | |||
671 | static int wl1273_fm_suspend(struct wl1273_device *radio) | 671 | static int wl1273_fm_suspend(struct wl1273_device *radio) |
672 | { | 672 | { |
673 | struct wl1273_core *core = radio->core; | 673 | struct wl1273_core *core = radio->core; |
674 | int r = 0; | 674 | int r; |
675 | 675 | ||
676 | /* Cannot go from OFF to SUSPENDED */ | 676 | /* Cannot go from OFF to SUSPENDED */ |
677 | if (core->mode == WL1273_MODE_RX) | 677 | if (core->mode == WL1273_MODE_RX) |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index e0054e0f410d..b94d66e53d4e 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -207,6 +207,15 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) | |||
207 | unsigned long time_left; | 207 | unsigned long time_left; |
208 | bool timed_out = false; | 208 | bool timed_out = false; |
209 | 209 | ||
210 | retval = si470x_get_register(radio, POWERCFG); | ||
211 | if (retval) | ||
212 | return retval; | ||
213 | |||
214 | if ((radio->registers[POWERCFG] & (POWERCFG_ENABLE|POWERCFG_DMUTE)) | ||
215 | != (POWERCFG_ENABLE|POWERCFG_DMUTE)) { | ||
216 | return 0; | ||
217 | } | ||
218 | |||
210 | /* start tuning */ | 219 | /* start tuning */ |
211 | radio->registers[CHANNEL] &= ~CHANNEL_CHAN; | 220 | radio->registers[CHANNEL] &= ~CHANNEL_CHAN; |
212 | radio->registers[CHANNEL] |= CHANNEL_TUNE | chan; | 221 | radio->registers[CHANNEL] |= CHANNEL_TUNE | chan; |
@@ -377,8 +386,12 @@ int si470x_start(struct si470x_device *radio) | |||
377 | goto done; | 386 | goto done; |
378 | 387 | ||
379 | /* sysconfig 1 */ | 388 | /* sysconfig 1 */ |
380 | radio->registers[SYSCONFIG1] = | 389 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN | SYSCONFIG1_STCIEN | |
381 | (de << 11) & SYSCONFIG1_DE; /* DE*/ | 390 | SYSCONFIG1_RDS; |
391 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2; | ||
392 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_GPIO2_INT; | ||
393 | if (de) | ||
394 | radio->registers[SYSCONFIG1] |= SYSCONFIG1_DE; | ||
382 | retval = si470x_set_register(radio, SYSCONFIG1); | 395 | retval = si470x_set_register(radio, SYSCONFIG1); |
383 | if (retval < 0) | 396 | if (retval < 0) |
384 | goto done; | 397 | goto done; |
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index b3034f80163f..41709b24b28f 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -43,7 +43,6 @@ static const struct i2c_device_id si470x_i2c_id[] = { | |||
43 | MODULE_DEVICE_TABLE(i2c, si470x_i2c_id); | 43 | MODULE_DEVICE_TABLE(i2c, si470x_i2c_id); |
44 | 44 | ||
45 | 45 | ||
46 | |||
47 | /************************************************************************** | 46 | /************************************************************************** |
48 | * Module Parameters | 47 | * Module Parameters |
49 | **************************************************************************/ | 48 | **************************************************************************/ |
@@ -362,22 +361,43 @@ static int si470x_i2c_probe(struct i2c_client *client, | |||
362 | mutex_init(&radio->lock); | 361 | mutex_init(&radio->lock); |
363 | init_completion(&radio->completion); | 362 | init_completion(&radio->completion); |
364 | 363 | ||
364 | retval = v4l2_device_register(&client->dev, &radio->v4l2_dev); | ||
365 | if (retval < 0) { | ||
366 | dev_err(&client->dev, "couldn't register v4l2_device\n"); | ||
367 | goto err_radio; | ||
368 | } | ||
369 | |||
370 | v4l2_ctrl_handler_init(&radio->hdl, 2); | ||
371 | v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops, | ||
372 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); | ||
373 | v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops, | ||
374 | V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15); | ||
375 | if (radio->hdl.error) { | ||
376 | retval = radio->hdl.error; | ||
377 | dev_err(&client->dev, "couldn't register control\n"); | ||
378 | goto err_dev; | ||
379 | } | ||
380 | |||
365 | /* video device initialization */ | 381 | /* video device initialization */ |
366 | radio->videodev = si470x_viddev_template; | 382 | radio->videodev = si470x_viddev_template; |
383 | radio->videodev.ctrl_handler = &radio->hdl; | ||
384 | radio->videodev.lock = &radio->lock; | ||
385 | radio->videodev.v4l2_dev = &radio->v4l2_dev; | ||
386 | radio->videodev.release = video_device_release_empty; | ||
367 | video_set_drvdata(&radio->videodev, radio); | 387 | video_set_drvdata(&radio->videodev, radio); |
368 | 388 | ||
369 | /* power up : need 110ms */ | 389 | /* power up : need 110ms */ |
370 | radio->registers[POWERCFG] = POWERCFG_ENABLE; | 390 | radio->registers[POWERCFG] = POWERCFG_ENABLE; |
371 | if (si470x_set_register(radio, POWERCFG) < 0) { | 391 | if (si470x_set_register(radio, POWERCFG) < 0) { |
372 | retval = -EIO; | 392 | retval = -EIO; |
373 | goto err_radio; | 393 | goto err_ctrl; |
374 | } | 394 | } |
375 | msleep(110); | 395 | msleep(110); |
376 | 396 | ||
377 | /* get device and chip versions */ | 397 | /* get device and chip versions */ |
378 | if (si470x_get_all_registers(radio) < 0) { | 398 | if (si470x_get_all_registers(radio) < 0) { |
379 | retval = -EIO; | 399 | retval = -EIO; |
380 | goto err_radio; | 400 | goto err_ctrl; |
381 | } | 401 | } |
382 | dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", | 402 | dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", |
383 | radio->registers[DEVICEID], radio->registers[SI_CHIPID]); | 403 | radio->registers[DEVICEID], radio->registers[SI_CHIPID]); |
@@ -407,7 +427,7 @@ static int si470x_i2c_probe(struct i2c_client *client, | |||
407 | radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); | 427 | radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); |
408 | if (!radio->buffer) { | 428 | if (!radio->buffer) { |
409 | retval = -EIO; | 429 | retval = -EIO; |
410 | goto err_radio; | 430 | goto err_ctrl; |
411 | } | 431 | } |
412 | 432 | ||
413 | /* rds buffer configuration */ | 433 | /* rds buffer configuration */ |
@@ -437,6 +457,10 @@ err_all: | |||
437 | free_irq(client->irq, radio); | 457 | free_irq(client->irq, radio); |
438 | err_rds: | 458 | err_rds: |
439 | kfree(radio->buffer); | 459 | kfree(radio->buffer); |
460 | err_ctrl: | ||
461 | v4l2_ctrl_handler_free(&radio->hdl); | ||
462 | err_dev: | ||
463 | v4l2_device_unregister(&radio->v4l2_dev); | ||
440 | err_radio: | 464 | err_radio: |
441 | kfree(radio); | 465 | kfree(radio); |
442 | err_initial: | 466 | err_initial: |
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index c311f9951d80..2277e850bb5e 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -578,7 +578,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
578 | struct si470x_device *radio; | 578 | struct si470x_device *radio; |
579 | struct usb_host_interface *iface_desc; | 579 | struct usb_host_interface *iface_desc; |
580 | struct usb_endpoint_descriptor *endpoint; | 580 | struct usb_endpoint_descriptor *endpoint; |
581 | int i, int_end_size, retval = 0; | 581 | int i, int_end_size, retval; |
582 | unsigned char version_warning = 0; | 582 | unsigned char version_warning = 0; |
583 | 583 | ||
584 | /* private data allocation and initialization */ | 584 | /* private data allocation and initialization */ |
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index eb7b834a0ae5..0202f8eb90c4 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h | |||
@@ -79,6 +79,8 @@ | |||
79 | #define SYSCONFIG1_BLNDADJ 0x00c0 /* bits 07..06: Stereo/Mono Blend Level Adjustment */ | 79 | #define SYSCONFIG1_BLNDADJ 0x00c0 /* bits 07..06: Stereo/Mono Blend Level Adjustment */ |
80 | #define SYSCONFIG1_GPIO3 0x0030 /* bits 05..04: General Purpose I/O 3 */ | 80 | #define SYSCONFIG1_GPIO3 0x0030 /* bits 05..04: General Purpose I/O 3 */ |
81 | #define SYSCONFIG1_GPIO2 0x000c /* bits 03..02: General Purpose I/O 2 */ | 81 | #define SYSCONFIG1_GPIO2 0x000c /* bits 03..02: General Purpose I/O 2 */ |
82 | #define SYSCONFIG1_GPIO2_DIS 0x0000 /* Disable GPIO 2 interrupt */ | ||
83 | #define SYSCONFIG1_GPIO2_INT 0x0004 /* Enable STC/RDS interrupt */ | ||
82 | #define SYSCONFIG1_GPIO1 0x0003 /* bits 01..00: General Purpose I/O 1 */ | 84 | #define SYSCONFIG1_GPIO1 0x0003 /* bits 01..00: General Purpose I/O 1 */ |
83 | 85 | ||
84 | #define SYSCONFIG2 5 /* System Configuration 2 */ | 86 | #define SYSCONFIG2 5 /* System Configuration 2 */ |
diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c index a115db24667b..05c66701a899 100644 --- a/drivers/media/radio/si4713/radio-usb-si4713.c +++ b/drivers/media/radio/si4713/radio-usb-si4713.c | |||
@@ -1,19 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. | 3 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. |
3 | * All rights reserved. | 4 | * All rights reserved. |
4 | * | ||
5 | * This program is free software; you may redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; version 2 of the License. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
10 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
11 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
12 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
13 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
15 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
16 | * SOFTWARE. | ||
17 | */ | 5 | */ |
18 | 6 | ||
19 | /* kernel includes */ | 7 | /* kernel includes */ |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index f14ead5954e0..eb2c3b6eca7f 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -28,14 +28,12 @@ config LIRC | |||
28 | menuconfig RC_DECODERS | 28 | menuconfig RC_DECODERS |
29 | bool "Remote controller decoders" | 29 | bool "Remote controller decoders" |
30 | depends on RC_CORE | 30 | depends on RC_CORE |
31 | default y | ||
32 | 31 | ||
33 | if RC_DECODERS | 32 | if RC_DECODERS |
34 | config IR_NEC_DECODER | 33 | config IR_NEC_DECODER |
35 | tristate "Enable IR raw decoder for the NEC protocol" | 34 | tristate "Enable IR raw decoder for the NEC protocol" |
36 | depends on RC_CORE | 35 | depends on RC_CORE |
37 | select BITREVERSE | 36 | select BITREVERSE |
38 | default y | ||
39 | 37 | ||
40 | ---help--- | 38 | ---help--- |
41 | Enable this option if you have IR with NEC protocol, and | 39 | Enable this option if you have IR with NEC protocol, and |
@@ -45,7 +43,6 @@ config IR_RC5_DECODER | |||
45 | tristate "Enable IR raw decoder for the RC-5 protocol" | 43 | tristate "Enable IR raw decoder for the RC-5 protocol" |
46 | depends on RC_CORE | 44 | depends on RC_CORE |
47 | select BITREVERSE | 45 | select BITREVERSE |
48 | default y | ||
49 | 46 | ||
50 | ---help--- | 47 | ---help--- |
51 | Enable this option if you have IR with RC-5 protocol, and | 48 | Enable this option if you have IR with RC-5 protocol, and |
@@ -55,7 +52,6 @@ config IR_RC6_DECODER | |||
55 | tristate "Enable IR raw decoder for the RC6 protocol" | 52 | tristate "Enable IR raw decoder for the RC6 protocol" |
56 | depends on RC_CORE | 53 | depends on RC_CORE |
57 | select BITREVERSE | 54 | select BITREVERSE |
58 | default y | ||
59 | 55 | ||
60 | ---help--- | 56 | ---help--- |
61 | Enable this option if you have an infrared remote control which | 57 | Enable this option if you have an infrared remote control which |
@@ -65,7 +61,6 @@ config IR_JVC_DECODER | |||
65 | tristate "Enable IR raw decoder for the JVC protocol" | 61 | tristate "Enable IR raw decoder for the JVC protocol" |
66 | depends on RC_CORE | 62 | depends on RC_CORE |
67 | select BITREVERSE | 63 | select BITREVERSE |
68 | default y | ||
69 | 64 | ||
70 | ---help--- | 65 | ---help--- |
71 | Enable this option if you have an infrared remote control which | 66 | Enable this option if you have an infrared remote control which |
@@ -75,7 +70,6 @@ config IR_SONY_DECODER | |||
75 | tristate "Enable IR raw decoder for the Sony protocol" | 70 | tristate "Enable IR raw decoder for the Sony protocol" |
76 | depends on RC_CORE | 71 | depends on RC_CORE |
77 | select BITREVERSE | 72 | select BITREVERSE |
78 | default y | ||
79 | 73 | ||
80 | ---help--- | 74 | ---help--- |
81 | Enable this option if you have an infrared remote control which | 75 | Enable this option if you have an infrared remote control which |
@@ -84,7 +78,6 @@ config IR_SONY_DECODER | |||
84 | config IR_SANYO_DECODER | 78 | config IR_SANYO_DECODER |
85 | tristate "Enable IR raw decoder for the Sanyo protocol" | 79 | tristate "Enable IR raw decoder for the Sanyo protocol" |
86 | depends on RC_CORE | 80 | depends on RC_CORE |
87 | default y | ||
88 | 81 | ||
89 | ---help--- | 82 | ---help--- |
90 | Enable this option if you have an infrared remote control which | 83 | Enable this option if you have an infrared remote control which |
@@ -94,7 +87,6 @@ config IR_SANYO_DECODER | |||
94 | config IR_SHARP_DECODER | 87 | config IR_SHARP_DECODER |
95 | tristate "Enable IR raw decoder for the Sharp protocol" | 88 | tristate "Enable IR raw decoder for the Sharp protocol" |
96 | depends on RC_CORE | 89 | depends on RC_CORE |
97 | default y | ||
98 | 90 | ||
99 | ---help--- | 91 | ---help--- |
100 | Enable this option if you have an infrared remote control which | 92 | Enable this option if you have an infrared remote control which |
@@ -105,7 +97,6 @@ config IR_MCE_KBD_DECODER | |||
105 | tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" | 97 | tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol" |
106 | depends on RC_CORE | 98 | depends on RC_CORE |
107 | select BITREVERSE | 99 | select BITREVERSE |
108 | default y | ||
109 | 100 | ||
110 | ---help--- | 101 | ---help--- |
111 | Enable this option if you have a Microsoft Remote Keyboard for | 102 | Enable this option if you have a Microsoft Remote Keyboard for |
@@ -116,11 +107,19 @@ config IR_XMP_DECODER | |||
116 | tristate "Enable IR raw decoder for the XMP protocol" | 107 | tristate "Enable IR raw decoder for the XMP protocol" |
117 | depends on RC_CORE | 108 | depends on RC_CORE |
118 | select BITREVERSE | 109 | select BITREVERSE |
119 | default y | ||
120 | 110 | ||
121 | ---help--- | 111 | ---help--- |
122 | Enable this option if you have IR with XMP protocol, and | 112 | Enable this option if you have IR with XMP protocol, and |
123 | if the IR is decoded in software | 113 | if the IR is decoded in software |
114 | |||
115 | config IR_IMON_DECODER | ||
116 | tristate "Enable IR raw decoder for the iMON protocol" | ||
117 | depends on RC_CORE | ||
118 | ---help--- | ||
119 | Enable this option if you have iMON PAD or Antec Veris infrared | ||
120 | remote control and you would like to use it with a raw IR | ||
121 | receiver, or if you wish to use an encoder to transmit this IR. | ||
122 | |||
124 | endif #RC_DECODERS | 123 | endif #RC_DECODERS |
125 | 124 | ||
126 | menuconfig RC_DEVICES | 125 | menuconfig RC_DEVICES |
@@ -185,6 +184,18 @@ config IR_IMON | |||
185 | To compile this driver as a module, choose M here: the | 184 | To compile this driver as a module, choose M here: the |
186 | module will be called imon. | 185 | module will be called imon. |
187 | 186 | ||
187 | config IR_IMON_RAW | ||
188 | tristate "SoundGraph iMON Receiver (early raw IR models)" | ||
189 | depends on USB_ARCH_HAS_HCD | ||
190 | depends on RC_CORE | ||
191 | select USB | ||
192 | ---help--- | ||
193 | Say Y here if you want to use a SoundGraph iMON IR Receiver, | ||
194 | early raw models. | ||
195 | |||
196 | To compile this driver as a module, choose M here: the | ||
197 | module will be called imon_raw. | ||
198 | |||
188 | config IR_MCEUSB | 199 | config IR_MCEUSB |
189 | tristate "Windows Media Center Ed. eHome Infrared Transceiver" | 200 | tristate "Windows Media Center Ed. eHome Infrared Transceiver" |
190 | depends on USB_ARCH_HAS_HCD | 201 | depends on USB_ARCH_HAS_HCD |
@@ -446,7 +457,6 @@ config IR_SERIAL | |||
446 | 457 | ||
447 | config IR_SERIAL_TRANSMITTER | 458 | config IR_SERIAL_TRANSMITTER |
448 | bool "Serial Port Transmitter" | 459 | bool "Serial Port Transmitter" |
449 | default y | ||
450 | depends on IR_SERIAL | 460 | depends on IR_SERIAL |
451 | ---help--- | 461 | ---help--- |
452 | Serial Port Transmitter support | 462 | Serial Port Transmitter support |
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 0e857816ac2d..2e1c87066f6c 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile | |||
@@ -14,11 +14,13 @@ obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o | |||
14 | obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o | 14 | obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o |
15 | obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o | 15 | obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o |
16 | obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o | 16 | obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o |
17 | obj-$(CONFIG_IR_IMON_DECODER) += ir-imon-decoder.o | ||
17 | 18 | ||
18 | # stand-alone IR receivers/transmitters | 19 | # stand-alone IR receivers/transmitters |
19 | obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o | 20 | obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o |
20 | obj-$(CONFIG_IR_HIX5HD2) += ir-hix5hd2.o | 21 | obj-$(CONFIG_IR_HIX5HD2) += ir-hix5hd2.o |
21 | obj-$(CONFIG_IR_IMON) += imon.o | 22 | obj-$(CONFIG_IR_IMON) += imon.o |
23 | obj-$(CONFIG_IR_IMON_RAW) += imon_raw.o | ||
22 | obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o | 24 | obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o |
23 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o | 25 | obj-$(CONFIG_IR_MCEUSB) += mceusb.o |
24 | obj-$(CONFIG_IR_FINTEK) += fintek-cir.o | 26 | obj-$(CONFIG_IR_FINTEK) += fintek-cir.o |
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 950d068ba806..1041c056854d 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c | |||
@@ -92,7 +92,6 @@ struct imon_usb_dev_descr { | |||
92 | __u16 flags; | 92 | __u16 flags; |
93 | #define IMON_NO_FLAGS 0 | 93 | #define IMON_NO_FLAGS 0 |
94 | #define IMON_NEED_20MS_PKT_DELAY 1 | 94 | #define IMON_NEED_20MS_PKT_DELAY 1 |
95 | #define IMON_IR_RAW 2 | ||
96 | struct imon_panel_key_table key_table[]; | 95 | struct imon_panel_key_table key_table[]; |
97 | }; | 96 | }; |
98 | 97 | ||
@@ -123,12 +122,6 @@ struct imon_context { | |||
123 | unsigned char usb_tx_buf[8]; | 122 | unsigned char usb_tx_buf[8]; |
124 | unsigned int send_packet_delay; | 123 | unsigned int send_packet_delay; |
125 | 124 | ||
126 | struct rx_data { | ||
127 | int count; /* length of 0 or 1 sequence */ | ||
128 | int prev_bit; /* logic level of sequence */ | ||
129 | int initial_space; /* initial space flag */ | ||
130 | } rx; | ||
131 | |||
132 | struct tx_t { | 125 | struct tx_t { |
133 | unsigned char data_buf[35]; /* user data buffer */ | 126 | unsigned char data_buf[35]; /* user data buffer */ |
134 | struct completion finished; /* wait for write to finish */ | 127 | struct completion finished; /* wait for write to finish */ |
@@ -331,10 +324,6 @@ static const struct imon_usb_dev_descr imon_DH102 = { | |||
331 | } | 324 | } |
332 | }; | 325 | }; |
333 | 326 | ||
334 | static const struct imon_usb_dev_descr imon_ir_raw = { | ||
335 | .flags = IMON_IR_RAW, | ||
336 | }; | ||
337 | |||
338 | /* | 327 | /* |
339 | * USB Device ID for iMON USB Control Boards | 328 | * USB Device ID for iMON USB Control Boards |
340 | * | 329 | * |
@@ -418,18 +407,6 @@ static const struct usb_device_id imon_usb_id_table[] = { | |||
418 | /* device specifics unknown */ | 407 | /* device specifics unknown */ |
419 | { USB_DEVICE(0x15c2, 0x0046), | 408 | { USB_DEVICE(0x15c2, 0x0046), |
420 | .driver_info = (unsigned long)&imon_default_table}, | 409 | .driver_info = (unsigned long)&imon_default_table}, |
421 | /* TriGem iMON (IR only) -- TG_iMON.inf */ | ||
422 | { USB_DEVICE(0x0aa8, 0x8001), | ||
423 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
424 | /* SoundGraph iMON (IR only) -- sg_imon.inf */ | ||
425 | { USB_DEVICE(0x04e8, 0xff30), | ||
426 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
427 | /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */ | ||
428 | { USB_DEVICE(0x0aa8, 0xffda), | ||
429 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
430 | /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */ | ||
431 | { USB_DEVICE(0x15c2, 0xffda), | ||
432 | .driver_info = (unsigned long)&imon_ir_raw}, | ||
433 | {} | 410 | {} |
434 | }; | 411 | }; |
435 | 412 | ||
@@ -1133,18 +1110,18 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) | |||
1133 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); | 1110 | dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); |
1134 | ir_proto_packet[0] = 0x01; | 1111 | ir_proto_packet[0] = 0x01; |
1135 | *rc_proto = RC_PROTO_BIT_RC6_MCE; | 1112 | *rc_proto = RC_PROTO_BIT_RC6_MCE; |
1136 | } else if (*rc_proto & RC_PROTO_BIT_OTHER) { | 1113 | } else if (*rc_proto & RC_PROTO_BIT_IMON) { |
1137 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); | 1114 | dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); |
1138 | if (!pad_stabilize) | 1115 | if (!pad_stabilize) |
1139 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); | 1116 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); |
1140 | /* ir_proto_packet[0] = 0x00; // already the default */ | 1117 | /* ir_proto_packet[0] = 0x00; // already the default */ |
1141 | *rc_proto = RC_PROTO_BIT_OTHER; | 1118 | *rc_proto = RC_PROTO_BIT_IMON; |
1142 | } else { | 1119 | } else { |
1143 | dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); | 1120 | dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n"); |
1144 | if (!pad_stabilize) | 1121 | if (!pad_stabilize) |
1145 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); | 1122 | dev_dbg(dev, "PAD stabilize functionality disabled\n"); |
1146 | /* ir_proto_packet[0] = 0x00; // already the default */ | 1123 | /* ir_proto_packet[0] = 0x00; // already the default */ |
1147 | *rc_proto = RC_PROTO_BIT_OTHER; | 1124 | *rc_proto = RC_PROTO_BIT_IMON; |
1148 | } | 1125 | } |
1149 | 1126 | ||
1150 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); | 1127 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); |
@@ -1411,7 +1388,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1411 | rel_x = buf[2]; | 1388 | rel_x = buf[2]; |
1412 | rel_y = buf[3]; | 1389 | rel_y = buf[3]; |
1413 | 1390 | ||
1414 | if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { | 1391 | if (ictx->rc_proto == RC_PROTO_BIT_IMON && pad_stabilize) { |
1415 | if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { | 1392 | if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { |
1416 | dir = stabilize((int)rel_x, (int)rel_y, | 1393 | dir = stabilize((int)rel_x, (int)rel_y, |
1417 | timeout, threshold); | 1394 | timeout, threshold); |
@@ -1478,7 +1455,7 @@ static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) | |||
1478 | buf[0] = 0x01; | 1455 | buf[0] = 0x01; |
1479 | buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; | 1456 | buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; |
1480 | 1457 | ||
1481 | if (ictx->rc_proto == RC_PROTO_BIT_OTHER && pad_stabilize) { | 1458 | if (ictx->rc_proto == RC_PROTO_BIT_IMON && pad_stabilize) { |
1482 | dir = stabilize((int)rel_x, (int)rel_y, | 1459 | dir = stabilize((int)rel_x, (int)rel_y, |
1483 | timeout, threshold); | 1460 | timeout, threshold); |
1484 | if (!dir) { | 1461 | if (!dir) { |
@@ -1572,94 +1549,11 @@ static int imon_parse_press_type(struct imon_context *ictx, | |||
1572 | /* | 1549 | /* |
1573 | * Process the incoming packet | 1550 | * Process the incoming packet |
1574 | */ | 1551 | */ |
1575 | /* | 1552 | static void imon_incoming_packet(struct imon_context *ictx, |
1576 | * Convert bit count to time duration (in us) and submit | ||
1577 | * the value to lirc_dev. | ||
1578 | */ | ||
1579 | static void submit_data(struct imon_context *context) | ||
1580 | { | ||
1581 | DEFINE_IR_RAW_EVENT(ev); | ||
1582 | |||
1583 | ev.pulse = context->rx.prev_bit; | ||
1584 | ev.duration = US_TO_NS(context->rx.count * BIT_DURATION); | ||
1585 | ir_raw_event_store_with_filter(context->rdev, &ev); | ||
1586 | } | ||
1587 | |||
1588 | /* | ||
1589 | * Process the incoming packet | ||
1590 | */ | ||
1591 | static void imon_incoming_ir_raw(struct imon_context *context, | ||
1592 | struct urb *urb, int intf) | 1553 | struct urb *urb, int intf) |
1593 | { | 1554 | { |
1594 | int len = urb->actual_length; | 1555 | int len = urb->actual_length; |
1595 | unsigned char *buf = urb->transfer_buffer; | 1556 | unsigned char *buf = urb->transfer_buffer; |
1596 | struct device *dev = context->dev; | ||
1597 | int octet, bit; | ||
1598 | unsigned char mask; | ||
1599 | |||
1600 | if (len != 8) { | ||
1601 | dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n", | ||
1602 | __func__, len, intf); | ||
1603 | return; | ||
1604 | } | ||
1605 | |||
1606 | if (debug) | ||
1607 | dev_info(dev, "raw packet: %*ph\n", len, buf); | ||
1608 | /* | ||
1609 | * Translate received data to pulse and space lengths. | ||
1610 | * Received data is active low, i.e. pulses are 0 and | ||
1611 | * spaces are 1. | ||
1612 | * | ||
1613 | * My original algorithm was essentially similar to | ||
1614 | * Changwoo Ryu's with the exception that he switched | ||
1615 | * the incoming bits to active high and also fed an | ||
1616 | * initial space to LIRC at the start of a new sequence | ||
1617 | * if the previous bit was a pulse. | ||
1618 | * | ||
1619 | * I've decided to adopt his algorithm. | ||
1620 | */ | ||
1621 | |||
1622 | if (buf[7] == 1 && context->rx.initial_space) { | ||
1623 | /* LIRC requires a leading space */ | ||
1624 | context->rx.prev_bit = 0; | ||
1625 | context->rx.count = 4; | ||
1626 | submit_data(context); | ||
1627 | context->rx.count = 0; | ||
1628 | } | ||
1629 | |||
1630 | for (octet = 0; octet < 5; ++octet) { | ||
1631 | mask = 0x80; | ||
1632 | for (bit = 0; bit < 8; ++bit) { | ||
1633 | int curr_bit = !(buf[octet] & mask); | ||
1634 | |||
1635 | if (curr_bit != context->rx.prev_bit) { | ||
1636 | if (context->rx.count) { | ||
1637 | submit_data(context); | ||
1638 | context->rx.count = 0; | ||
1639 | } | ||
1640 | context->rx.prev_bit = curr_bit; | ||
1641 | } | ||
1642 | ++context->rx.count; | ||
1643 | mask >>= 1; | ||
1644 | } | ||
1645 | } | ||
1646 | |||
1647 | if (buf[7] == 10) { | ||
1648 | if (context->rx.count) { | ||
1649 | submit_data(context); | ||
1650 | context->rx.count = 0; | ||
1651 | } | ||
1652 | context->rx.initial_space = context->rx.prev_bit; | ||
1653 | } | ||
1654 | |||
1655 | ir_raw_event_handle(context->rdev); | ||
1656 | } | ||
1657 | |||
1658 | static void imon_incoming_scancode(struct imon_context *ictx, | ||
1659 | struct urb *urb, int intf) | ||
1660 | { | ||
1661 | int len = urb->actual_length; | ||
1662 | unsigned char *buf = urb->transfer_buffer; | ||
1663 | struct device *dev = ictx->dev; | 1557 | struct device *dev = ictx->dev; |
1664 | unsigned long flags; | 1558 | unsigned long flags; |
1665 | u32 kc; | 1559 | u32 kc; |
@@ -1745,11 +1639,18 @@ static void imon_incoming_scancode(struct imon_context *ictx, | |||
1745 | if (press_type == 0) | 1639 | if (press_type == 0) |
1746 | rc_keyup(ictx->rdev); | 1640 | rc_keyup(ictx->rdev); |
1747 | else { | 1641 | else { |
1748 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || | 1642 | enum rc_proto proto; |
1749 | ictx->rc_proto == RC_PROTO_BIT_OTHER) | 1643 | |
1750 | rc_keydown(ictx->rdev, | 1644 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) |
1751 | ictx->rc_proto == RC_PROTO_BIT_RC6_MCE ? RC_PROTO_RC6_MCE : RC_PROTO_OTHER, | 1645 | proto = RC_PROTO_RC6_MCE; |
1752 | ictx->rc_scancode, ictx->rc_toggle); | 1646 | else if (ictx->rc_proto == RC_PROTO_BIT_IMON) |
1647 | proto = RC_PROTO_IMON; | ||
1648 | else | ||
1649 | return; | ||
1650 | |||
1651 | rc_keydown(ictx->rdev, proto, ictx->rc_scancode, | ||
1652 | ictx->rc_toggle); | ||
1653 | |||
1753 | spin_lock_irqsave(&ictx->kc_lock, flags); | 1654 | spin_lock_irqsave(&ictx->kc_lock, flags); |
1754 | ictx->last_keycode = ictx->kc; | 1655 | ictx->last_keycode = ictx->kc; |
1755 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | 1656 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
@@ -1839,10 +1740,7 @@ static void usb_rx_callback_intf0(struct urb *urb) | |||
1839 | break; | 1740 | break; |
1840 | 1741 | ||
1841 | case 0: | 1742 | case 0: |
1842 | if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW) | 1743 | imon_incoming_packet(ictx, urb, intfnum); |
1843 | imon_incoming_ir_raw(ictx, urb, intfnum); | ||
1844 | else | ||
1845 | imon_incoming_scancode(ictx, urb, intfnum); | ||
1846 | break; | 1744 | break; |
1847 | 1745 | ||
1848 | default: | 1746 | default: |
@@ -1883,10 +1781,7 @@ static void usb_rx_callback_intf1(struct urb *urb) | |||
1883 | break; | 1781 | break; |
1884 | 1782 | ||
1885 | case 0: | 1783 | case 0: |
1886 | if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW) | 1784 | imon_incoming_packet(ictx, urb, intfnum); |
1887 | imon_incoming_ir_raw(ictx, urb, intfnum); | ||
1888 | else | ||
1889 | imon_incoming_scancode(ictx, urb, intfnum); | ||
1890 | break; | 1785 | break; |
1891 | 1786 | ||
1892 | default: | 1787 | default: |
@@ -1912,7 +1807,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1912 | { | 1807 | { |
1913 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; | 1808 | u8 ffdc_cfg_byte = ictx->usb_rx_buf[6]; |
1914 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; | 1809 | u8 detected_display_type = IMON_DISPLAY_TYPE_NONE; |
1915 | u64 allowed_protos = RC_PROTO_BIT_OTHER; | 1810 | u64 allowed_protos = RC_PROTO_BIT_IMON; |
1916 | 1811 | ||
1917 | switch (ffdc_cfg_byte) { | 1812 | switch (ffdc_cfg_byte) { |
1918 | /* iMON Knob, no display, iMON IR + vol knob */ | 1813 | /* iMON Knob, no display, iMON IR + vol knob */ |
@@ -1960,8 +1855,10 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1960 | default: | 1855 | default: |
1961 | dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); | 1856 | dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR"); |
1962 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1857 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
1963 | /* We don't know which one it is, allow user to set the | 1858 | /* |
1964 | * RC6 one from userspace if OTHER wasn't correct. */ | 1859 | * We don't know which one it is, allow user to set the |
1860 | * RC6 one from userspace if IMON wasn't correct. | ||
1861 | */ | ||
1965 | allowed_protos |= RC_PROTO_BIT_RC6_MCE; | 1862 | allowed_protos |= RC_PROTO_BIT_RC6_MCE; |
1966 | break; | 1863 | break; |
1967 | } | 1864 | } |
@@ -2000,14 +1897,11 @@ static void imon_set_display_type(struct imon_context *ictx) | |||
2000 | case 0x0041: | 1897 | case 0x0041: |
2001 | case 0x0042: | 1898 | case 0x0042: |
2002 | case 0x0043: | 1899 | case 0x0043: |
2003 | case 0x8001: | ||
2004 | case 0xff30: | ||
2005 | configured_display_type = IMON_DISPLAY_TYPE_NONE; | 1900 | configured_display_type = IMON_DISPLAY_TYPE_NONE; |
2006 | ictx->display_supported = false; | 1901 | ictx->display_supported = false; |
2007 | break; | 1902 | break; |
2008 | case 0x0036: | 1903 | case 0x0036: |
2009 | case 0x0044: | 1904 | case 0x0044: |
2010 | case 0xffda: | ||
2011 | default: | 1905 | default: |
2012 | configured_display_type = IMON_DISPLAY_TYPE_VFD; | 1906 | configured_display_type = IMON_DISPLAY_TYPE_VFD; |
2013 | break; | 1907 | break; |
@@ -2032,8 +1926,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) | |||
2032 | static const unsigned char fp_packet[] = { | 1926 | static const unsigned char fp_packet[] = { |
2033 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 }; | 1927 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 }; |
2034 | 1928 | ||
2035 | rdev = rc_allocate_device(ictx->dev_descr->flags & IMON_IR_RAW ? | 1929 | rdev = rc_allocate_device(RC_DRIVER_SCANCODE); |
2036 | RC_DRIVER_IR_RAW : RC_DRIVER_SCANCODE); | ||
2037 | if (!rdev) { | 1930 | if (!rdev) { |
2038 | dev_err(ictx->dev, "remote control dev allocation failed\n"); | 1931 | dev_err(ictx->dev, "remote control dev allocation failed\n"); |
2039 | goto out; | 1932 | goto out; |
@@ -2051,12 +1944,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) | |||
2051 | rdev->dev.parent = ictx->dev; | 1944 | rdev->dev.parent = ictx->dev; |
2052 | 1945 | ||
2053 | rdev->priv = ictx; | 1946 | rdev->priv = ictx; |
2054 | if (ictx->dev_descr->flags & IMON_IR_RAW) | 1947 | /* iMON PAD or MCE */ |
2055 | rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; | 1948 | rdev->allowed_protocols = RC_PROTO_BIT_IMON | RC_PROTO_BIT_RC6_MCE; |
2056 | else | ||
2057 | /* iMON PAD or MCE */ | ||
2058 | rdev->allowed_protocols = RC_PROTO_BIT_OTHER | | ||
2059 | RC_PROTO_BIT_RC6_MCE; | ||
2060 | rdev->change_protocol = imon_ir_change_protocol; | 1949 | rdev->change_protocol = imon_ir_change_protocol; |
2061 | rdev->driver_name = MOD_NAME; | 1950 | rdev->driver_name = MOD_NAME; |
2062 | 1951 | ||
@@ -2074,8 +1963,7 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) | |||
2074 | 1963 | ||
2075 | imon_set_display_type(ictx); | 1964 | imon_set_display_type(ictx); |
2076 | 1965 | ||
2077 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE || | 1966 | if (ictx->rc_proto == RC_PROTO_BIT_RC6_MCE) |
2078 | ictx->dev_descr->flags & IMON_IR_RAW) | ||
2079 | rdev->map_name = RC_MAP_IMON_MCE; | 1967 | rdev->map_name = RC_MAP_IMON_MCE; |
2080 | else | 1968 | else |
2081 | rdev->map_name = RC_MAP_IMON_PAD; | 1969 | rdev->map_name = RC_MAP_IMON_PAD; |
diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c new file mode 100644 index 000000000000..32709f96de14 --- /dev/null +++ b/drivers/media/rc/imon_raw.c | |||
@@ -0,0 +1,199 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | // | ||
3 | // Copyright (C) 2018 Sean Young <sean@mess.org> | ||
4 | |||
5 | #include <linux/module.h> | ||
6 | #include <linux/usb.h> | ||
7 | #include <linux/usb/input.h> | ||
8 | #include <media/rc-core.h> | ||
9 | |||
10 | /* Each bit is 250us */ | ||
11 | #define BIT_DURATION 250000 | ||
12 | |||
13 | struct imon { | ||
14 | struct device *dev; | ||
15 | struct urb *ir_urb; | ||
16 | struct rc_dev *rcdev; | ||
17 | u8 ir_buf[8]; | ||
18 | char phys[64]; | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * ffs/find_next_bit() searches in the wrong direction, so open-code our own. | ||
23 | */ | ||
24 | static inline int is_bit_set(const u8 *buf, int bit) | ||
25 | { | ||
26 | return buf[bit / 8] & (0x80 >> (bit & 7)); | ||
27 | } | ||
28 | |||
29 | static void imon_ir_data(struct imon *imon) | ||
30 | { | ||
31 | DEFINE_IR_RAW_EVENT(rawir); | ||
32 | int offset = 0, size = 5 * 8; | ||
33 | int bit; | ||
34 | |||
35 | dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); | ||
36 | |||
37 | while (offset < size) { | ||
38 | bit = offset; | ||
39 | while (!is_bit_set(imon->ir_buf, bit) && bit < size) | ||
40 | bit++; | ||
41 | dev_dbg(imon->dev, "pulse: %d bits", bit - offset); | ||
42 | if (bit > offset) { | ||
43 | rawir.pulse = true; | ||
44 | rawir.duration = (bit - offset) * BIT_DURATION; | ||
45 | ir_raw_event_store_with_filter(imon->rcdev, &rawir); | ||
46 | } | ||
47 | |||
48 | if (bit >= size) | ||
49 | break; | ||
50 | |||
51 | offset = bit; | ||
52 | while (is_bit_set(imon->ir_buf, bit) && bit < size) | ||
53 | bit++; | ||
54 | dev_dbg(imon->dev, "space: %d bits", bit - offset); | ||
55 | |||
56 | rawir.pulse = false; | ||
57 | rawir.duration = (bit - offset) * BIT_DURATION; | ||
58 | ir_raw_event_store_with_filter(imon->rcdev, &rawir); | ||
59 | |||
60 | offset = bit; | ||
61 | } | ||
62 | |||
63 | if (imon->ir_buf[7] == 0x0a) { | ||
64 | ir_raw_event_set_idle(imon->rcdev, true); | ||
65 | ir_raw_event_handle(imon->rcdev); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | static void imon_ir_rx(struct urb *urb) | ||
70 | { | ||
71 | struct imon *imon = urb->context; | ||
72 | int ret; | ||
73 | |||
74 | switch (urb->status) { | ||
75 | case 0: | ||
76 | if (imon->ir_buf[7] != 0xff) | ||
77 | imon_ir_data(imon); | ||
78 | break; | ||
79 | case -ECONNRESET: | ||
80 | case -ENOENT: | ||
81 | case -ESHUTDOWN: | ||
82 | usb_unlink_urb(urb); | ||
83 | return; | ||
84 | case -EPIPE: | ||
85 | default: | ||
86 | dev_dbg(imon->dev, "error: urb status = %d", urb->status); | ||
87 | break; | ||
88 | } | ||
89 | |||
90 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
91 | if (ret && ret != -ENODEV) | ||
92 | dev_warn(imon->dev, "failed to resubmit urb: %d", ret); | ||
93 | } | ||
94 | |||
95 | static int imon_probe(struct usb_interface *intf, | ||
96 | const struct usb_device_id *id) | ||
97 | { | ||
98 | struct usb_endpoint_descriptor *ir_ep = NULL; | ||
99 | struct usb_host_interface *idesc; | ||
100 | struct usb_device *udev; | ||
101 | struct rc_dev *rcdev; | ||
102 | struct imon *imon; | ||
103 | int i, ret; | ||
104 | |||
105 | udev = interface_to_usbdev(intf); | ||
106 | idesc = intf->cur_altsetting; | ||
107 | |||
108 | for (i = 0; i < idesc->desc.bNumEndpoints; i++) { | ||
109 | struct usb_endpoint_descriptor *ep = &idesc->endpoint[i].desc; | ||
110 | |||
111 | if (usb_endpoint_is_int_in(ep)) { | ||
112 | ir_ep = ep; | ||
113 | break; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | if (!ir_ep) { | ||
118 | dev_err(&intf->dev, "IR endpoint missing"); | ||
119 | return -ENODEV; | ||
120 | } | ||
121 | |||
122 | imon = devm_kmalloc(&intf->dev, sizeof(*imon), GFP_KERNEL); | ||
123 | if (!imon) | ||
124 | return -ENOMEM; | ||
125 | |||
126 | imon->ir_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
127 | if (!imon->ir_urb) | ||
128 | return -ENOMEM; | ||
129 | |||
130 | imon->dev = &intf->dev; | ||
131 | usb_fill_int_urb(imon->ir_urb, udev, | ||
132 | usb_rcvintpipe(udev, ir_ep->bEndpointAddress), | ||
133 | imon->ir_buf, sizeof(imon->ir_buf), | ||
134 | imon_ir_rx, imon, ir_ep->bInterval); | ||
135 | |||
136 | rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_IR_RAW); | ||
137 | if (!rcdev) { | ||
138 | ret = -ENOMEM; | ||
139 | goto free_urb; | ||
140 | } | ||
141 | |||
142 | usb_make_path(udev, imon->phys, sizeof(imon->phys)); | ||
143 | |||
144 | rcdev->device_name = "iMON Station"; | ||
145 | rcdev->driver_name = KBUILD_MODNAME; | ||
146 | rcdev->input_phys = imon->phys; | ||
147 | usb_to_input_id(udev, &rcdev->input_id); | ||
148 | rcdev->dev.parent = &intf->dev; | ||
149 | rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; | ||
150 | rcdev->map_name = RC_MAP_IMON_RSC; | ||
151 | rcdev->rx_resolution = BIT_DURATION; | ||
152 | rcdev->priv = imon; | ||
153 | |||
154 | ret = devm_rc_register_device(&intf->dev, rcdev); | ||
155 | if (ret) | ||
156 | goto free_urb; | ||
157 | |||
158 | imon->rcdev = rcdev; | ||
159 | |||
160 | ret = usb_submit_urb(imon->ir_urb, GFP_KERNEL); | ||
161 | if (ret) | ||
162 | goto free_urb; | ||
163 | |||
164 | usb_set_intfdata(intf, imon); | ||
165 | |||
166 | return 0; | ||
167 | |||
168 | free_urb: | ||
169 | usb_free_urb(imon->ir_urb); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static void imon_disconnect(struct usb_interface *intf) | ||
174 | { | ||
175 | struct imon *imon = usb_get_intfdata(intf); | ||
176 | |||
177 | usb_kill_urb(imon->ir_urb); | ||
178 | usb_free_urb(imon->ir_urb); | ||
179 | } | ||
180 | |||
181 | static const struct usb_device_id imon_table[] = { | ||
182 | /* SoundGraph iMON (IR only) -- sg_imon.inf */ | ||
183 | { USB_DEVICE(0x04e8, 0xff30) }, | ||
184 | {} | ||
185 | }; | ||
186 | |||
187 | static struct usb_driver imon_driver = { | ||
188 | .name = KBUILD_MODNAME, | ||
189 | .probe = imon_probe, | ||
190 | .disconnect = imon_disconnect, | ||
191 | .id_table = imon_table | ||
192 | }; | ||
193 | |||
194 | module_usb_driver(imon_driver); | ||
195 | |||
196 | MODULE_DESCRIPTION("Early raw iMON IR devices"); | ||
197 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
198 | MODULE_LICENSE("GPL"); | ||
199 | MODULE_DEVICE_TABLE(usb, imon_table); | ||
diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index 0ce11c41dfae..700ab4c563d0 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c | |||
@@ -71,9 +71,10 @@ struct hix5hd2_ir_priv { | |||
71 | unsigned long rate; | 71 | unsigned long rate; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static void hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on) | 74 | static int hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on) |
75 | { | 75 | { |
76 | u32 val; | 76 | u32 val; |
77 | int ret = 0; | ||
77 | 78 | ||
78 | if (dev->regmap) { | 79 | if (dev->regmap) { |
79 | regmap_read(dev->regmap, IR_CLK, &val); | 80 | regmap_read(dev->regmap, IR_CLK, &val); |
@@ -87,10 +88,11 @@ static void hix5hd2_ir_enable(struct hix5hd2_ir_priv *dev, bool on) | |||
87 | regmap_write(dev->regmap, IR_CLK, val); | 88 | regmap_write(dev->regmap, IR_CLK, val); |
88 | } else { | 89 | } else { |
89 | if (on) | 90 | if (on) |
90 | clk_prepare_enable(dev->clock); | 91 | ret = clk_prepare_enable(dev->clock); |
91 | else | 92 | else |
92 | clk_disable_unprepare(dev->clock); | 93 | clk_disable_unprepare(dev->clock); |
93 | } | 94 | } |
95 | return ret; | ||
94 | } | 96 | } |
95 | 97 | ||
96 | static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv) | 98 | static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv) |
@@ -127,9 +129,18 @@ static int hix5hd2_ir_config(struct hix5hd2_ir_priv *priv) | |||
127 | static int hix5hd2_ir_open(struct rc_dev *rdev) | 129 | static int hix5hd2_ir_open(struct rc_dev *rdev) |
128 | { | 130 | { |
129 | struct hix5hd2_ir_priv *priv = rdev->priv; | 131 | struct hix5hd2_ir_priv *priv = rdev->priv; |
132 | int ret; | ||
133 | |||
134 | ret = hix5hd2_ir_enable(priv, true); | ||
135 | if (ret) | ||
136 | return ret; | ||
130 | 137 | ||
131 | hix5hd2_ir_enable(priv, true); | 138 | ret = hix5hd2_ir_config(priv); |
132 | return hix5hd2_ir_config(priv); | 139 | if (ret) { |
140 | hix5hd2_ir_enable(priv, false); | ||
141 | return ret; | ||
142 | } | ||
143 | return 0; | ||
133 | } | 144 | } |
134 | 145 | ||
135 | static void hix5hd2_ir_close(struct rc_dev *rdev) | 146 | static void hix5hd2_ir_close(struct rc_dev *rdev) |
@@ -239,7 +250,9 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) | |||
239 | ret = PTR_ERR(priv->clock); | 250 | ret = PTR_ERR(priv->clock); |
240 | goto err; | 251 | goto err; |
241 | } | 252 | } |
242 | clk_prepare_enable(priv->clock); | 253 | ret = clk_prepare_enable(priv->clock); |
254 | if (ret) | ||
255 | goto err; | ||
243 | priv->rate = clk_get_rate(priv->clock); | 256 | priv->rate = clk_get_rate(priv->clock); |
244 | 257 | ||
245 | rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; | 258 | rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; |
@@ -309,9 +322,17 @@ static int hix5hd2_ir_suspend(struct device *dev) | |||
309 | static int hix5hd2_ir_resume(struct device *dev) | 322 | static int hix5hd2_ir_resume(struct device *dev) |
310 | { | 323 | { |
311 | struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev); | 324 | struct hix5hd2_ir_priv *priv = dev_get_drvdata(dev); |
325 | int ret; | ||
312 | 326 | ||
313 | hix5hd2_ir_enable(priv, true); | 327 | ret = hix5hd2_ir_enable(priv, true); |
314 | clk_prepare_enable(priv->clock); | 328 | if (ret) |
329 | return ret; | ||
330 | |||
331 | ret = clk_prepare_enable(priv->clock); | ||
332 | if (ret) { | ||
333 | hix5hd2_ir_enable(priv, false); | ||
334 | return ret; | ||
335 | } | ||
315 | 336 | ||
316 | writel_relaxed(0x01, priv->base + IR_ENABLE); | 337 | writel_relaxed(0x01, priv->base + IR_ENABLE); |
317 | writel_relaxed(0x00, priv->base + IR_INTM); | 338 | writel_relaxed(0x00, priv->base + IR_INTM); |
diff --git a/drivers/media/rc/ir-imon-decoder.c b/drivers/media/rc/ir-imon-decoder.c new file mode 100644 index 000000000000..a1ff06a26542 --- /dev/null +++ b/drivers/media/rc/ir-imon-decoder.c | |||
@@ -0,0 +1,193 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | // ir-imon-decoder.c - handle iMon protocol | ||
3 | // | ||
4 | // Copyright (C) 2018 by Sean Young <sean@mess.org> | ||
5 | |||
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include "rc-core-priv.h" | ||
10 | |||
11 | #define IMON_UNIT 415662 /* ns */ | ||
12 | #define IMON_BITS 30 | ||
13 | #define IMON_CHKBITS (BIT(30) | BIT(25) | BIT(24) | BIT(22) | \ | ||
14 | BIT(21) | BIT(20) | BIT(19) | BIT(18) | \ | ||
15 | BIT(17) | BIT(16) | BIT(14) | BIT(13) | \ | ||
16 | BIT(12) | BIT(11) | BIT(10) | BIT(9)) | ||
17 | |||
18 | /* | ||
19 | * This protocol has 30 bits. The format is one IMON_UNIT header pulse, | ||
20 | * followed by 30 bits. Each bit is one IMON_UNIT check field, and then | ||
21 | * one IMON_UNIT field with the actual bit (1=space, 0=pulse). | ||
22 | * The check field is always space for some bits, for others it is pulse if | ||
23 | * both the preceding and current bit are zero, else space. IMON_CHKBITS | ||
24 | * defines which bits are of type check. | ||
25 | * | ||
26 | * There is no way to distinguish an incomplete message from one where | ||
27 | * the lower bits are all set, iow. the last pulse is for the lowest | ||
28 | * bit which is 0. | ||
29 | */ | ||
30 | enum imon_state { | ||
31 | STATE_INACTIVE, | ||
32 | STATE_BIT_CHK, | ||
33 | STATE_BIT_START, | ||
34 | STATE_FINISHED | ||
35 | }; | ||
36 | |||
37 | /** | ||
38 | * ir_imon_decode() - Decode one iMON pulse or space | ||
39 | * @dev: the struct rc_dev descriptor of the device | ||
40 | * @ev: the struct ir_raw_event descriptor of the pulse/space | ||
41 | * | ||
42 | * This function returns -EINVAL if the pulse violates the state machine | ||
43 | */ | ||
44 | static int ir_imon_decode(struct rc_dev *dev, struct ir_raw_event ev) | ||
45 | { | ||
46 | struct imon_dec *data = &dev->raw->imon; | ||
47 | |||
48 | if (!is_timing_event(ev)) { | ||
49 | if (ev.reset) | ||
50 | data->state = STATE_INACTIVE; | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | dev_dbg(&dev->dev, | ||
55 | "iMON decode started at state %d bitno %d (%uus %s)\n", | ||
56 | data->state, data->count, TO_US(ev.duration), | ||
57 | TO_STR(ev.pulse)); | ||
58 | |||
59 | for (;;) { | ||
60 | if (!geq_margin(ev.duration, IMON_UNIT, IMON_UNIT / 2)) | ||
61 | return 0; | ||
62 | |||
63 | decrease_duration(&ev, IMON_UNIT); | ||
64 | |||
65 | switch (data->state) { | ||
66 | case STATE_INACTIVE: | ||
67 | if (ev.pulse) { | ||
68 | data->state = STATE_BIT_CHK; | ||
69 | data->bits = 0; | ||
70 | data->count = IMON_BITS; | ||
71 | } | ||
72 | break; | ||
73 | case STATE_BIT_CHK: | ||
74 | if (IMON_CHKBITS & BIT(data->count)) | ||
75 | data->last_chk = ev.pulse; | ||
76 | else if (ev.pulse) | ||
77 | goto err_out; | ||
78 | data->state = STATE_BIT_START; | ||
79 | break; | ||
80 | case STATE_BIT_START: | ||
81 | data->bits <<= 1; | ||
82 | if (!ev.pulse) | ||
83 | data->bits |= 1; | ||
84 | |||
85 | if (IMON_CHKBITS & BIT(data->count)) { | ||
86 | if (data->last_chk != !(data->bits & 3)) | ||
87 | goto err_out; | ||
88 | } | ||
89 | |||
90 | if (!data->count--) | ||
91 | data->state = STATE_FINISHED; | ||
92 | else | ||
93 | data->state = STATE_BIT_CHK; | ||
94 | break; | ||
95 | case STATE_FINISHED: | ||
96 | if (ev.pulse) | ||
97 | goto err_out; | ||
98 | rc_keydown(dev, RC_PROTO_IMON, data->bits, 0); | ||
99 | data->state = STATE_INACTIVE; | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | err_out: | ||
105 | dev_dbg(&dev->dev, | ||
106 | "iMON decode failed at state %d bitno %d (%uus %s)\n", | ||
107 | data->state, data->count, TO_US(ev.duration), | ||
108 | TO_STR(ev.pulse)); | ||
109 | |||
110 | data->state = STATE_INACTIVE; | ||
111 | |||
112 | return -EINVAL; | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * ir_imon_encode() - Encode a scancode as a stream of raw events | ||
117 | * | ||
118 | * @protocol: protocol to encode | ||
119 | * @scancode: scancode to encode | ||
120 | * @events: array of raw ir events to write into | ||
121 | * @max: maximum size of @events | ||
122 | * | ||
123 | * Returns: The number of events written. | ||
124 | * -ENOBUFS if there isn't enough space in the array to fit the | ||
125 | * encoding. In this case all @max events will have been written. | ||
126 | */ | ||
127 | static int ir_imon_encode(enum rc_proto protocol, u32 scancode, | ||
128 | struct ir_raw_event *events, unsigned int max) | ||
129 | { | ||
130 | struct ir_raw_event *e = events; | ||
131 | int i, pulse; | ||
132 | |||
133 | if (!max--) | ||
134 | return -ENOBUFS; | ||
135 | init_ir_raw_event_duration(e, 1, IMON_UNIT); | ||
136 | |||
137 | for (i = IMON_BITS; i >= 0; i--) { | ||
138 | if (BIT(i) & IMON_CHKBITS) | ||
139 | pulse = !(scancode & (BIT(i) | BIT(i + 1))); | ||
140 | else | ||
141 | pulse = 0; | ||
142 | |||
143 | if (pulse == e->pulse) { | ||
144 | e->duration += IMON_UNIT; | ||
145 | } else { | ||
146 | if (!max--) | ||
147 | return -ENOBUFS; | ||
148 | init_ir_raw_event_duration(++e, pulse, IMON_UNIT); | ||
149 | } | ||
150 | |||
151 | pulse = !(scancode & BIT(i)); | ||
152 | |||
153 | if (pulse == e->pulse) { | ||
154 | e->duration += IMON_UNIT; | ||
155 | } else { | ||
156 | if (!max--) | ||
157 | return -ENOBUFS; | ||
158 | init_ir_raw_event_duration(++e, pulse, IMON_UNIT); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (e->pulse) | ||
163 | e++; | ||
164 | |||
165 | return e - events; | ||
166 | } | ||
167 | |||
168 | static struct ir_raw_handler imon_handler = { | ||
169 | .protocols = RC_PROTO_BIT_IMON, | ||
170 | .decode = ir_imon_decode, | ||
171 | .encode = ir_imon_encode, | ||
172 | .carrier = 38000, | ||
173 | }; | ||
174 | |||
175 | static int __init ir_imon_decode_init(void) | ||
176 | { | ||
177 | ir_raw_handler_register(&imon_handler); | ||
178 | |||
179 | pr_info("IR iMON protocol handler initialized\n"); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static void __exit ir_imon_decode_exit(void) | ||
184 | { | ||
185 | ir_raw_handler_unregister(&imon_handler); | ||
186 | } | ||
187 | |||
188 | module_init(ir_imon_decode_init); | ||
189 | module_exit(ir_imon_decode_exit); | ||
190 | |||
191 | MODULE_LICENSE("GPL"); | ||
192 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
193 | MODULE_DESCRIPTION("iMON IR protocol decoder"); | ||
diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index c03c776cfa54..8cb68ae43282 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c | |||
@@ -56,8 +56,8 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
56 | if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2)) | 56 | if (!geq_margin(ev.duration, JVC_UNIT, JVC_UNIT / 2)) |
57 | goto out; | 57 | goto out; |
58 | 58 | ||
59 | IR_dprintk(2, "JVC decode started at state %d (%uus %s)\n", | 59 | dev_dbg(&dev->dev, "JVC decode started at state %d (%uus %s)\n", |
60 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 60 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
61 | 61 | ||
62 | again: | 62 | again: |
63 | switch (data->state) { | 63 | switch (data->state) { |
@@ -136,15 +136,15 @@ again: | |||
136 | u32 scancode; | 136 | u32 scancode; |
137 | scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | | 137 | scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) | |
138 | (bitrev8((data->bits >> 0) & 0xff) << 0); | 138 | (bitrev8((data->bits >> 0) & 0xff) << 0); |
139 | IR_dprintk(1, "JVC scancode 0x%04x\n", scancode); | 139 | dev_dbg(&dev->dev, "JVC scancode 0x%04x\n", scancode); |
140 | rc_keydown(dev, RC_PROTO_JVC, scancode, data->toggle); | 140 | rc_keydown(dev, RC_PROTO_JVC, scancode, data->toggle); |
141 | data->first = false; | 141 | data->first = false; |
142 | data->old_bits = data->bits; | 142 | data->old_bits = data->bits; |
143 | } else if (data->bits == data->old_bits) { | 143 | } else if (data->bits == data->old_bits) { |
144 | IR_dprintk(1, "JVC repeat\n"); | 144 | dev_dbg(&dev->dev, "JVC repeat\n"); |
145 | rc_repeat(dev); | 145 | rc_repeat(dev); |
146 | } else { | 146 | } else { |
147 | IR_dprintk(1, "JVC invalid repeat msg\n"); | 147 | dev_dbg(&dev->dev, "JVC invalid repeat msg\n"); |
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | 150 | ||
@@ -164,8 +164,8 @@ again: | |||
164 | } | 164 | } |
165 | 165 | ||
166 | out: | 166 | out: |
167 | IR_dprintk(1, "JVC decode failed at state %d (%uus %s)\n", | 167 | dev_dbg(&dev->dev, "JVC decode failed at state %d (%uus %s)\n", |
168 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 168 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
169 | data->state = STATE_INACTIVE; | 169 | data->state = STATE_INACTIVE; |
170 | return -EINVAL; | 170 | return -EINVAL; |
171 | } | 171 | } |
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 2c3df02e05ff..c110984ca671 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c | |||
@@ -117,19 +117,19 @@ static unsigned char kbd_keycodes[256] = { | |||
117 | 117 | ||
118 | static void mce_kbd_rx_timeout(struct timer_list *t) | 118 | static void mce_kbd_rx_timeout(struct timer_list *t) |
119 | { | 119 | { |
120 | struct mce_kbd_dec *mce_kbd = from_timer(mce_kbd, t, rx_timeout); | 120 | struct ir_raw_event_ctrl *raw = from_timer(raw, t, mce_kbd.rx_timeout); |
121 | int i; | ||
122 | unsigned char maskcode; | 121 | unsigned char maskcode; |
122 | int i; | ||
123 | 123 | ||
124 | IR_dprintk(2, "timer callback clearing all keys\n"); | 124 | dev_dbg(&raw->dev->dev, "timer callback clearing all keys\n"); |
125 | 125 | ||
126 | for (i = 0; i < 7; i++) { | 126 | for (i = 0; i < 7; i++) { |
127 | maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; | 127 | maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; |
128 | input_report_key(mce_kbd->idev, maskcode, 0); | 128 | input_report_key(raw->mce_kbd.idev, maskcode, 0); |
129 | } | 129 | } |
130 | 130 | ||
131 | for (i = 0; i < MCIR2_MASK_KEYS_START; i++) | 131 | for (i = 0; i < MCIR2_MASK_KEYS_START; i++) |
132 | input_report_key(mce_kbd->idev, kbd_keycodes[i], 0); | 132 | input_report_key(raw->mce_kbd.idev, kbd_keycodes[i], 0); |
133 | } | 133 | } |
134 | 134 | ||
135 | static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data) | 135 | static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data) |
@@ -144,16 +144,16 @@ static enum mce_kbd_mode mce_kbd_mode(struct mce_kbd_dec *data) | |||
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | static void ir_mce_kbd_process_keyboard_data(struct input_dev *idev, | 147 | static void ir_mce_kbd_process_keyboard_data(struct rc_dev *dev, u32 scancode) |
148 | u32 scancode) | ||
149 | { | 148 | { |
149 | struct mce_kbd_dec *data = &dev->raw->mce_kbd; | ||
150 | u8 keydata = (scancode >> 8) & 0xff; | 150 | u8 keydata = (scancode >> 8) & 0xff; |
151 | u8 shiftmask = scancode & 0xff; | 151 | u8 shiftmask = scancode & 0xff; |
152 | unsigned char keycode, maskcode; | 152 | unsigned char keycode, maskcode; |
153 | int i, keystate; | 153 | int i, keystate; |
154 | 154 | ||
155 | IR_dprintk(1, "keyboard: keydata = 0x%02x, shiftmask = 0x%02x\n", | 155 | dev_dbg(&dev->dev, "keyboard: keydata = 0x%02x, shiftmask = 0x%02x\n", |
156 | keydata, shiftmask); | 156 | keydata, shiftmask); |
157 | 157 | ||
158 | for (i = 0; i < 7; i++) { | 158 | for (i = 0; i < 7; i++) { |
159 | maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; | 159 | maskcode = kbd_keycodes[MCIR2_MASK_KEYS_START + i]; |
@@ -161,20 +161,21 @@ static void ir_mce_kbd_process_keyboard_data(struct input_dev *idev, | |||
161 | keystate = 1; | 161 | keystate = 1; |
162 | else | 162 | else |
163 | keystate = 0; | 163 | keystate = 0; |
164 | input_report_key(idev, maskcode, keystate); | 164 | input_report_key(data->idev, maskcode, keystate); |
165 | } | 165 | } |
166 | 166 | ||
167 | if (keydata) { | 167 | if (keydata) { |
168 | keycode = kbd_keycodes[keydata]; | 168 | keycode = kbd_keycodes[keydata]; |
169 | input_report_key(idev, keycode, 1); | 169 | input_report_key(data->idev, keycode, 1); |
170 | } else { | 170 | } else { |
171 | for (i = 0; i < MCIR2_MASK_KEYS_START; i++) | 171 | for (i = 0; i < MCIR2_MASK_KEYS_START; i++) |
172 | input_report_key(idev, kbd_keycodes[i], 0); | 172 | input_report_key(data->idev, kbd_keycodes[i], 0); |
173 | } | 173 | } |
174 | } | 174 | } |
175 | 175 | ||
176 | static void ir_mce_kbd_process_mouse_data(struct input_dev *idev, u32 scancode) | 176 | static void ir_mce_kbd_process_mouse_data(struct rc_dev *dev, u32 scancode) |
177 | { | 177 | { |
178 | struct mce_kbd_dec *data = &dev->raw->mce_kbd; | ||
178 | /* raw mouse coordinates */ | 179 | /* raw mouse coordinates */ |
179 | u8 xdata = (scancode >> 7) & 0x7f; | 180 | u8 xdata = (scancode >> 7) & 0x7f; |
180 | u8 ydata = (scancode >> 14) & 0x7f; | 181 | u8 ydata = (scancode >> 14) & 0x7f; |
@@ -193,14 +194,14 @@ static void ir_mce_kbd_process_mouse_data(struct input_dev *idev, u32 scancode) | |||
193 | else | 194 | else |
194 | y = ydata; | 195 | y = ydata; |
195 | 196 | ||
196 | IR_dprintk(1, "mouse: x = %d, y = %d, btns = %s%s\n", | 197 | dev_dbg(&dev->dev, "mouse: x = %d, y = %d, btns = %s%s\n", |
197 | x, y, left ? "L" : "", right ? "R" : ""); | 198 | x, y, left ? "L" : "", right ? "R" : ""); |
198 | 199 | ||
199 | input_report_rel(idev, REL_X, x); | 200 | input_report_rel(data->idev, REL_X, x); |
200 | input_report_rel(idev, REL_Y, y); | 201 | input_report_rel(data->idev, REL_Y, y); |
201 | 202 | ||
202 | input_report_key(idev, BTN_LEFT, left); | 203 | input_report_key(data->idev, BTN_LEFT, left); |
203 | input_report_key(idev, BTN_RIGHT, right); | 204 | input_report_key(data->idev, BTN_RIGHT, right); |
204 | } | 205 | } |
205 | 206 | ||
206 | /** | 207 | /** |
@@ -227,8 +228,8 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
227 | goto out; | 228 | goto out; |
228 | 229 | ||
229 | again: | 230 | again: |
230 | IR_dprintk(2, "started at state %i (%uus %s)\n", | 231 | dev_dbg(&dev->dev, "started at state %i (%uus %s)\n", |
231 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 232 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
232 | 233 | ||
233 | if (!geq_margin(ev.duration, MCIR2_UNIT, MCIR2_UNIT / 2)) | 234 | if (!geq_margin(ev.duration, MCIR2_UNIT, MCIR2_UNIT / 2)) |
234 | return 0; | 235 | return 0; |
@@ -280,7 +281,7 @@ again: | |||
280 | data->wanted_bits = MCIR2_MOUSE_NBITS; | 281 | data->wanted_bits = MCIR2_MOUSE_NBITS; |
281 | break; | 282 | break; |
282 | default: | 283 | default: |
283 | IR_dprintk(1, "not keyboard or mouse data\n"); | 284 | dev_dbg(&dev->dev, "not keyboard or mouse data\n"); |
284 | goto out; | 285 | goto out; |
285 | } | 286 | } |
286 | 287 | ||
@@ -319,25 +320,26 @@ again: | |||
319 | switch (data->wanted_bits) { | 320 | switch (data->wanted_bits) { |
320 | case MCIR2_KEYBOARD_NBITS: | 321 | case MCIR2_KEYBOARD_NBITS: |
321 | scancode = data->body & 0xffff; | 322 | scancode = data->body & 0xffff; |
322 | IR_dprintk(1, "keyboard data 0x%08x\n", data->body); | 323 | dev_dbg(&dev->dev, "keyboard data 0x%08x\n", |
324 | data->body); | ||
323 | if (dev->timeout) | 325 | if (dev->timeout) |
324 | delay = usecs_to_jiffies(dev->timeout / 1000); | 326 | delay = usecs_to_jiffies(dev->timeout / 1000); |
325 | else | 327 | else |
326 | delay = msecs_to_jiffies(100); | 328 | delay = msecs_to_jiffies(100); |
327 | mod_timer(&data->rx_timeout, jiffies + delay); | 329 | mod_timer(&data->rx_timeout, jiffies + delay); |
328 | /* Pass data to keyboard buffer parser */ | 330 | /* Pass data to keyboard buffer parser */ |
329 | ir_mce_kbd_process_keyboard_data(data->idev, scancode); | 331 | ir_mce_kbd_process_keyboard_data(dev, scancode); |
330 | lsc.rc_proto = RC_PROTO_MCIR2_KBD; | 332 | lsc.rc_proto = RC_PROTO_MCIR2_KBD; |
331 | break; | 333 | break; |
332 | case MCIR2_MOUSE_NBITS: | 334 | case MCIR2_MOUSE_NBITS: |
333 | scancode = data->body & 0x1fffff; | 335 | scancode = data->body & 0x1fffff; |
334 | IR_dprintk(1, "mouse data 0x%06x\n", scancode); | 336 | dev_dbg(&dev->dev, "mouse data 0x%06x\n", scancode); |
335 | /* Pass data to mouse buffer parser */ | 337 | /* Pass data to mouse buffer parser */ |
336 | ir_mce_kbd_process_mouse_data(data->idev, scancode); | 338 | ir_mce_kbd_process_mouse_data(dev, scancode); |
337 | lsc.rc_proto = RC_PROTO_MCIR2_MSE; | 339 | lsc.rc_proto = RC_PROTO_MCIR2_MSE; |
338 | break; | 340 | break; |
339 | default: | 341 | default: |
340 | IR_dprintk(1, "not keyboard or mouse data\n"); | 342 | dev_dbg(&dev->dev, "not keyboard or mouse data\n"); |
341 | goto out; | 343 | goto out; |
342 | } | 344 | } |
343 | 345 | ||
@@ -350,8 +352,8 @@ again: | |||
350 | } | 352 | } |
351 | 353 | ||
352 | out: | 354 | out: |
353 | IR_dprintk(1, "failed at state %i (%uus %s)\n", | 355 | dev_dbg(&dev->dev, "failed at state %i (%uus %s)\n", |
354 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 356 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
355 | data->state = STATE_INACTIVE; | 357 | data->state = STATE_INACTIVE; |
356 | input_sync(data->idev); | 358 | input_sync(data->idev); |
357 | return -EINVAL; | 359 | return -EINVAL; |
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 31d7bafe7bda..21647b809e6f 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c | |||
@@ -49,8 +49,8 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
52 | IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n", | 52 | dev_dbg(&dev->dev, "NEC decode started at state %d (%uus %s)\n", |
53 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 53 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
54 | 54 | ||
55 | switch (data->state) { | 55 | switch (data->state) { |
56 | 56 | ||
@@ -99,13 +99,11 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
99 | break; | 99 | break; |
100 | 100 | ||
101 | if (data->necx_repeat && data->count == NECX_REPEAT_BITS && | 101 | if (data->necx_repeat && data->count == NECX_REPEAT_BITS && |
102 | geq_margin(ev.duration, | 102 | geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) { |
103 | NEC_TRAILER_SPACE, NEC_UNIT / 2)) { | 103 | dev_dbg(&dev->dev, "Repeat last key\n"); |
104 | IR_dprintk(1, "Repeat last key\n"); | 104 | rc_repeat(dev); |
105 | rc_repeat(dev); | 105 | data->state = STATE_INACTIVE; |
106 | data->state = STATE_INACTIVE; | 106 | return 0; |
107 | return 0; | ||
108 | |||
109 | } else if (data->count > NECX_REPEAT_BITS) | 107 | } else if (data->count > NECX_REPEAT_BITS) |
110 | data->necx_repeat = false; | 108 | data->necx_repeat = false; |
111 | 109 | ||
@@ -164,8 +162,8 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
164 | return 0; | 162 | return 0; |
165 | } | 163 | } |
166 | 164 | ||
167 | IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n", | 165 | dev_dbg(&dev->dev, "NEC decode failed at count %d state %d (%uus %s)\n", |
168 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 166 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
169 | data->state = STATE_INACTIVE; | 167 | data->state = STATE_INACTIVE; |
170 | return -EINVAL; | 168 | return -EINVAL; |
171 | } | 169 | } |
diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 11a28f8772da..74d3b859c3a2 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c | |||
@@ -54,8 +54,8 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
54 | goto out; | 54 | goto out; |
55 | 55 | ||
56 | again: | 56 | again: |
57 | IR_dprintk(2, "RC5(x/sz) decode started at state %i (%uus %s)\n", | 57 | dev_dbg(&dev->dev, "RC5(x/sz) decode started at state %i (%uus %s)\n", |
58 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 58 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
59 | 59 | ||
60 | if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) | 60 | if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) |
61 | return 0; | 61 | return 0; |
@@ -157,8 +157,8 @@ again: | |||
157 | } else | 157 | } else |
158 | break; | 158 | break; |
159 | 159 | ||
160 | IR_dprintk(1, "RC5(x/sz) scancode 0x%06x (p: %u, t: %u)\n", | 160 | dev_dbg(&dev->dev, "RC5(x/sz) scancode 0x%06x (p: %u, t: %u)\n", |
161 | scancode, protocol, toggle); | 161 | scancode, protocol, toggle); |
162 | 162 | ||
163 | rc_keydown(dev, protocol, scancode, toggle); | 163 | rc_keydown(dev, protocol, scancode, toggle); |
164 | data->state = STATE_INACTIVE; | 164 | data->state = STATE_INACTIVE; |
@@ -166,8 +166,8 @@ again: | |||
166 | } | 166 | } |
167 | 167 | ||
168 | out: | 168 | out: |
169 | IR_dprintk(1, "RC5(x/sz) decode failed at state %i count %d (%uus %s)\n", | 169 | dev_dbg(&dev->dev, "RC5(x/sz) decode failed at state %i count %d (%uus %s)\n", |
170 | data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); | 170 | data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); |
171 | data->state = STATE_INACTIVE; | 171 | data->state = STATE_INACTIVE; |
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | } | 173 | } |
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 55bb19bbd4e9..8314da32453f 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c | |||
@@ -100,8 +100,8 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
100 | goto out; | 100 | goto out; |
101 | 101 | ||
102 | again: | 102 | again: |
103 | IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n", | 103 | dev_dbg(&dev->dev, "RC6 decode started at state %i (%uus %s)\n", |
104 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 104 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
105 | 105 | ||
106 | if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) | 106 | if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) |
107 | return 0; | 107 | return 0; |
@@ -170,7 +170,7 @@ again: | |||
170 | break; | 170 | break; |
171 | 171 | ||
172 | if (!(data->header & RC6_STARTBIT_MASK)) { | 172 | if (!(data->header & RC6_STARTBIT_MASK)) { |
173 | IR_dprintk(1, "RC6 invalid start bit\n"); | 173 | dev_dbg(&dev->dev, "RC6 invalid start bit\n"); |
174 | break; | 174 | break; |
175 | } | 175 | } |
176 | 176 | ||
@@ -187,7 +187,7 @@ again: | |||
187 | data->wanted_bits = RC6_6A_NBITS; | 187 | data->wanted_bits = RC6_6A_NBITS; |
188 | break; | 188 | break; |
189 | default: | 189 | default: |
190 | IR_dprintk(1, "RC6 unknown mode\n"); | 190 | dev_dbg(&dev->dev, "RC6 unknown mode\n"); |
191 | goto out; | 191 | goto out; |
192 | } | 192 | } |
193 | goto again; | 193 | goto again; |
@@ -230,13 +230,13 @@ again: | |||
230 | scancode = data->body; | 230 | scancode = data->body; |
231 | toggle = data->toggle; | 231 | toggle = data->toggle; |
232 | protocol = RC_PROTO_RC6_0; | 232 | protocol = RC_PROTO_RC6_0; |
233 | IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n", | 233 | dev_dbg(&dev->dev, "RC6(0) scancode 0x%04x (toggle: %u)\n", |
234 | scancode, toggle); | 234 | scancode, toggle); |
235 | break; | 235 | break; |
236 | 236 | ||
237 | case RC6_MODE_6A: | 237 | case RC6_MODE_6A: |
238 | if (data->count > CHAR_BIT * sizeof data->body) { | 238 | if (data->count > CHAR_BIT * sizeof data->body) { |
239 | IR_dprintk(1, "RC6 too many (%u) data bits\n", | 239 | dev_dbg(&dev->dev, "RC6 too many (%u) data bits\n", |
240 | data->count); | 240 | data->count); |
241 | goto out; | 241 | goto out; |
242 | } | 242 | } |
@@ -262,15 +262,15 @@ again: | |||
262 | } | 262 | } |
263 | break; | 263 | break; |
264 | default: | 264 | default: |
265 | IR_dprintk(1, "RC6(6A) unsupported length\n"); | 265 | dev_dbg(&dev->dev, "RC6(6A) unsupported length\n"); |
266 | goto out; | 266 | goto out; |
267 | } | 267 | } |
268 | 268 | ||
269 | IR_dprintk(1, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n", | 269 | dev_dbg(&dev->dev, "RC6(6A) proto 0x%04x, scancode 0x%08x (toggle: %u)\n", |
270 | protocol, scancode, toggle); | 270 | protocol, scancode, toggle); |
271 | break; | 271 | break; |
272 | default: | 272 | default: |
273 | IR_dprintk(1, "RC6 unknown mode\n"); | 273 | dev_dbg(&dev->dev, "RC6 unknown mode\n"); |
274 | goto out; | 274 | goto out; |
275 | } | 275 | } |
276 | 276 | ||
@@ -280,8 +280,8 @@ again: | |||
280 | } | 280 | } |
281 | 281 | ||
282 | out: | 282 | out: |
283 | IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n", | 283 | dev_dbg(&dev->dev, "RC6 decode failed at state %i (%uus %s)\n", |
284 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 284 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
285 | data->state = STATE_INACTIVE; | 285 | data->state = STATE_INACTIVE; |
286 | return -EINVAL; | 286 | return -EINVAL; |
287 | } | 287 | } |
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index ded39cdfc6ef..4efe6db5376a 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c | |||
@@ -52,14 +52,14 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
52 | 52 | ||
53 | if (!is_timing_event(ev)) { | 53 | if (!is_timing_event(ev)) { |
54 | if (ev.reset) { | 54 | if (ev.reset) { |
55 | IR_dprintk(1, "SANYO event reset received. reset to state 0\n"); | 55 | dev_dbg(&dev->dev, "SANYO event reset received. reset to state 0\n"); |
56 | data->state = STATE_INACTIVE; | 56 | data->state = STATE_INACTIVE; |
57 | } | 57 | } |
58 | return 0; | 58 | return 0; |
59 | } | 59 | } |
60 | 60 | ||
61 | IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n", | 61 | dev_dbg(&dev->dev, "SANYO decode started at state %d (%uus %s)\n", |
62 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 62 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
63 | 63 | ||
64 | switch (data->state) { | 64 | switch (data->state) { |
65 | 65 | ||
@@ -102,7 +102,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
102 | 102 | ||
103 | if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { | 103 | if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) { |
104 | rc_repeat(dev); | 104 | rc_repeat(dev); |
105 | IR_dprintk(1, "SANYO repeat last key\n"); | 105 | dev_dbg(&dev->dev, "SANYO repeat last key\n"); |
106 | data->state = STATE_INACTIVE; | 106 | data->state = STATE_INACTIVE; |
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
@@ -144,21 +144,21 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
144 | not_command = bitrev8((data->bits >> 0) & 0xff); | 144 | not_command = bitrev8((data->bits >> 0) & 0xff); |
145 | 145 | ||
146 | if ((command ^ not_command) != 0xff) { | 146 | if ((command ^ not_command) != 0xff) { |
147 | IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n", | 147 | dev_dbg(&dev->dev, "SANYO checksum error: received 0x%08llx\n", |
148 | data->bits); | 148 | data->bits); |
149 | data->state = STATE_INACTIVE; | 149 | data->state = STATE_INACTIVE; |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
152 | 152 | ||
153 | scancode = address << 8 | command; | 153 | scancode = address << 8 | command; |
154 | IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode); | 154 | dev_dbg(&dev->dev, "SANYO scancode: 0x%06x\n", scancode); |
155 | rc_keydown(dev, RC_PROTO_SANYO, scancode, 0); | 155 | rc_keydown(dev, RC_PROTO_SANYO, scancode, 0); |
156 | data->state = STATE_INACTIVE; | 156 | data->state = STATE_INACTIVE; |
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
159 | 159 | ||
160 | IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n", | 160 | dev_dbg(&dev->dev, "SANYO decode failed at count %d state %d (%uus %s)\n", |
161 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 161 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
162 | data->state = STATE_INACTIVE; | 162 | data->state = STATE_INACTIVE; |
163 | return -EINVAL; | 163 | return -EINVAL; |
164 | } | 164 | } |
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c index df296991906c..6a38c50566a4 100644 --- a/drivers/media/rc/ir-sharp-decoder.c +++ b/drivers/media/rc/ir-sharp-decoder.c | |||
@@ -54,8 +54,8 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | IR_dprintk(2, "Sharp decode started at state %d (%uus %s)\n", | 57 | dev_dbg(&dev->dev, "Sharp decode started at state %d (%uus %s)\n", |
58 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 58 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
59 | 59 | ||
60 | switch (data->state) { | 60 | switch (data->state) { |
61 | 61 | ||
@@ -149,9 +149,9 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
149 | msg = (data->bits >> 15) & 0x7fff; | 149 | msg = (data->bits >> 15) & 0x7fff; |
150 | echo = data->bits & 0x7fff; | 150 | echo = data->bits & 0x7fff; |
151 | if ((msg ^ echo) != 0x3ff) { | 151 | if ((msg ^ echo) != 0x3ff) { |
152 | IR_dprintk(1, | 152 | dev_dbg(&dev->dev, |
153 | "Sharp checksum error: received 0x%04x, 0x%04x\n", | 153 | "Sharp checksum error: received 0x%04x, 0x%04x\n", |
154 | msg, echo); | 154 | msg, echo); |
155 | break; | 155 | break; |
156 | } | 156 | } |
157 | 157 | ||
@@ -159,16 +159,15 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
159 | command = bitrev8((msg >> 2) & 0xff); | 159 | command = bitrev8((msg >> 2) & 0xff); |
160 | 160 | ||
161 | scancode = address << 8 | command; | 161 | scancode = address << 8 | command; |
162 | IR_dprintk(1, "Sharp scancode 0x%04x\n", scancode); | 162 | dev_dbg(&dev->dev, "Sharp scancode 0x%04x\n", scancode); |
163 | 163 | ||
164 | rc_keydown(dev, RC_PROTO_SHARP, scancode, 0); | 164 | rc_keydown(dev, RC_PROTO_SHARP, scancode, 0); |
165 | data->state = STATE_INACTIVE; | 165 | data->state = STATE_INACTIVE; |
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
168 | 168 | ||
169 | IR_dprintk(1, "Sharp decode failed at count %d state %d (%uus %s)\n", | 169 | dev_dbg(&dev->dev, "Sharp decode failed at count %d state %d (%uus %s)\n", |
170 | data->count, data->state, TO_US(ev.duration), | 170 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
171 | TO_STR(ev.pulse)); | ||
172 | data->state = STATE_INACTIVE; | 171 | data->state = STATE_INACTIVE; |
173 | return -EINVAL; | 172 | return -EINVAL; |
174 | } | 173 | } |
diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index e4bcff21c025..6764ec9de646 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c | |||
@@ -55,8 +55,8 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
55 | if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) | 55 | if (!geq_margin(ev.duration, SONY_UNIT, SONY_UNIT / 2)) |
56 | goto out; | 56 | goto out; |
57 | 57 | ||
58 | IR_dprintk(2, "Sony decode started at state %d (%uus %s)\n", | 58 | dev_dbg(&dev->dev, "Sony decode started at state %d (%uus %s)\n", |
59 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 59 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
60 | 60 | ||
61 | switch (data->state) { | 61 | switch (data->state) { |
62 | 62 | ||
@@ -148,19 +148,21 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
148 | protocol = RC_PROTO_SONY20; | 148 | protocol = RC_PROTO_SONY20; |
149 | break; | 149 | break; |
150 | default: | 150 | default: |
151 | IR_dprintk(1, "Sony invalid bitcount %u\n", data->count); | 151 | dev_dbg(&dev->dev, "Sony invalid bitcount %u\n", |
152 | data->count); | ||
152 | goto out; | 153 | goto out; |
153 | } | 154 | } |
154 | 155 | ||
155 | scancode = device << 16 | subdevice << 8 | function; | 156 | scancode = device << 16 | subdevice << 8 | function; |
156 | IR_dprintk(1, "Sony(%u) scancode 0x%05x\n", data->count, scancode); | 157 | dev_dbg(&dev->dev, "Sony(%u) scancode 0x%05x\n", data->count, |
158 | scancode); | ||
157 | rc_keydown(dev, protocol, scancode, 0); | 159 | rc_keydown(dev, protocol, scancode, 0); |
158 | goto finish_state_machine; | 160 | goto finish_state_machine; |
159 | } | 161 | } |
160 | 162 | ||
161 | out: | 163 | out: |
162 | IR_dprintk(1, "Sony decode failed at state %d (%uus %s)\n", | 164 | dev_dbg(&dev->dev, "Sony decode failed at state %d (%uus %s)\n", |
163 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 165 | data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
164 | data->state = STATE_INACTIVE; | 166 | data->state = STATE_INACTIVE; |
165 | return -EINVAL; | 167 | return -EINVAL; |
166 | 168 | ||
diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c index a32a84ae2d0b..7163d5ce2e64 100644 --- a/drivers/media/rc/ir-spi.c +++ b/drivers/media/rc/ir-spi.c | |||
@@ -15,21 +15,11 @@ | |||
15 | 15 | ||
16 | #define IR_SPI_DRIVER_NAME "ir-spi" | 16 | #define IR_SPI_DRIVER_NAME "ir-spi" |
17 | 17 | ||
18 | /* pulse value for different duty cycles */ | ||
19 | #define IR_SPI_PULSE_DC_50 0xff00 | ||
20 | #define IR_SPI_PULSE_DC_60 0xfc00 | ||
21 | #define IR_SPI_PULSE_DC_70 0xf800 | ||
22 | #define IR_SPI_PULSE_DC_75 0xf000 | ||
23 | #define IR_SPI_PULSE_DC_80 0xc000 | ||
24 | #define IR_SPI_PULSE_DC_90 0x8000 | ||
25 | |||
26 | #define IR_SPI_DEFAULT_FREQUENCY 38000 | 18 | #define IR_SPI_DEFAULT_FREQUENCY 38000 |
27 | #define IR_SPI_BIT_PER_WORD 8 | ||
28 | #define IR_SPI_MAX_BUFSIZE 4096 | 19 | #define IR_SPI_MAX_BUFSIZE 4096 |
29 | 20 | ||
30 | struct ir_spi_data { | 21 | struct ir_spi_data { |
31 | u32 freq; | 22 | u32 freq; |
32 | u8 duty_cycle; | ||
33 | bool negated; | 23 | bool negated; |
34 | 24 | ||
35 | u16 tx_buf[IR_SPI_MAX_BUFSIZE]; | 25 | u16 tx_buf[IR_SPI_MAX_BUFSIZE]; |
@@ -105,19 +95,9 @@ static int ir_spi_set_tx_carrier(struct rc_dev *dev, u32 carrier) | |||
105 | static int ir_spi_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle) | 95 | static int ir_spi_set_duty_cycle(struct rc_dev *dev, u32 duty_cycle) |
106 | { | 96 | { |
107 | struct ir_spi_data *idata = dev->priv; | 97 | struct ir_spi_data *idata = dev->priv; |
98 | int bits = (duty_cycle * 15) / 100; | ||
108 | 99 | ||
109 | if (duty_cycle >= 90) | 100 | idata->pulse = GENMASK(bits, 0); |
110 | idata->pulse = IR_SPI_PULSE_DC_90; | ||
111 | else if (duty_cycle >= 80) | ||
112 | idata->pulse = IR_SPI_PULSE_DC_80; | ||
113 | else if (duty_cycle >= 75) | ||
114 | idata->pulse = IR_SPI_PULSE_DC_75; | ||
115 | else if (duty_cycle >= 70) | ||
116 | idata->pulse = IR_SPI_PULSE_DC_70; | ||
117 | else if (duty_cycle >= 60) | ||
118 | idata->pulse = IR_SPI_PULSE_DC_60; | ||
119 | else | ||
120 | idata->pulse = IR_SPI_PULSE_DC_50; | ||
121 | 101 | ||
122 | if (idata->negated) { | 102 | if (idata->negated) { |
123 | idata->pulse = ~idata->pulse; | 103 | idata->pulse = ~idata->pulse; |
diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c index 712bc6d76e92..58b47af1a763 100644 --- a/drivers/media/rc/ir-xmp-decoder.c +++ b/drivers/media/rc/ir-xmp-decoder.c | |||
@@ -49,8 +49,8 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
52 | IR_dprintk(2, "XMP decode started at state %d %d (%uus %s)\n", | 52 | dev_dbg(&dev->dev, "XMP decode started at state %d %d (%uus %s)\n", |
53 | data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); | 53 | data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); |
54 | 54 | ||
55 | switch (data->state) { | 55 | switch (data->state) { |
56 | 56 | ||
@@ -85,7 +85,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
85 | u32 scancode; | 85 | u32 scancode; |
86 | 86 | ||
87 | if (data->count != 16) { | 87 | if (data->count != 16) { |
88 | IR_dprintk(2, "received TRAILER period at index %d: %u\n", | 88 | dev_dbg(&dev->dev, "received TRAILER period at index %d: %u\n", |
89 | data->count, ev.duration); | 89 | data->count, ev.duration); |
90 | data->state = STATE_INACTIVE; | 90 | data->state = STATE_INACTIVE; |
91 | return -EINVAL; | 91 | return -EINVAL; |
@@ -99,7 +99,8 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
99 | */ | 99 | */ |
100 | divider = (n[3] - XMP_NIBBLE_PREFIX) / 15 - 2000; | 100 | divider = (n[3] - XMP_NIBBLE_PREFIX) / 15 - 2000; |
101 | if (divider < 50) { | 101 | if (divider < 50) { |
102 | IR_dprintk(2, "divider to small %d.\n", divider); | 102 | dev_dbg(&dev->dev, "divider to small %d.\n", |
103 | divider); | ||
103 | data->state = STATE_INACTIVE; | 104 | data->state = STATE_INACTIVE; |
104 | return -EINVAL; | 105 | return -EINVAL; |
105 | } | 106 | } |
@@ -113,7 +114,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
113 | n[12] + n[13] + n[14] + n[15]) % 16; | 114 | n[12] + n[13] + n[14] + n[15]) % 16; |
114 | 115 | ||
115 | if (sum1 != 15 || sum2 != 15) { | 116 | if (sum1 != 15 || sum2 != 15) { |
116 | IR_dprintk(2, "checksum errors sum1=0x%X sum2=0x%X\n", | 117 | dev_dbg(&dev->dev, "checksum errors sum1=0x%X sum2=0x%X\n", |
117 | sum1, sum2); | 118 | sum1, sum2); |
118 | data->state = STATE_INACTIVE; | 119 | data->state = STATE_INACTIVE; |
119 | return -EINVAL; | 120 | return -EINVAL; |
@@ -127,24 +128,24 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
127 | obc1 = n[12] << 4 | n[13]; | 128 | obc1 = n[12] << 4 | n[13]; |
128 | obc2 = n[14] << 4 | n[15]; | 129 | obc2 = n[14] << 4 | n[15]; |
129 | if (subaddr != subaddr2) { | 130 | if (subaddr != subaddr2) { |
130 | IR_dprintk(2, "subaddress nibbles mismatch 0x%02X != 0x%02X\n", | 131 | dev_dbg(&dev->dev, "subaddress nibbles mismatch 0x%02X != 0x%02X\n", |
131 | subaddr, subaddr2); | 132 | subaddr, subaddr2); |
132 | data->state = STATE_INACTIVE; | 133 | data->state = STATE_INACTIVE; |
133 | return -EINVAL; | 134 | return -EINVAL; |
134 | } | 135 | } |
135 | if (oem != 0x44) | 136 | if (oem != 0x44) |
136 | IR_dprintk(1, "Warning: OEM nibbles 0x%02X. Expected 0x44\n", | 137 | dev_dbg(&dev->dev, "Warning: OEM nibbles 0x%02X. Expected 0x44\n", |
137 | oem); | 138 | oem); |
138 | 139 | ||
139 | scancode = addr << 24 | subaddr << 16 | | 140 | scancode = addr << 24 | subaddr << 16 | |
140 | obc1 << 8 | obc2; | 141 | obc1 << 8 | obc2; |
141 | IR_dprintk(1, "XMP scancode 0x%06x\n", scancode); | 142 | dev_dbg(&dev->dev, "XMP scancode 0x%06x\n", scancode); |
142 | 143 | ||
143 | if (toggle == 0) { | 144 | if (toggle == 0) { |
144 | rc_keydown(dev, RC_PROTO_XMP, scancode, 0); | 145 | rc_keydown(dev, RC_PROTO_XMP, scancode, 0); |
145 | } else { | 146 | } else { |
146 | rc_repeat(dev); | 147 | rc_repeat(dev); |
147 | IR_dprintk(1, "Repeat last key\n"); | 148 | dev_dbg(&dev->dev, "Repeat last key\n"); |
148 | } | 149 | } |
149 | data->state = STATE_INACTIVE; | 150 | data->state = STATE_INACTIVE; |
150 | 151 | ||
@@ -153,7 +154,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
153 | } else if (geq_margin(ev.duration, XMP_HALFFRAME_SPACE, XMP_NIBBLE_PREFIX)) { | 154 | } else if (geq_margin(ev.duration, XMP_HALFFRAME_SPACE, XMP_NIBBLE_PREFIX)) { |
154 | /* Expect 8 or 16 nibble pulses. 16 in case of 'final' frame */ | 155 | /* Expect 8 or 16 nibble pulses. 16 in case of 'final' frame */ |
155 | if (data->count == 16) { | 156 | if (data->count == 16) { |
156 | IR_dprintk(2, "received half frame pulse at index %d. Probably a final frame key-up event: %u\n", | 157 | dev_dbg(&dev->dev, "received half frame pulse at index %d. Probably a final frame key-up event: %u\n", |
157 | data->count, ev.duration); | 158 | data->count, ev.duration); |
158 | /* | 159 | /* |
159 | * TODO: for now go back to half frame position | 160 | * TODO: for now go back to half frame position |
@@ -164,7 +165,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
164 | } | 165 | } |
165 | 166 | ||
166 | else if (data->count != 8) | 167 | else if (data->count != 8) |
167 | IR_dprintk(2, "received half frame pulse at index %d: %u\n", | 168 | dev_dbg(&dev->dev, "received half frame pulse at index %d: %u\n", |
168 | data->count, ev.duration); | 169 | data->count, ev.duration); |
169 | data->state = STATE_LEADER_PULSE; | 170 | data->state = STATE_LEADER_PULSE; |
170 | 171 | ||
@@ -173,7 +174,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
173 | } else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) { | 174 | } else if (geq_margin(ev.duration, XMP_NIBBLE_PREFIX, XMP_UNIT)) { |
174 | /* store nibble raw data, decode after trailer */ | 175 | /* store nibble raw data, decode after trailer */ |
175 | if (data->count == 16) { | 176 | if (data->count == 16) { |
176 | IR_dprintk(2, "to many pulses (%d) ignoring: %u\n", | 177 | dev_dbg(&dev->dev, "to many pulses (%d) ignoring: %u\n", |
177 | data->count, ev.duration); | 178 | data->count, ev.duration); |
178 | data->state = STATE_INACTIVE; | 179 | data->state = STATE_INACTIVE; |
179 | return -EINVAL; | 180 | return -EINVAL; |
@@ -189,8 +190,8 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) | |||
189 | break; | 190 | break; |
190 | } | 191 | } |
191 | 192 | ||
192 | IR_dprintk(1, "XMP decode failed at count %d state %d (%uus %s)\n", | 193 | dev_dbg(&dev->dev, "XMP decode failed at count %d state %d (%uus %s)\n", |
193 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); | 194 | data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); |
194 | data->state = STATE_INACTIVE; | 195 | data->state = STATE_INACTIVE; |
195 | return -EINVAL; | 196 | return -EINVAL; |
196 | } | 197 | } |
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 50b319355edf..d6b913a3032d 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile | |||
@@ -53,6 +53,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ | |||
53 | rc-hisi-tv-demo.o \ | 53 | rc-hisi-tv-demo.o \ |
54 | rc-imon-mce.o \ | 54 | rc-imon-mce.o \ |
55 | rc-imon-pad.o \ | 55 | rc-imon-pad.o \ |
56 | rc-imon-rsc.o \ | ||
56 | rc-iodata-bctv7e.o \ | 57 | rc-iodata-bctv7e.o \ |
57 | rc-it913x-v1.o \ | 58 | rc-it913x-v1.o \ |
58 | rc-it913x-v2.o \ | 59 | rc-it913x-v2.o \ |
diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c index a7296ffbf218..8501cf0a3253 100644 --- a/drivers/media/rc/keymaps/rc-imon-pad.c +++ b/drivers/media/rc/keymaps/rc-imon-pad.c | |||
@@ -134,8 +134,7 @@ static struct rc_map_list imon_pad_map = { | |||
134 | .map = { | 134 | .map = { |
135 | .scan = imon_pad, | 135 | .scan = imon_pad, |
136 | .size = ARRAY_SIZE(imon_pad), | 136 | .size = ARRAY_SIZE(imon_pad), |
137 | /* actual protocol details unknown, hardware decoder */ | 137 | .rc_proto = RC_PROTO_IMON, |
138 | .rc_proto = RC_PROTO_OTHER, | ||
139 | .name = RC_MAP_IMON_PAD, | 138 | .name = RC_MAP_IMON_PAD, |
140 | } | 139 | } |
141 | }; | 140 | }; |
diff --git a/drivers/media/rc/keymaps/rc-imon-rsc.c b/drivers/media/rc/keymaps/rc-imon-rsc.c new file mode 100644 index 000000000000..83e4564aaa22 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-imon-rsc.c | |||
@@ -0,0 +1,81 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | // | ||
3 | // Copyright (C) 2018 Sean Young <sean@mess.org> | ||
4 | |||
5 | #include <media/rc-map.h> | ||
6 | #include <linux/module.h> | ||
7 | |||
8 | // | ||
9 | // Note that this remote has a stick which its own IR protocol, | ||
10 | // with 16 directions. This is not supported yet. | ||
11 | // | ||
12 | static struct rc_map_table imon_rsc[] = { | ||
13 | { 0x801010, KEY_EXIT }, | ||
14 | { 0x80102f, KEY_POWER }, | ||
15 | { 0x80104a, KEY_SCREENSAVER }, /* Screensaver */ | ||
16 | { 0x801049, KEY_TIME }, /* Timer */ | ||
17 | { 0x801054, KEY_NUMERIC_1 }, | ||
18 | { 0x801055, KEY_NUMERIC_2 }, | ||
19 | { 0x801056, KEY_NUMERIC_3 }, | ||
20 | { 0x801057, KEY_NUMERIC_4 }, | ||
21 | { 0x801058, KEY_NUMERIC_5 }, | ||
22 | { 0x801059, KEY_NUMERIC_6 }, | ||
23 | { 0x80105a, KEY_NUMERIC_7 }, | ||
24 | { 0x80105b, KEY_NUMERIC_8 }, | ||
25 | { 0x80105c, KEY_NUMERIC_9 }, | ||
26 | { 0x801081, KEY_SCREEN }, /* Desktop */ | ||
27 | { 0x80105d, KEY_NUMERIC_0 }, | ||
28 | { 0x801082, KEY_MAX }, | ||
29 | { 0x801048, KEY_ESC }, | ||
30 | { 0x80104b, KEY_MEDIA }, /* Windows key */ | ||
31 | { 0x801083, KEY_MENU }, | ||
32 | { 0x801045, KEY_APPSELECT }, /* app launcher */ | ||
33 | { 0x801084, KEY_STOP }, | ||
34 | { 0x801046, KEY_CYCLEWINDOWS }, | ||
35 | { 0x801085, KEY_BACKSPACE }, | ||
36 | { 0x801086, KEY_KEYBOARD }, | ||
37 | { 0x801087, KEY_SPACE }, | ||
38 | { 0x80101e, KEY_RESERVED }, /* shift tab */ | ||
39 | { 0x801098, BTN_0 }, | ||
40 | { 0x80101f, KEY_TAB }, | ||
41 | { 0x80101b, BTN_LEFT }, | ||
42 | { 0x80101d, BTN_RIGHT }, | ||
43 | { 0x801016, BTN_MIDDLE }, /* drag and drop */ | ||
44 | { 0x801088, KEY_MUTE }, | ||
45 | { 0x80105e, KEY_VOLUMEDOWN }, | ||
46 | { 0x80105f, KEY_VOLUMEUP }, | ||
47 | { 0x80104c, KEY_PLAY }, | ||
48 | { 0x80104d, KEY_PAUSE }, | ||
49 | { 0x80104f, KEY_EJECTCD }, | ||
50 | { 0x801050, KEY_PREVIOUS }, | ||
51 | { 0x801051, KEY_NEXT }, | ||
52 | { 0x80104e, KEY_STOP }, | ||
53 | { 0x801052, KEY_REWIND }, | ||
54 | { 0x801053, KEY_FASTFORWARD }, | ||
55 | { 0x801089, KEY_ZOOM } /* full screen */ | ||
56 | }; | ||
57 | |||
58 | static struct rc_map_list imon_rsc_map = { | ||
59 | .map = { | ||
60 | .scan = imon_rsc, | ||
61 | .size = ARRAY_SIZE(imon_rsc), | ||
62 | .rc_proto = RC_PROTO_NEC, | ||
63 | .name = RC_MAP_IMON_RSC, | ||
64 | } | ||
65 | }; | ||
66 | |||
67 | static int __init init_rc_map_imon_rsc(void) | ||
68 | { | ||
69 | return rc_map_register(&imon_rsc_map); | ||
70 | } | ||
71 | |||
72 | static void __exit exit_rc_map_imon_rsc(void) | ||
73 | { | ||
74 | rc_map_unregister(&imon_rsc_map); | ||
75 | } | ||
76 | |||
77 | module_init(init_rc_map_imon_rsc) | ||
78 | module_exit(exit_rc_map_imon_rsc) | ||
79 | |||
80 | MODULE_LICENSE("GPL"); | ||
81 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index cc863044c880..24e9fbb80e81 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c | |||
@@ -60,12 +60,12 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev) | |||
60 | * space with the maximum time value. | 60 | * space with the maximum time value. |
61 | */ | 61 | */ |
62 | sample = LIRC_SPACE(LIRC_VALUE_MASK); | 62 | sample = LIRC_SPACE(LIRC_VALUE_MASK); |
63 | IR_dprintk(2, "delivering reset sync space to lirc_dev\n"); | 63 | dev_dbg(&dev->dev, "delivering reset sync space to lirc_dev\n"); |
64 | 64 | ||
65 | /* Carrier reports */ | 65 | /* Carrier reports */ |
66 | } else if (ev.carrier_report) { | 66 | } else if (ev.carrier_report) { |
67 | sample = LIRC_FREQUENCY(ev.carrier); | 67 | sample = LIRC_FREQUENCY(ev.carrier); |
68 | IR_dprintk(2, "carrier report (freq: %d)\n", sample); | 68 | dev_dbg(&dev->dev, "carrier report (freq: %d)\n", sample); |
69 | 69 | ||
70 | /* Packet end */ | 70 | /* Packet end */ |
71 | } else if (ev.timeout) { | 71 | } else if (ev.timeout) { |
@@ -77,7 +77,7 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev) | |||
77 | dev->gap_duration = ev.duration; | 77 | dev->gap_duration = ev.duration; |
78 | 78 | ||
79 | sample = LIRC_TIMEOUT(ev.duration / 1000); | 79 | sample = LIRC_TIMEOUT(ev.duration / 1000); |
80 | IR_dprintk(2, "timeout report (duration: %d)\n", sample); | 80 | dev_dbg(&dev->dev, "timeout report (duration: %d)\n", sample); |
81 | 81 | ||
82 | /* Normal sample */ | 82 | /* Normal sample */ |
83 | } else { | 83 | } else { |
@@ -100,8 +100,8 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev) | |||
100 | 100 | ||
101 | sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : | 101 | sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : |
102 | LIRC_SPACE(ev.duration / 1000); | 102 | LIRC_SPACE(ev.duration / 1000); |
103 | IR_dprintk(2, "delivering %uus %s to lirc_dev\n", | 103 | dev_dbg(&dev->dev, "delivering %uus %s to lirc_dev\n", |
104 | TO_US(ev.duration), TO_STR(ev.pulse)); | 104 | TO_US(ev.duration), TO_STR(ev.pulse)); |
105 | } | 105 | } |
106 | 106 | ||
107 | spin_lock_irqsave(&dev->lirc_fh_lock, flags); | 107 | spin_lock_irqsave(&dev->lirc_fh_lock, flags); |
@@ -249,8 +249,6 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, | |||
249 | goto out_unlock; | 249 | goto out_unlock; |
250 | } | 250 | } |
251 | 251 | ||
252 | start = ktime_get(); | ||
253 | |||
254 | if (!dev->tx_ir) { | 252 | if (!dev->tx_ir) { |
255 | ret = -EINVAL; | 253 | ret = -EINVAL; |
256 | goto out_unlock; | 254 | goto out_unlock; |
@@ -343,6 +341,8 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, | |||
343 | duration += txbuf[i]; | 341 | duration += txbuf[i]; |
344 | } | 342 | } |
345 | 343 | ||
344 | start = ktime_get(); | ||
345 | |||
346 | ret = dev->tx_ir(dev, txbuf, count); | 346 | ret = dev->tx_ir(dev, txbuf, count); |
347 | if (ret < 0) | 347 | if (ret < 0) |
348 | goto out_kfree; | 348 | goto out_kfree; |
@@ -570,7 +570,7 @@ static long ir_lirc_ioctl(struct file *file, unsigned int cmd, | |||
570 | ret = -EINVAL; | 570 | ret = -EINVAL; |
571 | else if (dev->s_timeout) | 571 | else if (dev->s_timeout) |
572 | ret = dev->s_timeout(dev, tmp); | 572 | ret = dev->s_timeout(dev, tmp); |
573 | else if (!ret) | 573 | else |
574 | dev->timeout = tmp; | 574 | dev->timeout = tmp; |
575 | } | 575 | } |
576 | break; | 576 | break; |
@@ -804,8 +804,8 @@ int __init lirc_dev_init(void) | |||
804 | return retval; | 804 | return retval; |
805 | } | 805 | } |
806 | 806 | ||
807 | pr_info("IR Remote Control driver registered, major %d\n", | 807 | pr_debug("IR Remote Control driver registered, major %d\n", |
808 | MAJOR(lirc_base_dev)); | 808 | MAJOR(lirc_base_dev)); |
809 | 809 | ||
810 | return 0; | 810 | return 0; |
811 | } | 811 | } |
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index a9187b0b46a1..69ba57372c05 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/pm_wakeup.h> | 42 | #include <linux/pm_wakeup.h> |
43 | #include <media/rc-core.h> | 43 | #include <media/rc-core.h> |
44 | 44 | ||
45 | #define DRIVER_VERSION "1.93" | 45 | #define DRIVER_VERSION "1.94" |
46 | #define DRIVER_AUTHOR "Jarod Wilson <jarod@redhat.com>" | 46 | #define DRIVER_AUTHOR "Jarod Wilson <jarod@redhat.com>" |
47 | #define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \ | 47 | #define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \ |
48 | "device driver" | 48 | "device driver" |
@@ -182,6 +182,7 @@ enum mceusb_model_type { | |||
182 | MCE_GEN1, | 182 | MCE_GEN1, |
183 | MCE_GEN3, | 183 | MCE_GEN3, |
184 | MCE_GEN2_TX_INV, | 184 | MCE_GEN2_TX_INV, |
185 | MCE_GEN2_TX_INV_RX_GOOD, | ||
185 | POLARIS_EVK, | 186 | POLARIS_EVK, |
186 | CX_HYBRID_TV, | 187 | CX_HYBRID_TV, |
187 | MULTIFUNCTION, | 188 | MULTIFUNCTION, |
@@ -198,6 +199,13 @@ struct mceusb_model { | |||
198 | u32 mce_gen3:1; | 199 | u32 mce_gen3:1; |
199 | u32 tx_mask_normal:1; | 200 | u32 tx_mask_normal:1; |
200 | u32 no_tx:1; | 201 | u32 no_tx:1; |
202 | /* | ||
203 | * 2nd IR receiver (short-range, wideband) for learning mode: | ||
204 | * 0, absent 2nd receiver (rx2) | ||
205 | * 1, rx2 present | ||
206 | * 2, rx2 which under counts IR carrier cycles | ||
207 | */ | ||
208 | u32 rx2; | ||
201 | 209 | ||
202 | int ir_intfnum; | 210 | int ir_intfnum; |
203 | 211 | ||
@@ -209,9 +217,11 @@ static const struct mceusb_model mceusb_model[] = { | |||
209 | [MCE_GEN1] = { | 217 | [MCE_GEN1] = { |
210 | .mce_gen1 = 1, | 218 | .mce_gen1 = 1, |
211 | .tx_mask_normal = 1, | 219 | .tx_mask_normal = 1, |
220 | .rx2 = 2, | ||
212 | }, | 221 | }, |
213 | [MCE_GEN2] = { | 222 | [MCE_GEN2] = { |
214 | .mce_gen2 = 1, | 223 | .mce_gen2 = 1, |
224 | .rx2 = 2, | ||
215 | }, | 225 | }, |
216 | [MCE_GEN2_NO_TX] = { | 226 | [MCE_GEN2_NO_TX] = { |
217 | .mce_gen2 = 1, | 227 | .mce_gen2 = 1, |
@@ -220,10 +230,17 @@ static const struct mceusb_model mceusb_model[] = { | |||
220 | [MCE_GEN2_TX_INV] = { | 230 | [MCE_GEN2_TX_INV] = { |
221 | .mce_gen2 = 1, | 231 | .mce_gen2 = 1, |
222 | .tx_mask_normal = 1, | 232 | .tx_mask_normal = 1, |
233 | .rx2 = 1, | ||
234 | }, | ||
235 | [MCE_GEN2_TX_INV_RX_GOOD] = { | ||
236 | .mce_gen2 = 1, | ||
237 | .tx_mask_normal = 1, | ||
238 | .rx2 = 2, | ||
223 | }, | 239 | }, |
224 | [MCE_GEN3] = { | 240 | [MCE_GEN3] = { |
225 | .mce_gen3 = 1, | 241 | .mce_gen3 = 1, |
226 | .tx_mask_normal = 1, | 242 | .tx_mask_normal = 1, |
243 | .rx2 = 2, | ||
227 | }, | 244 | }, |
228 | [POLARIS_EVK] = { | 245 | [POLARIS_EVK] = { |
229 | /* | 246 | /* |
@@ -232,6 +249,7 @@ static const struct mceusb_model mceusb_model[] = { | |||
232 | * to allow testing it | 249 | * to allow testing it |
233 | */ | 250 | */ |
234 | .name = "Conexant Hybrid TV (cx231xx) MCE IR", | 251 | .name = "Conexant Hybrid TV (cx231xx) MCE IR", |
252 | .rx2 = 2, | ||
235 | }, | 253 | }, |
236 | [CX_HYBRID_TV] = { | 254 | [CX_HYBRID_TV] = { |
237 | .no_tx = 1, /* tx isn't wired up at all */ | 255 | .no_tx = 1, /* tx isn't wired up at all */ |
@@ -244,10 +262,12 @@ static const struct mceusb_model mceusb_model[] = { | |||
244 | [MULTIFUNCTION] = { | 262 | [MULTIFUNCTION] = { |
245 | .mce_gen2 = 1, | 263 | .mce_gen2 = 1, |
246 | .ir_intfnum = 2, | 264 | .ir_intfnum = 2, |
265 | .rx2 = 2, | ||
247 | }, | 266 | }, |
248 | [TIVO_KIT] = { | 267 | [TIVO_KIT] = { |
249 | .mce_gen2 = 1, | 268 | .mce_gen2 = 1, |
250 | .rc_map = RC_MAP_TIVO, | 269 | .rc_map = RC_MAP_TIVO, |
270 | .rx2 = 2, | ||
251 | }, | 271 | }, |
252 | [EVROMEDIA_FULL_HYBRID_FULLHD] = { | 272 | [EVROMEDIA_FULL_HYBRID_FULLHD] = { |
253 | .name = "Evromedia USB Full Hybrid Full HD", | 273 | .name = "Evromedia USB Full Hybrid Full HD", |
@@ -290,7 +310,7 @@ static const struct usb_device_id mceusb_dev_table[] = { | |||
290 | .driver_info = MULTIFUNCTION }, | 310 | .driver_info = MULTIFUNCTION }, |
291 | /* SMK/Toshiba G83C0004D410 */ | 311 | /* SMK/Toshiba G83C0004D410 */ |
292 | { USB_DEVICE(VENDOR_SMK, 0x031d), | 312 | { USB_DEVICE(VENDOR_SMK, 0x031d), |
293 | .driver_info = MCE_GEN2_TX_INV }, | 313 | .driver_info = MCE_GEN2_TX_INV_RX_GOOD }, |
294 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ | 314 | /* SMK eHome Infrared Transceiver (Sony VAIO) */ |
295 | { USB_DEVICE(VENDOR_SMK, 0x0322), | 315 | { USB_DEVICE(VENDOR_SMK, 0x0322), |
296 | .driver_info = MCE_GEN2_TX_INV }, | 316 | .driver_info = MCE_GEN2_TX_INV }, |
@@ -427,7 +447,8 @@ struct mceusb_dev { | |||
427 | struct rc_dev *rc; | 447 | struct rc_dev *rc; |
428 | 448 | ||
429 | /* optional features we can enable */ | 449 | /* optional features we can enable */ |
430 | bool learning_enabled; | 450 | bool carrier_report_enabled; |
451 | bool wideband_rx_enabled; /* aka learning mode, short-range rx */ | ||
431 | 452 | ||
432 | /* core device bits */ | 453 | /* core device bits */ |
433 | struct device *dev; | 454 | struct device *dev; |
@@ -458,6 +479,7 @@ struct mceusb_dev { | |||
458 | u32 tx_mask_normal:1; | 479 | u32 tx_mask_normal:1; |
459 | u32 microsoft_gen1:1; | 480 | u32 microsoft_gen1:1; |
460 | u32 no_tx:1; | 481 | u32 no_tx:1; |
482 | u32 rx2; | ||
461 | } flags; | 483 | } flags; |
462 | 484 | ||
463 | /* transmit support */ | 485 | /* transmit support */ |
@@ -474,6 +496,11 @@ struct mceusb_dev { | |||
474 | u8 num_rxports; /* number of receive sensors */ | 496 | u8 num_rxports; /* number of receive sensors */ |
475 | u8 txports_cabled; /* bitmask of transmitters with cable */ | 497 | u8 txports_cabled; /* bitmask of transmitters with cable */ |
476 | u8 rxports_active; /* bitmask of active receive sensors */ | 498 | u8 rxports_active; /* bitmask of active receive sensors */ |
499 | bool learning_active; /* wideband rx is active */ | ||
500 | |||
501 | /* receiver carrier frequency detection support */ | ||
502 | u32 pulse_tunit; /* IR pulse "on" cumulative time units */ | ||
503 | u32 pulse_count; /* pulse "on" count in measurement interval */ | ||
477 | 504 | ||
478 | /* | 505 | /* |
479 | * support for async error handler mceusb_deferred_kevent() | 506 | * support for async error handler mceusb_deferred_kevent() |
@@ -684,8 +711,8 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len, | |||
684 | /* aka MCE_RSP_EQIRRXCFCNT */ | 711 | /* aka MCE_RSP_EQIRRXCFCNT */ |
685 | if (out) | 712 | if (out) |
686 | dev_dbg(dev, "Get receive sensor"); | 713 | dev_dbg(dev, "Get receive sensor"); |
687 | else if (ir->learning_enabled) | 714 | else |
688 | dev_dbg(dev, "RX pulse count: %d", | 715 | dev_dbg(dev, "RX carrier cycle count: %d", |
689 | ((data[0] << 8) | data[1])); | 716 | ((data[0] << 8) | data[1])); |
690 | break; | 717 | break; |
691 | case MCE_RSP_EQIRNUMPORTS: | 718 | case MCE_RSP_EQIRNUMPORTS: |
@@ -956,14 +983,78 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) | |||
956 | } | 983 | } |
957 | 984 | ||
958 | /* | 985 | /* |
986 | * Select or deselect the 2nd receiver port. | ||
987 | * Second receiver is learning mode, wide-band, short-range receiver. | ||
988 | * Only one receiver (long or short range) may be active at a time. | ||
989 | */ | ||
990 | static int mceusb_set_rx_wideband(struct rc_dev *dev, int enable) | ||
991 | { | ||
992 | struct mceusb_dev *ir = dev->priv; | ||
993 | unsigned char cmdbuf[3] = { MCE_CMD_PORT_IR, | ||
994 | MCE_CMD_SETIRRXPORTEN, 0x00 }; | ||
995 | |||
996 | dev_dbg(ir->dev, "select %s-range receive sensor", | ||
997 | enable ? "short" : "long"); | ||
998 | if (enable) { | ||
999 | ir->wideband_rx_enabled = true; | ||
1000 | cmdbuf[2] = 2; /* port 2 is short range receiver */ | ||
1001 | } else { | ||
1002 | ir->wideband_rx_enabled = false; | ||
1003 | cmdbuf[2] = 1; /* port 1 is long range receiver */ | ||
1004 | } | ||
1005 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | ||
1006 | /* response from device sets ir->learning_active */ | ||
1007 | |||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | /* | ||
1012 | * Enable/disable receiver carrier frequency pass through reporting. | ||
1013 | * Only the short-range receiver has carrier frequency measuring capability. | ||
1014 | * Implicitly select this receiver when enabling carrier frequency reporting. | ||
1015 | */ | ||
1016 | static int mceusb_set_rx_carrier_report(struct rc_dev *dev, int enable) | ||
1017 | { | ||
1018 | struct mceusb_dev *ir = dev->priv; | ||
1019 | unsigned char cmdbuf[3] = { MCE_CMD_PORT_IR, | ||
1020 | MCE_CMD_SETIRRXPORTEN, 0x00 }; | ||
1021 | |||
1022 | dev_dbg(ir->dev, "%s short-range receiver carrier reporting", | ||
1023 | enable ? "enable" : "disable"); | ||
1024 | if (enable) { | ||
1025 | ir->carrier_report_enabled = true; | ||
1026 | if (!ir->learning_active) { | ||
1027 | cmdbuf[2] = 2; /* port 2 is short range receiver */ | ||
1028 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | ||
1029 | } | ||
1030 | } else { | ||
1031 | ir->carrier_report_enabled = false; | ||
1032 | /* | ||
1033 | * Revert to normal (long-range) receiver only if the | ||
1034 | * wideband (short-range) receiver wasn't explicitly | ||
1035 | * enabled. | ||
1036 | */ | ||
1037 | if (ir->learning_active && !ir->wideband_rx_enabled) { | ||
1038 | cmdbuf[2] = 1; /* port 1 is long range receiver */ | ||
1039 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1046 | /* | ||
959 | * We don't do anything but print debug spew for many of the command bits | 1047 | * We don't do anything but print debug spew for many of the command bits |
960 | * we receive from the hardware, but some of them are useful information | 1048 | * we receive from the hardware, but some of them are useful information |
961 | * we want to store so that we can use them. | 1049 | * we want to store so that we can use them. |
962 | */ | 1050 | */ |
963 | static void mceusb_handle_command(struct mceusb_dev *ir, int index) | 1051 | static void mceusb_handle_command(struct mceusb_dev *ir, int index) |
964 | { | 1052 | { |
1053 | DEFINE_IR_RAW_EVENT(rawir); | ||
965 | u8 hi = ir->buf_in[index + 1] & 0xff; | 1054 | u8 hi = ir->buf_in[index + 1] & 0xff; |
966 | u8 lo = ir->buf_in[index + 2] & 0xff; | 1055 | u8 lo = ir->buf_in[index + 2] & 0xff; |
1056 | u32 carrier_cycles; | ||
1057 | u32 cycles_fix; | ||
967 | 1058 | ||
968 | switch (ir->buf_in[index]) { | 1059 | switch (ir->buf_in[index]) { |
969 | /* the one and only 5-byte return value command */ | 1060 | /* the one and only 5-byte return value command */ |
@@ -980,6 +1071,33 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) | |||
980 | ir->num_txports = hi; | 1071 | ir->num_txports = hi; |
981 | ir->num_rxports = lo; | 1072 | ir->num_rxports = lo; |
982 | break; | 1073 | break; |
1074 | case MCE_RSP_EQIRRXCFCNT: | ||
1075 | /* | ||
1076 | * The carrier cycle counter can overflow and wrap around | ||
1077 | * without notice from the device. So frequency measurement | ||
1078 | * will be inaccurate with long duration IR. | ||
1079 | * | ||
1080 | * The long-range (non learning) receiver always reports | ||
1081 | * zero count so we always ignore its report. | ||
1082 | */ | ||
1083 | if (ir->carrier_report_enabled && ir->learning_active && | ||
1084 | ir->pulse_tunit > 0) { | ||
1085 | carrier_cycles = (hi << 8 | lo); | ||
1086 | /* | ||
1087 | * Adjust carrier cycle count by adding | ||
1088 | * 1 missed count per pulse "on" | ||
1089 | */ | ||
1090 | cycles_fix = ir->flags.rx2 == 2 ? ir->pulse_count : 0; | ||
1091 | rawir.carrier_report = 1; | ||
1092 | rawir.carrier = (1000000u / MCE_TIME_UNIT) * | ||
1093 | (carrier_cycles + cycles_fix) / | ||
1094 | ir->pulse_tunit; | ||
1095 | dev_dbg(ir->dev, "RX carrier frequency %u Hz (pulse count = %u, cycles = %u, duration = %u, rx2 = %u)", | ||
1096 | rawir.carrier, ir->pulse_count, carrier_cycles, | ||
1097 | ir->pulse_tunit, ir->flags.rx2); | ||
1098 | ir_raw_event_store(ir->rc, &rawir); | ||
1099 | } | ||
1100 | break; | ||
983 | 1101 | ||
984 | /* 1-byte return value commands */ | 1102 | /* 1-byte return value commands */ |
985 | case MCE_RSP_EQEMVER: | 1103 | case MCE_RSP_EQEMVER: |
@@ -989,8 +1107,12 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) | |||
989 | ir->tx_mask = hi; | 1107 | ir->tx_mask = hi; |
990 | break; | 1108 | break; |
991 | case MCE_RSP_EQIRRXPORTEN: | 1109 | case MCE_RSP_EQIRRXPORTEN: |
992 | ir->learning_enabled = ((hi & 0x02) == 0x02); | 1110 | ir->learning_active = ((hi & 0x02) == 0x02); |
993 | ir->rxports_active = hi; | 1111 | if (ir->rxports_active != hi) { |
1112 | dev_info(ir->dev, "%s-range (0x%x) receiver active", | ||
1113 | ir->learning_active ? "short" : "long", hi); | ||
1114 | ir->rxports_active = hi; | ||
1115 | } | ||
994 | break; | 1116 | break; |
995 | case MCE_RSP_CMD_ILLEGAL: | 1117 | case MCE_RSP_CMD_ILLEGAL: |
996 | ir->need_reset = true; | 1118 | ir->need_reset = true; |
@@ -1027,12 +1149,16 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
1027 | ir->rem--; | 1149 | ir->rem--; |
1028 | init_ir_raw_event(&rawir); | 1150 | init_ir_raw_event(&rawir); |
1029 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); | 1151 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); |
1030 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | 1152 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK); |
1031 | * US_TO_NS(MCE_TIME_UNIT); | 1153 | if (rawir.pulse) { |
1154 | ir->pulse_tunit += rawir.duration; | ||
1155 | ir->pulse_count++; | ||
1156 | } | ||
1157 | rawir.duration *= US_TO_NS(MCE_TIME_UNIT); | ||
1032 | 1158 | ||
1033 | dev_dbg(ir->dev, "Storing %s with duration %u", | 1159 | dev_dbg(ir->dev, "Storing %s %u ns (%02x)", |
1034 | rawir.pulse ? "pulse" : "space", | 1160 | rawir.pulse ? "pulse" : "space", |
1035 | rawir.duration); | 1161 | rawir.duration, ir->buf_in[i]); |
1036 | 1162 | ||
1037 | if (ir_raw_event_store_with_filter(ir->rc, &rawir)) | 1163 | if (ir_raw_event_store_with_filter(ir->rc, &rawir)) |
1038 | event = true; | 1164 | event = true; |
@@ -1053,10 +1179,13 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
1053 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); | 1179 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); |
1054 | mceusb_dev_printdata(ir, ir->buf_in, buf_len, | 1180 | mceusb_dev_printdata(ir, ir->buf_in, buf_len, |
1055 | i, ir->rem + 1, false); | 1181 | i, ir->rem + 1, false); |
1056 | if (ir->rem) | 1182 | if (ir->rem) { |
1057 | ir->parser_state = PARSE_IRDATA; | 1183 | ir->parser_state = PARSE_IRDATA; |
1058 | else | 1184 | } else { |
1059 | ir_raw_event_reset(ir->rc); | 1185 | ir_raw_event_reset(ir->rc); |
1186 | ir->pulse_tunit = 0; | ||
1187 | ir->pulse_count = 0; | ||
1188 | } | ||
1060 | break; | 1189 | break; |
1061 | } | 1190 | } |
1062 | 1191 | ||
@@ -1292,6 +1421,10 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) | |||
1292 | rc->s_tx_carrier = mceusb_set_tx_carrier; | 1421 | rc->s_tx_carrier = mceusb_set_tx_carrier; |
1293 | rc->tx_ir = mceusb_tx_ir; | 1422 | rc->tx_ir = mceusb_tx_ir; |
1294 | } | 1423 | } |
1424 | if (ir->flags.rx2 > 0) { | ||
1425 | rc->s_learning_mode = mceusb_set_rx_wideband; | ||
1426 | rc->s_carrier_report = mceusb_set_rx_carrier_report; | ||
1427 | } | ||
1295 | rc->driver_name = DRIVER_NAME; | 1428 | rc->driver_name = DRIVER_NAME; |
1296 | 1429 | ||
1297 | switch (le16_to_cpu(udev->descriptor.idVendor)) { | 1430 | switch (le16_to_cpu(udev->descriptor.idVendor)) { |
@@ -1406,6 +1539,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, | |||
1406 | ir->flags.microsoft_gen1 = is_microsoft_gen1; | 1539 | ir->flags.microsoft_gen1 = is_microsoft_gen1; |
1407 | ir->flags.tx_mask_normal = tx_mask_normal; | 1540 | ir->flags.tx_mask_normal = tx_mask_normal; |
1408 | ir->flags.no_tx = mceusb_model[model].no_tx; | 1541 | ir->flags.no_tx = mceusb_model[model].no_tx; |
1542 | ir->flags.rx2 = mceusb_model[model].rx2; | ||
1409 | ir->model = model; | 1543 | ir->model = model; |
1410 | 1544 | ||
1411 | /* Saving usb interface data for use by the transmitter routine */ | 1545 | /* Saving usb interface data for use by the transmitter routine */ |
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index f2204eb77e2a..f449b35d25e7 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c | |||
@@ -97,8 +97,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) | |||
97 | status = readl_relaxed(ir->reg + IR_DEC_STATUS); | 97 | status = readl_relaxed(ir->reg + IR_DEC_STATUS); |
98 | rawir.pulse = !!(status & STATUS_IR_DEC_IN); | 98 | rawir.pulse = !!(status & STATUS_IR_DEC_IN); |
99 | 99 | ||
100 | ir_raw_event_store(ir->rc, &rawir); | 100 | ir_raw_event_store_with_timeout(ir->rc, &rawir); |
101 | ir_raw_event_handle(ir->rc); | ||
102 | 101 | ||
103 | spin_unlock(&ir->lock); | 102 | spin_unlock(&ir->lock); |
104 | 103 | ||
@@ -145,7 +144,9 @@ static int meson_ir_probe(struct platform_device *pdev) | |||
145 | ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; | 144 | ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; |
146 | ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; | 145 | ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; |
147 | ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); | 146 | ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); |
148 | ir->rc->timeout = MS_TO_NS(200); | 147 | ir->rc->min_timeout = 1; |
148 | ir->rc->timeout = IR_DEFAULT_TIMEOUT; | ||
149 | ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; | ||
149 | ir->rc->driver_name = DRIVER_NAME; | 150 | ir->rc->driver_name = DRIVER_NAME; |
150 | 151 | ||
151 | spin_lock_init(&ir->lock); | 152 | spin_lock_init(&ir->lock); |
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 458e9eb2d6a9..e0e6a17460f6 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h | |||
@@ -50,8 +50,9 @@ struct ir_raw_event_ctrl { | |||
50 | DECLARE_KFIFO(kfifo, struct ir_raw_event, MAX_IR_EVENT_SIZE); | 50 | DECLARE_KFIFO(kfifo, struct ir_raw_event, MAX_IR_EVENT_SIZE); |
51 | ktime_t last_event; /* when last event occurred */ | 51 | ktime_t last_event; /* when last event occurred */ |
52 | struct rc_dev *dev; /* pointer to the parent rc_dev */ | 52 | struct rc_dev *dev; /* pointer to the parent rc_dev */ |
53 | /* edge driver */ | 53 | /* handle delayed ir_raw_event_store_edge processing */ |
54 | struct timer_list edge_handle; | 54 | spinlock_t edge_spinlock; |
55 | struct timer_list edge_handle; | ||
55 | 56 | ||
56 | /* raw decoder state follows */ | 57 | /* raw decoder state follows */ |
57 | struct ir_raw_event prev_ev; | 58 | struct ir_raw_event prev_ev; |
@@ -117,6 +118,12 @@ struct ir_raw_event_ctrl { | |||
117 | unsigned count; | 118 | unsigned count; |
118 | u32 durations[16]; | 119 | u32 durations[16]; |
119 | } xmp; | 120 | } xmp; |
121 | struct imon_dec { | ||
122 | int state; | ||
123 | int count; | ||
124 | int last_chk; | ||
125 | unsigned int bits; | ||
126 | } imon; | ||
120 | }; | 127 | }; |
121 | 128 | ||
122 | /* macros for IR decoders */ | 129 | /* macros for IR decoders */ |
@@ -292,11 +299,4 @@ static inline int ir_lirc_register(struct rc_dev *dev) { return 0; } | |||
292 | static inline void ir_lirc_unregister(struct rc_dev *dev) { } | 299 | static inline void ir_lirc_unregister(struct rc_dev *dev) { } |
293 | #endif | 300 | #endif |
294 | 301 | ||
295 | /* | ||
296 | * Decoder initialization code | ||
297 | * | ||
298 | * Those load logic are called during ir-core init, and automatically | ||
299 | * loads the compiled decoders for their usage with IR raw events | ||
300 | */ | ||
301 | |||
302 | #endif /* _RC_CORE_PRIV */ | 302 | #endif /* _RC_CORE_PRIV */ |
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 18504870b9f0..374f83105a23 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c | |||
@@ -65,8 +65,8 @@ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) | |||
65 | if (!dev->raw) | 65 | if (!dev->raw) |
66 | return -EINVAL; | 66 | return -EINVAL; |
67 | 67 | ||
68 | IR_dprintk(2, "sample: (%05dus %s)\n", | 68 | dev_dbg(&dev->dev, "sample: (%05dus %s)\n", |
69 | TO_US(ev->duration), TO_STR(ev->pulse)); | 69 | TO_US(ev->duration), TO_STR(ev->pulse)); |
70 | 70 | ||
71 | if (!kfifo_put(&dev->raw->kfifo, *ev)) { | 71 | if (!kfifo_put(&dev->raw->kfifo, *ev)) { |
72 | dev_err(&dev->dev, "IR event FIFO is full!\n"); | 72 | dev_err(&dev->dev, "IR event FIFO is full!\n"); |
@@ -92,7 +92,6 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) | |||
92 | { | 92 | { |
93 | ktime_t now; | 93 | ktime_t now; |
94 | DEFINE_IR_RAW_EVENT(ev); | 94 | DEFINE_IR_RAW_EVENT(ev); |
95 | int rc = 0; | ||
96 | 95 | ||
97 | if (!dev->raw) | 96 | if (!dev->raw) |
98 | return -EINVAL; | 97 | return -EINVAL; |
@@ -101,7 +100,33 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) | |||
101 | ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); | 100 | ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); |
102 | ev.pulse = !pulse; | 101 | ev.pulse = !pulse; |
103 | 102 | ||
104 | rc = ir_raw_event_store(dev, &ev); | 103 | return ir_raw_event_store_with_timeout(dev, &ev); |
104 | } | ||
105 | EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); | ||
106 | |||
107 | /* | ||
108 | * ir_raw_event_store_with_timeout() - pass a pulse/space duration to the raw | ||
109 | * ir decoders, schedule decoding and | ||
110 | * timeout | ||
111 | * @dev: the struct rc_dev device descriptor | ||
112 | * @ev: the struct ir_raw_event descriptor of the pulse/space | ||
113 | * | ||
114 | * This routine (which may be called from an interrupt context) stores a | ||
115 | * pulse/space duration for the raw ir decoding state machines, schedules | ||
116 | * decoding and generates a timeout. | ||
117 | */ | ||
118 | int ir_raw_event_store_with_timeout(struct rc_dev *dev, struct ir_raw_event *ev) | ||
119 | { | ||
120 | ktime_t now; | ||
121 | int rc = 0; | ||
122 | |||
123 | if (!dev->raw) | ||
124 | return -EINVAL; | ||
125 | |||
126 | now = ktime_get(); | ||
127 | |||
128 | spin_lock(&dev->raw->edge_spinlock); | ||
129 | rc = ir_raw_event_store(dev, ev); | ||
105 | 130 | ||
106 | dev->raw->last_event = now; | 131 | dev->raw->last_event = now; |
107 | 132 | ||
@@ -112,10 +137,11 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) | |||
112 | mod_timer(&dev->raw->edge_handle, | 137 | mod_timer(&dev->raw->edge_handle, |
113 | jiffies + msecs_to_jiffies(15)); | 138 | jiffies + msecs_to_jiffies(15)); |
114 | } | 139 | } |
140 | spin_unlock(&dev->raw->edge_spinlock); | ||
115 | 141 | ||
116 | return rc; | 142 | return rc; |
117 | } | 143 | } |
118 | EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); | 144 | EXPORT_SYMBOL_GPL(ir_raw_event_store_with_timeout); |
119 | 145 | ||
120 | /** | 146 | /** |
121 | * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing | 147 | * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing |
@@ -168,7 +194,7 @@ void ir_raw_event_set_idle(struct rc_dev *dev, bool idle) | |||
168 | if (!dev->raw) | 194 | if (!dev->raw) |
169 | return; | 195 | return; |
170 | 196 | ||
171 | IR_dprintk(2, "%s idle mode\n", idle ? "enter" : "leave"); | 197 | dev_dbg(&dev->dev, "%s idle mode\n", idle ? "enter" : "leave"); |
172 | 198 | ||
173 | if (idle) { | 199 | if (idle) { |
174 | dev->raw->this_ev.timeout = true; | 200 | dev->raw->this_ev.timeout = true; |
@@ -462,12 +488,26 @@ int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, | |||
462 | } | 488 | } |
463 | EXPORT_SYMBOL(ir_raw_encode_scancode); | 489 | EXPORT_SYMBOL(ir_raw_encode_scancode); |
464 | 490 | ||
465 | static void edge_handle(struct timer_list *t) | 491 | /** |
492 | * ir_raw_edge_handle() - Handle ir_raw_event_store_edge() processing | ||
493 | * | ||
494 | * @t: timer_list | ||
495 | * | ||
496 | * This callback is armed by ir_raw_event_store_edge(). It does two things: | ||
497 | * first of all, rather than calling ir_raw_event_handle() for each | ||
498 | * edge and waking up the rc thread, 15 ms after the first edge | ||
499 | * ir_raw_event_handle() is called. Secondly, generate a timeout event | ||
500 | * no more IR is received after the rc_dev timeout. | ||
501 | */ | ||
502 | static void ir_raw_edge_handle(struct timer_list *t) | ||
466 | { | 503 | { |
467 | struct ir_raw_event_ctrl *raw = from_timer(raw, t, edge_handle); | 504 | struct ir_raw_event_ctrl *raw = from_timer(raw, t, edge_handle); |
468 | struct rc_dev *dev = raw->dev; | 505 | struct rc_dev *dev = raw->dev; |
469 | ktime_t interval = ktime_sub(ktime_get(), dev->raw->last_event); | 506 | unsigned long flags; |
507 | ktime_t interval; | ||
470 | 508 | ||
509 | spin_lock_irqsave(&dev->raw->edge_spinlock, flags); | ||
510 | interval = ktime_sub(ktime_get(), dev->raw->last_event); | ||
471 | if (ktime_to_ns(interval) >= dev->timeout) { | 511 | if (ktime_to_ns(interval) >= dev->timeout) { |
472 | DEFINE_IR_RAW_EVENT(ev); | 512 | DEFINE_IR_RAW_EVENT(ev); |
473 | 513 | ||
@@ -480,6 +520,7 @@ static void edge_handle(struct timer_list *t) | |||
480 | jiffies + nsecs_to_jiffies(dev->timeout - | 520 | jiffies + nsecs_to_jiffies(dev->timeout - |
481 | ktime_to_ns(interval))); | 521 | ktime_to_ns(interval))); |
482 | } | 522 | } |
523 | spin_unlock_irqrestore(&dev->raw->edge_spinlock, flags); | ||
483 | 524 | ||
484 | ir_raw_event_handle(dev); | 525 | ir_raw_event_handle(dev); |
485 | } | 526 | } |
@@ -528,7 +569,8 @@ int ir_raw_event_prepare(struct rc_dev *dev) | |||
528 | 569 | ||
529 | dev->raw->dev = dev; | 570 | dev->raw->dev = dev; |
530 | dev->change_protocol = change_protocol; | 571 | dev->change_protocol = change_protocol; |
531 | timer_setup(&dev->raw->edge_handle, edge_handle, 0); | 572 | spin_lock_init(&dev->raw->edge_spinlock); |
573 | timer_setup(&dev->raw->edge_handle, ir_raw_edge_handle, 0); | ||
532 | INIT_KFIFO(dev->raw->kfifo); | 574 | INIT_KFIFO(dev->raw->kfifo); |
533 | 575 | ||
534 | return 0; | 576 | return 0; |
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 1db8d38fed7c..b67be33bd62f 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -68,6 +68,8 @@ static const struct { | |||
68 | .scancode_bits = 0x1fff, .repeat_period = 250 }, | 68 | .scancode_bits = 0x1fff, .repeat_period = 250 }, |
69 | [RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 250 }, | 69 | [RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 250 }, |
70 | [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 550 }, | 70 | [RC_PROTO_CEC] = { .name = "cec", .repeat_period = 550 }, |
71 | [RC_PROTO_IMON] = { .name = "imon", | ||
72 | .scancode_bits = 0x7fffffff, .repeat_period = 250 }, | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | /* Used to keep track of known keymaps */ | 75 | /* Used to keep track of known keymaps */ |
@@ -156,6 +158,7 @@ static struct rc_map_list empty_map = { | |||
156 | 158 | ||
157 | /** | 159 | /** |
158 | * ir_create_table() - initializes a scancode table | 160 | * ir_create_table() - initializes a scancode table |
161 | * @dev: the rc_dev device | ||
159 | * @rc_map: the rc_map to initialize | 162 | * @rc_map: the rc_map to initialize |
160 | * @name: name to assign to the table | 163 | * @name: name to assign to the table |
161 | * @rc_proto: ir type to assign to the new table | 164 | * @rc_proto: ir type to assign to the new table |
@@ -166,7 +169,7 @@ static struct rc_map_list empty_map = { | |||
166 | * | 169 | * |
167 | * return: zero on success or a negative error code | 170 | * return: zero on success or a negative error code |
168 | */ | 171 | */ |
169 | static int ir_create_table(struct rc_map *rc_map, | 172 | static int ir_create_table(struct rc_dev *dev, struct rc_map *rc_map, |
170 | const char *name, u64 rc_proto, size_t size) | 173 | const char *name, u64 rc_proto, size_t size) |
171 | { | 174 | { |
172 | rc_map->name = kstrdup(name, GFP_KERNEL); | 175 | rc_map->name = kstrdup(name, GFP_KERNEL); |
@@ -182,8 +185,8 @@ static int ir_create_table(struct rc_map *rc_map, | |||
182 | return -ENOMEM; | 185 | return -ENOMEM; |
183 | } | 186 | } |
184 | 187 | ||
185 | IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", | 188 | dev_dbg(&dev->dev, "Allocated space for %u keycode entries (%u bytes)\n", |
186 | rc_map->size, rc_map->alloc); | 189 | rc_map->size, rc_map->alloc); |
187 | return 0; | 190 | return 0; |
188 | } | 191 | } |
189 | 192 | ||
@@ -205,6 +208,7 @@ static void ir_free_table(struct rc_map *rc_map) | |||
205 | 208 | ||
206 | /** | 209 | /** |
207 | * ir_resize_table() - resizes a scancode table if necessary | 210 | * ir_resize_table() - resizes a scancode table if necessary |
211 | * @dev: the rc_dev device | ||
208 | * @rc_map: the rc_map to resize | 212 | * @rc_map: the rc_map to resize |
209 | * @gfp_flags: gfp flags to use when allocating memory | 213 | * @gfp_flags: gfp flags to use when allocating memory |
210 | * | 214 | * |
@@ -213,7 +217,8 @@ static void ir_free_table(struct rc_map *rc_map) | |||
213 | * | 217 | * |
214 | * return: zero on success or a negative error code | 218 | * return: zero on success or a negative error code |
215 | */ | 219 | */ |
216 | static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) | 220 | static int ir_resize_table(struct rc_dev *dev, struct rc_map *rc_map, |
221 | gfp_t gfp_flags) | ||
217 | { | 222 | { |
218 | unsigned int oldalloc = rc_map->alloc; | 223 | unsigned int oldalloc = rc_map->alloc; |
219 | unsigned int newalloc = oldalloc; | 224 | unsigned int newalloc = oldalloc; |
@@ -226,23 +231,21 @@ static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags) | |||
226 | return -ENOMEM; | 231 | return -ENOMEM; |
227 | 232 | ||
228 | newalloc *= 2; | 233 | newalloc *= 2; |
229 | IR_dprintk(1, "Growing table to %u bytes\n", newalloc); | 234 | dev_dbg(&dev->dev, "Growing table to %u bytes\n", newalloc); |
230 | } | 235 | } |
231 | 236 | ||
232 | if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) { | 237 | if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) { |
233 | /* Less than 1/3 of entries in use -> shrink keytable */ | 238 | /* Less than 1/3 of entries in use -> shrink keytable */ |
234 | newalloc /= 2; | 239 | newalloc /= 2; |
235 | IR_dprintk(1, "Shrinking table to %u bytes\n", newalloc); | 240 | dev_dbg(&dev->dev, "Shrinking table to %u bytes\n", newalloc); |
236 | } | 241 | } |
237 | 242 | ||
238 | if (newalloc == oldalloc) | 243 | if (newalloc == oldalloc) |
239 | return 0; | 244 | return 0; |
240 | 245 | ||
241 | newscan = kmalloc(newalloc, gfp_flags); | 246 | newscan = kmalloc(newalloc, gfp_flags); |
242 | if (!newscan) { | 247 | if (!newscan) |
243 | IR_dprintk(1, "Failed to kmalloc %u bytes\n", newalloc); | ||
244 | return -ENOMEM; | 248 | return -ENOMEM; |
245 | } | ||
246 | 249 | ||
247 | memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table)); | 250 | memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table)); |
248 | rc_map->scan = newscan; | 251 | rc_map->scan = newscan; |
@@ -275,16 +278,16 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, | |||
275 | 278 | ||
276 | /* Did the user wish to remove the mapping? */ | 279 | /* Did the user wish to remove the mapping? */ |
277 | if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { | 280 | if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) { |
278 | IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", | 281 | dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n", |
279 | index, rc_map->scan[index].scancode); | 282 | index, rc_map->scan[index].scancode); |
280 | rc_map->len--; | 283 | rc_map->len--; |
281 | memmove(&rc_map->scan[index], &rc_map->scan[index+ 1], | 284 | memmove(&rc_map->scan[index], &rc_map->scan[index+ 1], |
282 | (rc_map->len - index) * sizeof(struct rc_map_table)); | 285 | (rc_map->len - index) * sizeof(struct rc_map_table)); |
283 | } else { | 286 | } else { |
284 | IR_dprintk(1, "#%d: %s scan 0x%04x with key 0x%04x\n", | 287 | dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n", |
285 | index, | 288 | index, |
286 | old_keycode == KEY_RESERVED ? "New" : "Replacing", | 289 | old_keycode == KEY_RESERVED ? "New" : "Replacing", |
287 | rc_map->scan[index].scancode, new_keycode); | 290 | rc_map->scan[index].scancode, new_keycode); |
288 | rc_map->scan[index].keycode = new_keycode; | 291 | rc_map->scan[index].keycode = new_keycode; |
289 | __set_bit(new_keycode, dev->input_dev->keybit); | 292 | __set_bit(new_keycode, dev->input_dev->keybit); |
290 | } | 293 | } |
@@ -301,7 +304,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev, | |||
301 | } | 304 | } |
302 | 305 | ||
303 | /* Possibly shrink the keytable, failure is not a problem */ | 306 | /* Possibly shrink the keytable, failure is not a problem */ |
304 | ir_resize_table(rc_map, GFP_ATOMIC); | 307 | ir_resize_table(dev, rc_map, GFP_ATOMIC); |
305 | } | 308 | } |
306 | 309 | ||
307 | return old_keycode; | 310 | return old_keycode; |
@@ -352,7 +355,7 @@ static unsigned int ir_establish_scancode(struct rc_dev *dev, | |||
352 | 355 | ||
353 | /* No previous mapping found, we might need to grow the table */ | 356 | /* No previous mapping found, we might need to grow the table */ |
354 | if (rc_map->size == rc_map->len) { | 357 | if (rc_map->size == rc_map->len) { |
355 | if (!resize || ir_resize_table(rc_map, GFP_ATOMIC)) | 358 | if (!resize || ir_resize_table(dev, rc_map, GFP_ATOMIC)) |
356 | return -1U; | 359 | return -1U; |
357 | } | 360 | } |
358 | 361 | ||
@@ -431,8 +434,8 @@ static int ir_setkeytable(struct rc_dev *dev, | |||
431 | unsigned int i, index; | 434 | unsigned int i, index; |
432 | int rc; | 435 | int rc; |
433 | 436 | ||
434 | rc = ir_create_table(rc_map, from->name, | 437 | rc = ir_create_table(dev, rc_map, from->name, from->rc_proto, |
435 | from->rc_proto, from->size); | 438 | from->size); |
436 | if (rc) | 439 | if (rc) |
437 | return rc; | 440 | return rc; |
438 | 441 | ||
@@ -576,8 +579,8 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) | |||
576 | spin_unlock_irqrestore(&rc_map->lock, flags); | 579 | spin_unlock_irqrestore(&rc_map->lock, flags); |
577 | 580 | ||
578 | if (keycode != KEY_RESERVED) | 581 | if (keycode != KEY_RESERVED) |
579 | IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n", | 582 | dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n", |
580 | dev->device_name, scancode, keycode); | 583 | dev->device_name, scancode, keycode); |
581 | 584 | ||
582 | return keycode; | 585 | return keycode; |
583 | } | 586 | } |
@@ -596,7 +599,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync) | |||
596 | if (!dev->keypressed) | 599 | if (!dev->keypressed) |
597 | return; | 600 | return; |
598 | 601 | ||
599 | IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); | 602 | dev_dbg(&dev->dev, "keyup key 0x%04x\n", dev->last_keycode); |
600 | del_timer(&dev->timer_repeat); | 603 | del_timer(&dev->timer_repeat); |
601 | input_report_key(dev->input_dev, dev->last_keycode, 0); | 604 | input_report_key(dev->input_dev, dev->last_keycode, 0); |
602 | led_trigger_event(led_feedback, LED_OFF); | 605 | led_trigger_event(led_feedback, LED_OFF); |
@@ -751,8 +754,8 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, | |||
751 | /* Register a keypress */ | 754 | /* Register a keypress */ |
752 | dev->keypressed = true; | 755 | dev->keypressed = true; |
753 | 756 | ||
754 | IR_dprintk(1, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", | 757 | dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n", |
755 | dev->device_name, keycode, protocol, scancode); | 758 | dev->device_name, keycode, protocol, scancode); |
756 | input_report_key(dev->input_dev, keycode, 1); | 759 | input_report_key(dev->input_dev, keycode, 1); |
757 | 760 | ||
758 | led_trigger_event(led_feedback, LED_FULL); | 761 | led_trigger_event(led_feedback, LED_FULL); |
@@ -1003,6 +1006,7 @@ static const struct { | |||
1003 | RC_PROTO_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" }, | 1006 | RC_PROTO_BIT_MCIR2_MSE, "mce_kbd", "ir-mce_kbd-decoder" }, |
1004 | { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, | 1007 | { RC_PROTO_BIT_XMP, "xmp", "ir-xmp-decoder" }, |
1005 | { RC_PROTO_BIT_CEC, "cec", NULL }, | 1008 | { RC_PROTO_BIT_CEC, "cec", NULL }, |
1009 | { RC_PROTO_BIT_IMON, "imon", "ir-imon-decoder" }, | ||
1006 | }; | 1010 | }; |
1007 | 1011 | ||
1008 | /** | 1012 | /** |
@@ -1056,8 +1060,8 @@ static ssize_t show_protocols(struct device *device, | |||
1056 | 1060 | ||
1057 | mutex_unlock(&dev->lock); | 1061 | mutex_unlock(&dev->lock); |
1058 | 1062 | ||
1059 | IR_dprintk(1, "%s: allowed - 0x%llx, enabled - 0x%llx\n", | 1063 | dev_dbg(&dev->dev, "%s: allowed - 0x%llx, enabled - 0x%llx\n", |
1060 | __func__, (long long)allowed, (long long)enabled); | 1064 | __func__, (long long)allowed, (long long)enabled); |
1061 | 1065 | ||
1062 | for (i = 0; i < ARRAY_SIZE(proto_names); i++) { | 1066 | for (i = 0; i < ARRAY_SIZE(proto_names); i++) { |
1063 | if (allowed & enabled & proto_names[i].type) | 1067 | if (allowed & enabled & proto_names[i].type) |
@@ -1083,6 +1087,7 @@ static ssize_t show_protocols(struct device *device, | |||
1083 | 1087 | ||
1084 | /** | 1088 | /** |
1085 | * parse_protocol_change() - parses a protocol change request | 1089 | * parse_protocol_change() - parses a protocol change request |
1090 | * @dev: rc_dev device | ||
1086 | * @protocols: pointer to the bitmask of current protocols | 1091 | * @protocols: pointer to the bitmask of current protocols |
1087 | * @buf: pointer to the buffer with a list of changes | 1092 | * @buf: pointer to the buffer with a list of changes |
1088 | * | 1093 | * |
@@ -1092,7 +1097,8 @@ static ssize_t show_protocols(struct device *device, | |||
1092 | * Writing "none" will disable all protocols. | 1097 | * Writing "none" will disable all protocols. |
1093 | * Returns the number of changes performed or a negative error code. | 1098 | * Returns the number of changes performed or a negative error code. |
1094 | */ | 1099 | */ |
1095 | static int parse_protocol_change(u64 *protocols, const char *buf) | 1100 | static int parse_protocol_change(struct rc_dev *dev, u64 *protocols, |
1101 | const char *buf) | ||
1096 | { | 1102 | { |
1097 | const char *tmp; | 1103 | const char *tmp; |
1098 | unsigned count = 0; | 1104 | unsigned count = 0; |
@@ -1128,7 +1134,8 @@ static int parse_protocol_change(u64 *protocols, const char *buf) | |||
1128 | if (!strcasecmp(tmp, "lirc")) | 1134 | if (!strcasecmp(tmp, "lirc")) |
1129 | mask = 0; | 1135 | mask = 0; |
1130 | else { | 1136 | else { |
1131 | IR_dprintk(1, "Unknown protocol: '%s'\n", tmp); | 1137 | dev_dbg(&dev->dev, "Unknown protocol: '%s'\n", |
1138 | tmp); | ||
1132 | return -EINVAL; | 1139 | return -EINVAL; |
1133 | } | 1140 | } |
1134 | } | 1141 | } |
@@ -1144,7 +1151,7 @@ static int parse_protocol_change(u64 *protocols, const char *buf) | |||
1144 | } | 1151 | } |
1145 | 1152 | ||
1146 | if (!count) { | 1153 | if (!count) { |
1147 | IR_dprintk(1, "Protocol not specified\n"); | 1154 | dev_dbg(&dev->dev, "Protocol not specified\n"); |
1148 | return -EINVAL; | 1155 | return -EINVAL; |
1149 | } | 1156 | } |
1150 | 1157 | ||
@@ -1217,12 +1224,12 @@ static ssize_t store_protocols(struct device *device, | |||
1217 | u64 old_protocols, new_protocols; | 1224 | u64 old_protocols, new_protocols; |
1218 | ssize_t rc; | 1225 | ssize_t rc; |
1219 | 1226 | ||
1220 | IR_dprintk(1, "Normal protocol change requested\n"); | 1227 | dev_dbg(&dev->dev, "Normal protocol change requested\n"); |
1221 | current_protocols = &dev->enabled_protocols; | 1228 | current_protocols = &dev->enabled_protocols; |
1222 | filter = &dev->scancode_filter; | 1229 | filter = &dev->scancode_filter; |
1223 | 1230 | ||
1224 | if (!dev->change_protocol) { | 1231 | if (!dev->change_protocol) { |
1225 | IR_dprintk(1, "Protocol switching not supported\n"); | 1232 | dev_dbg(&dev->dev, "Protocol switching not supported\n"); |
1226 | return -EINVAL; | 1233 | return -EINVAL; |
1227 | } | 1234 | } |
1228 | 1235 | ||
@@ -1230,14 +1237,14 @@ static ssize_t store_protocols(struct device *device, | |||
1230 | 1237 | ||
1231 | old_protocols = *current_protocols; | 1238 | old_protocols = *current_protocols; |
1232 | new_protocols = old_protocols; | 1239 | new_protocols = old_protocols; |
1233 | rc = parse_protocol_change(&new_protocols, buf); | 1240 | rc = parse_protocol_change(dev, &new_protocols, buf); |
1234 | if (rc < 0) | 1241 | if (rc < 0) |
1235 | goto out; | 1242 | goto out; |
1236 | 1243 | ||
1237 | rc = dev->change_protocol(dev, &new_protocols); | 1244 | rc = dev->change_protocol(dev, &new_protocols); |
1238 | if (rc < 0) { | 1245 | if (rc < 0) { |
1239 | IR_dprintk(1, "Error setting protocols to 0x%llx\n", | 1246 | dev_dbg(&dev->dev, "Error setting protocols to 0x%llx\n", |
1240 | (long long)new_protocols); | 1247 | (long long)new_protocols); |
1241 | goto out; | 1248 | goto out; |
1242 | } | 1249 | } |
1243 | 1250 | ||
@@ -1246,8 +1253,8 @@ static ssize_t store_protocols(struct device *device, | |||
1246 | 1253 | ||
1247 | if (new_protocols != old_protocols) { | 1254 | if (new_protocols != old_protocols) { |
1248 | *current_protocols = new_protocols; | 1255 | *current_protocols = new_protocols; |
1249 | IR_dprintk(1, "Protocols changed to 0x%llx\n", | 1256 | dev_dbg(&dev->dev, "Protocols changed to 0x%llx\n", |
1250 | (long long)new_protocols); | 1257 | (long long)new_protocols); |
1251 | } | 1258 | } |
1252 | 1259 | ||
1253 | /* | 1260 | /* |
@@ -1435,8 +1442,8 @@ static ssize_t show_wakeup_protocols(struct device *device, | |||
1435 | 1442 | ||
1436 | mutex_unlock(&dev->lock); | 1443 | mutex_unlock(&dev->lock); |
1437 | 1444 | ||
1438 | IR_dprintk(1, "%s: allowed - 0x%llx, enabled - %d\n", | 1445 | dev_dbg(&dev->dev, "%s: allowed - 0x%llx, enabled - %d\n", |
1439 | __func__, (long long)allowed, enabled); | 1446 | __func__, (long long)allowed, enabled); |
1440 | 1447 | ||
1441 | for (i = 0; i < ARRAY_SIZE(protocols); i++) { | 1448 | for (i = 0; i < ARRAY_SIZE(protocols); i++) { |
1442 | if (allowed & (1ULL << i)) { | 1449 | if (allowed & (1ULL << i)) { |
@@ -1511,7 +1518,7 @@ static ssize_t store_wakeup_protocols(struct device *device, | |||
1511 | 1518 | ||
1512 | if (dev->wakeup_protocol != protocol) { | 1519 | if (dev->wakeup_protocol != protocol) { |
1513 | dev->wakeup_protocol = protocol; | 1520 | dev->wakeup_protocol = protocol; |
1514 | IR_dprintk(1, "Wakeup protocol changed to %d\n", protocol); | 1521 | dev_dbg(&dev->dev, "Wakeup protocol changed to %d\n", protocol); |
1515 | 1522 | ||
1516 | if (protocol == RC_PROTO_RC6_MCE) | 1523 | if (protocol == RC_PROTO_RC6_MCE) |
1517 | dev->scancode_wakeup_filter.data = 0x800f0000; | 1524 | dev->scancode_wakeup_filter.data = 0x800f0000; |
@@ -1874,9 +1881,8 @@ int rc_register_device(struct rc_dev *dev) | |||
1874 | 1881 | ||
1875 | dev->registered = true; | 1882 | dev->registered = true; |
1876 | 1883 | ||
1877 | IR_dprintk(1, "Registered rc%u (driver: %s)\n", | 1884 | dev_dbg(&dev->dev, "Registered rc%u (driver: %s)\n", dev->minor, |
1878 | dev->minor, | 1885 | dev->driver_name ? dev->driver_name : "unknown"); |
1879 | dev->driver_name ? dev->driver_name : "unknown"); | ||
1880 | 1886 | ||
1881 | return 0; | 1887 | return 0; |
1882 | 1888 | ||
@@ -1929,12 +1935,12 @@ void rc_unregister_device(struct rc_dev *dev) | |||
1929 | if (!dev) | 1935 | if (!dev) |
1930 | return; | 1936 | return; |
1931 | 1937 | ||
1932 | del_timer_sync(&dev->timer_keyup); | ||
1933 | del_timer_sync(&dev->timer_repeat); | ||
1934 | |||
1935 | if (dev->driver_type == RC_DRIVER_IR_RAW) | 1938 | if (dev->driver_type == RC_DRIVER_IR_RAW) |
1936 | ir_raw_event_unregister(dev); | 1939 | ir_raw_event_unregister(dev); |
1937 | 1940 | ||
1941 | del_timer_sync(&dev->timer_keyup); | ||
1942 | del_timer_sync(&dev->timer_repeat); | ||
1943 | |||
1938 | rc_free_rx_device(dev); | 1944 | rc_free_rx_device(dev); |
1939 | 1945 | ||
1940 | mutex_lock(&dev->lock); | 1946 | mutex_lock(&dev->lock); |
@@ -1994,9 +2000,5 @@ static void __exit rc_core_exit(void) | |||
1994 | subsys_initcall(rc_core_init); | 2000 | subsys_initcall(rc_core_init); |
1995 | module_exit(rc_core_exit); | 2001 | module_exit(rc_core_exit); |
1996 | 2002 | ||
1997 | int rc_core_debug; /* ir_debug level (0,1,2) */ | ||
1998 | EXPORT_SYMBOL_GPL(rc_core_debug); | ||
1999 | module_param_named(debug, rc_core_debug, int, 0644); | ||
2000 | |||
2001 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | 2003 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
2002 | MODULE_LICENSE("GPL v2"); | 2004 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index 97f367b446c4..f500cea228a9 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c | |||
@@ -72,12 +72,8 @@ | |||
72 | /* CIR_REG register idle threshold */ | 72 | /* CIR_REG register idle threshold */ |
73 | #define REG_CIR_ITHR(val) (((val) << 8) & (GENMASK(15, 8))) | 73 | #define REG_CIR_ITHR(val) (((val) << 8) & (GENMASK(15, 8))) |
74 | 74 | ||
75 | /* Required frequency for IR0 or IR1 clock in CIR mode */ | 75 | /* Required frequency for IR0 or IR1 clock in CIR mode (default) */ |
76 | #define SUNXI_IR_BASE_CLK 8000000 | 76 | #define SUNXI_IR_BASE_CLK 8000000 |
77 | /* Frequency after IR internal divider */ | ||
78 | #define SUNXI_IR_CLK (SUNXI_IR_BASE_CLK / 64) | ||
79 | /* Sample period in ns */ | ||
80 | #define SUNXI_IR_SAMPLE (1000000000ul / SUNXI_IR_CLK) | ||
81 | /* Noise threshold in samples */ | 77 | /* Noise threshold in samples */ |
82 | #define SUNXI_IR_RXNOISE 1 | 78 | #define SUNXI_IR_RXNOISE 1 |
83 | /* Idle Threshold in samples */ | 79 | /* Idle Threshold in samples */ |
@@ -122,7 +118,8 @@ static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) | |||
122 | /* for each bit in fifo */ | 118 | /* for each bit in fifo */ |
123 | dt = readb(ir->base + SUNXI_IR_RXFIFO_REG); | 119 | dt = readb(ir->base + SUNXI_IR_RXFIFO_REG); |
124 | rawir.pulse = (dt & 0x80) != 0; | 120 | rawir.pulse = (dt & 0x80) != 0; |
125 | rawir.duration = ((dt & 0x7f) + 1) * SUNXI_IR_SAMPLE; | 121 | rawir.duration = ((dt & 0x7f) + 1) * |
122 | ir->rc->rx_resolution; | ||
126 | ir_raw_event_store_with_filter(ir->rc, &rawir); | 123 | ir_raw_event_store_with_filter(ir->rc, &rawir); |
127 | } | 124 | } |
128 | } | 125 | } |
@@ -148,6 +145,7 @@ static int sunxi_ir_probe(struct platform_device *pdev) | |||
148 | struct device_node *dn = dev->of_node; | 145 | struct device_node *dn = dev->of_node; |
149 | struct resource *res; | 146 | struct resource *res; |
150 | struct sunxi_ir *ir; | 147 | struct sunxi_ir *ir; |
148 | u32 b_clk_freq = SUNXI_IR_BASE_CLK; | ||
151 | 149 | ||
152 | ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL); | 150 | ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL); |
153 | if (!ir) | 151 | if (!ir) |
@@ -172,6 +170,9 @@ static int sunxi_ir_probe(struct platform_device *pdev) | |||
172 | return PTR_ERR(ir->clk); | 170 | return PTR_ERR(ir->clk); |
173 | } | 171 | } |
174 | 172 | ||
173 | /* Base clock frequency (optional) */ | ||
174 | of_property_read_u32(dn, "clock-frequency", &b_clk_freq); | ||
175 | |||
175 | /* Reset (optional) */ | 176 | /* Reset (optional) */ |
176 | ir->rst = devm_reset_control_get_optional_exclusive(dev, NULL); | 177 | ir->rst = devm_reset_control_get_optional_exclusive(dev, NULL); |
177 | if (IS_ERR(ir->rst)) | 178 | if (IS_ERR(ir->rst)) |
@@ -180,11 +181,12 @@ static int sunxi_ir_probe(struct platform_device *pdev) | |||
180 | if (ret) | 181 | if (ret) |
181 | return ret; | 182 | return ret; |
182 | 183 | ||
183 | ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK); | 184 | ret = clk_set_rate(ir->clk, b_clk_freq); |
184 | if (ret) { | 185 | if (ret) { |
185 | dev_err(dev, "set ir base clock failed!\n"); | 186 | dev_err(dev, "set ir base clock failed!\n"); |
186 | goto exit_reset_assert; | 187 | goto exit_reset_assert; |
187 | } | 188 | } |
189 | dev_dbg(dev, "set base clock frequency to %d Hz.\n", b_clk_freq); | ||
188 | 190 | ||
189 | if (clk_prepare_enable(ir->apb_clk)) { | 191 | if (clk_prepare_enable(ir->apb_clk)) { |
190 | dev_err(dev, "try to enable apb_ir_clk failed\n"); | 192 | dev_err(dev, "try to enable apb_ir_clk failed\n"); |
@@ -225,7 +227,8 @@ static int sunxi_ir_probe(struct platform_device *pdev) | |||
225 | ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY; | 227 | ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY; |
226 | ir->rc->dev.parent = dev; | 228 | ir->rc->dev.parent = dev; |
227 | ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; | 229 | ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; |
228 | ir->rc->rx_resolution = SUNXI_IR_SAMPLE; | 230 | /* Frequency after IR internal divider with sample period in ns */ |
231 | ir->rc->rx_resolution = (1000000000ul / (b_clk_freq / 64)); | ||
229 | ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT); | 232 | ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT); |
230 | ir->rc->driver_name = SUNXI_IR_DEV; | 233 | ir->rc->driver_name = SUNXI_IR_DEV; |
231 | 234 | ||
diff --git a/drivers/media/spi/Kconfig b/drivers/media/spi/Kconfig index a21f5a39a440..b07ac86fc53c 100644 --- a/drivers/media/spi/Kconfig +++ b/drivers/media/spi/Kconfig | |||
@@ -12,3 +12,17 @@ config VIDEO_GS1662 | |||
12 | endmenu | 12 | endmenu |
13 | 13 | ||
14 | endif | 14 | endif |
15 | |||
16 | if SPI | ||
17 | menu "Media SPI Adapters" | ||
18 | |||
19 | config CXD2880_SPI_DRV | ||
20 | tristate "Sony CXD2880 SPI support" | ||
21 | depends on DVB_CORE && SPI | ||
22 | default m if !MEDIA_SUBDRV_AUTOSELECT | ||
23 | help | ||
24 | Choose if you would like to have SPI interface support for Sony CXD2880. | ||
25 | |||
26 | endmenu | ||
27 | |||
28 | endif | ||
diff --git a/drivers/media/spi/Makefile b/drivers/media/spi/Makefile index ea64013d16cc..9e536777a330 100644 --- a/drivers/media/spi/Makefile +++ b/drivers/media/spi/Makefile | |||
@@ -1 +1,6 @@ | |||
1 | obj-$(CONFIG_VIDEO_GS1662) += gs1662.o | 1 | obj-$(CONFIG_VIDEO_GS1662) += gs1662.o |
2 | obj-$(CONFIG_CXD2880_SPI_DRV) += cxd2880-spi.o | ||
3 | |||
4 | ccflags-y += -Idrivers/media/dvb-core | ||
5 | ccflags-y += -Idrivers/media/dvb-frontends | ||
6 | ccflags-y += -Idrivers/media/dvb-frontends/cxd2880 | ||
diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c new file mode 100644 index 000000000000..4df3bd312f48 --- /dev/null +++ b/drivers/media/spi/cxd2880-spi.c | |||
@@ -0,0 +1,670 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * cxd2880-spi.c | ||
4 | * Sony CXD2880 DVB-T2/T tuner + demodulator driver | ||
5 | * SPI adapter | ||
6 | * | ||
7 | * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation | ||
8 | */ | ||
9 | |||
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ | ||
11 | |||
12 | #include <linux/spi/spi.h> | ||
13 | #include <linux/ktime.h> | ||
14 | |||
15 | #include <media/dvb_demux.h> | ||
16 | #include <media/dmxdev.h> | ||
17 | #include <media/dvb_frontend.h> | ||
18 | #include "cxd2880.h" | ||
19 | |||
20 | #define CXD2880_MAX_FILTER_SIZE 32 | ||
21 | #define BURST_WRITE_MAX 128 | ||
22 | #define MAX_TRANS_PKT 300 | ||
23 | |||
24 | struct cxd2880_ts_buf_info { | ||
25 | u8 read_ready:1; | ||
26 | u8 almost_full:1; | ||
27 | u8 almost_empty:1; | ||
28 | u8 overflow:1; | ||
29 | u8 underflow:1; | ||
30 | u16 pkt_num; | ||
31 | }; | ||
32 | |||
33 | struct cxd2880_pid_config { | ||
34 | u8 is_enable; | ||
35 | u16 pid; | ||
36 | }; | ||
37 | |||
38 | struct cxd2880_pid_filter_config { | ||
39 | u8 is_negative; | ||
40 | struct cxd2880_pid_config pid_config[CXD2880_MAX_FILTER_SIZE]; | ||
41 | }; | ||
42 | |||
43 | struct cxd2880_dvb_spi { | ||
44 | struct dvb_frontend dvb_fe; | ||
45 | struct dvb_adapter adapter; | ||
46 | struct dvb_demux demux; | ||
47 | struct dmxdev dmxdev; | ||
48 | struct dmx_frontend dmx_fe; | ||
49 | struct task_struct *cxd2880_ts_read_thread; | ||
50 | struct spi_device *spi; | ||
51 | struct mutex spi_mutex; /* For SPI access exclusive control */ | ||
52 | int feed_count; | ||
53 | int all_pid_feed_count; | ||
54 | u8 *ts_buf; | ||
55 | struct cxd2880_pid_filter_config filter_config; | ||
56 | }; | ||
57 | |||
58 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
59 | |||
60 | static int cxd2880_write_spi(struct spi_device *spi, u8 *data, u32 size) | ||
61 | { | ||
62 | struct spi_message msg; | ||
63 | struct spi_transfer tx; | ||
64 | |||
65 | if (!spi || !data) { | ||
66 | pr_err("invalid arg\n"); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | |||
70 | memset(&tx, 0, sizeof(tx)); | ||
71 | tx.tx_buf = data; | ||
72 | tx.len = size; | ||
73 | |||
74 | spi_message_init(&msg); | ||
75 | spi_message_add_tail(&tx, &msg); | ||
76 | |||
77 | return spi_sync(spi, &msg); | ||
78 | } | ||
79 | |||
80 | static int cxd2880_write_reg(struct spi_device *spi, | ||
81 | u8 sub_address, const u8 *data, u32 size) | ||
82 | { | ||
83 | u8 send_data[BURST_WRITE_MAX + 4]; | ||
84 | const u8 *write_data_top = NULL; | ||
85 | int ret = 0; | ||
86 | |||
87 | if (!spi || !data) { | ||
88 | pr_err("invalid arg\n"); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | if (size > BURST_WRITE_MAX) { | ||
92 | pr_err("data size > WRITE_MAX\n"); | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | |||
96 | if (sub_address + size > 0x100) { | ||
97 | pr_err("out of range\n"); | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | |||
101 | send_data[0] = 0x0e; | ||
102 | write_data_top = data; | ||
103 | |||
104 | while (size > 0) { | ||
105 | send_data[1] = sub_address; | ||
106 | if (size > 255) | ||
107 | send_data[2] = 255; | ||
108 | else | ||
109 | send_data[2] = (u8)size; | ||
110 | |||
111 | memcpy(&send_data[3], write_data_top, send_data[2]); | ||
112 | |||
113 | ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3); | ||
114 | if (ret) { | ||
115 | pr_err("write spi failed %d\n", ret); | ||
116 | break; | ||
117 | } | ||
118 | sub_address += send_data[2]; | ||
119 | write_data_top += send_data[2]; | ||
120 | size -= send_data[2]; | ||
121 | } | ||
122 | |||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | static int cxd2880_spi_read_ts(struct spi_device *spi, | ||
127 | u8 *read_data, | ||
128 | u32 packet_num) | ||
129 | { | ||
130 | int ret; | ||
131 | u8 data[3]; | ||
132 | struct spi_message message; | ||
133 | struct spi_transfer transfer[2]; | ||
134 | |||
135 | if (!spi || !read_data || !packet_num) { | ||
136 | pr_err("invalid arg\n"); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | if (packet_num > 0xffff) { | ||
140 | pr_err("packet num > 0xffff\n"); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | |||
144 | data[0] = 0x10; | ||
145 | data[1] = packet_num >> 8; | ||
146 | data[2] = packet_num; | ||
147 | |||
148 | spi_message_init(&message); | ||
149 | memset(transfer, 0, sizeof(transfer)); | ||
150 | |||
151 | transfer[0].len = 3; | ||
152 | transfer[0].tx_buf = data; | ||
153 | spi_message_add_tail(&transfer[0], &message); | ||
154 | transfer[1].len = packet_num * 188; | ||
155 | transfer[1].rx_buf = read_data; | ||
156 | spi_message_add_tail(&transfer[1], &message); | ||
157 | |||
158 | ret = spi_sync(spi, &message); | ||
159 | if (ret) | ||
160 | pr_err("spi_write_then_read failed\n"); | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static int cxd2880_spi_read_ts_buffer_info(struct spi_device *spi, | ||
166 | struct cxd2880_ts_buf_info *info) | ||
167 | { | ||
168 | u8 send_data = 0x20; | ||
169 | u8 recv_data[2]; | ||
170 | int ret; | ||
171 | |||
172 | if (!spi || !info) { | ||
173 | pr_err("invalid arg\n"); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | ret = spi_write_then_read(spi, &send_data, 1, | ||
178 | recv_data, sizeof(recv_data)); | ||
179 | if (ret) | ||
180 | pr_err("spi_write_then_read failed\n"); | ||
181 | |||
182 | info->read_ready = (recv_data[0] & 0x80) ? 1 : 0; | ||
183 | info->almost_full = (recv_data[0] & 0x40) ? 1 : 0; | ||
184 | info->almost_empty = (recv_data[0] & 0x20) ? 1 : 0; | ||
185 | info->overflow = (recv_data[0] & 0x10) ? 1 : 0; | ||
186 | info->underflow = (recv_data[0] & 0x08) ? 1 : 0; | ||
187 | info->pkt_num = ((recv_data[0] & 0x07) << 8) | recv_data[1]; | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static int cxd2880_spi_clear_ts_buffer(struct spi_device *spi) | ||
193 | { | ||
194 | u8 data = 0x03; | ||
195 | int ret; | ||
196 | |||
197 | ret = cxd2880_write_spi(spi, &data, 1); | ||
198 | |||
199 | if (ret) | ||
200 | pr_err("write spi failed\n"); | ||
201 | |||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | static int cxd2880_set_pid_filter(struct spi_device *spi, | ||
206 | struct cxd2880_pid_filter_config *cfg) | ||
207 | { | ||
208 | u8 data[65]; | ||
209 | int i; | ||
210 | u16 pid = 0; | ||
211 | int ret; | ||
212 | |||
213 | if (!spi) { | ||
214 | pr_err("invalid arg\n"); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | data[0] = 0x00; | ||
219 | ret = cxd2880_write_reg(spi, 0x00, &data[0], 1); | ||
220 | if (ret) | ||
221 | return ret; | ||
222 | if (!cfg) { | ||
223 | data[0] = 0x02; | ||
224 | ret = cxd2880_write_reg(spi, 0x50, &data[0], 1); | ||
225 | } else { | ||
226 | data[0] = cfg->is_negative ? 0x01 : 0x00; | ||
227 | |||
228 | for (i = 0; i < CXD2880_MAX_FILTER_SIZE; i++) { | ||
229 | pid = cfg->pid_config[i].pid; | ||
230 | if (cfg->pid_config[i].is_enable) { | ||
231 | data[1 + (i * 2)] = (pid >> 8) | 0x20; | ||
232 | data[2 + (i * 2)] = pid & 0xff; | ||
233 | } else { | ||
234 | data[1 + (i * 2)] = 0x00; | ||
235 | data[2 + (i * 2)] = 0x00; | ||
236 | } | ||
237 | } | ||
238 | ret = cxd2880_write_reg(spi, 0x50, data, 65); | ||
239 | } | ||
240 | |||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | static int cxd2880_update_pid_filter(struct cxd2880_dvb_spi *dvb_spi, | ||
245 | struct cxd2880_pid_filter_config *cfg, | ||
246 | bool is_all_pid_filter) | ||
247 | { | ||
248 | int ret; | ||
249 | |||
250 | if (!dvb_spi || !cfg) { | ||
251 | pr_err("invalid arg.\n"); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
255 | mutex_lock(&dvb_spi->spi_mutex); | ||
256 | if (is_all_pid_filter) { | ||
257 | struct cxd2880_pid_filter_config tmpcfg; | ||
258 | |||
259 | memset(&tmpcfg, 0, sizeof(tmpcfg)); | ||
260 | tmpcfg.is_negative = 1; | ||
261 | tmpcfg.pid_config[0].is_enable = 1; | ||
262 | tmpcfg.pid_config[0].pid = 0x1fff; | ||
263 | |||
264 | ret = cxd2880_set_pid_filter(dvb_spi->spi, &tmpcfg); | ||
265 | } else { | ||
266 | ret = cxd2880_set_pid_filter(dvb_spi->spi, cfg); | ||
267 | } | ||
268 | mutex_unlock(&dvb_spi->spi_mutex); | ||
269 | |||
270 | if (ret) | ||
271 | pr_err("set_pid_filter failed\n"); | ||
272 | |||
273 | return ret; | ||
274 | } | ||
275 | |||
276 | static int cxd2880_ts_read(void *arg) | ||
277 | { | ||
278 | struct cxd2880_dvb_spi *dvb_spi = NULL; | ||
279 | struct cxd2880_ts_buf_info info; | ||
280 | ktime_t start; | ||
281 | u32 i; | ||
282 | int ret; | ||
283 | |||
284 | dvb_spi = arg; | ||
285 | if (!dvb_spi) { | ||
286 | pr_err("invalid arg\n"); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | ret = cxd2880_spi_clear_ts_buffer(dvb_spi->spi); | ||
291 | if (ret) { | ||
292 | pr_err("set_clear_ts_buffer failed\n"); | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | start = ktime_get(); | ||
297 | while (!kthread_should_stop()) { | ||
298 | ret = cxd2880_spi_read_ts_buffer_info(dvb_spi->spi, | ||
299 | &info); | ||
300 | if (ret) { | ||
301 | pr_err("spi_read_ts_buffer_info error\n"); | ||
302 | return ret; | ||
303 | } | ||
304 | |||
305 | if (info.pkt_num > MAX_TRANS_PKT) { | ||
306 | for (i = 0; i < info.pkt_num / MAX_TRANS_PKT; i++) { | ||
307 | cxd2880_spi_read_ts(dvb_spi->spi, | ||
308 | dvb_spi->ts_buf, | ||
309 | MAX_TRANS_PKT); | ||
310 | dvb_dmx_swfilter(&dvb_spi->demux, | ||
311 | dvb_spi->ts_buf, | ||
312 | MAX_TRANS_PKT * 188); | ||
313 | } | ||
314 | start = ktime_get(); | ||
315 | } else if ((info.pkt_num > 0) && | ||
316 | (ktime_to_ms(ktime_sub(ktime_get(), start)) >= 500)) { | ||
317 | cxd2880_spi_read_ts(dvb_spi->spi, | ||
318 | dvb_spi->ts_buf, | ||
319 | info.pkt_num); | ||
320 | dvb_dmx_swfilter(&dvb_spi->demux, | ||
321 | dvb_spi->ts_buf, | ||
322 | info.pkt_num * 188); | ||
323 | start = ktime_get(); | ||
324 | } else { | ||
325 | usleep_range(10000, 11000); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int cxd2880_start_feed(struct dvb_demux_feed *feed) | ||
333 | { | ||
334 | int ret = 0; | ||
335 | int i = 0; | ||
336 | struct dvb_demux *demux = NULL; | ||
337 | struct cxd2880_dvb_spi *dvb_spi = NULL; | ||
338 | |||
339 | if (!feed) { | ||
340 | pr_err("invalid arg\n"); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | demux = feed->demux; | ||
345 | if (!demux) { | ||
346 | pr_err("feed->demux is NULL\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | dvb_spi = demux->priv; | ||
350 | |||
351 | if (dvb_spi->feed_count == CXD2880_MAX_FILTER_SIZE) { | ||
352 | pr_err("Exceeded maximum PID count (32)."); | ||
353 | pr_err("Selected PID cannot be enabled.\n"); | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | |||
357 | if (feed->pid == 0x2000) { | ||
358 | if (dvb_spi->all_pid_feed_count == 0) { | ||
359 | ret = cxd2880_update_pid_filter(dvb_spi, | ||
360 | &dvb_spi->filter_config, | ||
361 | true); | ||
362 | if (ret) { | ||
363 | pr_err("update pid filter failed\n"); | ||
364 | return ret; | ||
365 | } | ||
366 | } | ||
367 | dvb_spi->all_pid_feed_count++; | ||
368 | |||
369 | pr_debug("all PID feed (count = %d)\n", | ||
370 | dvb_spi->all_pid_feed_count); | ||
371 | } else { | ||
372 | struct cxd2880_pid_filter_config cfgtmp; | ||
373 | |||
374 | cfgtmp = dvb_spi->filter_config; | ||
375 | |||
376 | for (i = 0; i < CXD2880_MAX_FILTER_SIZE; i++) { | ||
377 | if (cfgtmp.pid_config[i].is_enable == 0) { | ||
378 | cfgtmp.pid_config[i].is_enable = 1; | ||
379 | cfgtmp.pid_config[i].pid = feed->pid; | ||
380 | pr_debug("store PID %d to #%d\n", | ||
381 | feed->pid, i); | ||
382 | break; | ||
383 | } | ||
384 | } | ||
385 | if (i == CXD2880_MAX_FILTER_SIZE) { | ||
386 | pr_err("PID filter is full. Assumed bug.\n"); | ||
387 | return -EINVAL; | ||
388 | } | ||
389 | if (!dvb_spi->all_pid_feed_count) | ||
390 | ret = cxd2880_update_pid_filter(dvb_spi, | ||
391 | &cfgtmp, | ||
392 | false); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | |||
396 | dvb_spi->filter_config = cfgtmp; | ||
397 | } | ||
398 | |||
399 | if (dvb_spi->feed_count == 0) { | ||
400 | dvb_spi->ts_buf = | ||
401 | kmalloc(MAX_TRANS_PKT * 188, | ||
402 | GFP_KERNEL | GFP_DMA); | ||
403 | if (!dvb_spi->ts_buf) { | ||
404 | pr_err("ts buffer allocate failed\n"); | ||
405 | memset(&dvb_spi->filter_config, 0, | ||
406 | sizeof(dvb_spi->filter_config)); | ||
407 | dvb_spi->all_pid_feed_count = 0; | ||
408 | return -ENOMEM; | ||
409 | } | ||
410 | dvb_spi->cxd2880_ts_read_thread = kthread_run(cxd2880_ts_read, | ||
411 | dvb_spi, | ||
412 | "cxd2880_ts_read"); | ||
413 | if (IS_ERR(dvb_spi->cxd2880_ts_read_thread)) { | ||
414 | pr_err("kthread_run failed/\n"); | ||
415 | kfree(dvb_spi->ts_buf); | ||
416 | dvb_spi->ts_buf = NULL; | ||
417 | memset(&dvb_spi->filter_config, 0, | ||
418 | sizeof(dvb_spi->filter_config)); | ||
419 | dvb_spi->all_pid_feed_count = 0; | ||
420 | return PTR_ERR(dvb_spi->cxd2880_ts_read_thread); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | dvb_spi->feed_count++; | ||
425 | |||
426 | pr_debug("start feed (count %d)\n", dvb_spi->feed_count); | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int cxd2880_stop_feed(struct dvb_demux_feed *feed) | ||
431 | { | ||
432 | int i = 0; | ||
433 | int ret; | ||
434 | struct dvb_demux *demux = NULL; | ||
435 | struct cxd2880_dvb_spi *dvb_spi = NULL; | ||
436 | |||
437 | if (!feed) { | ||
438 | pr_err("invalid arg\n"); | ||
439 | return -EINVAL; | ||
440 | } | ||
441 | |||
442 | demux = feed->demux; | ||
443 | if (!demux) { | ||
444 | pr_err("feed->demux is NULL\n"); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | dvb_spi = demux->priv; | ||
448 | |||
449 | if (!dvb_spi->feed_count) { | ||
450 | pr_err("no feed is started\n"); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | |||
454 | if (feed->pid == 0x2000) { | ||
455 | /* | ||
456 | * Special PID case. | ||
457 | * Number of 0x2000 feed request was stored | ||
458 | * in dvb_spi->all_pid_feed_count. | ||
459 | */ | ||
460 | if (dvb_spi->all_pid_feed_count <= 0) { | ||
461 | pr_err("PID %d not found.\n", feed->pid); | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | dvb_spi->all_pid_feed_count--; | ||
465 | } else { | ||
466 | struct cxd2880_pid_filter_config cfgtmp; | ||
467 | |||
468 | cfgtmp = dvb_spi->filter_config; | ||
469 | |||
470 | for (i = 0; i < CXD2880_MAX_FILTER_SIZE; i++) { | ||
471 | if (feed->pid == cfgtmp.pid_config[i].pid && | ||
472 | cfgtmp.pid_config[i].is_enable != 0) { | ||
473 | cfgtmp.pid_config[i].is_enable = 0; | ||
474 | cfgtmp.pid_config[i].pid = 0; | ||
475 | pr_debug("removed PID %d from #%d\n", | ||
476 | feed->pid, i); | ||
477 | break; | ||
478 | } | ||
479 | } | ||
480 | dvb_spi->filter_config = cfgtmp; | ||
481 | |||
482 | if (i == CXD2880_MAX_FILTER_SIZE) { | ||
483 | pr_err("PID %d not found\n", feed->pid); | ||
484 | return -EINVAL; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | ret = cxd2880_update_pid_filter(dvb_spi, | ||
489 | &dvb_spi->filter_config, | ||
490 | dvb_spi->all_pid_feed_count > 0); | ||
491 | dvb_spi->feed_count--; | ||
492 | |||
493 | if (dvb_spi->feed_count == 0) { | ||
494 | int ret_stop = 0; | ||
495 | |||
496 | ret_stop = kthread_stop(dvb_spi->cxd2880_ts_read_thread); | ||
497 | if (ret_stop) { | ||
498 | pr_err("'kthread_stop failed. (%d)\n", ret_stop); | ||
499 | ret = ret_stop; | ||
500 | } | ||
501 | kfree(dvb_spi->ts_buf); | ||
502 | dvb_spi->ts_buf = NULL; | ||
503 | } | ||
504 | |||
505 | pr_debug("stop feed ok.(count %d)\n", dvb_spi->feed_count); | ||
506 | |||
507 | return ret; | ||
508 | } | ||
509 | |||
510 | static const struct of_device_id cxd2880_spi_of_match[] = { | ||
511 | { .compatible = "sony,cxd2880" }, | ||
512 | { /* sentinel */ } | ||
513 | }; | ||
514 | |||
515 | MODULE_DEVICE_TABLE(of, cxd2880_spi_of_match); | ||
516 | |||
517 | static int | ||
518 | cxd2880_spi_probe(struct spi_device *spi) | ||
519 | { | ||
520 | int ret; | ||
521 | struct cxd2880_dvb_spi *dvb_spi = NULL; | ||
522 | struct cxd2880_config config; | ||
523 | |||
524 | if (!spi) { | ||
525 | pr_err("invalid arg.\n"); | ||
526 | return -EINVAL; | ||
527 | } | ||
528 | |||
529 | dvb_spi = kzalloc(sizeof(struct cxd2880_dvb_spi), GFP_KERNEL); | ||
530 | if (!dvb_spi) | ||
531 | return -ENOMEM; | ||
532 | |||
533 | dvb_spi->spi = spi; | ||
534 | mutex_init(&dvb_spi->spi_mutex); | ||
535 | dev_set_drvdata(&spi->dev, dvb_spi); | ||
536 | config.spi = spi; | ||
537 | config.spi_mutex = &dvb_spi->spi_mutex; | ||
538 | |||
539 | ret = dvb_register_adapter(&dvb_spi->adapter, | ||
540 | "CXD2880", | ||
541 | THIS_MODULE, | ||
542 | &spi->dev, | ||
543 | adapter_nr); | ||
544 | if (ret < 0) { | ||
545 | pr_err("dvb_register_adapter() failed\n"); | ||
546 | goto fail_adapter; | ||
547 | } | ||
548 | |||
549 | if (!dvb_attach(cxd2880_attach, &dvb_spi->dvb_fe, &config)) { | ||
550 | pr_err("cxd2880_attach failed\n"); | ||
551 | goto fail_attach; | ||
552 | } | ||
553 | |||
554 | ret = dvb_register_frontend(&dvb_spi->adapter, | ||
555 | &dvb_spi->dvb_fe); | ||
556 | if (ret < 0) { | ||
557 | pr_err("dvb_register_frontend() failed\n"); | ||
558 | goto fail_frontend; | ||
559 | } | ||
560 | |||
561 | dvb_spi->demux.dmx.capabilities = DMX_TS_FILTERING; | ||
562 | dvb_spi->demux.priv = dvb_spi; | ||
563 | dvb_spi->demux.filternum = CXD2880_MAX_FILTER_SIZE; | ||
564 | dvb_spi->demux.feednum = CXD2880_MAX_FILTER_SIZE; | ||
565 | dvb_spi->demux.start_feed = cxd2880_start_feed; | ||
566 | dvb_spi->demux.stop_feed = cxd2880_stop_feed; | ||
567 | |||
568 | ret = dvb_dmx_init(&dvb_spi->demux); | ||
569 | if (ret < 0) { | ||
570 | pr_err("dvb_dmx_init() failed\n"); | ||
571 | goto fail_dmx; | ||
572 | } | ||
573 | |||
574 | dvb_spi->dmxdev.filternum = CXD2880_MAX_FILTER_SIZE; | ||
575 | dvb_spi->dmxdev.demux = &dvb_spi->demux.dmx; | ||
576 | dvb_spi->dmxdev.capabilities = 0; | ||
577 | ret = dvb_dmxdev_init(&dvb_spi->dmxdev, | ||
578 | &dvb_spi->adapter); | ||
579 | if (ret < 0) { | ||
580 | pr_err("dvb_dmxdev_init() failed\n"); | ||
581 | goto fail_dmxdev; | ||
582 | } | ||
583 | |||
584 | dvb_spi->dmx_fe.source = DMX_FRONTEND_0; | ||
585 | ret = dvb_spi->demux.dmx.add_frontend(&dvb_spi->demux.dmx, | ||
586 | &dvb_spi->dmx_fe); | ||
587 | if (ret < 0) { | ||
588 | pr_err("add_frontend() failed\n"); | ||
589 | goto fail_dmx_fe; | ||
590 | } | ||
591 | |||
592 | ret = dvb_spi->demux.dmx.connect_frontend(&dvb_spi->demux.dmx, | ||
593 | &dvb_spi->dmx_fe); | ||
594 | if (ret < 0) { | ||
595 | pr_err("dvb_register_frontend() failed\n"); | ||
596 | goto fail_fe_conn; | ||
597 | } | ||
598 | |||
599 | pr_info("Sony CXD2880 has successfully attached.\n"); | ||
600 | |||
601 | return 0; | ||
602 | |||
603 | fail_fe_conn: | ||
604 | dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx, | ||
605 | &dvb_spi->dmx_fe); | ||
606 | fail_dmx_fe: | ||
607 | dvb_dmxdev_release(&dvb_spi->dmxdev); | ||
608 | fail_dmxdev: | ||
609 | dvb_dmx_release(&dvb_spi->demux); | ||
610 | fail_dmx: | ||
611 | dvb_unregister_frontend(&dvb_spi->dvb_fe); | ||
612 | fail_frontend: | ||
613 | dvb_frontend_detach(&dvb_spi->dvb_fe); | ||
614 | fail_attach: | ||
615 | dvb_unregister_adapter(&dvb_spi->adapter); | ||
616 | fail_adapter: | ||
617 | kfree(dvb_spi); | ||
618 | return ret; | ||
619 | } | ||
620 | |||
621 | static int | ||
622 | cxd2880_spi_remove(struct spi_device *spi) | ||
623 | { | ||
624 | struct cxd2880_dvb_spi *dvb_spi; | ||
625 | |||
626 | if (!spi) { | ||
627 | pr_err("invalid arg\n"); | ||
628 | return -EINVAL; | ||
629 | } | ||
630 | |||
631 | dvb_spi = dev_get_drvdata(&spi->dev); | ||
632 | |||
633 | if (!dvb_spi) { | ||
634 | pr_err("failed\n"); | ||
635 | return -EINVAL; | ||
636 | } | ||
637 | dvb_spi->demux.dmx.remove_frontend(&dvb_spi->demux.dmx, | ||
638 | &dvb_spi->dmx_fe); | ||
639 | dvb_dmxdev_release(&dvb_spi->dmxdev); | ||
640 | dvb_dmx_release(&dvb_spi->demux); | ||
641 | dvb_unregister_frontend(&dvb_spi->dvb_fe); | ||
642 | dvb_frontend_detach(&dvb_spi->dvb_fe); | ||
643 | dvb_unregister_adapter(&dvb_spi->adapter); | ||
644 | |||
645 | kfree(dvb_spi); | ||
646 | pr_info("cxd2880_spi remove ok.\n"); | ||
647 | |||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | static const struct spi_device_id cxd2880_spi_id[] = { | ||
652 | { "cxd2880", 0 }, | ||
653 | { /* sentinel */ } | ||
654 | }; | ||
655 | MODULE_DEVICE_TABLE(spi, cxd2880_spi_id); | ||
656 | |||
657 | static struct spi_driver cxd2880_spi_driver = { | ||
658 | .driver = { | ||
659 | .name = "cxd2880", | ||
660 | .of_match_table = cxd2880_spi_of_match, | ||
661 | }, | ||
662 | .id_table = cxd2880_spi_id, | ||
663 | .probe = cxd2880_spi_probe, | ||
664 | .remove = cxd2880_spi_remove, | ||
665 | }; | ||
666 | module_spi_driver(cxd2880_spi_driver); | ||
667 | |||
668 | MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver SPI adapter"); | ||
669 | MODULE_AUTHOR("Sony Semiconductor Solutions Corporation"); | ||
670 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 564a000f503e..b5b9d87ba75c 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c | |||
@@ -293,28 +293,18 @@ static inline struct e4000_dev *e4000_subdev_to_dev(struct v4l2_subdev *sd) | |||
293 | return container_of(sd, struct e4000_dev, sd); | 293 | return container_of(sd, struct e4000_dev, sd); |
294 | } | 294 | } |
295 | 295 | ||
296 | static int e4000_s_power(struct v4l2_subdev *sd, int on) | 296 | static int e4000_standby(struct v4l2_subdev *sd) |
297 | { | 297 | { |
298 | struct e4000_dev *dev = e4000_subdev_to_dev(sd); | 298 | struct e4000_dev *dev = e4000_subdev_to_dev(sd); |
299 | struct i2c_client *client = dev->client; | ||
300 | int ret; | 299 | int ret; |
301 | 300 | ||
302 | dev_dbg(&client->dev, "on=%d\n", on); | 301 | ret = e4000_sleep(dev); |
303 | |||
304 | if (on) | ||
305 | ret = e4000_init(dev); | ||
306 | else | ||
307 | ret = e4000_sleep(dev); | ||
308 | if (ret) | 302 | if (ret) |
309 | return ret; | 303 | return ret; |
310 | 304 | ||
311 | return e4000_set_params(dev); | 305 | return e4000_set_params(dev); |
312 | } | 306 | } |
313 | 307 | ||
314 | static const struct v4l2_subdev_core_ops e4000_subdev_core_ops = { | ||
315 | .s_power = e4000_s_power, | ||
316 | }; | ||
317 | |||
318 | static int e4000_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) | 308 | static int e4000_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) |
319 | { | 309 | { |
320 | struct e4000_dev *dev = e4000_subdev_to_dev(sd); | 310 | struct e4000_dev *dev = e4000_subdev_to_dev(sd); |
@@ -382,6 +372,7 @@ static int e4000_enum_freq_bands(struct v4l2_subdev *sd, | |||
382 | } | 372 | } |
383 | 373 | ||
384 | static const struct v4l2_subdev_tuner_ops e4000_subdev_tuner_ops = { | 374 | static const struct v4l2_subdev_tuner_ops e4000_subdev_tuner_ops = { |
375 | .standby = e4000_standby, | ||
385 | .g_tuner = e4000_g_tuner, | 376 | .g_tuner = e4000_g_tuner, |
386 | .s_tuner = e4000_s_tuner, | 377 | .s_tuner = e4000_s_tuner, |
387 | .g_frequency = e4000_g_frequency, | 378 | .g_frequency = e4000_g_frequency, |
@@ -390,7 +381,6 @@ static const struct v4l2_subdev_tuner_ops e4000_subdev_tuner_ops = { | |||
390 | }; | 381 | }; |
391 | 382 | ||
392 | static const struct v4l2_subdev_ops e4000_subdev_ops = { | 383 | static const struct v4l2_subdev_ops e4000_subdev_ops = { |
393 | .core = &e4000_subdev_core_ops, | ||
394 | .tuner = &e4000_subdev_tuner_ops, | 384 | .tuner = &e4000_subdev_tuner_ops, |
395 | }; | 385 | }; |
396 | 386 | ||
diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index f4d4665de168..743184ae0d26 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c | |||
@@ -386,28 +386,18 @@ static inline struct fc2580_dev *fc2580_subdev_to_dev(struct v4l2_subdev *sd) | |||
386 | return container_of(sd, struct fc2580_dev, subdev); | 386 | return container_of(sd, struct fc2580_dev, subdev); |
387 | } | 387 | } |
388 | 388 | ||
389 | static int fc2580_s_power(struct v4l2_subdev *sd, int on) | 389 | static int fc2580_standby(struct v4l2_subdev *sd) |
390 | { | 390 | { |
391 | struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); | 391 | struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); |
392 | struct i2c_client *client = dev->client; | ||
393 | int ret; | 392 | int ret; |
394 | 393 | ||
395 | dev_dbg(&client->dev, "on=%d\n", on); | 394 | ret = fc2580_sleep(dev); |
396 | |||
397 | if (on) | ||
398 | ret = fc2580_init(dev); | ||
399 | else | ||
400 | ret = fc2580_sleep(dev); | ||
401 | if (ret) | 395 | if (ret) |
402 | return ret; | 396 | return ret; |
403 | 397 | ||
404 | return fc2580_set_params(dev); | 398 | return fc2580_set_params(dev); |
405 | } | 399 | } |
406 | 400 | ||
407 | static const struct v4l2_subdev_core_ops fc2580_subdev_core_ops = { | ||
408 | .s_power = fc2580_s_power, | ||
409 | }; | ||
410 | |||
411 | static int fc2580_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) | 401 | static int fc2580_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) |
412 | { | 402 | { |
413 | struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); | 403 | struct fc2580_dev *dev = fc2580_subdev_to_dev(sd); |
@@ -475,6 +465,7 @@ static int fc2580_enum_freq_bands(struct v4l2_subdev *sd, | |||
475 | } | 465 | } |
476 | 466 | ||
477 | static const struct v4l2_subdev_tuner_ops fc2580_subdev_tuner_ops = { | 467 | static const struct v4l2_subdev_tuner_ops fc2580_subdev_tuner_ops = { |
468 | .standby = fc2580_standby, | ||
478 | .g_tuner = fc2580_g_tuner, | 469 | .g_tuner = fc2580_g_tuner, |
479 | .s_tuner = fc2580_s_tuner, | 470 | .s_tuner = fc2580_s_tuner, |
480 | .g_frequency = fc2580_g_frequency, | 471 | .g_frequency = fc2580_g_frequency, |
@@ -483,7 +474,6 @@ static const struct v4l2_subdev_tuner_ops fc2580_subdev_tuner_ops = { | |||
483 | }; | 474 | }; |
484 | 475 | ||
485 | static const struct v4l2_subdev_ops fc2580_subdev_ops = { | 476 | static const struct v4l2_subdev_ops fc2580_subdev_ops = { |
486 | .core = &fc2580_subdev_core_ops, | ||
487 | .tuner = &fc2580_subdev_tuner_ops, | 477 | .tuner = &fc2580_subdev_tuner_ops, |
488 | }; | 478 | }; |
489 | 479 | ||
diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c index 3a12ef35682b..5de6ed728708 100644 --- a/drivers/media/tuners/msi001.c +++ b/drivers/media/tuners/msi001.c | |||
@@ -291,26 +291,13 @@ err: | |||
291 | return ret; | 291 | return ret; |
292 | } | 292 | } |
293 | 293 | ||
294 | static int msi001_s_power(struct v4l2_subdev *sd, int on) | 294 | static int msi001_standby(struct v4l2_subdev *sd) |
295 | { | 295 | { |
296 | struct msi001_dev *dev = sd_to_msi001_dev(sd); | 296 | struct msi001_dev *dev = sd_to_msi001_dev(sd); |
297 | struct spi_device *spi = dev->spi; | ||
298 | int ret; | ||
299 | |||
300 | dev_dbg(&spi->dev, "on=%d\n", on); | ||
301 | |||
302 | if (on) | ||
303 | ret = 0; | ||
304 | else | ||
305 | ret = msi001_wreg(dev, 0x000000); | ||
306 | 297 | ||
307 | return ret; | 298 | return msi001_wreg(dev, 0x000000); |
308 | } | 299 | } |
309 | 300 | ||
310 | static const struct v4l2_subdev_core_ops msi001_core_ops = { | ||
311 | .s_power = msi001_s_power, | ||
312 | }; | ||
313 | |||
314 | static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) | 301 | static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v) |
315 | { | 302 | { |
316 | struct msi001_dev *dev = sd_to_msi001_dev(sd); | 303 | struct msi001_dev *dev = sd_to_msi001_dev(sd); |
@@ -386,6 +373,7 @@ static int msi001_enum_freq_bands(struct v4l2_subdev *sd, | |||
386 | } | 373 | } |
387 | 374 | ||
388 | static const struct v4l2_subdev_tuner_ops msi001_tuner_ops = { | 375 | static const struct v4l2_subdev_tuner_ops msi001_tuner_ops = { |
376 | .standby = msi001_standby, | ||
389 | .g_tuner = msi001_g_tuner, | 377 | .g_tuner = msi001_g_tuner, |
390 | .s_tuner = msi001_s_tuner, | 378 | .s_tuner = msi001_s_tuner, |
391 | .g_frequency = msi001_g_frequency, | 379 | .g_frequency = msi001_g_frequency, |
@@ -394,7 +382,6 @@ static const struct v4l2_subdev_tuner_ops msi001_tuner_ops = { | |||
394 | }; | 382 | }; |
395 | 383 | ||
396 | static const struct v4l2_subdev_ops msi001_ops = { | 384 | static const struct v4l2_subdev_ops msi001_ops = { |
397 | .core = &msi001_core_ops, | ||
398 | .tuner = &msi001_tuner_ops, | 385 | .tuner = &msi001_tuner_ops, |
399 | }; | 386 | }; |
400 | 387 | ||
diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig index bfaa806633df..65fc067eb864 100644 --- a/drivers/media/usb/au0828/Kconfig +++ b/drivers/media/usb/au0828/Kconfig | |||
@@ -4,7 +4,7 @@ config VIDEO_AU0828 | |||
4 | depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 | 4 | depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 |
5 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
6 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
7 | select VIDEOBUF2_VMALLOC | 7 | select VIDEOBUF2_VMALLOC if VIDEO_V4L2 |
8 | select DVB_AU8522_DTV if MEDIA_SUBDRV_AUTOSELECT | 8 | select DVB_AU8522_DTV if MEDIA_SUBDRV_AUTOSELECT |
9 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT | 9 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT |
10 | select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT | 10 | select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT |
@@ -18,7 +18,8 @@ config VIDEO_AU0828 | |||
18 | 18 | ||
19 | config VIDEO_AU0828_V4L2 | 19 | config VIDEO_AU0828_V4L2 |
20 | bool "Auvitek AU0828 v4l2 analog video support" | 20 | bool "Auvitek AU0828 v4l2 analog video support" |
21 | depends on VIDEO_AU0828 && VIDEO_V4L2 | 21 | depends on VIDEO_AU0828 |
22 | depends on VIDEO_V4L2=y || VIDEO_V4L2=VIDEO_AU0828 | ||
22 | select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT | 23 | select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT |
23 | select VIDEO_TUNER | 24 | select VIDEO_TUNER |
24 | default y | 25 | default y |
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index c765d546114d..964cd7bcdd2c 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c | |||
@@ -1091,8 +1091,8 @@ static int au0828_v4l2_close(struct file *filp) | |||
1091 | */ | 1091 | */ |
1092 | ret = v4l_enable_media_source(vdev); | 1092 | ret = v4l_enable_media_source(vdev); |
1093 | if (ret == 0) | 1093 | if (ret == 0) |
1094 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, | 1094 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, |
1095 | s_power, 0); | 1095 | standby); |
1096 | dev->std_set_in_tuner_core = 0; | 1096 | dev->std_set_in_tuner_core = 0; |
1097 | 1097 | ||
1098 | /* When close the device, set the usb intf0 into alt0 to free | 1098 | /* When close the device, set the usb intf0 into alt0 to free |
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index f3a1e5b1e57c..b51fc372ca25 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c | |||
@@ -910,9 +910,6 @@ static void cpia2_usb_disconnect(struct usb_interface *intf) | |||
910 | wake_up_interruptible(&cam->wq_stream); | 910 | wake_up_interruptible(&cam->wq_stream); |
911 | } | 911 | } |
912 | 912 | ||
913 | DBG("Releasing interface\n"); | ||
914 | usb_driver_release_interface(&cpia2_driver, intf); | ||
915 | |||
916 | LOG("CPiA2 camera disconnected.\n"); | 913 | LOG("CPiA2 camera disconnected.\n"); |
917 | } | 914 | } |
918 | 915 | ||
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index f9ec7fedcd5b..c76b2101193c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |||
@@ -922,6 +922,85 @@ struct cx231xx_board cx231xx_boards[] = { | |||
922 | .gpio = NULL, | 922 | .gpio = NULL, |
923 | } }, | 923 | } }, |
924 | }, | 924 | }, |
925 | [CX231XX_BOARD_HAUPPAUGE_935C] = { | ||
926 | .name = "Hauppauge WinTV-HVR-935C", | ||
927 | .tuner_type = TUNER_ABSENT, | ||
928 | .tuner_addr = 0x60, | ||
929 | .tuner_gpio = RDE250_XCV_TUNER, | ||
930 | .tuner_sif_gpio = 0x05, | ||
931 | .tuner_scl_gpio = 0x1a, | ||
932 | .tuner_sda_gpio = 0x1b, | ||
933 | .decoder = CX231XX_AVDECODER, | ||
934 | .output_mode = OUT_MODE_VIP11, | ||
935 | .demod_xfer_mode = 0, | ||
936 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
937 | .agc_analog_digital_select_gpio = 0x0c, | ||
938 | .gpio_pin_status_mask = 0x4001000, | ||
939 | .tuner_i2c_master = I2C_1_MUX_3, | ||
940 | .demod_i2c_master = I2C_1_MUX_3, | ||
941 | .has_dvb = 1, | ||
942 | .demod_addr = 0x64, /* 0xc8 >> 1 */ | ||
943 | .norm = V4L2_STD_PAL, | ||
944 | |||
945 | .input = {{ | ||
946 | .type = CX231XX_VMUX_TELEVISION, | ||
947 | .vmux = CX231XX_VIN_3_1, | ||
948 | .amux = CX231XX_AMUX_VIDEO, | ||
949 | .gpio = NULL, | ||
950 | }, { | ||
951 | .type = CX231XX_VMUX_COMPOSITE1, | ||
952 | .vmux = CX231XX_VIN_2_1, | ||
953 | .amux = CX231XX_AMUX_LINE_IN, | ||
954 | .gpio = NULL, | ||
955 | }, { | ||
956 | .type = CX231XX_VMUX_SVIDEO, | ||
957 | .vmux = CX231XX_VIN_1_1 | | ||
958 | (CX231XX_VIN_1_2 << 8) | | ||
959 | CX25840_SVIDEO_ON, | ||
960 | .amux = CX231XX_AMUX_LINE_IN, | ||
961 | .gpio = NULL, | ||
962 | } }, | ||
963 | }, | ||
964 | [CX231XX_BOARD_HAUPPAUGE_975] = { | ||
965 | .name = "Hauppauge WinTV-HVR-975", | ||
966 | .tuner_type = TUNER_ABSENT, | ||
967 | .tuner_addr = 0x60, | ||
968 | .tuner_gpio = RDE250_XCV_TUNER, | ||
969 | .tuner_sif_gpio = 0x05, | ||
970 | .tuner_scl_gpio = 0x1a, | ||
971 | .tuner_sda_gpio = 0x1b, | ||
972 | .decoder = CX231XX_AVDECODER, | ||
973 | .output_mode = OUT_MODE_VIP11, | ||
974 | .demod_xfer_mode = 0, | ||
975 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
976 | .agc_analog_digital_select_gpio = 0x0c, | ||
977 | .gpio_pin_status_mask = 0x4001000, | ||
978 | .tuner_i2c_master = I2C_1_MUX_3, | ||
979 | .demod_i2c_master = I2C_1_MUX_3, | ||
980 | .has_dvb = 1, | ||
981 | .demod_addr = 0x59, /* 0xb2 >> 1 */ | ||
982 | .demod_addr2 = 0x64, /* 0xc8 >> 1 */ | ||
983 | .norm = V4L2_STD_ALL, | ||
984 | |||
985 | .input = {{ | ||
986 | .type = CX231XX_VMUX_TELEVISION, | ||
987 | .vmux = CX231XX_VIN_3_1, | ||
988 | .amux = CX231XX_AMUX_VIDEO, | ||
989 | .gpio = NULL, | ||
990 | }, { | ||
991 | .type = CX231XX_VMUX_COMPOSITE1, | ||
992 | .vmux = CX231XX_VIN_2_1, | ||
993 | .amux = CX231XX_AMUX_LINE_IN, | ||
994 | .gpio = NULL, | ||
995 | }, { | ||
996 | .type = CX231XX_VMUX_SVIDEO, | ||
997 | .vmux = CX231XX_VIN_1_1 | | ||
998 | (CX231XX_VIN_1_2 << 8) | | ||
999 | CX25840_SVIDEO_ON, | ||
1000 | .amux = CX231XX_AMUX_LINE_IN, | ||
1001 | .gpio = NULL, | ||
1002 | } }, | ||
1003 | }, | ||
925 | }; | 1004 | }; |
926 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | 1005 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); |
927 | 1006 | ||
@@ -953,6 +1032,10 @@ struct usb_device_id cx231xx_id_table[] = { | |||
953 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, | 1032 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, |
954 | {USB_DEVICE(0x2040, 0xb123), | 1033 | {USB_DEVICE(0x2040, 0xb123), |
955 | .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, | 1034 | .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, |
1035 | {USB_DEVICE(0x2040, 0xb151), | ||
1036 | .driver_info = CX231XX_BOARD_HAUPPAUGE_935C}, | ||
1037 | {USB_DEVICE(0x2040, 0xb150), | ||
1038 | .driver_info = CX231XX_BOARD_HAUPPAUGE_975}, | ||
956 | {USB_DEVICE(0x2040, 0xb130), | 1039 | {USB_DEVICE(0x2040, 0xb130), |
957 | .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, | 1040 | .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, |
958 | {USB_DEVICE(0x2040, 0xb131), | 1041 | {USB_DEVICE(0x2040, 0xb131), |
@@ -1135,7 +1218,7 @@ static void cx231xx_config_tuner(struct cx231xx *dev) | |||
1135 | static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, | 1218 | static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, |
1136 | u8 *eedata, int len) | 1219 | u8 *eedata, int len) |
1137 | { | 1220 | { |
1138 | int ret = 0; | 1221 | int ret; |
1139 | u8 start_offset = 0; | 1222 | u8 start_offset = 0; |
1140 | int len_todo = len; | 1223 | int len_todo = len; |
1141 | u8 *eedata_cur = eedata; | 1224 | u8 *eedata_cur = eedata; |
@@ -1211,6 +1294,8 @@ void cx231xx_card_setup(struct cx231xx *dev) | |||
1211 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: | 1294 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: |
1212 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: | 1295 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: |
1213 | case CX231XX_BOARD_HAUPPAUGE_955Q: | 1296 | case CX231XX_BOARD_HAUPPAUGE_955Q: |
1297 | case CX231XX_BOARD_HAUPPAUGE_935C: | ||
1298 | case CX231XX_BOARD_HAUPPAUGE_975: | ||
1214 | { | 1299 | { |
1215 | struct eeprom { | 1300 | struct eeprom { |
1216 | struct tveeprom tvee; | 1301 | struct tveeprom tvee; |
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index fb5654062b1a..713029420fcf 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c | |||
@@ -53,9 +53,10 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | |||
53 | #define CX231XX_DVB_NUM_BUFS 5 | 53 | #define CX231XX_DVB_NUM_BUFS 5 |
54 | #define CX231XX_DVB_MAX_PACKETSIZE 564 | 54 | #define CX231XX_DVB_MAX_PACKETSIZE 564 |
55 | #define CX231XX_DVB_MAX_PACKETS 64 | 55 | #define CX231XX_DVB_MAX_PACKETS 64 |
56 | #define CX231XX_DVB_MAX_FRONTENDS 2 | ||
56 | 57 | ||
57 | struct cx231xx_dvb { | 58 | struct cx231xx_dvb { |
58 | struct dvb_frontend *frontend; | 59 | struct dvb_frontend *frontend[CX231XX_DVB_MAX_FRONTENDS]; |
59 | 60 | ||
60 | /* feed count management */ | 61 | /* feed count management */ |
61 | struct mutex lock; | 62 | struct mutex lock; |
@@ -68,7 +69,7 @@ struct cx231xx_dvb { | |||
68 | struct dmx_frontend fe_hw; | 69 | struct dmx_frontend fe_hw; |
69 | struct dmx_frontend fe_mem; | 70 | struct dmx_frontend fe_mem; |
70 | struct dvb_net net; | 71 | struct dvb_net net; |
71 | struct i2c_client *i2c_client_demod; | 72 | struct i2c_client *i2c_client_demod[2]; |
72 | struct i2c_client *i2c_client_tuner; | 73 | struct i2c_client *i2c_client_tuner; |
73 | }; | 74 | }; |
74 | 75 | ||
@@ -79,7 +80,7 @@ static struct s5h1432_config dvico_s5h1432_config = { | |||
79 | .vsb_if = S5H1432_IF_4000, | 80 | .vsb_if = S5H1432_IF_4000, |
80 | .inversion = S5H1432_INVERSION_OFF, | 81 | .inversion = S5H1432_INVERSION_OFF, |
81 | .status_mode = S5H1432_DEMODLOCKING, | 82 | .status_mode = S5H1432_DEMODLOCKING, |
82 | .mpeg_timing = S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 83 | .mpeg_timing = S5H1432_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
83 | }; | 84 | }; |
84 | 85 | ||
85 | static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { | 86 | static struct tda18271_std_map cnxt_rde253s_tda18271_std_map = { |
@@ -108,7 +109,7 @@ static struct s5h1411_config tda18271_s5h1411_config = { | |||
108 | .qam_if = S5H1411_IF_4000, | 109 | .qam_if = S5H1411_IF_4000, |
109 | .inversion = S5H1411_INVERSION_ON, | 110 | .inversion = S5H1411_INVERSION_ON, |
110 | .status_mode = S5H1411_DEMODLOCKING, | 111 | .status_mode = S5H1411_DEMODLOCKING, |
111 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 112 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
112 | }; | 113 | }; |
113 | static struct s5h1411_config xc5000_s5h1411_config = { | 114 | static struct s5h1411_config xc5000_s5h1411_config = { |
114 | .output_mode = S5H1411_SERIAL_OUTPUT, | 115 | .output_mode = S5H1411_SERIAL_OUTPUT, |
@@ -117,7 +118,7 @@ static struct s5h1411_config xc5000_s5h1411_config = { | |||
117 | .qam_if = S5H1411_IF_3250, | 118 | .qam_if = S5H1411_IF_3250, |
118 | .inversion = S5H1411_INVERSION_OFF, | 119 | .inversion = S5H1411_INVERSION_OFF, |
119 | .status_mode = S5H1411_DEMODLOCKING, | 120 | .status_mode = S5H1411_DEMODLOCKING, |
120 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | 121 | .mpeg_timing = S5H1411_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK, |
121 | }; | 122 | }; |
122 | 123 | ||
123 | static struct lgdt3305_config hcw_lgdt3305_config = { | 124 | static struct lgdt3305_config hcw_lgdt3305_config = { |
@@ -386,17 +387,17 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) | |||
386 | cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); | 387 | cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); |
387 | cfg.i2c_addr = addr; | 388 | cfg.i2c_addr = addr; |
388 | 389 | ||
389 | if (!dev->dvb->frontend) { | 390 | if (!dev->dvb->frontend[0]) { |
390 | dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n", | 391 | dev_err(dev->dev, "%s/2: dvb frontend not attached. Can't attach xc5000\n", |
391 | dev->name); | 392 | dev->name); |
392 | return -EINVAL; | 393 | return -EINVAL; |
393 | } | 394 | } |
394 | 395 | ||
395 | fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg); | 396 | fe = dvb_attach(xc5000_attach, dev->dvb->frontend[0], &cfg); |
396 | if (!fe) { | 397 | if (!fe) { |
397 | dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name); | 398 | dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name); |
398 | dvb_frontend_detach(dev->dvb->frontend); | 399 | dvb_frontend_detach(dev->dvb->frontend[0]); |
399 | dev->dvb->frontend = NULL; | 400 | dev->dvb->frontend[0] = NULL; |
400 | return -EINVAL; | 401 | return -EINVAL; |
401 | } | 402 | } |
402 | 403 | ||
@@ -408,9 +409,9 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) | |||
408 | 409 | ||
409 | int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) | 410 | int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) |
410 | { | 411 | { |
411 | if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { | 412 | if (dev->dvb && dev->dvb->frontend[0]) { |
412 | 413 | ||
413 | struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; | 414 | struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops; |
414 | 415 | ||
415 | if (dops->set_analog_params != NULL) { | 416 | if (dops->set_analog_params != NULL) { |
416 | struct analog_parameters params; | 417 | struct analog_parameters params; |
@@ -421,7 +422,7 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq) | |||
421 | /*params.audmode = ; */ | 422 | /*params.audmode = ; */ |
422 | 423 | ||
423 | /* Set the analog parameters to set the frequency */ | 424 | /* Set the analog parameters to set the frequency */ |
424 | dops->set_analog_params(dev->dvb->frontend, ¶ms); | 425 | dops->set_analog_params(dev->dvb->frontend[0], ¶ms); |
425 | } | 426 | } |
426 | 427 | ||
427 | } | 428 | } |
@@ -433,15 +434,15 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) | |||
433 | { | 434 | { |
434 | int status = 0; | 435 | int status = 0; |
435 | 436 | ||
436 | if ((dev->dvb != NULL) && (dev->dvb->frontend != NULL)) { | 437 | if (dev->dvb && dev->dvb->frontend[0]) { |
437 | 438 | ||
438 | struct dvb_tuner_ops *dops = &dev->dvb->frontend->ops.tuner_ops; | 439 | struct dvb_tuner_ops *dops = &dev->dvb->frontend[0]->ops.tuner_ops; |
439 | 440 | ||
440 | if (dops->init != NULL && !dev->xc_fw_load_done) { | 441 | if (dops->init != NULL && !dev->xc_fw_load_done) { |
441 | 442 | ||
442 | dev_dbg(dev->dev, | 443 | dev_dbg(dev->dev, |
443 | "Reloading firmware for XC5000\n"); | 444 | "Reloading firmware for XC5000\n"); |
444 | status = dops->init(dev->dvb->frontend); | 445 | status = dops->init(dev->dvb->frontend[0]); |
445 | if (status == 0) { | 446 | if (status == 0) { |
446 | dev->xc_fw_load_done = 1; | 447 | dev->xc_fw_load_done = 1; |
447 | dev_dbg(dev->dev, | 448 | dev_dbg(dev->dev, |
@@ -481,17 +482,32 @@ static int register_dvb(struct cx231xx_dvb *dvb, | |||
481 | dvb_register_media_controller(&dvb->adapter, dev->media_dev); | 482 | dvb_register_media_controller(&dvb->adapter, dev->media_dev); |
482 | 483 | ||
483 | /* Ensure all frontends negotiate bus access */ | 484 | /* Ensure all frontends negotiate bus access */ |
484 | dvb->frontend->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; | 485 | dvb->frontend[0]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; |
486 | if (dvb->frontend[1]) | ||
487 | dvb->frontend[1]->ops.ts_bus_ctrl = cx231xx_dvb_bus_ctrl; | ||
485 | 488 | ||
486 | dvb->adapter.priv = dev; | 489 | dvb->adapter.priv = dev; |
487 | 490 | ||
488 | /* register frontend */ | 491 | /* register frontend */ |
489 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend); | 492 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend[0]); |
490 | if (result < 0) { | 493 | if (result < 0) { |
491 | dev_warn(dev->dev, | 494 | dev_warn(dev->dev, |
492 | "%s: dvb_register_frontend failed (errno = %d)\n", | 495 | "%s: dvb_register_frontend failed (errno = %d)\n", |
493 | dev->name, result); | 496 | dev->name, result); |
494 | goto fail_frontend; | 497 | goto fail_frontend0; |
498 | } | ||
499 | |||
500 | if (dvb->frontend[1]) { | ||
501 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend[1]); | ||
502 | if (result < 0) { | ||
503 | dev_warn(dev->dev, | ||
504 | "%s: 2nd dvb_register_frontend failed (errno = %d)\n", | ||
505 | dev->name, result); | ||
506 | goto fail_frontend1; | ||
507 | } | ||
508 | |||
509 | /* MFE lock */ | ||
510 | dvb->adapter.mfe_shared = 1; | ||
495 | } | 511 | } |
496 | 512 | ||
497 | /* register demux stuff */ | 513 | /* register demux stuff */ |
@@ -569,9 +585,14 @@ fail_fe_hw: | |||
569 | fail_dmxdev: | 585 | fail_dmxdev: |
570 | dvb_dmx_release(&dvb->demux); | 586 | dvb_dmx_release(&dvb->demux); |
571 | fail_dmx: | 587 | fail_dmx: |
572 | dvb_unregister_frontend(dvb->frontend); | 588 | if (dvb->frontend[1]) |
573 | fail_frontend: | 589 | dvb_unregister_frontend(dvb->frontend[1]); |
574 | dvb_frontend_detach(dvb->frontend); | 590 | dvb_unregister_frontend(dvb->frontend[0]); |
591 | fail_frontend1: | ||
592 | if (dvb->frontend[1]) | ||
593 | dvb_frontend_detach(dvb->frontend[1]); | ||
594 | fail_frontend0: | ||
595 | dvb_frontend_detach(dvb->frontend[0]); | ||
575 | dvb_unregister_adapter(&dvb->adapter); | 596 | dvb_unregister_adapter(&dvb->adapter); |
576 | fail_adapter: | 597 | fail_adapter: |
577 | return result; | 598 | return result; |
@@ -585,8 +606,12 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) | |||
585 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | 606 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); |
586 | dvb_dmxdev_release(&dvb->dmxdev); | 607 | dvb_dmxdev_release(&dvb->dmxdev); |
587 | dvb_dmx_release(&dvb->demux); | 608 | dvb_dmx_release(&dvb->demux); |
588 | dvb_unregister_frontend(dvb->frontend); | 609 | if (dvb->frontend[1]) |
589 | dvb_frontend_detach(dvb->frontend); | 610 | dvb_unregister_frontend(dvb->frontend[1]); |
611 | dvb_unregister_frontend(dvb->frontend[0]); | ||
612 | if (dvb->frontend[1]) | ||
613 | dvb_frontend_detach(dvb->frontend[1]); | ||
614 | dvb_frontend_detach(dvb->frontend[0]); | ||
590 | dvb_unregister_adapter(&dvb->adapter); | 615 | dvb_unregister_adapter(&dvb->adapter); |
591 | /* remove I2C tuner */ | 616 | /* remove I2C tuner */ |
592 | client = dvb->i2c_client_tuner; | 617 | client = dvb->i2c_client_tuner; |
@@ -595,7 +620,12 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) | |||
595 | i2c_unregister_device(client); | 620 | i2c_unregister_device(client); |
596 | } | 621 | } |
597 | /* remove I2C demod */ | 622 | /* remove I2C demod */ |
598 | client = dvb->i2c_client_demod; | 623 | client = dvb->i2c_client_demod[1]; |
624 | if (client) { | ||
625 | module_put(client->dev.driver->owner); | ||
626 | i2c_unregister_device(client); | ||
627 | } | ||
628 | client = dvb->i2c_client_demod[0]; | ||
599 | if (client) { | 629 | if (client) { |
600 | module_put(client->dev.driver->owner); | 630 | module_put(client->dev.driver->owner); |
601 | i2c_unregister_device(client); | 631 | i2c_unregister_device(client); |
@@ -604,7 +634,7 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) | |||
604 | 634 | ||
605 | static int dvb_init(struct cx231xx *dev) | 635 | static int dvb_init(struct cx231xx *dev) |
606 | { | 636 | { |
607 | int result = 0; | 637 | int result; |
608 | struct cx231xx_dvb *dvb; | 638 | struct cx231xx_dvb *dvb; |
609 | struct i2c_adapter *tuner_i2c; | 639 | struct i2c_adapter *tuner_i2c; |
610 | struct i2c_adapter *demod_i2c; | 640 | struct i2c_adapter *demod_i2c; |
@@ -635,11 +665,11 @@ static int dvb_init(struct cx231xx *dev) | |||
635 | case CX231XX_BOARD_CNXT_CARRAERA: | 665 | case CX231XX_BOARD_CNXT_CARRAERA: |
636 | case CX231XX_BOARD_CNXT_RDE_250: | 666 | case CX231XX_BOARD_CNXT_RDE_250: |
637 | 667 | ||
638 | dev->dvb->frontend = dvb_attach(s5h1432_attach, | 668 | dev->dvb->frontend[0] = dvb_attach(s5h1432_attach, |
639 | &dvico_s5h1432_config, | 669 | &dvico_s5h1432_config, |
640 | demod_i2c); | 670 | demod_i2c); |
641 | 671 | ||
642 | if (dev->dvb->frontend == NULL) { | 672 | if (!dev->dvb->frontend[0]) { |
643 | dev_err(dev->dev, | 673 | dev_err(dev->dev, |
644 | "Failed to attach s5h1432 front end\n"); | 674 | "Failed to attach s5h1432 front end\n"); |
645 | result = -EINVAL; | 675 | result = -EINVAL; |
@@ -647,9 +677,9 @@ static int dvb_init(struct cx231xx *dev) | |||
647 | } | 677 | } |
648 | 678 | ||
649 | /* define general-purpose callback pointer */ | 679 | /* define general-purpose callback pointer */ |
650 | dvb->frontend->callback = cx231xx_tuner_callback; | 680 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
651 | 681 | ||
652 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, | 682 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0], |
653 | tuner_i2c, | 683 | tuner_i2c, |
654 | &cnxt_rde250_tunerconfig)) { | 684 | &cnxt_rde250_tunerconfig)) { |
655 | result = -EINVAL; | 685 | result = -EINVAL; |
@@ -660,11 +690,11 @@ static int dvb_init(struct cx231xx *dev) | |||
660 | case CX231XX_BOARD_CNXT_SHELBY: | 690 | case CX231XX_BOARD_CNXT_SHELBY: |
661 | case CX231XX_BOARD_CNXT_RDU_250: | 691 | case CX231XX_BOARD_CNXT_RDU_250: |
662 | 692 | ||
663 | dev->dvb->frontend = dvb_attach(s5h1411_attach, | 693 | dev->dvb->frontend[0] = dvb_attach(s5h1411_attach, |
664 | &xc5000_s5h1411_config, | 694 | &xc5000_s5h1411_config, |
665 | demod_i2c); | 695 | demod_i2c); |
666 | 696 | ||
667 | if (dev->dvb->frontend == NULL) { | 697 | if (!dev->dvb->frontend[0]) { |
668 | dev_err(dev->dev, | 698 | dev_err(dev->dev, |
669 | "Failed to attach s5h1411 front end\n"); | 699 | "Failed to attach s5h1411 front end\n"); |
670 | result = -EINVAL; | 700 | result = -EINVAL; |
@@ -672,9 +702,9 @@ static int dvb_init(struct cx231xx *dev) | |||
672 | } | 702 | } |
673 | 703 | ||
674 | /* define general-purpose callback pointer */ | 704 | /* define general-purpose callback pointer */ |
675 | dvb->frontend->callback = cx231xx_tuner_callback; | 705 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
676 | 706 | ||
677 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend, | 707 | if (!dvb_attach(xc5000_attach, dev->dvb->frontend[0], |
678 | tuner_i2c, | 708 | tuner_i2c, |
679 | &cnxt_rdu250_tunerconfig)) { | 709 | &cnxt_rdu250_tunerconfig)) { |
680 | result = -EINVAL; | 710 | result = -EINVAL; |
@@ -683,11 +713,11 @@ static int dvb_init(struct cx231xx *dev) | |||
683 | break; | 713 | break; |
684 | case CX231XX_BOARD_CNXT_RDE_253S: | 714 | case CX231XX_BOARD_CNXT_RDE_253S: |
685 | 715 | ||
686 | dev->dvb->frontend = dvb_attach(s5h1432_attach, | 716 | dev->dvb->frontend[0] = dvb_attach(s5h1432_attach, |
687 | &dvico_s5h1432_config, | 717 | &dvico_s5h1432_config, |
688 | demod_i2c); | 718 | demod_i2c); |
689 | 719 | ||
690 | if (dev->dvb->frontend == NULL) { | 720 | if (!dev->dvb->frontend[0]) { |
691 | dev_err(dev->dev, | 721 | dev_err(dev->dev, |
692 | "Failed to attach s5h1432 front end\n"); | 722 | "Failed to attach s5h1432 front end\n"); |
693 | result = -EINVAL; | 723 | result = -EINVAL; |
@@ -695,9 +725,9 @@ static int dvb_init(struct cx231xx *dev) | |||
695 | } | 725 | } |
696 | 726 | ||
697 | /* define general-purpose callback pointer */ | 727 | /* define general-purpose callback pointer */ |
698 | dvb->frontend->callback = cx231xx_tuner_callback; | 728 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
699 | 729 | ||
700 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend, | 730 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0], |
701 | 0x60, tuner_i2c, | 731 | 0x60, tuner_i2c, |
702 | &cnxt_rde253s_tunerconfig)) { | 732 | &cnxt_rde253s_tunerconfig)) { |
703 | result = -EINVAL; | 733 | result = -EINVAL; |
@@ -707,11 +737,11 @@ static int dvb_init(struct cx231xx *dev) | |||
707 | case CX231XX_BOARD_CNXT_RDU_253S: | 737 | case CX231XX_BOARD_CNXT_RDU_253S: |
708 | case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID: | 738 | case CX231XX_BOARD_KWORLD_UB445_USB_HYBRID: |
709 | 739 | ||
710 | dev->dvb->frontend = dvb_attach(s5h1411_attach, | 740 | dev->dvb->frontend[0] = dvb_attach(s5h1411_attach, |
711 | &tda18271_s5h1411_config, | 741 | &tda18271_s5h1411_config, |
712 | demod_i2c); | 742 | demod_i2c); |
713 | 743 | ||
714 | if (dev->dvb->frontend == NULL) { | 744 | if (!dev->dvb->frontend[0]) { |
715 | dev_err(dev->dev, | 745 | dev_err(dev->dev, |
716 | "Failed to attach s5h1411 front end\n"); | 746 | "Failed to attach s5h1411 front end\n"); |
717 | result = -EINVAL; | 747 | result = -EINVAL; |
@@ -719,9 +749,9 @@ static int dvb_init(struct cx231xx *dev) | |||
719 | } | 749 | } |
720 | 750 | ||
721 | /* define general-purpose callback pointer */ | 751 | /* define general-purpose callback pointer */ |
722 | dvb->frontend->callback = cx231xx_tuner_callback; | 752 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
723 | 753 | ||
724 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend, | 754 | if (!dvb_attach(tda18271_attach, dev->dvb->frontend[0], |
725 | 0x60, tuner_i2c, | 755 | 0x60, tuner_i2c, |
726 | &cnxt_rde253s_tunerconfig)) { | 756 | &cnxt_rde253s_tunerconfig)) { |
727 | result = -EINVAL; | 757 | result = -EINVAL; |
@@ -734,11 +764,11 @@ static int dvb_init(struct cx231xx *dev) | |||
734 | "%s: looking for tuner / demod on i2c bus: %d\n", | 764 | "%s: looking for tuner / demod on i2c bus: %d\n", |
735 | __func__, i2c_adapter_id(tuner_i2c)); | 765 | __func__, i2c_adapter_id(tuner_i2c)); |
736 | 766 | ||
737 | dev->dvb->frontend = dvb_attach(lgdt3305_attach, | 767 | dev->dvb->frontend[0] = dvb_attach(lgdt3305_attach, |
738 | &hcw_lgdt3305_config, | 768 | &hcw_lgdt3305_config, |
739 | demod_i2c); | 769 | demod_i2c); |
740 | 770 | ||
741 | if (dev->dvb->frontend == NULL) { | 771 | if (!dev->dvb->frontend[0]) { |
742 | dev_err(dev->dev, | 772 | dev_err(dev->dev, |
743 | "Failed to attach LG3305 front end\n"); | 773 | "Failed to attach LG3305 front end\n"); |
744 | result = -EINVAL; | 774 | result = -EINVAL; |
@@ -746,9 +776,9 @@ static int dvb_init(struct cx231xx *dev) | |||
746 | } | 776 | } |
747 | 777 | ||
748 | /* define general-purpose callback pointer */ | 778 | /* define general-purpose callback pointer */ |
749 | dvb->frontend->callback = cx231xx_tuner_callback; | 779 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
750 | 780 | ||
751 | dvb_attach(tda18271_attach, dev->dvb->frontend, | 781 | dvb_attach(tda18271_attach, dev->dvb->frontend[0], |
752 | 0x60, tuner_i2c, | 782 | 0x60, tuner_i2c, |
753 | &hcw_tda18271_config); | 783 | &hcw_tda18271_config); |
754 | break; | 784 | break; |
@@ -761,7 +791,7 @@ static int dvb_init(struct cx231xx *dev) | |||
761 | 791 | ||
762 | /* attach demod */ | 792 | /* attach demod */ |
763 | memset(&si2165_pdata, 0, sizeof(si2165_pdata)); | 793 | memset(&si2165_pdata, 0, sizeof(si2165_pdata)); |
764 | si2165_pdata.fe = &dev->dvb->frontend; | 794 | si2165_pdata.fe = &dev->dvb->frontend[0]; |
765 | si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL; | 795 | si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL; |
766 | si2165_pdata.ref_freq_hz = 16000000; | 796 | si2165_pdata.ref_freq_hz = 16000000; |
767 | 797 | ||
@@ -771,7 +801,7 @@ static int dvb_init(struct cx231xx *dev) | |||
771 | info.platform_data = &si2165_pdata; | 801 | info.platform_data = &si2165_pdata; |
772 | request_module(info.type); | 802 | request_module(info.type); |
773 | client = i2c_new_device(demod_i2c, &info); | 803 | client = i2c_new_device(demod_i2c, &info); |
774 | if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { | 804 | if (!client || !client->dev.driver || !dev->dvb->frontend[0]) { |
775 | dev_err(dev->dev, | 805 | dev_err(dev->dev, |
776 | "Failed to attach SI2165 front end\n"); | 806 | "Failed to attach SI2165 front end\n"); |
777 | result = -EINVAL; | 807 | result = -EINVAL; |
@@ -784,14 +814,14 @@ static int dvb_init(struct cx231xx *dev) | |||
784 | goto out_free; | 814 | goto out_free; |
785 | } | 815 | } |
786 | 816 | ||
787 | dvb->i2c_client_demod = client; | 817 | dvb->i2c_client_demod[0] = client; |
788 | 818 | ||
789 | dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; | 819 | dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; |
790 | 820 | ||
791 | /* define general-purpose callback pointer */ | 821 | /* define general-purpose callback pointer */ |
792 | dvb->frontend->callback = cx231xx_tuner_callback; | 822 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
793 | 823 | ||
794 | dvb_attach(tda18271_attach, dev->dvb->frontend, | 824 | dvb_attach(tda18271_attach, dev->dvb->frontend[0], |
795 | 0x60, | 825 | 0x60, |
796 | tuner_i2c, | 826 | tuner_i2c, |
797 | &hcw_tda18271_config); | 827 | &hcw_tda18271_config); |
@@ -808,7 +838,7 @@ static int dvb_init(struct cx231xx *dev) | |||
808 | 838 | ||
809 | /* attach demod */ | 839 | /* attach demod */ |
810 | memset(&si2165_pdata, 0, sizeof(si2165_pdata)); | 840 | memset(&si2165_pdata, 0, sizeof(si2165_pdata)); |
811 | si2165_pdata.fe = &dev->dvb->frontend; | 841 | si2165_pdata.fe = &dev->dvb->frontend[0]; |
812 | si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT; | 842 | si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT; |
813 | si2165_pdata.ref_freq_hz = 24000000; | 843 | si2165_pdata.ref_freq_hz = 24000000; |
814 | 844 | ||
@@ -818,7 +848,7 @@ static int dvb_init(struct cx231xx *dev) | |||
818 | info.platform_data = &si2165_pdata; | 848 | info.platform_data = &si2165_pdata; |
819 | request_module(info.type); | 849 | request_module(info.type); |
820 | client = i2c_new_device(demod_i2c, &info); | 850 | client = i2c_new_device(demod_i2c, &info); |
821 | if (client == NULL || client->dev.driver == NULL || dev->dvb->frontend == NULL) { | 851 | if (!client || !client->dev.driver || !dev->dvb->frontend[0]) { |
822 | dev_err(dev->dev, | 852 | dev_err(dev->dev, |
823 | "Failed to attach SI2165 front end\n"); | 853 | "Failed to attach SI2165 front end\n"); |
824 | result = -EINVAL; | 854 | result = -EINVAL; |
@@ -831,18 +861,18 @@ static int dvb_init(struct cx231xx *dev) | |||
831 | goto out_free; | 861 | goto out_free; |
832 | } | 862 | } |
833 | 863 | ||
834 | dvb->i2c_client_demod = client; | 864 | dvb->i2c_client_demod[0] = client; |
835 | 865 | ||
836 | memset(&info, 0, sizeof(struct i2c_board_info)); | 866 | memset(&info, 0, sizeof(struct i2c_board_info)); |
837 | 867 | ||
838 | dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; | 868 | dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; |
839 | 869 | ||
840 | /* define general-purpose callback pointer */ | 870 | /* define general-purpose callback pointer */ |
841 | dvb->frontend->callback = cx231xx_tuner_callback; | 871 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
842 | 872 | ||
843 | /* attach tuner */ | 873 | /* attach tuner */ |
844 | memset(&si2157_config, 0, sizeof(si2157_config)); | 874 | memset(&si2157_config, 0, sizeof(si2157_config)); |
845 | si2157_config.fe = dev->dvb->frontend; | 875 | si2157_config.fe = dev->dvb->frontend[0]; |
846 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | 876 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB |
847 | si2157_config.mdev = dev->media_dev; | 877 | si2157_config.mdev = dev->media_dev; |
848 | #endif | 878 | #endif |
@@ -857,14 +887,14 @@ static int dvb_init(struct cx231xx *dev) | |||
857 | tuner_i2c, | 887 | tuner_i2c, |
858 | &info); | 888 | &info); |
859 | if (client == NULL || client->dev.driver == NULL) { | 889 | if (client == NULL || client->dev.driver == NULL) { |
860 | dvb_frontend_detach(dev->dvb->frontend); | 890 | dvb_frontend_detach(dev->dvb->frontend[0]); |
861 | result = -ENODEV; | 891 | result = -ENODEV; |
862 | goto out_free; | 892 | goto out_free; |
863 | } | 893 | } |
864 | 894 | ||
865 | if (!try_module_get(client->dev.driver->owner)) { | 895 | if (!try_module_get(client->dev.driver->owner)) { |
866 | i2c_unregister_device(client); | 896 | i2c_unregister_device(client); |
867 | dvb_frontend_detach(dev->dvb->frontend); | 897 | dvb_frontend_detach(dev->dvb->frontend[0]); |
868 | result = -ENODEV; | 898 | result = -ENODEV; |
869 | goto out_free; | 899 | goto out_free; |
870 | } | 900 | } |
@@ -882,26 +912,26 @@ static int dvb_init(struct cx231xx *dev) | |||
882 | 912 | ||
883 | memset(&info, 0, sizeof(struct i2c_board_info)); | 913 | memset(&info, 0, sizeof(struct i2c_board_info)); |
884 | 914 | ||
885 | dev->dvb->frontend = dvb_attach(lgdt3306a_attach, | 915 | dev->dvb->frontend[0] = dvb_attach(lgdt3306a_attach, |
886 | &hauppauge_955q_lgdt3306a_config, | 916 | &hauppauge_955q_lgdt3306a_config, |
887 | demod_i2c | 917 | demod_i2c |
888 | ); | 918 | ); |
889 | 919 | ||
890 | if (dev->dvb->frontend == NULL) { | 920 | if (!dev->dvb->frontend[0]) { |
891 | dev_err(dev->dev, | 921 | dev_err(dev->dev, |
892 | "Failed to attach LGDT3306A frontend.\n"); | 922 | "Failed to attach LGDT3306A frontend.\n"); |
893 | result = -EINVAL; | 923 | result = -EINVAL; |
894 | goto out_free; | 924 | goto out_free; |
895 | } | 925 | } |
896 | 926 | ||
897 | dev->dvb->frontend->ops.i2c_gate_ctrl = NULL; | 927 | dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; |
898 | 928 | ||
899 | /* define general-purpose callback pointer */ | 929 | /* define general-purpose callback pointer */ |
900 | dvb->frontend->callback = cx231xx_tuner_callback; | 930 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
901 | 931 | ||
902 | /* attach tuner */ | 932 | /* attach tuner */ |
903 | memset(&si2157_config, 0, sizeof(si2157_config)); | 933 | memset(&si2157_config, 0, sizeof(si2157_config)); |
904 | si2157_config.fe = dev->dvb->frontend; | 934 | si2157_config.fe = dev->dvb->frontend[0]; |
905 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | 935 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB |
906 | si2157_config.mdev = dev->media_dev; | 936 | si2157_config.mdev = dev->media_dev; |
907 | #endif | 937 | #endif |
@@ -916,14 +946,14 @@ static int dvb_init(struct cx231xx *dev) | |||
916 | tuner_i2c, | 946 | tuner_i2c, |
917 | &info); | 947 | &info); |
918 | if (client == NULL || client->dev.driver == NULL) { | 948 | if (client == NULL || client->dev.driver == NULL) { |
919 | dvb_frontend_detach(dev->dvb->frontend); | 949 | dvb_frontend_detach(dev->dvb->frontend[0]); |
920 | result = -ENODEV; | 950 | result = -ENODEV; |
921 | goto out_free; | 951 | goto out_free; |
922 | } | 952 | } |
923 | 953 | ||
924 | if (!try_module_get(client->dev.driver->owner)) { | 954 | if (!try_module_get(client->dev.driver->owner)) { |
925 | i2c_unregister_device(client); | 955 | i2c_unregister_device(client); |
926 | dvb_frontend_detach(dev->dvb->frontend); | 956 | dvb_frontend_detach(dev->dvb->frontend[0]); |
927 | result = -ENODEV; | 957 | result = -ENODEV; |
928 | goto out_free; | 958 | goto out_free; |
929 | } | 959 | } |
@@ -940,11 +970,11 @@ static int dvb_init(struct cx231xx *dev) | |||
940 | "%s: looking for demod on i2c bus: %d\n", | 970 | "%s: looking for demod on i2c bus: %d\n", |
941 | __func__, i2c_adapter_id(tuner_i2c)); | 971 | __func__, i2c_adapter_id(tuner_i2c)); |
942 | 972 | ||
943 | dev->dvb->frontend = dvb_attach(mb86a20s_attach, | 973 | dev->dvb->frontend[0] = dvb_attach(mb86a20s_attach, |
944 | &pv_mb86a20s_config, | 974 | &pv_mb86a20s_config, |
945 | demod_i2c); | 975 | demod_i2c); |
946 | 976 | ||
947 | if (dev->dvb->frontend == NULL) { | 977 | if (!dev->dvb->frontend[0]) { |
948 | dev_err(dev->dev, | 978 | dev_err(dev->dev, |
949 | "Failed to attach mb86a20s demod\n"); | 979 | "Failed to attach mb86a20s demod\n"); |
950 | result = -EINVAL; | 980 | result = -EINVAL; |
@@ -952,9 +982,9 @@ static int dvb_init(struct cx231xx *dev) | |||
952 | } | 982 | } |
953 | 983 | ||
954 | /* define general-purpose callback pointer */ | 984 | /* define general-purpose callback pointer */ |
955 | dvb->frontend->callback = cx231xx_tuner_callback; | 985 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
956 | 986 | ||
957 | dvb_attach(tda18271_attach, dev->dvb->frontend, | 987 | dvb_attach(tda18271_attach, dev->dvb->frontend[0], |
958 | 0x60, tuner_i2c, | 988 | 0x60, tuner_i2c, |
959 | &pv_tda18271_config); | 989 | &pv_tda18271_config); |
960 | break; | 990 | break; |
@@ -969,7 +999,7 @@ static int dvb_init(struct cx231xx *dev) | |||
969 | 999 | ||
970 | /* attach demodulator chip */ | 1000 | /* attach demodulator chip */ |
971 | si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */ | 1001 | si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */ |
972 | si2168_config.fe = &dev->dvb->frontend; | 1002 | si2168_config.fe = &dev->dvb->frontend[0]; |
973 | si2168_config.i2c_adapter = &adapter; | 1003 | si2168_config.i2c_adapter = &adapter; |
974 | si2168_config.ts_clock_inv = true; | 1004 | si2168_config.ts_clock_inv = true; |
975 | 1005 | ||
@@ -991,10 +1021,10 @@ static int dvb_init(struct cx231xx *dev) | |||
991 | goto out_free; | 1021 | goto out_free; |
992 | } | 1022 | } |
993 | 1023 | ||
994 | dvb->i2c_client_demod = client; | 1024 | dvb->i2c_client_demod[0] = client; |
995 | 1025 | ||
996 | /* attach tuner chip */ | 1026 | /* attach tuner chip */ |
997 | si2157_config.fe = dev->dvb->frontend; | 1027 | si2157_config.fe = dev->dvb->frontend[0]; |
998 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | 1028 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB |
999 | si2157_config.mdev = dev->media_dev; | 1029 | si2157_config.mdev = dev->media_dev; |
1000 | #endif | 1030 | #endif |
@@ -1010,16 +1040,16 @@ static int dvb_init(struct cx231xx *dev) | |||
1010 | client = i2c_new_device(tuner_i2c, &info); | 1040 | client = i2c_new_device(tuner_i2c, &info); |
1011 | 1041 | ||
1012 | if (client == NULL || client->dev.driver == NULL) { | 1042 | if (client == NULL || client->dev.driver == NULL) { |
1013 | module_put(dvb->i2c_client_demod->dev.driver->owner); | 1043 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); |
1014 | i2c_unregister_device(dvb->i2c_client_demod); | 1044 | i2c_unregister_device(dvb->i2c_client_demod[0]); |
1015 | result = -ENODEV; | 1045 | result = -ENODEV; |
1016 | goto out_free; | 1046 | goto out_free; |
1017 | } | 1047 | } |
1018 | 1048 | ||
1019 | if (!try_module_get(client->dev.driver->owner)) { | 1049 | if (!try_module_get(client->dev.driver->owner)) { |
1020 | i2c_unregister_device(client); | 1050 | i2c_unregister_device(client); |
1021 | module_put(dvb->i2c_client_demod->dev.driver->owner); | 1051 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); |
1022 | i2c_unregister_device(dvb->i2c_client_demod); | 1052 | i2c_unregister_device(dvb->i2c_client_demod[0]); |
1023 | result = -ENODEV; | 1053 | result = -ENODEV; |
1024 | goto out_free; | 1054 | goto out_free; |
1025 | } | 1055 | } |
@@ -1037,7 +1067,7 @@ static int dvb_init(struct cx231xx *dev) | |||
1037 | /* attach demodulator chip */ | 1067 | /* attach demodulator chip */ |
1038 | mn88473_config.i2c_wr_max = 16; | 1068 | mn88473_config.i2c_wr_max = 16; |
1039 | mn88473_config.xtal = 25000000; | 1069 | mn88473_config.xtal = 25000000; |
1040 | mn88473_config.fe = &dev->dvb->frontend; | 1070 | mn88473_config.fe = &dev->dvb->frontend[0]; |
1041 | 1071 | ||
1042 | strlcpy(info.type, "mn88473", sizeof(info.type)); | 1072 | strlcpy(info.type, "mn88473", sizeof(info.type)); |
1043 | info.addr = dev->board.demod_addr; | 1073 | info.addr = dev->board.demod_addr; |
@@ -1057,24 +1087,219 @@ static int dvb_init(struct cx231xx *dev) | |||
1057 | goto out_free; | 1087 | goto out_free; |
1058 | } | 1088 | } |
1059 | 1089 | ||
1060 | dvb->i2c_client_demod = client; | 1090 | dvb->i2c_client_demod[0] = client; |
1061 | 1091 | ||
1062 | /* define general-purpose callback pointer */ | 1092 | /* define general-purpose callback pointer */ |
1063 | dvb->frontend->callback = cx231xx_tuner_callback; | 1093 | dvb->frontend[0]->callback = cx231xx_tuner_callback; |
1064 | 1094 | ||
1065 | /* attach tuner chip */ | 1095 | /* attach tuner chip */ |
1066 | dvb_attach(r820t_attach, dev->dvb->frontend, | 1096 | dvb_attach(r820t_attach, dev->dvb->frontend[0], |
1067 | tuner_i2c, | 1097 | tuner_i2c, |
1068 | &astrometa_t2hybrid_r820t_config); | 1098 | &astrometa_t2hybrid_r820t_config); |
1069 | break; | 1099 | break; |
1070 | } | 1100 | } |
1101 | case CX231XX_BOARD_HAUPPAUGE_935C: | ||
1102 | { | ||
1103 | struct i2c_client *client; | ||
1104 | struct i2c_adapter *adapter; | ||
1105 | struct i2c_board_info info = {}; | ||
1106 | struct si2157_config si2157_config = {}; | ||
1107 | struct si2168_config si2168_config = {}; | ||
1108 | |||
1109 | /* attach demodulator chip */ | ||
1110 | si2168_config.ts_mode = SI2168_TS_SERIAL; | ||
1111 | si2168_config.fe = &dev->dvb->frontend[0]; | ||
1112 | si2168_config.i2c_adapter = &adapter; | ||
1113 | si2168_config.ts_clock_inv = true; | ||
1114 | |||
1115 | strlcpy(info.type, "si2168", sizeof(info.type)); | ||
1116 | info.addr = dev->board.demod_addr; | ||
1117 | info.platform_data = &si2168_config; | ||
1118 | |||
1119 | request_module(info.type); | ||
1120 | client = i2c_new_device(demod_i2c, &info); | ||
1121 | if (client == NULL || client->dev.driver == NULL) { | ||
1122 | result = -ENODEV; | ||
1123 | goto out_free; | ||
1124 | } | ||
1125 | |||
1126 | if (!try_module_get(client->dev.driver->owner)) { | ||
1127 | dev_err(dev->dev, | ||
1128 | "Failed to attach %s frontend.\n", info.type); | ||
1129 | i2c_unregister_device(client); | ||
1130 | result = -ENODEV; | ||
1131 | goto out_free; | ||
1132 | } | ||
1133 | |||
1134 | dvb->i2c_client_demod[0] = client; | ||
1135 | dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; | ||
1136 | |||
1137 | /* define general-purpose callback pointer */ | ||
1138 | dvb->frontend[0]->callback = cx231xx_tuner_callback; | ||
1139 | |||
1140 | /* attach tuner */ | ||
1141 | si2157_config.fe = dev->dvb->frontend[0]; | ||
1142 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1143 | si2157_config.mdev = dev->media_dev; | ||
1144 | #endif | ||
1145 | si2157_config.if_port = 1; | ||
1146 | si2157_config.inversion = true; | ||
1147 | |||
1148 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1149 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
1150 | info.addr = dev->board.tuner_addr; | ||
1151 | info.platform_data = &si2157_config; | ||
1152 | request_module("si2157"); | ||
1153 | |||
1154 | client = i2c_new_device(adapter, &info); | ||
1155 | if (client == NULL || client->dev.driver == NULL) { | ||
1156 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); | ||
1157 | i2c_unregister_device(dvb->i2c_client_demod[0]); | ||
1158 | result = -ENODEV; | ||
1159 | goto out_free; | ||
1160 | } | ||
1161 | |||
1162 | if (!try_module_get(client->dev.driver->owner)) { | ||
1163 | dev_err(dev->dev, | ||
1164 | "Failed to obtain %s tuner.\n", info.type); | ||
1165 | i2c_unregister_device(client); | ||
1166 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); | ||
1167 | i2c_unregister_device(dvb->i2c_client_demod[0]); | ||
1168 | result = -ENODEV; | ||
1169 | goto out_free; | ||
1170 | } | ||
1171 | |||
1172 | dev->cx231xx_reset_analog_tuner = NULL; | ||
1173 | dev->dvb->i2c_client_tuner = client; | ||
1174 | break; | ||
1175 | } | ||
1176 | case CX231XX_BOARD_HAUPPAUGE_975: | ||
1177 | { | ||
1178 | struct i2c_client *client; | ||
1179 | struct i2c_adapter *adapter; | ||
1180 | struct i2c_adapter *adapter2; | ||
1181 | struct i2c_board_info info = {}; | ||
1182 | struct si2157_config si2157_config = {}; | ||
1183 | struct lgdt3306a_config lgdt3306a_config = {}; | ||
1184 | struct si2168_config si2168_config = {}; | ||
1185 | |||
1186 | /* attach first demodulator chip */ | ||
1187 | lgdt3306a_config = hauppauge_955q_lgdt3306a_config; | ||
1188 | lgdt3306a_config.fe = &dev->dvb->frontend[0]; | ||
1189 | lgdt3306a_config.i2c_adapter = &adapter; | ||
1190 | lgdt3306a_config.deny_i2c_rptr = 0; | ||
1191 | |||
1192 | strlcpy(info.type, "lgdt3306a", sizeof(info.type)); | ||
1193 | info.addr = dev->board.demod_addr; | ||
1194 | info.platform_data = &lgdt3306a_config; | ||
1195 | |||
1196 | request_module(info.type); | ||
1197 | client = i2c_new_device(demod_i2c, &info); | ||
1198 | if (client == NULL || client->dev.driver == NULL) { | ||
1199 | result = -ENODEV; | ||
1200 | goto out_free; | ||
1201 | } | ||
1202 | |||
1203 | if (!try_module_get(client->dev.driver->owner)) { | ||
1204 | dev_err(dev->dev, | ||
1205 | "Failed to attach %s frontend.\n", info.type); | ||
1206 | i2c_unregister_device(client); | ||
1207 | result = -ENODEV; | ||
1208 | goto out_free; | ||
1209 | } | ||
1210 | |||
1211 | dvb->i2c_client_demod[0] = client; | ||
1212 | |||
1213 | /* attach second demodulator chip */ | ||
1214 | si2168_config.ts_mode = SI2168_TS_SERIAL; | ||
1215 | si2168_config.fe = &dev->dvb->frontend[1]; | ||
1216 | si2168_config.i2c_adapter = &adapter2; | ||
1217 | si2168_config.ts_clock_inv = true; | ||
1218 | |||
1219 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1220 | strlcpy(info.type, "si2168", sizeof(info.type)); | ||
1221 | info.addr = dev->board.demod_addr2; | ||
1222 | info.platform_data = &si2168_config; | ||
1223 | |||
1224 | request_module(info.type); | ||
1225 | client = i2c_new_device(adapter, &info); | ||
1226 | if (client == NULL || client->dev.driver == NULL) { | ||
1227 | dev_err(dev->dev, | ||
1228 | "Failed to attach %s frontend.\n", info.type); | ||
1229 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); | ||
1230 | i2c_unregister_device(dvb->i2c_client_demod[0]); | ||
1231 | result = -ENODEV; | ||
1232 | goto out_free; | ||
1233 | } | ||
1234 | |||
1235 | if (!try_module_get(client->dev.driver->owner)) { | ||
1236 | i2c_unregister_device(client); | ||
1237 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); | ||
1238 | i2c_unregister_device(dvb->i2c_client_demod[0]); | ||
1239 | result = -ENODEV; | ||
1240 | goto out_free; | ||
1241 | } | ||
1242 | |||
1243 | dvb->i2c_client_demod[1] = client; | ||
1244 | dvb->frontend[1]->id = 1; | ||
1245 | |||
1246 | /* define general-purpose callback pointer */ | ||
1247 | dvb->frontend[0]->callback = cx231xx_tuner_callback; | ||
1248 | dvb->frontend[1]->callback = cx231xx_tuner_callback; | ||
1249 | |||
1250 | /* attach tuner */ | ||
1251 | si2157_config.fe = dev->dvb->frontend[0]; | ||
1252 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1253 | si2157_config.mdev = dev->media_dev; | ||
1254 | #endif | ||
1255 | si2157_config.if_port = 1; | ||
1256 | si2157_config.inversion = true; | ||
1257 | |||
1258 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1259 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
1260 | info.addr = dev->board.tuner_addr; | ||
1261 | info.platform_data = &si2157_config; | ||
1262 | request_module("si2157"); | ||
1263 | |||
1264 | client = i2c_new_device(adapter, &info); | ||
1265 | if (client == NULL || client->dev.driver == NULL) { | ||
1266 | module_put(dvb->i2c_client_demod[1]->dev.driver->owner); | ||
1267 | i2c_unregister_device(dvb->i2c_client_demod[1]); | ||
1268 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); | ||
1269 | i2c_unregister_device(dvb->i2c_client_demod[0]); | ||
1270 | result = -ENODEV; | ||
1271 | goto out_free; | ||
1272 | } | ||
1273 | |||
1274 | if (!try_module_get(client->dev.driver->owner)) { | ||
1275 | dev_err(dev->dev, | ||
1276 | "Failed to obtain %s tuner.\n", info.type); | ||
1277 | i2c_unregister_device(client); | ||
1278 | module_put(dvb->i2c_client_demod[1]->dev.driver->owner); | ||
1279 | i2c_unregister_device(dvb->i2c_client_demod[1]); | ||
1280 | module_put(dvb->i2c_client_demod[0]->dev.driver->owner); | ||
1281 | i2c_unregister_device(dvb->i2c_client_demod[0]); | ||
1282 | result = -ENODEV; | ||
1283 | goto out_free; | ||
1284 | } | ||
1285 | |||
1286 | dev->cx231xx_reset_analog_tuner = NULL; | ||
1287 | dvb->i2c_client_tuner = client; | ||
1288 | |||
1289 | dvb->frontend[1]->tuner_priv = dvb->frontend[0]->tuner_priv; | ||
1290 | |||
1291 | memcpy(&dvb->frontend[1]->ops.tuner_ops, | ||
1292 | &dvb->frontend[0]->ops.tuner_ops, | ||
1293 | sizeof(struct dvb_tuner_ops)); | ||
1294 | break; | ||
1295 | } | ||
1071 | default: | 1296 | default: |
1072 | dev_err(dev->dev, | 1297 | dev_err(dev->dev, |
1073 | "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", | 1298 | "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", |
1074 | dev->name); | 1299 | dev->name); |
1075 | break; | 1300 | break; |
1076 | } | 1301 | } |
1077 | if (NULL == dvb->frontend) { | 1302 | if (!dvb->frontend[0]) { |
1078 | dev_err(dev->dev, | 1303 | dev_err(dev->dev, |
1079 | "%s/2: frontend initialization failed\n", dev->name); | 1304 | "%s/2: frontend initialization failed\n", dev->name); |
1080 | result = -EINVAL; | 1305 | result = -EINVAL; |
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 5b321b8ada3a..f7fcd733a2ca 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c | |||
@@ -1941,7 +1941,7 @@ static int cx231xx_close(struct file *filp) | |||
1941 | } | 1941 | } |
1942 | 1942 | ||
1943 | /* Save some power by putting tuner to sleep */ | 1943 | /* Save some power by putting tuner to sleep */ |
1944 | call_all(dev, core, s_power, 0); | 1944 | call_all(dev, tuner, standby); |
1945 | 1945 | ||
1946 | /* do this before setting alternate! */ | 1946 | /* do this before setting alternate! */ |
1947 | if (dev->USE_ISO) | 1947 | if (dev->USE_ISO) |
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 65b039cf80be..6ffa4bd96484 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h | |||
@@ -81,6 +81,8 @@ | |||
81 | #define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23 | 81 | #define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23 |
82 | #define CX231XX_BOARD_ASTROMETA_T2HYBRID 24 | 82 | #define CX231XX_BOARD_ASTROMETA_T2HYBRID 24 |
83 | #define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25 | 83 | #define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25 |
84 | #define CX231XX_BOARD_HAUPPAUGE_935C 26 | ||
85 | #define CX231XX_BOARD_HAUPPAUGE_975 27 | ||
84 | 86 | ||
85 | /* Limits minimum and default number of buffers */ | 87 | /* Limits minimum and default number of buffers */ |
86 | #define CX231XX_MIN_BUF 4 | 88 | #define CX231XX_MIN_BUF 4 |
@@ -343,6 +345,7 @@ struct cx231xx_board { | |||
343 | 345 | ||
344 | /* demod related */ | 346 | /* demod related */ |
345 | int demod_addr; | 347 | int demod_addr; |
348 | int demod_addr2; | ||
346 | u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */ | 349 | u8 demod_xfer_mode; /* 0 - Serial; 1 - parallel */ |
347 | 350 | ||
348 | /* GPIO Pins */ | 351 | /* GPIO Pins */ |
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 0e4944b2b0f4..37053477b84d 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig | |||
@@ -15,7 +15,8 @@ config DVB_USB_V2 | |||
15 | 15 | ||
16 | config DVB_USB_AF9015 | 16 | config DVB_USB_AF9015 |
17 | tristate "Afatech AF9015 DVB-T USB2.0 support" | 17 | tristate "Afatech AF9015 DVB-T USB2.0 support" |
18 | depends on DVB_USB_V2 | 18 | depends on DVB_USB_V2 && I2C_MUX |
19 | select REGMAP | ||
19 | select DVB_AF9013 | 20 | select DVB_AF9013 |
20 | select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT | 21 | select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT |
21 | select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT | 22 | select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT |
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 8013659c41b1..39f9ffce3caa 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c | |||
@@ -29,6 +29,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) | |||
29 | #define REQ_HDR_LEN 8 /* send header size */ | 29 | #define REQ_HDR_LEN 8 /* send header size */ |
30 | #define ACK_HDR_LEN 2 /* rece header size */ | 30 | #define ACK_HDR_LEN 2 /* rece header size */ |
31 | struct af9015_state *state = d_to_priv(d); | 31 | struct af9015_state *state = d_to_priv(d); |
32 | struct usb_interface *intf = d->intf; | ||
32 | int ret, wlen, rlen; | 33 | int ret, wlen, rlen; |
33 | u8 write = 1; | 34 | u8 write = 1; |
34 | 35 | ||
@@ -66,23 +67,24 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) | |||
66 | case BOOT: | 67 | case BOOT: |
67 | break; | 68 | break; |
68 | default: | 69 | default: |
69 | dev_err(&d->udev->dev, "%s: unknown command=%d\n", | 70 | dev_err(&intf->dev, "unknown cmd %d\n", req->cmd); |
70 | KBUILD_MODNAME, req->cmd); | ||
71 | ret = -EIO; | 71 | ret = -EIO; |
72 | goto error; | 72 | goto error; |
73 | } | 73 | } |
74 | 74 | ||
75 | /* buffer overflow check */ | 75 | /* Buffer overflow check */ |
76 | if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) || | 76 | if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) || |
77 | (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { | 77 | (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { |
78 | dev_err(&d->udev->dev, "%s: too much data; cmd=%d len=%d\n", | 78 | dev_err(&intf->dev, "too much data, cmd %u, len %u\n", |
79 | KBUILD_MODNAME, req->cmd, req->data_len); | 79 | req->cmd, req->data_len); |
80 | ret = -EINVAL; | 80 | ret = -EINVAL; |
81 | goto error; | 81 | goto error; |
82 | } | 82 | } |
83 | 83 | ||
84 | /* write receives seq + status = 2 bytes | 84 | /* |
85 | read receives seq + status + data = 2 + N bytes */ | 85 | * Write receives seq + status = 2 bytes |
86 | * Read receives seq + status + data = 2 + N bytes | ||
87 | */ | ||
86 | wlen = REQ_HDR_LEN; | 88 | wlen = REQ_HDR_LEN; |
87 | rlen = ACK_HDR_LEN; | 89 | rlen = ACK_HDR_LEN; |
88 | if (write) { | 90 | if (write) { |
@@ -96,15 +98,14 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) | |||
96 | if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) | 98 | if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) |
97 | rlen = 0; | 99 | rlen = 0; |
98 | 100 | ||
99 | ret = dvb_usbv2_generic_rw_locked(d, | 101 | ret = dvb_usbv2_generic_rw_locked(d, state->buf, wlen, |
100 | state->buf, wlen, state->buf, rlen); | 102 | state->buf, rlen); |
101 | if (ret) | 103 | if (ret) |
102 | goto error; | 104 | goto error; |
103 | 105 | ||
104 | /* check status */ | 106 | /* check status */ |
105 | if (rlen && state->buf[1]) { | 107 | if (rlen && state->buf[1]) { |
106 | dev_err(&d->udev->dev, "%s: command failed=%d\n", | 108 | dev_err(&intf->dev, "cmd failed %u\n", state->buf[1]); |
107 | KBUILD_MODNAME, state->buf[1]); | ||
108 | ret = -EIO; | 109 | ret = -EIO; |
109 | goto error; | 110 | goto error; |
110 | } | 111 | } |
@@ -118,121 +119,66 @@ error: | |||
118 | return ret; | 119 | return ret; |
119 | } | 120 | } |
120 | 121 | ||
121 | static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, | ||
122 | u8 len) | ||
123 | { | ||
124 | struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, | ||
125 | val}; | ||
126 | return af9015_ctrl_msg(d, &req); | ||
127 | } | ||
128 | |||
129 | static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) | ||
130 | { | ||
131 | struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, | ||
132 | val}; | ||
133 | return af9015_ctrl_msg(d, &req); | ||
134 | } | ||
135 | |||
136 | static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) | ||
137 | { | ||
138 | return af9015_write_regs(d, addr, &val, 1); | ||
139 | } | ||
140 | |||
141 | static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) | ||
142 | { | ||
143 | return af9015_read_regs(d, addr, val, 1); | ||
144 | } | ||
145 | |||
146 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, | 122 | static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, |
147 | u8 val) | 123 | u8 val) |
148 | { | 124 | { |
149 | struct af9015_state *state = d_to_priv(d); | 125 | struct af9015_state *state = d_to_priv(d); |
150 | struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; | 126 | struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; |
151 | 127 | ||
152 | if (addr == state->af9013_config[0].i2c_addr || | 128 | if (addr == state->af9013_i2c_addr[0] || |
153 | addr == state->af9013_config[1].i2c_addr) | 129 | addr == state->af9013_i2c_addr[1]) |
154 | req.addr_len = 3; | 130 | req.addr_len = 3; |
155 | 131 | ||
156 | return af9015_ctrl_msg(d, &req); | 132 | return af9015_ctrl_msg(d, &req); |
157 | } | 133 | } |
158 | 134 | ||
159 | static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, | 135 | static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, |
160 | u8 *val) | 136 | u8 *val) |
161 | { | 137 | { |
162 | struct af9015_state *state = d_to_priv(d); | 138 | struct af9015_state *state = d_to_priv(d); |
163 | struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; | 139 | struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; |
164 | 140 | ||
165 | if (addr == state->af9013_config[0].i2c_addr || | 141 | if (addr == state->af9013_i2c_addr[0] || |
166 | addr == state->af9013_config[1].i2c_addr) | 142 | addr == state->af9013_i2c_addr[1]) |
167 | req.addr_len = 3; | 143 | req.addr_len = 3; |
168 | 144 | ||
169 | return af9015_ctrl_msg(d, &req); | 145 | return af9015_ctrl_msg(d, &req); |
170 | } | 146 | } |
171 | 147 | ||
172 | static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op) | ||
173 | { | ||
174 | int ret; | ||
175 | u8 val, mask = 0x01; | ||
176 | |||
177 | ret = af9015_read_reg(d, addr, &val); | ||
178 | if (ret) | ||
179 | return ret; | ||
180 | |||
181 | mask <<= bit; | ||
182 | if (op) { | ||
183 | /* set bit */ | ||
184 | val |= mask; | ||
185 | } else { | ||
186 | /* clear bit */ | ||
187 | mask ^= 0xff; | ||
188 | val &= mask; | ||
189 | } | ||
190 | |||
191 | return af9015_write_reg(d, addr, val); | ||
192 | } | ||
193 | |||
194 | static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) | ||
195 | { | ||
196 | return af9015_do_reg_bit(d, addr, bit, 1); | ||
197 | } | ||
198 | |||
199 | static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) | ||
200 | { | ||
201 | return af9015_do_reg_bit(d, addr, bit, 0); | ||
202 | } | ||
203 | |||
204 | static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | 148 | static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], |
205 | int num) | 149 | int num) |
206 | { | 150 | { |
207 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 151 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
208 | struct af9015_state *state = d_to_priv(d); | 152 | struct af9015_state *state = d_to_priv(d); |
153 | struct usb_interface *intf = d->intf; | ||
209 | int ret; | 154 | int ret; |
210 | u16 addr; | 155 | u16 addr; |
211 | u8 mbox, addr_len; | 156 | u8 mbox, addr_len; |
212 | struct req_t req; | 157 | struct req_t req; |
213 | 158 | ||
214 | /* | 159 | /* |
215 | The bus lock is needed because there is two tuners both using same I2C-address. | 160 | * I2C multiplexing: |
216 | Due to that the only way to select correct tuner is use demodulator I2C-gate. | 161 | * There could be two tuners, both using same I2C address. Demodulator |
217 | 162 | * I2C-gate is only possibility to select correct tuner. | |
218 | ................................................ | 163 | * |
219 | . AF9015 includes integrated AF9013 demodulator. | 164 | * ........................................... |
220 | . ____________ ____________ . ____________ | 165 | * . AF9015 integrates AF9013 demodulator . |
221 | .| uC | | demod | . | tuner | | 166 | * . ____________ ____________ . ____________ |
222 | .|------------| |------------| . |------------| | 167 | * .| USB IF | | demod |. | tuner | |
223 | .| AF9015 | | AF9013/5 | . | MXL5003 | | 168 | * .|------------| |------------|. |------------| |
224 | .| |--+----I2C-------|-----/ -----|-.-----I2C-------| | | 169 | * .| AF9015 | | AF9013 |. | MXL5003 | |
225 | .| | | | addr 0x38 | . | addr 0xc6 | | 170 | * .| |--+--I2C-----|-----/ -----|.----I2C-----| | |
226 | .|____________| | |____________| . |____________| | 171 | * .| | | | addr 0x1c |. | addr 0x63 | |
227 | .................|.............................. | 172 | * .|____________| | |____________|. |____________| |
228 | | ____________ ____________ | 173 | * .................|......................... |
229 | | | demod | | tuner | | 174 | * | ____________ ____________ |
230 | | |------------| |------------| | 175 | * | | demod | | tuner | |
231 | | | AF9013 | | MXL5003 | | 176 | * | |------------| |------------| |
232 | +----I2C-------|-----/ -----|-------I2C-------| | | 177 | * | | AF9013 | | MXL5003 | |
233 | | addr 0x3a | | addr 0xc6 | | 178 | * +--I2C-----|-----/ -----|-----I2C-----| | |
234 | |____________| |____________| | 179 | * | addr 0x1d | | addr 0x63 | |
235 | */ | 180 | * |____________| |____________| |
181 | */ | ||
236 | 182 | ||
237 | if (msg[0].len == 0 || msg[0].flags & I2C_M_RD) { | 183 | if (msg[0].len == 0 || msg[0].flags & I2C_M_RD) { |
238 | addr = 0x0000; | 184 | addr = 0x0000; |
@@ -243,11 +189,11 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
243 | mbox = 0; | 189 | mbox = 0; |
244 | addr_len = 1; | 190 | addr_len = 1; |
245 | } else if (msg[0].len == 2) { | 191 | } else if (msg[0].len == 2) { |
246 | addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0; | 192 | addr = msg[0].buf[0] << 8 | msg[0].buf[1] << 0; |
247 | mbox = 0; | 193 | mbox = 0; |
248 | addr_len = 2; | 194 | addr_len = 2; |
249 | } else { | 195 | } else { |
250 | addr = msg[0].buf[0] << 8|msg[0].buf[1] << 0; | 196 | addr = msg[0].buf[0] << 8 | msg[0].buf[1] << 0; |
251 | mbox = msg[0].buf[2]; | 197 | mbox = msg[0].buf[2]; |
252 | addr_len = 3; | 198 | addr_len = 3; |
253 | } | 199 | } |
@@ -258,7 +204,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
258 | ret = -EOPNOTSUPP; | 204 | ret = -EOPNOTSUPP; |
259 | goto err; | 205 | goto err; |
260 | } | 206 | } |
261 | if (msg[0].addr == state->af9013_config[0].i2c_addr) | 207 | if (msg[0].addr == state->af9013_i2c_addr[0]) |
262 | req.cmd = WRITE_MEMORY; | 208 | req.cmd = WRITE_MEMORY; |
263 | else | 209 | else |
264 | req.cmd = WRITE_I2C; | 210 | req.cmd = WRITE_I2C; |
@@ -266,7 +212,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
266 | req.addr = addr; | 212 | req.addr = addr; |
267 | req.mbox = mbox; | 213 | req.mbox = mbox; |
268 | req.addr_len = addr_len; | 214 | req.addr_len = addr_len; |
269 | req.data_len = msg[0].len-addr_len; | 215 | req.data_len = msg[0].len - addr_len; |
270 | req.data = &msg[0].buf[addr_len]; | 216 | req.data = &msg[0].buf[addr_len]; |
271 | ret = af9015_ctrl_msg(d, &req); | 217 | ret = af9015_ctrl_msg(d, &req); |
272 | } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && | 218 | } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && |
@@ -276,7 +222,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
276 | ret = -EOPNOTSUPP; | 222 | ret = -EOPNOTSUPP; |
277 | goto err; | 223 | goto err; |
278 | } | 224 | } |
279 | if (msg[0].addr == state->af9013_config[0].i2c_addr) | 225 | if (msg[0].addr == state->af9013_i2c_addr[0]) |
280 | req.cmd = READ_MEMORY; | 226 | req.cmd = READ_MEMORY; |
281 | else | 227 | else |
282 | req.cmd = READ_I2C; | 228 | req.cmd = READ_I2C; |
@@ -293,7 +239,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
293 | ret = -EOPNOTSUPP; | 239 | ret = -EOPNOTSUPP; |
294 | goto err; | 240 | goto err; |
295 | } | 241 | } |
296 | if (msg[0].addr == state->af9013_config[0].i2c_addr) { | 242 | if (msg[0].addr == state->af9013_i2c_addr[0]) { |
297 | ret = -EINVAL; | 243 | ret = -EINVAL; |
298 | goto err; | 244 | goto err; |
299 | } | 245 | } |
@@ -307,15 +253,14 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. | |||
307 | ret = af9015_ctrl_msg(d, &req); | 253 | ret = af9015_ctrl_msg(d, &req); |
308 | } else { | 254 | } else { |
309 | ret = -EOPNOTSUPP; | 255 | ret = -EOPNOTSUPP; |
310 | dev_dbg(&d->udev->dev, "%s: unknown msg, num %u\n", | 256 | dev_dbg(&intf->dev, "unknown msg, num %u\n", num); |
311 | __func__, num); | ||
312 | } | 257 | } |
313 | if (ret) | 258 | if (ret) |
314 | goto err; | 259 | goto err; |
315 | 260 | ||
316 | return num; | 261 | return num; |
317 | err: | 262 | err: |
318 | dev_dbg(&d->udev->dev, "%s: failed %d\n", __func__, ret); | 263 | dev_dbg(&intf->dev, "failed %d\n", ret); |
319 | return ret; | 264 | return ret; |
320 | } | 265 | } |
321 | 266 | ||
@@ -331,6 +276,7 @@ static struct i2c_algorithm af9015_i2c_algo = { | |||
331 | 276 | ||
332 | static int af9015_identify_state(struct dvb_usb_device *d, const char **name) | 277 | static int af9015_identify_state(struct dvb_usb_device *d, const char **name) |
333 | { | 278 | { |
279 | struct usb_interface *intf = d->intf; | ||
334 | int ret; | 280 | int ret; |
335 | u8 reply; | 281 | u8 reply; |
336 | struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; | 282 | struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; |
@@ -339,7 +285,7 @@ static int af9015_identify_state(struct dvb_usb_device *d, const char **name) | |||
339 | if (ret) | 285 | if (ret) |
340 | return ret; | 286 | return ret; |
341 | 287 | ||
342 | dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply); | 288 | dev_dbg(&intf->dev, "reply %02x\n", reply); |
343 | 289 | ||
344 | if (reply == 0x02) | 290 | if (reply == 0x02) |
345 | ret = WARM; | 291 | ret = WARM; |
@@ -350,52 +296,47 @@ static int af9015_identify_state(struct dvb_usb_device *d, const char **name) | |||
350 | } | 296 | } |
351 | 297 | ||
352 | static int af9015_download_firmware(struct dvb_usb_device *d, | 298 | static int af9015_download_firmware(struct dvb_usb_device *d, |
353 | const struct firmware *fw) | 299 | const struct firmware *firmware) |
354 | { | 300 | { |
355 | struct af9015_state *state = d_to_priv(d); | 301 | struct af9015_state *state = d_to_priv(d); |
356 | int i, len, remaining, ret; | 302 | struct usb_interface *intf = d->intf; |
303 | int ret, i, rem; | ||
357 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; | 304 | struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; |
358 | u16 checksum = 0; | 305 | u16 checksum; |
359 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
360 | 306 | ||
361 | /* calc checksum */ | 307 | dev_dbg(&intf->dev, "\n"); |
362 | for (i = 0; i < fw->size; i++) | ||
363 | checksum += fw->data[i]; | ||
364 | 308 | ||
365 | state->firmware_size = fw->size; | 309 | /* Calc checksum, we need it when copy firmware to slave demod */ |
366 | state->firmware_checksum = checksum; | 310 | for (i = 0, checksum = 0; i < firmware->size; i++) |
311 | checksum += firmware->data[i]; | ||
367 | 312 | ||
368 | #define FW_ADDR 0x5100 /* firmware start address */ | 313 | state->firmware_size = firmware->size; |
369 | #define LEN_MAX 55 /* max packet size */ | 314 | state->firmware_checksum = checksum; |
370 | for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { | ||
371 | len = remaining; | ||
372 | if (len > LEN_MAX) | ||
373 | len = LEN_MAX; | ||
374 | |||
375 | req.data_len = len; | ||
376 | req.data = (u8 *) &fw->data[fw->size - remaining]; | ||
377 | req.addr = FW_ADDR + fw->size - remaining; | ||
378 | 315 | ||
316 | #define LEN_MAX (BUF_LEN - REQ_HDR_LEN) /* Max payload size */ | ||
317 | for (rem = firmware->size; rem > 0; rem -= LEN_MAX) { | ||
318 | req.data_len = min(LEN_MAX, rem); | ||
319 | req.data = (u8 *)&firmware->data[firmware->size - rem]; | ||
320 | req.addr = 0x5100 + firmware->size - rem; | ||
379 | ret = af9015_ctrl_msg(d, &req); | 321 | ret = af9015_ctrl_msg(d, &req); |
380 | if (ret) { | 322 | if (ret) { |
381 | dev_err(&d->udev->dev, | 323 | dev_err(&intf->dev, "firmware download failed %d\n", |
382 | "%s: firmware download failed=%d\n", | 324 | ret); |
383 | KBUILD_MODNAME, ret); | 325 | goto err; |
384 | goto error; | ||
385 | } | 326 | } |
386 | } | 327 | } |
387 | 328 | ||
388 | /* firmware loaded, request boot */ | ||
389 | req.cmd = BOOT; | 329 | req.cmd = BOOT; |
390 | req.data_len = 0; | 330 | req.data_len = 0; |
391 | ret = af9015_ctrl_msg(d, &req); | 331 | ret = af9015_ctrl_msg(d, &req); |
392 | if (ret) { | 332 | if (ret) { |
393 | dev_err(&d->udev->dev, "%s: firmware boot failed=%d\n", | 333 | dev_err(&intf->dev, "firmware boot failed %d\n", ret); |
394 | KBUILD_MODNAME, ret); | 334 | goto err; |
395 | goto error; | ||
396 | } | 335 | } |
397 | 336 | ||
398 | error: | 337 | return 0; |
338 | err: | ||
339 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
399 | return ret; | 340 | return ret; |
400 | } | 341 | } |
401 | 342 | ||
@@ -407,6 +348,7 @@ error: | |||
407 | static int af9015_eeprom_hash(struct dvb_usb_device *d) | 348 | static int af9015_eeprom_hash(struct dvb_usb_device *d) |
408 | { | 349 | { |
409 | struct af9015_state *state = d_to_priv(d); | 350 | struct af9015_state *state = d_to_priv(d); |
351 | struct usb_interface *intf = d->intf; | ||
410 | int ret, i; | 352 | int ret, i; |
411 | u8 buf[AF9015_EEPROM_SIZE]; | 353 | u8 buf[AF9015_EEPROM_SIZE]; |
412 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, NULL}; | 354 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, NULL}; |
@@ -427,24 +369,24 @@ static int af9015_eeprom_hash(struct dvb_usb_device *d) | |||
427 | } | 369 | } |
428 | 370 | ||
429 | for (i = 0; i < AF9015_EEPROM_SIZE; i += 16) | 371 | for (i = 0; i < AF9015_EEPROM_SIZE; i += 16) |
430 | dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 16, buf + i); | 372 | dev_dbg(&intf->dev, "%*ph\n", 16, buf + i); |
431 | 373 | ||
432 | dev_dbg(&d->udev->dev, "%s: eeprom sum=%.8x\n", | 374 | dev_dbg(&intf->dev, "eeprom sum %.8x\n", state->eeprom_sum); |
433 | __func__, state->eeprom_sum); | ||
434 | return 0; | 375 | return 0; |
435 | err: | 376 | err: |
436 | dev_err(&d->udev->dev, "%s: eeprom failed=%d\n", KBUILD_MODNAME, ret); | 377 | dev_dbg(&intf->dev, "failed %d\n", ret); |
437 | return ret; | 378 | return ret; |
438 | } | 379 | } |
439 | 380 | ||
440 | static int af9015_read_config(struct dvb_usb_device *d) | 381 | static int af9015_read_config(struct dvb_usb_device *d) |
441 | { | 382 | { |
442 | struct af9015_state *state = d_to_priv(d); | 383 | struct af9015_state *state = d_to_priv(d); |
384 | struct usb_interface *intf = d->intf; | ||
443 | int ret; | 385 | int ret; |
444 | u8 val, i, offset = 0; | 386 | u8 val, i, offset = 0; |
445 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; | 387 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; |
446 | 388 | ||
447 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | 389 | dev_dbg(&intf->dev, "\n"); |
448 | 390 | ||
449 | /* IR remote controller */ | 391 | /* IR remote controller */ |
450 | req.addr = AF9015_EEPROM_IR_MODE; | 392 | req.addr = AF9015_EEPROM_IR_MODE; |
@@ -462,7 +404,7 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
462 | goto error; | 404 | goto error; |
463 | 405 | ||
464 | state->ir_mode = val; | 406 | state->ir_mode = val; |
465 | dev_dbg(&d->udev->dev, "%s: IR mode=%d\n", __func__, val); | 407 | dev_dbg(&intf->dev, "ir mode %02x\n", val); |
466 | 408 | ||
467 | /* TS mode - one or two receivers */ | 409 | /* TS mode - one or two receivers */ |
468 | req.addr = AF9015_EEPROM_TS_MODE; | 410 | req.addr = AF9015_EEPROM_TS_MODE; |
@@ -471,13 +413,9 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
471 | goto error; | 413 | goto error; |
472 | 414 | ||
473 | state->dual_mode = val; | 415 | state->dual_mode = val; |
474 | dev_dbg(&d->udev->dev, "%s: TS mode=%d\n", __func__, state->dual_mode); | 416 | dev_dbg(&intf->dev, "ts mode %02x\n", state->dual_mode); |
475 | 417 | ||
476 | /* disable 2nd adapter because we don't have PID-filters */ | 418 | state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD; |
477 | if (d->udev->speed == USB_SPEED_FULL) | ||
478 | state->dual_mode = 0; | ||
479 | |||
480 | state->af9013_config[0].i2c_addr = AF9015_I2C_DEMOD; | ||
481 | 419 | ||
482 | if (state->dual_mode) { | 420 | if (state->dual_mode) { |
483 | /* read 2nd demodulator I2C address */ | 421 | /* read 2nd demodulator I2C address */ |
@@ -486,7 +424,7 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
486 | if (ret) | 424 | if (ret) |
487 | goto error; | 425 | goto error; |
488 | 426 | ||
489 | state->af9013_config[1].i2c_addr = val >> 1; | 427 | state->af9013_i2c_addr[1] = val >> 1; |
490 | } | 428 | } |
491 | 429 | ||
492 | for (i = 0; i < state->dual_mode + 1; i++) { | 430 | for (i = 0; i < state->dual_mode + 1; i++) { |
@@ -499,21 +437,20 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
499 | goto error; | 437 | goto error; |
500 | switch (val) { | 438 | switch (val) { |
501 | case 0: | 439 | case 0: |
502 | state->af9013_config[i].clock = 28800000; | 440 | state->af9013_pdata[i].clk = 28800000; |
503 | break; | 441 | break; |
504 | case 1: | 442 | case 1: |
505 | state->af9013_config[i].clock = 20480000; | 443 | state->af9013_pdata[i].clk = 20480000; |
506 | break; | 444 | break; |
507 | case 2: | 445 | case 2: |
508 | state->af9013_config[i].clock = 28000000; | 446 | state->af9013_pdata[i].clk = 28000000; |
509 | break; | 447 | break; |
510 | case 3: | 448 | case 3: |
511 | state->af9013_config[i].clock = 25000000; | 449 | state->af9013_pdata[i].clk = 25000000; |
512 | break; | 450 | break; |
513 | } | 451 | } |
514 | dev_dbg(&d->udev->dev, "%s: [%d] xtal=%d set clock=%d\n", | 452 | dev_dbg(&intf->dev, "[%d] xtal %02x, clk %u\n", |
515 | __func__, i, val, | 453 | i, val, state->af9013_pdata[i].clk); |
516 | state->af9013_config[i].clock); | ||
517 | 454 | ||
518 | /* IF frequency */ | 455 | /* IF frequency */ |
519 | req.addr = AF9015_EEPROM_IF1H + offset; | 456 | req.addr = AF9015_EEPROM_IF1H + offset; |
@@ -521,17 +458,17 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
521 | if (ret) | 458 | if (ret) |
522 | goto error; | 459 | goto error; |
523 | 460 | ||
524 | state->af9013_config[i].if_frequency = val << 8; | 461 | state->af9013_pdata[i].if_frequency = val << 8; |
525 | 462 | ||
526 | req.addr = AF9015_EEPROM_IF1L + offset; | 463 | req.addr = AF9015_EEPROM_IF1L + offset; |
527 | ret = af9015_ctrl_msg(d, &req); | 464 | ret = af9015_ctrl_msg(d, &req); |
528 | if (ret) | 465 | if (ret) |
529 | goto error; | 466 | goto error; |
530 | 467 | ||
531 | state->af9013_config[i].if_frequency += val; | 468 | state->af9013_pdata[i].if_frequency += val; |
532 | state->af9013_config[i].if_frequency *= 1000; | 469 | state->af9013_pdata[i].if_frequency *= 1000; |
533 | dev_dbg(&d->udev->dev, "%s: [%d] IF frequency=%d\n", __func__, | 470 | dev_dbg(&intf->dev, "[%d] if frequency %u\n", |
534 | i, state->af9013_config[i].if_frequency); | 471 | i, state->af9013_pdata[i].if_frequency); |
535 | 472 | ||
536 | /* MT2060 IF1 */ | 473 | /* MT2060 IF1 */ |
537 | req.addr = AF9015_EEPROM_MT2060_IF1H + offset; | 474 | req.addr = AF9015_EEPROM_MT2060_IF1H + offset; |
@@ -544,8 +481,8 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
544 | if (ret) | 481 | if (ret) |
545 | goto error; | 482 | goto error; |
546 | state->mt2060_if1[i] += val; | 483 | state->mt2060_if1[i] += val; |
547 | dev_dbg(&d->udev->dev, "%s: [%d] MT2060 IF1=%d\n", __func__, i, | 484 | dev_dbg(&intf->dev, "[%d] MT2060 IF1 %u\n", |
548 | state->mt2060_if1[i]); | 485 | i, state->mt2060_if1[i]); |
549 | 486 | ||
550 | /* tuner */ | 487 | /* tuner */ |
551 | req.addr = AF9015_EEPROM_TUNER_ID1 + offset; | 488 | req.addr = AF9015_EEPROM_TUNER_ID1 + offset; |
@@ -561,71 +498,177 @@ static int af9015_read_config(struct dvb_usb_device *d) | |||
561 | case AF9013_TUNER_TDA18271: | 498 | case AF9013_TUNER_TDA18271: |
562 | case AF9013_TUNER_QT1010A: | 499 | case AF9013_TUNER_QT1010A: |
563 | case AF9013_TUNER_TDA18218: | 500 | case AF9013_TUNER_TDA18218: |
564 | state->af9013_config[i].spec_inv = 1; | 501 | state->af9013_pdata[i].spec_inv = 1; |
565 | break; | 502 | break; |
566 | case AF9013_TUNER_MXL5003D: | 503 | case AF9013_TUNER_MXL5003D: |
567 | case AF9013_TUNER_MXL5005D: | 504 | case AF9013_TUNER_MXL5005D: |
568 | case AF9013_TUNER_MXL5005R: | 505 | case AF9013_TUNER_MXL5005R: |
569 | case AF9013_TUNER_MXL5007T: | 506 | case AF9013_TUNER_MXL5007T: |
570 | state->af9013_config[i].spec_inv = 0; | 507 | state->af9013_pdata[i].spec_inv = 0; |
571 | break; | 508 | break; |
572 | case AF9013_TUNER_MC44S803: | 509 | case AF9013_TUNER_MC44S803: |
573 | state->af9013_config[i].gpio[1] = AF9013_GPIO_LO; | 510 | state->af9013_pdata[i].gpio[1] = AF9013_GPIO_LO; |
574 | state->af9013_config[i].spec_inv = 1; | 511 | state->af9013_pdata[i].spec_inv = 1; |
575 | break; | 512 | break; |
576 | default: | 513 | default: |
577 | dev_err(&d->udev->dev, "%s: tuner id=%d not " \ | 514 | dev_err(&intf->dev, |
578 | "supported, please report!\n", | 515 | "tuner id %02x not supported, please report!\n", |
579 | KBUILD_MODNAME, val); | 516 | val); |
580 | return -ENODEV; | 517 | return -ENODEV; |
581 | } | 518 | } |
582 | 519 | ||
583 | state->af9013_config[i].tuner = val; | 520 | state->af9013_pdata[i].tuner = val; |
584 | dev_dbg(&d->udev->dev, "%s: [%d] tuner id=%d\n", | 521 | dev_dbg(&intf->dev, "[%d] tuner id %02x\n", i, val); |
585 | __func__, i, val); | ||
586 | } | 522 | } |
587 | 523 | ||
588 | error: | 524 | error: |
589 | if (ret) | 525 | if (ret) |
590 | dev_err(&d->udev->dev, "%s: eeprom read failed=%d\n", | 526 | dev_err(&intf->dev, "eeprom read failed %d\n", ret); |
591 | KBUILD_MODNAME, ret); | ||
592 | 527 | ||
593 | /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM | 528 | /* |
594 | content :-( Override some wrong values here. Ditto for the | 529 | * AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM |
595 | AVerTV Red HD+ (A850T) device. */ | 530 | * content :-( Override some wrong values here. Ditto for the |
531 | * AVerTV Red HD+ (A850T) device. | ||
532 | */ | ||
596 | if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && | 533 | if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA && |
597 | ((le16_to_cpu(d->udev->descriptor.idProduct) == | 534 | ((le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850) || |
598 | USB_PID_AVERMEDIA_A850) || | 535 | (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_A850T))) { |
599 | (le16_to_cpu(d->udev->descriptor.idProduct) == | 536 | dev_dbg(&intf->dev, "AverMedia A850: overriding config\n"); |
600 | USB_PID_AVERMEDIA_A850T))) { | ||
601 | dev_dbg(&d->udev->dev, | ||
602 | "%s: AverMedia A850: overriding config\n", | ||
603 | __func__); | ||
604 | /* disable dual mode */ | 537 | /* disable dual mode */ |
605 | state->dual_mode = 0; | 538 | state->dual_mode = 0; |
606 | 539 | ||
607 | /* set correct IF */ | 540 | /* set correct IF */ |
608 | state->af9013_config[0].if_frequency = 4570000; | 541 | state->af9013_pdata[0].if_frequency = 4570000; |
609 | } | 542 | } |
610 | 543 | ||
611 | return ret; | 544 | return ret; |
612 | } | 545 | } |
613 | 546 | ||
614 | static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, | 547 | static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, |
615 | struct usb_data_stream_properties *stream) | 548 | struct usb_data_stream_properties *stream) |
616 | { | 549 | { |
617 | struct dvb_usb_device *d = fe_to_d(fe); | 550 | struct dvb_usb_device *d = fe_to_d(fe); |
618 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, fe_to_adap(fe)->id); | 551 | struct usb_interface *intf = d->intf; |
552 | |||
553 | dev_dbg(&intf->dev, "adap %u\n", fe_to_adap(fe)->id); | ||
619 | 554 | ||
620 | if (d->udev->speed == USB_SPEED_FULL) | 555 | if (d->udev->speed == USB_SPEED_FULL) |
621 | stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE; | 556 | stream->u.bulk.buffersize = 5 * 188; |
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int af9015_streaming_ctrl(struct dvb_frontend *fe, int onoff) | ||
562 | { | ||
563 | struct dvb_usb_device *d = fe_to_d(fe); | ||
564 | struct af9015_state *state = d_to_priv(d); | ||
565 | struct usb_interface *intf = d->intf; | ||
566 | int ret; | ||
567 | unsigned int utmp1, utmp2, reg1, reg2; | ||
568 | u8 buf[2]; | ||
569 | const unsigned int adap_id = fe_to_adap(fe)->id; | ||
570 | |||
571 | dev_dbg(&intf->dev, "adap id %d, onoff %d\n", adap_id, onoff); | ||
572 | |||
573 | if (!state->usb_ts_if_configured[adap_id]) { | ||
574 | dev_dbg(&intf->dev, "set usb and ts interface\n"); | ||
575 | |||
576 | /* USB IF stream settings */ | ||
577 | utmp1 = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4; | ||
578 | utmp2 = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4; | ||
579 | |||
580 | buf[0] = (utmp1 >> 0) & 0xff; | ||
581 | buf[1] = (utmp1 >> 8) & 0xff; | ||
582 | if (adap_id == 0) { | ||
583 | /* 1st USB IF (EP4) stream settings */ | ||
584 | reg1 = 0xdd88; | ||
585 | reg2 = 0xdd0c; | ||
586 | } else { | ||
587 | /* 2nd USB IF (EP5) stream settings */ | ||
588 | reg1 = 0xdd8a; | ||
589 | reg2 = 0xdd0d; | ||
590 | } | ||
591 | ret = regmap_bulk_write(state->regmap, reg1, buf, 2); | ||
592 | if (ret) | ||
593 | goto err; | ||
594 | ret = regmap_write(state->regmap, reg2, utmp2); | ||
595 | if (ret) | ||
596 | goto err; | ||
597 | |||
598 | /* TS IF settings */ | ||
599 | if (state->dual_mode) { | ||
600 | utmp1 = 0x01; | ||
601 | utmp2 = 0x10; | ||
602 | } else { | ||
603 | utmp1 = 0x00; | ||
604 | utmp2 = 0x00; | ||
605 | } | ||
606 | ret = regmap_update_bits(state->regmap, 0xd50b, 0x01, utmp1); | ||
607 | if (ret) | ||
608 | goto err; | ||
609 | ret = regmap_update_bits(state->regmap, 0xd520, 0x10, utmp2); | ||
610 | if (ret) | ||
611 | goto err; | ||
612 | |||
613 | state->usb_ts_if_configured[adap_id] = true; | ||
614 | } | ||
615 | |||
616 | if (adap_id == 0 && onoff) { | ||
617 | /* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */ | ||
618 | ret = regmap_update_bits(state->regmap, 0xdd13, 0x20, 0x00); | ||
619 | if (ret) | ||
620 | goto err; | ||
621 | ret = regmap_update_bits(state->regmap, 0xdd11, 0x20, 0x20); | ||
622 | if (ret) | ||
623 | goto err; | ||
624 | ret = regmap_update_bits(state->regmap, 0xd507, 0x04, 0x00); | ||
625 | if (ret) | ||
626 | goto err; | ||
627 | } else if (adap_id == 1 && onoff) { | ||
628 | /* Adapter 1 stream on. EP5: clear NAK, enable, clear reset */ | ||
629 | ret = regmap_update_bits(state->regmap, 0xdd13, 0x40, 0x00); | ||
630 | if (ret) | ||
631 | goto err; | ||
632 | ret = regmap_update_bits(state->regmap, 0xdd11, 0x40, 0x40); | ||
633 | if (ret) | ||
634 | goto err; | ||
635 | ret = regmap_update_bits(state->regmap, 0xd50b, 0x02, 0x00); | ||
636 | if (ret) | ||
637 | goto err; | ||
638 | } else if (adap_id == 0 && !onoff) { | ||
639 | /* Adapter 0 stream off. EP4: set reset, disable, set NAK */ | ||
640 | ret = regmap_update_bits(state->regmap, 0xd507, 0x04, 0x04); | ||
641 | if (ret) | ||
642 | goto err; | ||
643 | ret = regmap_update_bits(state->regmap, 0xdd11, 0x20, 0x00); | ||
644 | if (ret) | ||
645 | goto err; | ||
646 | ret = regmap_update_bits(state->regmap, 0xdd13, 0x20, 0x20); | ||
647 | if (ret) | ||
648 | goto err; | ||
649 | } else if (adap_id == 1 && !onoff) { | ||
650 | /* Adapter 1 stream off. EP5: set reset, disable, set NAK */ | ||
651 | ret = regmap_update_bits(state->regmap, 0xd50b, 0x02, 0x02); | ||
652 | if (ret) | ||
653 | goto err; | ||
654 | ret = regmap_update_bits(state->regmap, 0xdd11, 0x40, 0x00); | ||
655 | if (ret) | ||
656 | goto err; | ||
657 | ret = regmap_update_bits(state->regmap, 0xdd13, 0x40, 0x40); | ||
658 | if (ret) | ||
659 | goto err; | ||
660 | } | ||
622 | 661 | ||
623 | return 0; | 662 | return 0; |
663 | err: | ||
664 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
665 | return ret; | ||
624 | } | 666 | } |
625 | 667 | ||
626 | static int af9015_get_adapter_count(struct dvb_usb_device *d) | 668 | static int af9015_get_adapter_count(struct dvb_usb_device *d) |
627 | { | 669 | { |
628 | struct af9015_state *state = d_to_priv(d); | 670 | struct af9015_state *state = d_to_priv(d); |
671 | |||
629 | return state->dual_mode + 1; | 672 | return state->dual_mode + 1; |
630 | } | 673 | } |
631 | 674 | ||
@@ -647,7 +690,7 @@ static int af9015_af9013_set_frontend(struct dvb_frontend *fe) | |||
647 | 690 | ||
648 | /* override demod callbacks for resource locking */ | 691 | /* override demod callbacks for resource locking */ |
649 | static int af9015_af9013_read_status(struct dvb_frontend *fe, | 692 | static int af9015_af9013_read_status(struct dvb_frontend *fe, |
650 | enum fe_status *status) | 693 | enum fe_status *status) |
651 | { | 694 | { |
652 | int ret; | 695 | int ret; |
653 | struct af9015_state *state = fe_to_priv(fe); | 696 | struct af9015_state *state = fe_to_priv(fe); |
@@ -729,102 +772,105 @@ static int af9015_tuner_sleep(struct dvb_frontend *fe) | |||
729 | static int af9015_copy_firmware(struct dvb_usb_device *d) | 772 | static int af9015_copy_firmware(struct dvb_usb_device *d) |
730 | { | 773 | { |
731 | struct af9015_state *state = d_to_priv(d); | 774 | struct af9015_state *state = d_to_priv(d); |
775 | struct usb_interface *intf = d->intf; | ||
732 | int ret; | 776 | int ret; |
733 | u8 fw_params[4]; | 777 | unsigned long timeout; |
734 | u8 val, i; | 778 | u8 val, firmware_info[4]; |
735 | struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), | 779 | struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, 4, firmware_info}; |
736 | fw_params }; | ||
737 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
738 | |||
739 | fw_params[0] = state->firmware_size >> 8; | ||
740 | fw_params[1] = state->firmware_size & 0xff; | ||
741 | fw_params[2] = state->firmware_checksum >> 8; | ||
742 | fw_params[3] = state->firmware_checksum & 0xff; | ||
743 | |||
744 | ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, | ||
745 | 0x98be, &val); | ||
746 | if (ret) | ||
747 | goto error; | ||
748 | else | ||
749 | dev_dbg(&d->udev->dev, "%s: firmware status=%02x\n", | ||
750 | __func__, val); | ||
751 | 780 | ||
752 | if (val == 0x0c) /* fw is running, no need for download */ | 781 | dev_dbg(&intf->dev, "\n"); |
753 | goto exit; | ||
754 | 782 | ||
755 | /* set I2C master clock to fast (to speed up firmware copy) */ | 783 | firmware_info[0] = (state->firmware_size >> 8) & 0xff; |
756 | ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ | 784 | firmware_info[1] = (state->firmware_size >> 0) & 0xff; |
785 | firmware_info[2] = (state->firmware_checksum >> 8) & 0xff; | ||
786 | firmware_info[3] = (state->firmware_checksum >> 0) & 0xff; | ||
787 | |||
788 | /* Check whether firmware is already running */ | ||
789 | ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], 0x98be, &val); | ||
757 | if (ret) | 790 | if (ret) |
758 | goto error; | 791 | goto err; |
759 | 792 | ||
760 | msleep(50); | 793 | dev_dbg(&intf->dev, "firmware status %02x\n", val); |
761 | 794 | ||
762 | /* copy firmware */ | 795 | if (val == 0x0c) |
763 | ret = af9015_ctrl_msg(d, &req); | 796 | return 0; |
797 | |||
798 | /* Set i2c clock to 625kHz to speed up firmware copy */ | ||
799 | ret = regmap_write(state->regmap, 0xd416, 0x04); | ||
764 | if (ret) | 800 | if (ret) |
765 | dev_err(&d->udev->dev, "%s: firmware copy cmd failed=%d\n", | 801 | goto err; |
766 | KBUILD_MODNAME, ret); | ||
767 | 802 | ||
768 | dev_dbg(&d->udev->dev, "%s: firmware copy done\n", __func__); | 803 | /* Copy firmware from master demod to slave demod */ |
804 | ret = af9015_ctrl_msg(d, &req); | ||
805 | if (ret) { | ||
806 | dev_err(&intf->dev, "firmware copy cmd failed %d\n", ret); | ||
807 | goto err; | ||
808 | } | ||
769 | 809 | ||
770 | /* set I2C master clock back to normal */ | 810 | /* Set i2c clock to 125kHz */ |
771 | ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ | 811 | ret = regmap_write(state->regmap, 0xd416, 0x14); |
772 | if (ret) | 812 | if (ret) |
773 | goto error; | 813 | goto err; |
774 | 814 | ||
775 | /* request boot firmware */ | 815 | /* Boot firmware */ |
776 | ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr, | 816 | ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1], 0xe205, 0x01); |
777 | 0xe205, 1); | ||
778 | dev_dbg(&d->udev->dev, "%s: firmware boot cmd status=%d\n", | ||
779 | __func__, ret); | ||
780 | if (ret) | 817 | if (ret) |
781 | goto error; | 818 | goto err; |
782 | 819 | ||
783 | for (i = 0; i < 15; i++) { | 820 | /* Poll firmware ready */ |
784 | msleep(100); | 821 | for (val = 0x00, timeout = jiffies + msecs_to_jiffies(1000); |
822 | !time_after(jiffies, timeout) && val != 0x0c && val != 0x04;) { | ||
823 | msleep(20); | ||
785 | 824 | ||
786 | /* check firmware status */ | 825 | /* Check firmware status. 0c=OK, 04=fail */ |
787 | ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr, | 826 | ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], |
788 | 0x98be, &val); | 827 | 0x98be, &val); |
789 | dev_dbg(&d->udev->dev, "%s: firmware status cmd status=%d " \ | ||
790 | "firmware status=%02x\n", __func__, ret, val); | ||
791 | if (ret) | 828 | if (ret) |
792 | goto error; | 829 | goto err; |
793 | 830 | ||
794 | if (val == 0x0c || val == 0x04) /* success or fail */ | 831 | dev_dbg(&intf->dev, "firmware status %02x\n", val); |
795 | break; | ||
796 | } | 832 | } |
797 | 833 | ||
834 | dev_dbg(&intf->dev, "firmware boot took %u ms\n", | ||
835 | jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - 1000)); | ||
836 | |||
798 | if (val == 0x04) { | 837 | if (val == 0x04) { |
799 | dev_err(&d->udev->dev, "%s: firmware did not run\n", | 838 | ret = -ENODEV; |
800 | KBUILD_MODNAME); | 839 | dev_err(&intf->dev, "firmware did not run\n"); |
801 | ret = -ETIMEDOUT; | 840 | goto err; |
802 | } else if (val != 0x0c) { | 841 | } else if (val != 0x0c) { |
803 | dev_err(&d->udev->dev, "%s: firmware boot timeout\n", | ||
804 | KBUILD_MODNAME); | ||
805 | ret = -ETIMEDOUT; | 842 | ret = -ETIMEDOUT; |
843 | dev_err(&intf->dev, "firmware boot timeout\n"); | ||
844 | goto err; | ||
806 | } | 845 | } |
807 | 846 | ||
808 | error: | 847 | return 0; |
809 | exit: | 848 | err: |
849 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
810 | return ret; | 850 | return ret; |
811 | } | 851 | } |
812 | 852 | ||
813 | static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) | 853 | static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) |
814 | { | 854 | { |
815 | int ret; | ||
816 | struct af9015_state *state = adap_to_priv(adap); | 855 | struct af9015_state *state = adap_to_priv(adap); |
856 | struct dvb_usb_device *d = adap_to_d(adap); | ||
857 | struct usb_interface *intf = d->intf; | ||
858 | struct i2c_client *client; | ||
859 | int ret; | ||
860 | |||
861 | dev_dbg(&intf->dev, "adap id %u\n", adap->id); | ||
817 | 862 | ||
818 | if (adap->id == 0) { | 863 | if (adap->id == 0) { |
819 | state->af9013_config[0].ts_mode = AF9013_TS_USB; | 864 | state->af9013_pdata[0].ts_mode = AF9013_TS_MODE_USB; |
820 | memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4); | 865 | memcpy(state->af9013_pdata[0].api_version, "\x0\x1\x9\x0", 4); |
821 | state->af9013_config[0].gpio[0] = AF9013_GPIO_HI; | 866 | state->af9013_pdata[0].gpio[0] = AF9013_GPIO_HI; |
822 | state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON; | 867 | state->af9013_pdata[0].gpio[3] = AF9013_GPIO_TUNER_ON; |
823 | } else if (adap->id == 1) { | 868 | } else if (adap->id == 1) { |
824 | state->af9013_config[1].ts_mode = AF9013_TS_SERIAL; | 869 | state->af9013_pdata[1].ts_mode = AF9013_TS_MODE_SERIAL; |
825 | memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4); | 870 | state->af9013_pdata[1].ts_output_pin = 7; |
826 | state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON; | 871 | memcpy(state->af9013_pdata[1].api_version, "\x0\x1\x9\x0", 4); |
827 | state->af9013_config[1].gpio[1] = AF9013_GPIO_LO; | 872 | state->af9013_pdata[1].gpio[0] = AF9013_GPIO_TUNER_ON; |
873 | state->af9013_pdata[1].gpio[1] = AF9013_GPIO_LO; | ||
828 | 874 | ||
829 | /* copy firmware to 2nd demodulator */ | 875 | /* copy firmware to 2nd demodulator */ |
830 | if (state->dual_mode) { | 876 | if (state->dual_mode) { |
@@ -833,21 +879,27 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) | |||
833 | 879 | ||
834 | ret = af9015_copy_firmware(adap_to_d(adap)); | 880 | ret = af9015_copy_firmware(adap_to_d(adap)); |
835 | if (ret) { | 881 | if (ret) { |
836 | dev_err(&adap_to_d(adap)->udev->dev, | 882 | dev_err(&intf->dev, |
837 | "%s: firmware copy to 2nd " \ | 883 | "firmware copy to 2nd frontend failed, will disable it\n"); |
838 | "frontend failed, will " \ | ||
839 | "disable it\n", KBUILD_MODNAME); | ||
840 | state->dual_mode = 0; | 884 | state->dual_mode = 0; |
841 | return -ENODEV; | 885 | goto err; |
842 | } | 886 | } |
843 | } else { | 887 | } else { |
844 | return -ENODEV; | 888 | ret = -ENODEV; |
889 | goto err; | ||
845 | } | 890 | } |
846 | } | 891 | } |
847 | 892 | ||
848 | /* attach demodulator */ | 893 | /* Add I2C demod */ |
849 | adap->fe[0] = dvb_attach(af9013_attach, | 894 | client = dvb_module_probe("af9013", NULL, &d->i2c_adap, |
850 | &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap); | 895 | state->af9013_i2c_addr[adap->id], |
896 | &state->af9013_pdata[adap->id]); | ||
897 | if (!client) { | ||
898 | ret = -ENODEV; | ||
899 | goto err; | ||
900 | } | ||
901 | adap->fe[0] = state->af9013_pdata[adap->id].get_dvb_frontend(client); | ||
902 | state->demod_i2c_client[adap->id] = client; | ||
851 | 903 | ||
852 | /* | 904 | /* |
853 | * AF9015 firmware does not like if it gets interrupted by I2C adapter | 905 | * AF9015 firmware does not like if it gets interrupted by I2C adapter |
@@ -857,24 +909,36 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) | |||
857 | * those "critical" paths to keep AF9015 happy. | 909 | * those "critical" paths to keep AF9015 happy. |
858 | */ | 910 | */ |
859 | if (adap->fe[0]) { | 911 | if (adap->fe[0]) { |
860 | state->set_frontend[adap->id] = | 912 | state->set_frontend[adap->id] = adap->fe[0]->ops.set_frontend; |
861 | adap->fe[0]->ops.set_frontend; | 913 | adap->fe[0]->ops.set_frontend = af9015_af9013_set_frontend; |
862 | adap->fe[0]->ops.set_frontend = | 914 | state->read_status[adap->id] = adap->fe[0]->ops.read_status; |
863 | af9015_af9013_set_frontend; | 915 | adap->fe[0]->ops.read_status = af9015_af9013_read_status; |
864 | |||
865 | state->read_status[adap->id] = | ||
866 | adap->fe[0]->ops.read_status; | ||
867 | adap->fe[0]->ops.read_status = | ||
868 | af9015_af9013_read_status; | ||
869 | |||
870 | state->init[adap->id] = adap->fe[0]->ops.init; | 916 | state->init[adap->id] = adap->fe[0]->ops.init; |
871 | adap->fe[0]->ops.init = af9015_af9013_init; | 917 | adap->fe[0]->ops.init = af9015_af9013_init; |
872 | |||
873 | state->sleep[adap->id] = adap->fe[0]->ops.sleep; | 918 | state->sleep[adap->id] = adap->fe[0]->ops.sleep; |
874 | adap->fe[0]->ops.sleep = af9015_af9013_sleep; | 919 | adap->fe[0]->ops.sleep = af9015_af9013_sleep; |
875 | } | 920 | } |
876 | 921 | ||
877 | return adap->fe[0] == NULL ? -ENODEV : 0; | 922 | return 0; |
923 | err: | ||
924 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
925 | return ret; | ||
926 | } | ||
927 | |||
928 | static int af9015_frontend_detach(struct dvb_usb_adapter *adap) | ||
929 | { | ||
930 | struct af9015_state *state = adap_to_priv(adap); | ||
931 | struct dvb_usb_device *d = adap_to_d(adap); | ||
932 | struct usb_interface *intf = d->intf; | ||
933 | struct i2c_client *client; | ||
934 | |||
935 | dev_dbg(&intf->dev, "adap id %u\n", adap->id); | ||
936 | |||
937 | /* Remove I2C demod */ | ||
938 | client = state->demod_i2c_client[adap->id]; | ||
939 | dvb_module_release(client); | ||
940 | |||
941 | return 0; | ||
878 | } | 942 | } |
879 | 943 | ||
880 | static struct mt2060_config af9015_mt2060_config = { | 944 | static struct mt2060_config af9015_mt2060_config = { |
@@ -944,64 +1008,61 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
944 | { | 1008 | { |
945 | struct dvb_usb_device *d = adap_to_d(adap); | 1009 | struct dvb_usb_device *d = adap_to_d(adap); |
946 | struct af9015_state *state = d_to_priv(d); | 1010 | struct af9015_state *state = d_to_priv(d); |
1011 | struct usb_interface *intf = d->intf; | ||
1012 | struct i2c_client *client; | ||
1013 | struct i2c_adapter *adapter; | ||
947 | int ret; | 1014 | int ret; |
948 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | ||
949 | 1015 | ||
950 | switch (state->af9013_config[adap->id].tuner) { | 1016 | dev_dbg(&intf->dev, "adap id %u\n", adap->id); |
1017 | |||
1018 | client = state->demod_i2c_client[adap->id]; | ||
1019 | adapter = state->af9013_pdata[adap->id].get_i2c_adapter(client); | ||
1020 | |||
1021 | switch (state->af9013_pdata[adap->id].tuner) { | ||
951 | case AF9013_TUNER_MT2060: | 1022 | case AF9013_TUNER_MT2060: |
952 | case AF9013_TUNER_MT2060_2: | 1023 | case AF9013_TUNER_MT2060_2: |
953 | ret = dvb_attach(mt2060_attach, adap->fe[0], | 1024 | ret = dvb_attach(mt2060_attach, adap->fe[0], adapter, |
954 | &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config, | 1025 | &af9015_mt2060_config, |
955 | state->mt2060_if1[adap->id]) | 1026 | state->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0; |
956 | == NULL ? -ENODEV : 0; | ||
957 | break; | 1027 | break; |
958 | case AF9013_TUNER_QT1010: | 1028 | case AF9013_TUNER_QT1010: |
959 | case AF9013_TUNER_QT1010A: | 1029 | case AF9013_TUNER_QT1010A: |
960 | ret = dvb_attach(qt1010_attach, adap->fe[0], | 1030 | ret = dvb_attach(qt1010_attach, adap->fe[0], adapter, |
961 | &adap_to_d(adap)->i2c_adap, | 1031 | &af9015_qt1010_config) == NULL ? -ENODEV : 0; |
962 | &af9015_qt1010_config) == NULL ? -ENODEV : 0; | ||
963 | break; | 1032 | break; |
964 | case AF9013_TUNER_TDA18271: | 1033 | case AF9013_TUNER_TDA18271: |
965 | ret = dvb_attach(tda18271_attach, adap->fe[0], 0x60, | 1034 | ret = dvb_attach(tda18271_attach, adap->fe[0], 0x60, adapter, |
966 | &adap_to_d(adap)->i2c_adap, | 1035 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; |
967 | &af9015_tda18271_config) == NULL ? -ENODEV : 0; | ||
968 | break; | 1036 | break; |
969 | case AF9013_TUNER_TDA18218: | 1037 | case AF9013_TUNER_TDA18218: |
970 | ret = dvb_attach(tda18218_attach, adap->fe[0], | 1038 | ret = dvb_attach(tda18218_attach, adap->fe[0], adapter, |
971 | &adap_to_d(adap)->i2c_adap, | 1039 | &af9015_tda18218_config) == NULL ? -ENODEV : 0; |
972 | &af9015_tda18218_config) == NULL ? -ENODEV : 0; | ||
973 | break; | 1040 | break; |
974 | case AF9013_TUNER_MXL5003D: | 1041 | case AF9013_TUNER_MXL5003D: |
975 | ret = dvb_attach(mxl5005s_attach, adap->fe[0], | 1042 | ret = dvb_attach(mxl5005s_attach, adap->fe[0], adapter, |
976 | &adap_to_d(adap)->i2c_adap, | 1043 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; |
977 | &af9015_mxl5003_config) == NULL ? -ENODEV : 0; | ||
978 | break; | 1044 | break; |
979 | case AF9013_TUNER_MXL5005D: | 1045 | case AF9013_TUNER_MXL5005D: |
980 | case AF9013_TUNER_MXL5005R: | 1046 | case AF9013_TUNER_MXL5005R: |
981 | ret = dvb_attach(mxl5005s_attach, adap->fe[0], | 1047 | ret = dvb_attach(mxl5005s_attach, adap->fe[0], adapter, |
982 | &adap_to_d(adap)->i2c_adap, | 1048 | &af9015_mxl5005_config) == NULL ? -ENODEV : 0; |
983 | &af9015_mxl5005_config) == NULL ? -ENODEV : 0; | ||
984 | break; | 1049 | break; |
985 | case AF9013_TUNER_ENV77H11D5: | 1050 | case AF9013_TUNER_ENV77H11D5: |
986 | ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0x60, | 1051 | ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0x60, adapter, |
987 | &adap_to_d(adap)->i2c_adap, | 1052 | DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; |
988 | DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; | ||
989 | break; | 1053 | break; |
990 | case AF9013_TUNER_MC44S803: | 1054 | case AF9013_TUNER_MC44S803: |
991 | ret = dvb_attach(mc44s803_attach, adap->fe[0], | 1055 | ret = dvb_attach(mc44s803_attach, adap->fe[0], adapter, |
992 | &adap_to_d(adap)->i2c_adap, | 1056 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; |
993 | &af9015_mc44s803_config) == NULL ? -ENODEV : 0; | ||
994 | break; | 1057 | break; |
995 | case AF9013_TUNER_MXL5007T: | 1058 | case AF9013_TUNER_MXL5007T: |
996 | ret = dvb_attach(mxl5007t_attach, adap->fe[0], | 1059 | ret = dvb_attach(mxl5007t_attach, adap->fe[0], adapter, |
997 | &adap_to_d(adap)->i2c_adap, | 1060 | 0x60, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; |
998 | 0x60, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; | ||
999 | break; | 1061 | break; |
1000 | case AF9013_TUNER_UNKNOWN: | 1062 | case AF9013_TUNER_UNKNOWN: |
1001 | default: | 1063 | default: |
1002 | dev_err(&d->udev->dev, "%s: unknown tuner id=%d\n", | 1064 | dev_err(&intf->dev, "unknown tuner, tuner id %02x\n", |
1003 | KBUILD_MODNAME, | 1065 | state->af9013_pdata[adap->id].tuner); |
1004 | state->af9013_config[adap->id].tuner); | ||
1005 | ret = -ENODEV; | 1066 | ret = -ENODEV; |
1006 | } | 1067 | } |
1007 | 1068 | ||
@@ -1022,136 +1083,27 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) | |||
1022 | 1083 | ||
1023 | static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) | 1084 | static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) |
1024 | { | 1085 | { |
1025 | struct dvb_usb_device *d = adap_to_d(adap); | 1086 | struct af9015_state *state = adap_to_priv(adap); |
1026 | int ret; | 1087 | struct af9013_platform_data *pdata = &state->af9013_pdata[adap->id]; |
1027 | dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); | ||
1028 | |||
1029 | if (onoff) | ||
1030 | ret = af9015_set_reg_bit(d, 0xd503, 0); | ||
1031 | else | ||
1032 | ret = af9015_clear_reg_bit(d, 0xd503, 0); | ||
1033 | |||
1034 | return ret; | ||
1035 | } | ||
1036 | |||
1037 | static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, | ||
1038 | int onoff) | ||
1039 | { | ||
1040 | struct dvb_usb_device *d = adap_to_d(adap); | ||
1041 | int ret; | 1088 | int ret; |
1042 | u8 idx; | ||
1043 | dev_dbg(&d->udev->dev, "%s: index=%d pid=%04x onoff=%d\n", | ||
1044 | __func__, index, pid, onoff); | ||
1045 | |||
1046 | ret = af9015_write_reg(d, 0xd505, (pid & 0xff)); | ||
1047 | if (ret) | ||
1048 | goto error; | ||
1049 | 1089 | ||
1050 | ret = af9015_write_reg(d, 0xd506, (pid >> 8)); | 1090 | mutex_lock(&state->fe_mutex); |
1051 | if (ret) | 1091 | ret = pdata->pid_filter_ctrl(adap->fe[0], onoff); |
1052 | goto error; | 1092 | mutex_unlock(&state->fe_mutex); |
1053 | |||
1054 | idx = ((index & 0x1f) | (1 << 5)); | ||
1055 | ret = af9015_write_reg(d, 0xd504, idx); | ||
1056 | 1093 | ||
1057 | error: | ||
1058 | return ret; | 1094 | return ret; |
1059 | } | 1095 | } |
1060 | 1096 | ||
1061 | static int af9015_init_endpoint(struct dvb_usb_device *d) | 1097 | static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, |
1098 | u16 pid, int onoff) | ||
1062 | { | 1099 | { |
1063 | struct af9015_state *state = d_to_priv(d); | 1100 | struct af9015_state *state = adap_to_priv(adap); |
1101 | struct af9013_platform_data *pdata = &state->af9013_pdata[adap->id]; | ||
1064 | int ret; | 1102 | int ret; |
1065 | u16 frame_size; | ||
1066 | u8 packet_size; | ||
1067 | dev_dbg(&d->udev->dev, "%s: USB speed=%d\n", __func__, d->udev->speed); | ||
1068 | |||
1069 | if (d->udev->speed == USB_SPEED_FULL) { | ||
1070 | frame_size = TS_USB11_FRAME_SIZE/4; | ||
1071 | packet_size = TS_USB11_MAX_PACKET_SIZE/4; | ||
1072 | } else { | ||
1073 | frame_size = TS_USB20_FRAME_SIZE/4; | ||
1074 | packet_size = TS_USB20_MAX_PACKET_SIZE/4; | ||
1075 | } | ||
1076 | |||
1077 | ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */ | ||
1078 | if (ret) | ||
1079 | goto error; | ||
1080 | ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */ | ||
1081 | if (ret) | ||
1082 | goto error; | ||
1083 | ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */ | ||
1084 | if (ret) | ||
1085 | goto error; | ||
1086 | ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */ | ||
1087 | if (ret) | ||
1088 | goto error; | ||
1089 | ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */ | ||
1090 | if (ret) | ||
1091 | goto error; | ||
1092 | if (state->dual_mode) { | ||
1093 | ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */ | ||
1094 | if (ret) | ||
1095 | goto error; | ||
1096 | } | ||
1097 | ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */ | ||
1098 | if (ret) | ||
1099 | goto error; | ||
1100 | if (state->dual_mode) { | ||
1101 | ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */ | ||
1102 | if (ret) | ||
1103 | goto error; | ||
1104 | } | ||
1105 | /* EP4 xfer length */ | ||
1106 | ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff); | ||
1107 | if (ret) | ||
1108 | goto error; | ||
1109 | ret = af9015_write_reg(d, 0xdd89, frame_size >> 8); | ||
1110 | if (ret) | ||
1111 | goto error; | ||
1112 | /* EP5 xfer length */ | ||
1113 | ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff); | ||
1114 | if (ret) | ||
1115 | goto error; | ||
1116 | ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8); | ||
1117 | if (ret) | ||
1118 | goto error; | ||
1119 | ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */ | ||
1120 | if (ret) | ||
1121 | goto error; | ||
1122 | ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */ | ||
1123 | if (ret) | ||
1124 | goto error; | ||
1125 | ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */ | ||
1126 | if (ret) | ||
1127 | goto error; | ||
1128 | if (state->dual_mode) { | ||
1129 | ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */ | ||
1130 | if (ret) | ||
1131 | goto error; | ||
1132 | } | ||
1133 | 1103 | ||
1134 | /* enable / disable mp2if2 */ | 1104 | mutex_lock(&state->fe_mutex); |
1135 | if (state->dual_mode) { | 1105 | ret = pdata->pid_filter(adap->fe[0], index, pid, onoff); |
1136 | ret = af9015_set_reg_bit(d, 0xd50b, 0); | 1106 | mutex_unlock(&state->fe_mutex); |
1137 | if (ret) | ||
1138 | goto error; | ||
1139 | ret = af9015_set_reg_bit(d, 0xd520, 4); | ||
1140 | if (ret) | ||
1141 | goto error; | ||
1142 | } else { | ||
1143 | ret = af9015_clear_reg_bit(d, 0xd50b, 0); | ||
1144 | if (ret) | ||
1145 | goto error; | ||
1146 | ret = af9015_clear_reg_bit(d, 0xd520, 4); | ||
1147 | if (ret) | ||
1148 | goto error; | ||
1149 | } | ||
1150 | |||
1151 | error: | ||
1152 | if (ret) | ||
1153 | dev_err(&d->udev->dev, "%s: endpoint init failed=%d\n", | ||
1154 | KBUILD_MODNAME, ret); | ||
1155 | 1107 | ||
1156 | return ret; | 1108 | return ret; |
1157 | } | 1109 | } |
@@ -1159,17 +1111,15 @@ error: | |||
1159 | static int af9015_init(struct dvb_usb_device *d) | 1111 | static int af9015_init(struct dvb_usb_device *d) |
1160 | { | 1112 | { |
1161 | struct af9015_state *state = d_to_priv(d); | 1113 | struct af9015_state *state = d_to_priv(d); |
1114 | struct usb_interface *intf = d->intf; | ||
1162 | int ret; | 1115 | int ret; |
1163 | dev_dbg(&d->udev->dev, "%s:\n", __func__); | 1116 | |
1117 | dev_dbg(&intf->dev, "\n"); | ||
1164 | 1118 | ||
1165 | mutex_init(&state->fe_mutex); | 1119 | mutex_init(&state->fe_mutex); |
1166 | 1120 | ||
1167 | /* init RC canary */ | 1121 | /* init RC canary */ |
1168 | ret = af9015_write_reg(d, 0x98e9, 0xff); | 1122 | ret = regmap_write(state->regmap, 0x98e9, 0xff); |
1169 | if (ret) | ||
1170 | goto error; | ||
1171 | |||
1172 | ret = af9015_init_endpoint(d); | ||
1173 | if (ret) | 1123 | if (ret) |
1174 | goto error; | 1124 | goto error; |
1175 | 1125 | ||
@@ -1184,7 +1134,7 @@ struct af9015_rc_setup { | |||
1184 | }; | 1134 | }; |
1185 | 1135 | ||
1186 | static char *af9015_rc_setup_match(unsigned int id, | 1136 | static char *af9015_rc_setup_match(unsigned int id, |
1187 | const struct af9015_rc_setup *table) | 1137 | const struct af9015_rc_setup *table) |
1188 | { | 1138 | { |
1189 | for (; table->rc_codes; table++) | 1139 | for (; table->rc_codes; table++) |
1190 | if (table->id == id) | 1140 | if (table->id == id) |
@@ -1212,24 +1162,25 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { | |||
1212 | static int af9015_rc_query(struct dvb_usb_device *d) | 1162 | static int af9015_rc_query(struct dvb_usb_device *d) |
1213 | { | 1163 | { |
1214 | struct af9015_state *state = d_to_priv(d); | 1164 | struct af9015_state *state = d_to_priv(d); |
1165 | struct usb_interface *intf = d->intf; | ||
1215 | int ret; | 1166 | int ret; |
1216 | u8 buf[17]; | 1167 | u8 buf[17]; |
1217 | 1168 | ||
1218 | /* read registers needed to detect remote controller code */ | 1169 | /* read registers needed to detect remote controller code */ |
1219 | ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | 1170 | ret = regmap_bulk_read(state->regmap, 0x98d9, buf, sizeof(buf)); |
1220 | if (ret) | 1171 | if (ret) |
1221 | goto error; | 1172 | goto error; |
1222 | 1173 | ||
1223 | /* If any of these are non-zero, assume invalid data */ | 1174 | /* If any of these are non-zero, assume invalid data */ |
1224 | if (buf[1] || buf[2] || buf[3]) { | 1175 | if (buf[1] || buf[2] || buf[3]) { |
1225 | dev_dbg(&d->udev->dev, "%s: invalid data\n", __func__); | 1176 | dev_dbg(&intf->dev, "invalid data\n"); |
1226 | return ret; | 1177 | return ret; |
1227 | } | 1178 | } |
1228 | 1179 | ||
1229 | /* Check for repeat of previous code */ | 1180 | /* Check for repeat of previous code */ |
1230 | if ((state->rc_repeat != buf[6] || buf[0]) && | 1181 | if ((state->rc_repeat != buf[6] || buf[0]) && |
1231 | !memcmp(&buf[12], state->rc_last, 4)) { | 1182 | !memcmp(&buf[12], state->rc_last, 4)) { |
1232 | dev_dbg(&d->udev->dev, "%s: key repeated\n", __func__); | 1183 | dev_dbg(&intf->dev, "key repeated\n"); |
1233 | rc_repeat(d->rc_dev); | 1184 | rc_repeat(d->rc_dev); |
1234 | state->rc_repeat = buf[6]; | 1185 | state->rc_repeat = buf[6]; |
1235 | return ret; | 1186 | return ret; |
@@ -1238,18 +1189,18 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1238 | /* Only process key if canary killed */ | 1189 | /* Only process key if canary killed */ |
1239 | if (buf[16] != 0xff && buf[0] != 0x01) { | 1190 | if (buf[16] != 0xff && buf[0] != 0x01) { |
1240 | enum rc_proto proto; | 1191 | enum rc_proto proto; |
1241 | dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n", | 1192 | |
1242 | __func__, 4, buf + 12); | 1193 | dev_dbg(&intf->dev, "key pressed %*ph\n", 4, buf + 12); |
1243 | 1194 | ||
1244 | /* Reset the canary */ | 1195 | /* Reset the canary */ |
1245 | ret = af9015_write_reg(d, 0x98e9, 0xff); | 1196 | ret = regmap_write(state->regmap, 0x98e9, 0xff); |
1246 | if (ret) | 1197 | if (ret) |
1247 | goto error; | 1198 | goto error; |
1248 | 1199 | ||
1249 | /* Remember this key */ | 1200 | /* Remember this key */ |
1250 | memcpy(state->rc_last, &buf[12], 4); | 1201 | memcpy(state->rc_last, &buf[12], 4); |
1251 | if (buf[14] == (u8) ~buf[15]) { | 1202 | if (buf[14] == (u8)~buf[15]) { |
1252 | if (buf[12] == (u8) ~buf[13]) { | 1203 | if (buf[12] == (u8)~buf[13]) { |
1253 | /* NEC */ | 1204 | /* NEC */ |
1254 | state->rc_keycode = RC_SCANCODE_NEC(buf[12], | 1205 | state->rc_keycode = RC_SCANCODE_NEC(buf[12], |
1255 | buf[14]); | 1206 | buf[14]); |
@@ -1271,7 +1222,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1271 | } | 1222 | } |
1272 | rc_keydown(d->rc_dev, proto, state->rc_keycode, 0); | 1223 | rc_keydown(d->rc_dev, proto, state->rc_keycode, 0); |
1273 | } else { | 1224 | } else { |
1274 | dev_dbg(&d->udev->dev, "%s: no key press\n", __func__); | 1225 | dev_dbg(&intf->dev, "no key press\n"); |
1275 | /* Invalidate last keypress */ | 1226 | /* Invalidate last keypress */ |
1276 | /* Not really needed, but helps with debug */ | 1227 | /* Not really needed, but helps with debug */ |
1277 | state->rc_last[2] = state->rc_last[3]; | 1228 | state->rc_last[2] = state->rc_last[3]; |
@@ -1282,8 +1233,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) | |||
1282 | 1233 | ||
1283 | error: | 1234 | error: |
1284 | if (ret) { | 1235 | if (ret) { |
1285 | dev_warn(&d->udev->dev, "%s: rc query failed=%d\n", | 1236 | dev_warn(&intf->dev, "rc query failed %d\n", ret); |
1286 | KBUILD_MODNAME, ret); | ||
1287 | 1237 | ||
1288 | /* allow random errors as dvb-usb will stop polling on error */ | 1238 | /* allow random errors as dvb-usb will stop polling on error */ |
1289 | if (!state->rc_failed) | 1239 | if (!state->rc_failed) |
@@ -1306,29 +1256,33 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) | |||
1306 | /* try to load remote based module param */ | 1256 | /* try to load remote based module param */ |
1307 | if (!rc->map_name) | 1257 | if (!rc->map_name) |
1308 | rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote, | 1258 | rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote, |
1309 | af9015_rc_setup_modparam); | 1259 | af9015_rc_setup_modparam); |
1310 | 1260 | ||
1311 | /* try to load remote based eeprom hash */ | 1261 | /* try to load remote based eeprom hash */ |
1312 | if (!rc->map_name) | 1262 | if (!rc->map_name) |
1313 | rc->map_name = af9015_rc_setup_match(state->eeprom_sum, | 1263 | rc->map_name = af9015_rc_setup_match(state->eeprom_sum, |
1314 | af9015_rc_setup_hashes); | 1264 | af9015_rc_setup_hashes); |
1315 | 1265 | ||
1316 | /* try to load remote based USB iManufacturer string */ | 1266 | /* try to load remote based USB iManufacturer string */ |
1317 | if (!rc->map_name && vid == USB_VID_AFATECH) { | 1267 | if (!rc->map_name && vid == USB_VID_AFATECH) { |
1318 | /* Check USB manufacturer and product strings and try | 1268 | /* |
1319 | to determine correct remote in case of chip vendor | 1269 | * Check USB manufacturer and product strings and try |
1320 | reference IDs are used. | 1270 | * to determine correct remote in case of chip vendor |
1321 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */ | 1271 | * reference IDs are used. |
1272 | * DO NOT ADD ANYTHING NEW HERE. Use hashes instead. | ||
1273 | */ | ||
1322 | char manufacturer[10]; | 1274 | char manufacturer[10]; |
1275 | |||
1323 | memset(manufacturer, 0, sizeof(manufacturer)); | 1276 | memset(manufacturer, 0, sizeof(manufacturer)); |
1324 | usb_string(d->udev, d->udev->descriptor.iManufacturer, | 1277 | usb_string(d->udev, d->udev->descriptor.iManufacturer, |
1325 | manufacturer, sizeof(manufacturer)); | 1278 | manufacturer, sizeof(manufacturer)); |
1326 | if (!strcmp("MSI", manufacturer)) { | 1279 | if (!strcmp("MSI", manufacturer)) { |
1327 | /* iManufacturer 1 MSI | 1280 | /* |
1328 | iProduct 2 MSI K-VOX */ | 1281 | * iManufacturer 1 MSI |
1329 | rc->map_name = af9015_rc_setup_match( | 1282 | * iProduct 2 MSI K-VOX |
1330 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | 1283 | */ |
1331 | af9015_rc_setup_modparam); | 1284 | rc->map_name = af9015_rc_setup_match(AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, |
1285 | af9015_rc_setup_modparam); | ||
1332 | } | 1286 | } |
1333 | } | 1287 | } |
1334 | 1288 | ||
@@ -1347,15 +1301,68 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) | |||
1347 | #define af9015_get_rc_config NULL | 1301 | #define af9015_get_rc_config NULL |
1348 | #endif | 1302 | #endif |
1349 | 1303 | ||
1350 | static int af9015_probe(struct usb_interface *intf, | 1304 | static int af9015_regmap_write(void *context, const void *data, size_t count) |
1351 | const struct usb_device_id *id) | ||
1352 | { | 1305 | { |
1306 | struct dvb_usb_device *d = context; | ||
1307 | struct usb_interface *intf = d->intf; | ||
1308 | int ret; | ||
1309 | u16 reg = ((u8 *)data)[0] << 8 | ((u8 *)data)[1] << 0; | ||
1310 | u8 *val = &((u8 *)data)[2]; | ||
1311 | const unsigned int len = count - 2; | ||
1312 | struct req_t req = {WRITE_MEMORY, 0, reg, 0, 0, len, val}; | ||
1313 | |||
1314 | ret = af9015_ctrl_msg(d, &req); | ||
1315 | if (ret) | ||
1316 | goto err; | ||
1317 | |||
1318 | return 0; | ||
1319 | err: | ||
1320 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
1321 | return ret; | ||
1322 | } | ||
1323 | |||
1324 | static int af9015_regmap_read(void *context, const void *reg_buf, | ||
1325 | size_t reg_size, void *val_buf, size_t val_size) | ||
1326 | { | ||
1327 | struct dvb_usb_device *d = context; | ||
1328 | struct usb_interface *intf = d->intf; | ||
1329 | int ret; | ||
1330 | u16 reg = ((u8 *)reg_buf)[0] << 8 | ((u8 *)reg_buf)[1] << 0; | ||
1331 | u8 *val = &((u8 *)val_buf)[0]; | ||
1332 | const unsigned int len = val_size; | ||
1333 | struct req_t req = {READ_MEMORY, 0, reg, 0, 0, len, val}; | ||
1334 | |||
1335 | ret = af9015_ctrl_msg(d, &req); | ||
1336 | if (ret) | ||
1337 | goto err; | ||
1338 | |||
1339 | return 0; | ||
1340 | err: | ||
1341 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
1342 | return ret; | ||
1343 | } | ||
1344 | |||
1345 | static int af9015_probe(struct dvb_usb_device *d) | ||
1346 | { | ||
1347 | struct af9015_state *state = d_to_priv(d); | ||
1348 | struct usb_interface *intf = d->intf; | ||
1353 | struct usb_device *udev = interface_to_usbdev(intf); | 1349 | struct usb_device *udev = interface_to_usbdev(intf); |
1350 | int ret; | ||
1354 | char manufacturer[sizeof("ITE Technologies, Inc.")]; | 1351 | char manufacturer[sizeof("ITE Technologies, Inc.")]; |
1352 | static const struct regmap_config regmap_config = { | ||
1353 | .reg_bits = 16, | ||
1354 | .val_bits = 8, | ||
1355 | }; | ||
1356 | static const struct regmap_bus regmap_bus = { | ||
1357 | .read = af9015_regmap_read, | ||
1358 | .write = af9015_regmap_write, | ||
1359 | }; | ||
1360 | |||
1361 | dev_dbg(&intf->dev, "\n"); | ||
1355 | 1362 | ||
1356 | memset(manufacturer, 0, sizeof(manufacturer)); | 1363 | memset(manufacturer, 0, sizeof(manufacturer)); |
1357 | usb_string(udev, udev->descriptor.iManufacturer, | 1364 | usb_string(udev, udev->descriptor.iManufacturer, |
1358 | manufacturer, sizeof(manufacturer)); | 1365 | manufacturer, sizeof(manufacturer)); |
1359 | /* | 1366 | /* |
1360 | * There is two devices having same ID but different chipset. One uses | 1367 | * There is two devices having same ID but different chipset. One uses |
1361 | * AF9015 and the other IT9135 chipset. Only difference seen on lsusb | 1368 | * AF9015 and the other IT9135 chipset. Only difference seen on lsusb |
@@ -1374,19 +1381,41 @@ static int af9015_probe(struct usb_interface *intf, | |||
1374 | * iProduct 2 DVB-T TV Stick | 1381 | * iProduct 2 DVB-T TV Stick |
1375 | */ | 1382 | */ |
1376 | if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) && | 1383 | if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) && |
1377 | (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) { | 1384 | (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) { |
1378 | if (!strcmp("ITE Technologies, Inc.", manufacturer)) { | 1385 | if (!strcmp("ITE Technologies, Inc.", manufacturer)) { |
1379 | dev_dbg(&udev->dev, "%s: rejecting device\n", __func__); | 1386 | ret = -ENODEV; |
1380 | return -ENODEV; | 1387 | dev_dbg(&intf->dev, "rejecting device\n"); |
1388 | goto err; | ||
1381 | } | 1389 | } |
1382 | } | 1390 | } |
1383 | 1391 | ||
1384 | return dvb_usbv2_probe(intf, id); | 1392 | state->regmap = regmap_init(&intf->dev, ®map_bus, d, ®map_config); |
1393 | if (IS_ERR(state->regmap)) { | ||
1394 | ret = PTR_ERR(state->regmap); | ||
1395 | goto err; | ||
1396 | } | ||
1397 | |||
1398 | return 0; | ||
1399 | err: | ||
1400 | dev_dbg(&intf->dev, "failed %d\n", ret); | ||
1401 | return ret; | ||
1385 | } | 1402 | } |
1386 | 1403 | ||
1387 | /* interface 0 is used by DVB-T receiver and | 1404 | static void af9015_disconnect(struct dvb_usb_device *d) |
1388 | interface 1 is for remote controller (HID) */ | 1405 | { |
1389 | static struct dvb_usb_device_properties af9015_props = { | 1406 | struct af9015_state *state = d_to_priv(d); |
1407 | struct usb_interface *intf = d->intf; | ||
1408 | |||
1409 | dev_dbg(&intf->dev, "\n"); | ||
1410 | |||
1411 | regmap_exit(state->regmap); | ||
1412 | } | ||
1413 | |||
1414 | /* | ||
1415 | * Interface 0 is used by DVB-T receiver and | ||
1416 | * interface 1 is for remote controller (HID) | ||
1417 | */ | ||
1418 | static const struct dvb_usb_device_properties af9015_props = { | ||
1390 | .driver_name = KBUILD_MODNAME, | 1419 | .driver_name = KBUILD_MODNAME, |
1391 | .owner = THIS_MODULE, | 1420 | .owner = THIS_MODULE, |
1392 | .adapter_nr = adapter_nr, | 1421 | .adapter_nr = adapter_nr, |
@@ -1395,6 +1424,8 @@ static struct dvb_usb_device_properties af9015_props = { | |||
1395 | .generic_bulk_ctrl_endpoint = 0x02, | 1424 | .generic_bulk_ctrl_endpoint = 0x02, |
1396 | .generic_bulk_ctrl_endpoint_response = 0x81, | 1425 | .generic_bulk_ctrl_endpoint_response = 0x81, |
1397 | 1426 | ||
1427 | .probe = af9015_probe, | ||
1428 | .disconnect = af9015_disconnect, | ||
1398 | .identify_state = af9015_identify_state, | 1429 | .identify_state = af9015_identify_state, |
1399 | .firmware = AF9015_FIRMWARE, | 1430 | .firmware = AF9015_FIRMWARE, |
1400 | .download_firmware = af9015_download_firmware, | 1431 | .download_firmware = af9015_download_firmware, |
@@ -1402,10 +1433,12 @@ static struct dvb_usb_device_properties af9015_props = { | |||
1402 | .i2c_algo = &af9015_i2c_algo, | 1433 | .i2c_algo = &af9015_i2c_algo, |
1403 | .read_config = af9015_read_config, | 1434 | .read_config = af9015_read_config, |
1404 | .frontend_attach = af9015_af9013_frontend_attach, | 1435 | .frontend_attach = af9015_af9013_frontend_attach, |
1436 | .frontend_detach = af9015_frontend_detach, | ||
1405 | .tuner_attach = af9015_tuner_attach, | 1437 | .tuner_attach = af9015_tuner_attach, |
1406 | .init = af9015_init, | 1438 | .init = af9015_init, |
1407 | .get_rc_config = af9015_get_rc_config, | 1439 | .get_rc_config = af9015_get_rc_config, |
1408 | .get_stream_config = af9015_get_stream_config, | 1440 | .get_stream_config = af9015_get_stream_config, |
1441 | .streaming_ctrl = af9015_streaming_ctrl, | ||
1409 | 1442 | ||
1410 | .get_adapter_count = af9015_get_adapter_count, | 1443 | .get_adapter_count = af9015_get_adapter_count, |
1411 | .adapter = { | 1444 | .adapter = { |
@@ -1416,9 +1449,15 @@ static struct dvb_usb_device_properties af9015_props = { | |||
1416 | .pid_filter = af9015_pid_filter, | 1449 | .pid_filter = af9015_pid_filter, |
1417 | .pid_filter_ctrl = af9015_pid_filter_ctrl, | 1450 | .pid_filter_ctrl = af9015_pid_filter_ctrl, |
1418 | 1451 | ||
1419 | .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE), | 1452 | .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188), |
1420 | }, { | 1453 | }, { |
1421 | .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE), | 1454 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | |
1455 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
1456 | .pid_filter_count = 32, | ||
1457 | .pid_filter = af9015_pid_filter, | ||
1458 | .pid_filter_ctrl = af9015_pid_filter_ctrl, | ||
1459 | |||
1460 | .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188), | ||
1422 | }, | 1461 | }, |
1423 | }, | 1462 | }, |
1424 | }; | 1463 | }; |
@@ -1509,7 +1548,7 @@ MODULE_DEVICE_TABLE(usb, af9015_id_table); | |||
1509 | static struct usb_driver af9015_usb_driver = { | 1548 | static struct usb_driver af9015_usb_driver = { |
1510 | .name = KBUILD_MODNAME, | 1549 | .name = KBUILD_MODNAME, |
1511 | .id_table = af9015_id_table, | 1550 | .id_table = af9015_id_table, |
1512 | .probe = af9015_probe, | 1551 | .probe = dvb_usbv2_probe, |
1513 | .disconnect = dvb_usbv2_disconnect, | 1552 | .disconnect = dvb_usbv2_disconnect, |
1514 | .suspend = dvb_usbv2_suspend, | 1553 | .suspend = dvb_usbv2_suspend, |
1515 | .resume = dvb_usbv2_resume, | 1554 | .resume = dvb_usbv2_resume, |
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h index 3a9d9815ab7a..ad2b045cc39c 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.h +++ b/drivers/media/usb/dvb-usb-v2/af9015.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define AF9015_H | 21 | #define AF9015_H |
22 | 22 | ||
23 | #include <linux/hash.h> | 23 | #include <linux/hash.h> |
24 | #include <linux/regmap.h> | ||
24 | #include "dvb_usb.h" | 25 | #include "dvb_usb.h" |
25 | #include "af9013.h" | 26 | #include "af9013.h" |
26 | #include "dvb-pll.h" | 27 | #include "dvb-pll.h" |
@@ -34,19 +35,6 @@ | |||
34 | 35 | ||
35 | #define AF9015_FIRMWARE "dvb-usb-af9015.fw" | 36 | #define AF9015_FIRMWARE "dvb-usb-af9015.fw" |
36 | 37 | ||
37 | /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0. | ||
38 | We use smaller - about 1/4 from the original, 5 and 87. */ | ||
39 | #define TS_PACKET_SIZE 188 | ||
40 | |||
41 | #define TS_USB20_PACKET_COUNT 87 | ||
42 | #define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT) | ||
43 | |||
44 | #define TS_USB11_PACKET_COUNT 5 | ||
45 | #define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT) | ||
46 | |||
47 | #define TS_USB20_MAX_PACKET_SIZE 512 | ||
48 | #define TS_USB11_MAX_PACKET_SIZE 64 | ||
49 | |||
50 | #define AF9015_I2C_EEPROM 0x50 | 38 | #define AF9015_I2C_EEPROM 0x50 |
51 | #define AF9015_I2C_DEMOD 0x1c | 39 | #define AF9015_I2C_DEMOD 0x1c |
52 | #define AF9015_USB_TIMEOUT 2000 | 40 | #define AF9015_USB_TIMEOUT 2000 |
@@ -113,6 +101,7 @@ enum af9015_ir_mode { | |||
113 | 101 | ||
114 | #define BUF_LEN 63 | 102 | #define BUF_LEN 63 |
115 | struct af9015_state { | 103 | struct af9015_state { |
104 | struct regmap *regmap; | ||
116 | u8 buf[BUF_LEN]; /* bulk USB control message */ | 105 | u8 buf[BUF_LEN]; /* bulk USB control message */ |
117 | u8 ir_mode; | 106 | u8 ir_mode; |
118 | u8 rc_repeat; | 107 | u8 rc_repeat; |
@@ -125,7 +114,10 @@ struct af9015_state { | |||
125 | u16 firmware_size; | 114 | u16 firmware_size; |
126 | u16 firmware_checksum; | 115 | u16 firmware_checksum; |
127 | u32 eeprom_sum; | 116 | u32 eeprom_sum; |
128 | struct af9013_config af9013_config[2]; | 117 | struct af9013_platform_data af9013_pdata[2]; |
118 | struct i2c_client *demod_i2c_client[2]; | ||
119 | u8 af9013_i2c_addr[2]; | ||
120 | bool usb_ts_if_configured[2]; | ||
129 | 121 | ||
130 | /* for demod callback override */ | 122 | /* for demod callback override */ |
131 | int (*set_frontend[2]) (struct dvb_frontend *fe); | 123 | int (*set_frontend[2]) (struct dvb_frontend *fe); |
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index d2e80537b2f7..3fd6cc0d6340 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h | |||
@@ -203,6 +203,8 @@ struct dvb_usb_adapter_properties { | |||
203 | * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for | 203 | * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for |
204 | * receive | 204 | * receive |
205 | * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message | 205 | * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message |
206 | * @probe: like probe on driver model | ||
207 | * @disconnect: like disconnect on driver model | ||
206 | * @identify_state: called to determine the firmware state (cold or warm) and | 208 | * @identify_state: called to determine the firmware state (cold or warm) and |
207 | * return possible firmware file name to be loaded | 209 | * return possible firmware file name to be loaded |
208 | * @firmware: name of the firmware file to be loaded | 210 | * @firmware: name of the firmware file to be loaded |
@@ -239,6 +241,8 @@ struct dvb_usb_device_properties { | |||
239 | u8 generic_bulk_ctrl_endpoint_response; | 241 | u8 generic_bulk_ctrl_endpoint_response; |
240 | unsigned int generic_bulk_ctrl_delay; | 242 | unsigned int generic_bulk_ctrl_delay; |
241 | 243 | ||
244 | int (*probe)(struct dvb_usb_device *); | ||
245 | void (*disconnect)(struct dvb_usb_device *); | ||
242 | #define WARM 0 | 246 | #define WARM 0 |
243 | #define COLD 1 | 247 | #define COLD 1 |
244 | int (*identify_state) (struct dvb_usb_device *, const char **); | 248 | int (*identify_state) (struct dvb_usb_device *, const char **); |
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 2bf3bd81280a..afdcdbf005e9 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | |||
@@ -854,8 +854,6 @@ static int dvb_usbv2_exit(struct dvb_usb_device *d) | |||
854 | dvb_usbv2_remote_exit(d); | 854 | dvb_usbv2_remote_exit(d); |
855 | dvb_usbv2_adapter_exit(d); | 855 | dvb_usbv2_adapter_exit(d); |
856 | dvb_usbv2_i2c_exit(d); | 856 | dvb_usbv2_i2c_exit(d); |
857 | kfree(d->priv); | ||
858 | kfree(d); | ||
859 | 857 | ||
860 | return 0; | 858 | return 0; |
861 | } | 859 | } |
@@ -934,7 +932,7 @@ int dvb_usbv2_probe(struct usb_interface *intf, | |||
934 | if (intf->cur_altsetting->desc.bInterfaceNumber != | 932 | if (intf->cur_altsetting->desc.bInterfaceNumber != |
935 | d->props->bInterfaceNumber) { | 933 | d->props->bInterfaceNumber) { |
936 | ret = -ENODEV; | 934 | ret = -ENODEV; |
937 | goto err_free_all; | 935 | goto err_kfree_d; |
938 | } | 936 | } |
939 | 937 | ||
940 | mutex_init(&d->usb_mutex); | 938 | mutex_init(&d->usb_mutex); |
@@ -946,10 +944,16 @@ int dvb_usbv2_probe(struct usb_interface *intf, | |||
946 | dev_err(&d->udev->dev, "%s: kzalloc() failed\n", | 944 | dev_err(&d->udev->dev, "%s: kzalloc() failed\n", |
947 | KBUILD_MODNAME); | 945 | KBUILD_MODNAME); |
948 | ret = -ENOMEM; | 946 | ret = -ENOMEM; |
949 | goto err_free_all; | 947 | goto err_kfree_d; |
950 | } | 948 | } |
951 | } | 949 | } |
952 | 950 | ||
951 | if (d->props->probe) { | ||
952 | ret = d->props->probe(d); | ||
953 | if (ret) | ||
954 | goto err_kfree_priv; | ||
955 | } | ||
956 | |||
953 | if (d->props->identify_state) { | 957 | if (d->props->identify_state) { |
954 | const char *name = NULL; | 958 | const char *name = NULL; |
955 | ret = d->props->identify_state(d, &name); | 959 | ret = d->props->identify_state(d, &name); |
@@ -1001,6 +1005,12 @@ exit: | |||
1001 | return 0; | 1005 | return 0; |
1002 | err_free_all: | 1006 | err_free_all: |
1003 | dvb_usbv2_exit(d); | 1007 | dvb_usbv2_exit(d); |
1008 | if (d->props->disconnect) | ||
1009 | d->props->disconnect(d); | ||
1010 | err_kfree_priv: | ||
1011 | kfree(d->priv); | ||
1012 | err_kfree_d: | ||
1013 | kfree(d); | ||
1004 | err: | 1014 | err: |
1005 | dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret); | 1015 | dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret); |
1006 | return ret; | 1016 | return ret; |
@@ -1021,6 +1031,12 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) | |||
1021 | 1031 | ||
1022 | dvb_usbv2_exit(d); | 1032 | dvb_usbv2_exit(d); |
1023 | 1033 | ||
1034 | if (d->props->disconnect) | ||
1035 | d->props->disconnect(d); | ||
1036 | |||
1037 | kfree(d->priv); | ||
1038 | kfree(d); | ||
1039 | |||
1024 | pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n", | 1040 | pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n", |
1025 | KBUILD_MODNAME, drvname, devname); | 1041 | KBUILD_MODNAME, drvname, devname); |
1026 | kfree(devname); | 1042 | kfree(devname); |
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 2abd15c6df81..387a074ea6ec 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c | |||
@@ -1243,82 +1243,6 @@ static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) | |||
1243 | return 0; | 1243 | return 0; |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | static int cxusb_mygica_t230c_frontend_attach(struct dvb_usb_adapter *adap) | ||
1247 | { | ||
1248 | struct dvb_usb_device *d = adap->dev; | ||
1249 | struct cxusb_state *st = d->priv; | ||
1250 | struct i2c_adapter *adapter; | ||
1251 | struct i2c_client *client_demod; | ||
1252 | struct i2c_client *client_tuner; | ||
1253 | struct i2c_board_info info; | ||
1254 | struct si2168_config si2168_config; | ||
1255 | struct si2157_config si2157_config; | ||
1256 | |||
1257 | /* Select required USB configuration */ | ||
1258 | if (usb_set_interface(d->udev, 0, 0) < 0) | ||
1259 | err("set interface failed"); | ||
1260 | |||
1261 | /* Unblock all USB pipes */ | ||
1262 | usb_clear_halt(d->udev, | ||
1263 | usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | ||
1264 | usb_clear_halt(d->udev, | ||
1265 | usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); | ||
1266 | usb_clear_halt(d->udev, | ||
1267 | usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); | ||
1268 | |||
1269 | /* attach frontend */ | ||
1270 | memset(&si2168_config, 0, sizeof(si2168_config)); | ||
1271 | si2168_config.i2c_adapter = &adapter; | ||
1272 | si2168_config.fe = &adap->fe_adap[0].fe; | ||
1273 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | ||
1274 | si2168_config.ts_clock_inv = 1; | ||
1275 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1276 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | ||
1277 | info.addr = 0x64; | ||
1278 | info.platform_data = &si2168_config; | ||
1279 | request_module(info.type); | ||
1280 | client_demod = i2c_new_device(&d->i2c_adap, &info); | ||
1281 | if (client_demod == NULL || client_demod->dev.driver == NULL) | ||
1282 | return -ENODEV; | ||
1283 | |||
1284 | if (!try_module_get(client_demod->dev.driver->owner)) { | ||
1285 | i2c_unregister_device(client_demod); | ||
1286 | return -ENODEV; | ||
1287 | } | ||
1288 | |||
1289 | /* attach tuner */ | ||
1290 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
1291 | si2157_config.fe = adap->fe_adap[0].fe; | ||
1292 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1293 | strlcpy(info.type, "si2141", I2C_NAME_SIZE); | ||
1294 | info.addr = 0x60; | ||
1295 | info.platform_data = &si2157_config; | ||
1296 | request_module("si2157"); | ||
1297 | client_tuner = i2c_new_device(adapter, &info); | ||
1298 | if (client_tuner == NULL || client_tuner->dev.driver == NULL) { | ||
1299 | module_put(client_demod->dev.driver->owner); | ||
1300 | i2c_unregister_device(client_demod); | ||
1301 | return -ENODEV; | ||
1302 | } | ||
1303 | if (!try_module_get(client_tuner->dev.driver->owner)) { | ||
1304 | i2c_unregister_device(client_tuner); | ||
1305 | module_put(client_demod->dev.driver->owner); | ||
1306 | i2c_unregister_device(client_demod); | ||
1307 | return -ENODEV; | ||
1308 | } | ||
1309 | |||
1310 | st->i2c_client_demod = client_demod; | ||
1311 | st->i2c_client_tuner = client_tuner; | ||
1312 | |||
1313 | /* hook fe: need to resync the slave fifo when signal locks. */ | ||
1314 | mutex_init(&st->stream_mutex); | ||
1315 | st->last_lock = 0; | ||
1316 | st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; | ||
1317 | adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; | ||
1318 | |||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | /* | 1246 | /* |
1323 | * DViCO has shipped two devices with the same USB ID, but only one of them | 1247 | * DViCO has shipped two devices with the same USB ID, but only one of them |
1324 | * needs a firmware download. Check the device class details to see if they | 1248 | * needs a firmware download. Check the device class details to see if they |
@@ -1401,7 +1325,6 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties; | |||
1401 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties; | 1325 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties; |
1402 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties; | 1326 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties; |
1403 | static struct dvb_usb_device_properties cxusb_mygica_t230_properties; | 1327 | static struct dvb_usb_device_properties cxusb_mygica_t230_properties; |
1404 | static struct dvb_usb_device_properties cxusb_mygica_t230c_properties; | ||
1405 | 1328 | ||
1406 | static int cxusb_probe(struct usb_interface *intf, | 1329 | static int cxusb_probe(struct usb_interface *intf, |
1407 | const struct usb_device_id *id) | 1330 | const struct usb_device_id *id) |
@@ -1434,8 +1357,6 @@ static int cxusb_probe(struct usb_interface *intf, | |||
1434 | THIS_MODULE, NULL, adapter_nr) || | 1357 | THIS_MODULE, NULL, adapter_nr) || |
1435 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, | 1358 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, |
1436 | THIS_MODULE, NULL, adapter_nr) || | 1359 | THIS_MODULE, NULL, adapter_nr) || |
1437 | 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230c_properties, | ||
1438 | THIS_MODULE, NULL, adapter_nr) || | ||
1439 | 0) | 1360 | 0) |
1440 | return 0; | 1361 | return 0; |
1441 | 1362 | ||
@@ -1487,7 +1408,6 @@ enum cxusb_table_index { | |||
1487 | CONEXANT_D680_DMB, | 1408 | CONEXANT_D680_DMB, |
1488 | MYGICA_D689, | 1409 | MYGICA_D689, |
1489 | MYGICA_T230, | 1410 | MYGICA_T230, |
1490 | MYGICA_T230C, | ||
1491 | NR__cxusb_table_index | 1411 | NR__cxusb_table_index |
1492 | }; | 1412 | }; |
1493 | 1413 | ||
@@ -1555,9 +1475,6 @@ static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { | |||
1555 | [MYGICA_T230] = { | 1475 | [MYGICA_T230] = { |
1556 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) | 1476 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) |
1557 | }, | 1477 | }, |
1558 | [MYGICA_T230C] = { | ||
1559 | USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230+1) | ||
1560 | }, | ||
1561 | {} /* Terminating entry */ | 1478 | {} /* Terminating entry */ |
1562 | }; | 1479 | }; |
1563 | MODULE_DEVICE_TABLE (usb, cxusb_table); | 1480 | MODULE_DEVICE_TABLE (usb, cxusb_table); |
@@ -2143,7 +2060,7 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { | |||
2143 | 2060 | ||
2144 | .rc.core = { | 2061 | .rc.core = { |
2145 | .rc_interval = 100, | 2062 | .rc_interval = 100, |
2146 | .rc_codes = RC_MAP_D680_DMB, | 2063 | .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, |
2147 | .module_name = KBUILD_MODNAME, | 2064 | .module_name = KBUILD_MODNAME, |
2148 | .rc_query = cxusb_d680_dmb_rc_query, | 2065 | .rc_query = cxusb_d680_dmb_rc_query, |
2149 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, | 2066 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, |
@@ -2252,7 +2169,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { | |||
2252 | 2169 | ||
2253 | .rc.core = { | 2170 | .rc.core = { |
2254 | .rc_interval = 100, | 2171 | .rc_interval = 100, |
2255 | .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, | 2172 | .rc_codes = RC_MAP_D680_DMB, |
2256 | .module_name = KBUILD_MODNAME, | 2173 | .module_name = KBUILD_MODNAME, |
2257 | .rc_query = cxusb_d680_dmb_rc_query, | 2174 | .rc_query = cxusb_d680_dmb_rc_query, |
2258 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, | 2175 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, |
@@ -2268,60 +2185,6 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { | |||
2268 | } | 2185 | } |
2269 | }; | 2186 | }; |
2270 | 2187 | ||
2271 | static struct dvb_usb_device_properties cxusb_mygica_t230c_properties = { | ||
2272 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
2273 | |||
2274 | .usb_ctrl = CYPRESS_FX2, | ||
2275 | |||
2276 | .size_of_priv = sizeof(struct cxusb_state), | ||
2277 | |||
2278 | .num_adapters = 1, | ||
2279 | .adapter = { | ||
2280 | { | ||
2281 | .num_frontends = 1, | ||
2282 | .fe = {{ | ||
2283 | .streaming_ctrl = cxusb_streaming_ctrl, | ||
2284 | .frontend_attach = cxusb_mygica_t230c_frontend_attach, | ||
2285 | |||
2286 | /* parameter for the MPEG2-data transfer */ | ||
2287 | .stream = { | ||
2288 | .type = USB_BULK, | ||
2289 | .count = 5, | ||
2290 | .endpoint = 0x02, | ||
2291 | .u = { | ||
2292 | .bulk = { | ||
2293 | .buffersize = 8192, | ||
2294 | } | ||
2295 | } | ||
2296 | }, | ||
2297 | } }, | ||
2298 | }, | ||
2299 | }, | ||
2300 | |||
2301 | .power_ctrl = cxusb_d680_dmb_power_ctrl, | ||
2302 | |||
2303 | .i2c_algo = &cxusb_i2c_algo, | ||
2304 | |||
2305 | .generic_bulk_ctrl_endpoint = 0x01, | ||
2306 | |||
2307 | .rc.core = { | ||
2308 | .rc_interval = 100, | ||
2309 | .rc_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02, | ||
2310 | .module_name = KBUILD_MODNAME, | ||
2311 | .rc_query = cxusb_d680_dmb_rc_query, | ||
2312 | .allowed_protos = RC_PROTO_BIT_UNKNOWN, | ||
2313 | }, | ||
2314 | |||
2315 | .num_device_descs = 1, | ||
2316 | .devices = { | ||
2317 | { | ||
2318 | "Mygica T230C DVB-T/T2/C", | ||
2319 | { NULL }, | ||
2320 | { &cxusb_table[MYGICA_T230C], NULL }, | ||
2321 | }, | ||
2322 | } | ||
2323 | }; | ||
2324 | |||
2325 | static struct usb_driver cxusb_driver = { | 2188 | static struct usb_driver cxusb_driver = { |
2326 | .name = "dvb_usb_cxusb", | 2189 | .name = "dvb_usb_cxusb", |
2327 | .probe = cxusb_probe, | 2190 | .probe = cxusb_probe, |
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 3d99e141d566..c53a969bc6be 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c | |||
@@ -3412,7 +3412,7 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap) | |||
3412 | static struct s5h1411_config pinnacle_801e_config = { | 3412 | static struct s5h1411_config pinnacle_801e_config = { |
3413 | .output_mode = S5H1411_PARALLEL_OUTPUT, | 3413 | .output_mode = S5H1411_PARALLEL_OUTPUT, |
3414 | .gpio = S5H1411_GPIO_OFF, | 3414 | .gpio = S5H1411_GPIO_OFF, |
3415 | .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, | 3415 | .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINUOUS_NONINVERTING_CLOCK, |
3416 | .qam_if = S5H1411_IF_44000, | 3416 | .qam_if = S5H1411_IF_44000, |
3417 | .vsb_if = S5H1411_IF_44000, | 3417 | .vsb_if = S5H1411_IF_44000, |
3418 | .inversion = S5H1411_INVERSION_OFF, | 3418 | .inversion = S5H1411_INVERSION_OFF, |
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 4628d73f46f2..8e799ae1df69 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c | |||
@@ -1,25 +1,25 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | * Empiatech em28x1 audio extension | 2 | // |
3 | * | 3 | // Empiatech em28x1 audio extension |
4 | * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> | 4 | // |
5 | * | 5 | // Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> |
6 | * Copyright (C) 2007-2016 Mauro Carvalho Chehab | 6 | // |
7 | * - Port to work with the in-kernel driver | 7 | // Copyright (C) 2007-2016 Mauro Carvalho Chehab |
8 | * - Cleanups, fixes, alsa-controls, etc. | 8 | // - Port to work with the in-kernel driver |
9 | * | 9 | // - Cleanups, fixes, alsa-controls, etc. |
10 | * This driver is based on my previous au600 usb pstn audio driver | 10 | // |
11 | * and inherits all the copyrights | 11 | // This driver is based on my previous au600 usb pstn audio driver |
12 | * | 12 | // and inherits all the copyrights |
13 | * This program is free software; you can redistribute it and/or modify | 13 | // |
14 | * it under the terms of the GNU General Public License as published by | 14 | // This program is free software; you can redistribute it and/or modify |
15 | * the Free Software Foundation; either version 2 of the License, or | 15 | // it under the terms of the GNU General Public License as published by |
16 | * (at your option) any later version. | 16 | // the Free Software Foundation; either version 2 of the License, or |
17 | * | 17 | // (at your option) any later version. |
18 | * This program is distributed in the hope that it will be useful, | 18 | // |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 19 | // This program is distributed in the hope that it will be useful, |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | * GNU General Public License for more details. | 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | */ | 22 | // GNU General Public License for more details. |
23 | 23 | ||
24 | #include "em28xx.h" | 24 | #include "em28xx.h" |
25 | 25 | ||
@@ -103,7 +103,7 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
103 | case -ESHUTDOWN: | 103 | case -ESHUTDOWN: |
104 | return; | 104 | return; |
105 | default: /* error */ | 105 | default: /* error */ |
106 | dprintk("urb completition error %d.\n", urb->status); | 106 | dprintk("urb completion error %d.\n", urb->status); |
107 | break; | 107 | break; |
108 | } | 108 | } |
109 | 109 | ||
@@ -165,12 +165,11 @@ static void em28xx_audio_isocirq(struct urb *urb) | |||
165 | dev_err(&dev->intf->dev, | 165 | dev_err(&dev->intf->dev, |
166 | "resubmit of audio urb failed (error=%i)\n", | 166 | "resubmit of audio urb failed (error=%i)\n", |
167 | status); | 167 | status); |
168 | return; | ||
169 | } | 168 | } |
170 | 169 | ||
171 | static int em28xx_init_audio_isoc(struct em28xx *dev) | 170 | static int em28xx_init_audio_isoc(struct em28xx *dev) |
172 | { | 171 | { |
173 | int i, errCode; | 172 | int i, err; |
174 | 173 | ||
175 | dprintk("Starting isoc transfers\n"); | 174 | dprintk("Starting isoc transfers\n"); |
176 | 175 | ||
@@ -179,16 +178,15 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) | |||
179 | memset(dev->adev.transfer_buffer[i], 0x80, | 178 | memset(dev->adev.transfer_buffer[i], 0x80, |
180 | dev->adev.urb[i]->transfer_buffer_length); | 179 | dev->adev.urb[i]->transfer_buffer_length); |
181 | 180 | ||
182 | errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); | 181 | err = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); |
183 | if (errCode) { | 182 | if (err) { |
184 | dev_err(&dev->intf->dev, | 183 | dev_err(&dev->intf->dev, |
185 | "submit of audio urb failed (error=%i)\n", | 184 | "submit of audio urb failed (error=%i)\n", |
186 | errCode); | 185 | err); |
187 | em28xx_deinit_isoc_audio(dev); | 186 | em28xx_deinit_isoc_audio(dev); |
188 | atomic_set(&dev->adev.stream_started, 0); | 187 | atomic_set(&dev->adev.stream_started, 0); |
189 | return errCode; | 188 | return err; |
190 | } | 189 | } |
191 | |||
192 | } | 190 | } |
193 | 191 | ||
194 | return 0; | 192 | return 0; |
@@ -268,14 +266,17 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | |||
268 | if (nonblock) { | 266 | if (nonblock) { |
269 | if (!mutex_trylock(&dev->lock)) | 267 | if (!mutex_trylock(&dev->lock)) |
270 | return -EAGAIN; | 268 | return -EAGAIN; |
271 | } else | 269 | } else { |
272 | mutex_lock(&dev->lock); | 270 | mutex_lock(&dev->lock); |
271 | } | ||
273 | 272 | ||
274 | runtime->hw = snd_em28xx_hw_capture; | 273 | runtime->hw = snd_em28xx_hw_capture; |
275 | 274 | ||
276 | if (dev->adev.users == 0) { | 275 | if (dev->adev.users == 0) { |
277 | if (dev->alt == 0 || dev->is_audio_only) { | 276 | if (!dev->alt || dev->is_audio_only) { |
278 | struct usb_device *udev = interface_to_usbdev(dev->intf); | 277 | struct usb_device *udev; |
278 | |||
279 | udev = interface_to_usbdev(dev->intf); | ||
279 | 280 | ||
280 | if (dev->is_audio_only) | 281 | if (dev->is_audio_only) |
281 | /* audio is on a separate interface */ | 282 | /* audio is on a separate interface */ |
@@ -367,9 +368,11 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, | |||
367 | if (ret < 0) | 368 | if (ret < 0) |
368 | return ret; | 369 | return ret; |
369 | #if 0 | 370 | #if 0 |
370 | /* TODO: set up em28xx audio chip to deliver the correct audio format, | 371 | /* |
371 | current default is 48000hz multiplexed => 96000hz mono | 372 | * TODO: set up em28xx audio chip to deliver the correct audio format, |
372 | which shouldn't matter since analogue TV only supports mono */ | 373 | * current default is 48000hz multiplexed => 96000hz mono |
374 | * which shouldn't matter since analogue TV only supports mono | ||
375 | */ | ||
373 | unsigned int channels, rate, format; | 376 | unsigned int channels, rate, format; |
374 | 377 | ||
375 | format = params_format(hw_params); | 378 | format = params_format(hw_params); |
@@ -513,8 +516,9 @@ static int em28xx_vol_put(struct snd_kcontrol *kcontrol, | |||
513 | if (nonblock) { | 516 | if (nonblock) { |
514 | if (!mutex_trylock(&dev->lock)) | 517 | if (!mutex_trylock(&dev->lock)) |
515 | return -EAGAIN; | 518 | return -EAGAIN; |
516 | } else | 519 | } else { |
517 | mutex_lock(&dev->lock); | 520 | mutex_lock(&dev->lock); |
521 | } | ||
518 | rc = em28xx_read_ac97(dev, kcontrol->private_value); | 522 | rc = em28xx_read_ac97(dev, kcontrol->private_value); |
519 | if (rc < 0) | 523 | if (rc < 0) |
520 | goto err; | 524 | goto err; |
@@ -551,8 +555,9 @@ static int em28xx_vol_get(struct snd_kcontrol *kcontrol, | |||
551 | if (nonblock) { | 555 | if (nonblock) { |
552 | if (!mutex_trylock(&dev->lock)) | 556 | if (!mutex_trylock(&dev->lock)) |
553 | return -EAGAIN; | 557 | return -EAGAIN; |
554 | } else | 558 | } else { |
555 | mutex_lock(&dev->lock); | 559 | mutex_lock(&dev->lock); |
560 | } | ||
556 | val = em28xx_read_ac97(dev, kcontrol->private_value); | 561 | val = em28xx_read_ac97(dev, kcontrol->private_value); |
557 | mutex_unlock(&dev->lock); | 562 | mutex_unlock(&dev->lock); |
558 | if (val < 0) | 563 | if (val < 0) |
@@ -586,8 +591,9 @@ static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol, | |||
586 | if (nonblock) { | 591 | if (nonblock) { |
587 | if (!mutex_trylock(&dev->lock)) | 592 | if (!mutex_trylock(&dev->lock)) |
588 | return -EAGAIN; | 593 | return -EAGAIN; |
589 | } else | 594 | } else { |
590 | mutex_lock(&dev->lock); | 595 | mutex_lock(&dev->lock); |
596 | } | ||
591 | rc = em28xx_read_ac97(dev, kcontrol->private_value); | 597 | rc = em28xx_read_ac97(dev, kcontrol->private_value); |
592 | if (rc < 0) | 598 | if (rc < 0) |
593 | goto err; | 599 | goto err; |
@@ -627,8 +633,9 @@ static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol, | |||
627 | if (nonblock) { | 633 | if (nonblock) { |
628 | if (!mutex_trylock(&dev->lock)) | 634 | if (!mutex_trylock(&dev->lock)) |
629 | return -EAGAIN; | 635 | return -EAGAIN; |
630 | } else | 636 | } else { |
631 | mutex_lock(&dev->lock); | 637 | mutex_lock(&dev->lock); |
638 | } | ||
632 | val = em28xx_read_ac97(dev, kcontrol->private_value); | 639 | val = em28xx_read_ac97(dev, kcontrol->private_value); |
633 | mutex_unlock(&dev->lock); | 640 | mutex_unlock(&dev->lock); |
634 | if (val < 0) | 641 | if (val < 0) |
@@ -762,7 +769,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) | |||
762 | 769 | ||
763 | if (intf->num_altsetting <= alt) { | 770 | if (intf->num_altsetting <= alt) { |
764 | dev_err(&dev->intf->dev, "alt %d doesn't exist on interface %d\n", | 771 | dev_err(&dev->intf->dev, "alt %d doesn't exist on interface %d\n", |
765 | dev->ifnum, alt); | 772 | dev->ifnum, alt); |
766 | return -ENODEV; | 773 | return -ENODEV; |
767 | } | 774 | } |
768 | 775 | ||
@@ -836,9 +843,8 @@ static int em28xx_audio_urb_init(struct em28xx *dev) | |||
836 | dev->adev.transfer_buffer = kcalloc(num_urb, | 843 | dev->adev.transfer_buffer = kcalloc(num_urb, |
837 | sizeof(*dev->adev.transfer_buffer), | 844 | sizeof(*dev->adev.transfer_buffer), |
838 | GFP_ATOMIC); | 845 | GFP_ATOMIC); |
839 | if (!dev->adev.transfer_buffer) { | 846 | if (!dev->adev.transfer_buffer) |
840 | return -ENOMEM; | 847 | return -ENOMEM; |
841 | } | ||
842 | 848 | ||
843 | dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC); | 849 | dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_ATOMIC); |
844 | if (!dev->adev.urb) { | 850 | if (!dev->adev.urb) { |
@@ -899,9 +905,11 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
899 | int err; | 905 | int err; |
900 | 906 | ||
901 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { | 907 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { |
902 | /* This device does not support the extension (in this case | 908 | /* |
903 | the device is expecting the snd-usb-audio module or | 909 | * This device does not support the extension (in this case |
904 | doesn't have analog audio support at all) */ | 910 | * the device is expecting the snd-usb-audio module or |
911 | * doesn't have analog audio support at all) | ||
912 | */ | ||
905 | return 0; | 913 | return 0; |
906 | } | 914 | } |
907 | 915 | ||
@@ -977,13 +985,15 @@ card_free: | |||
977 | 985 | ||
978 | static int em28xx_audio_fini(struct em28xx *dev) | 986 | static int em28xx_audio_fini(struct em28xx *dev) |
979 | { | 987 | { |
980 | if (dev == NULL) | 988 | if (!dev) |
981 | return 0; | 989 | return 0; |
982 | 990 | ||
983 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { | 991 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) { |
984 | /* This device does not support the extension (in this case | 992 | /* |
985 | the device is expecting the snd-usb-audio module or | 993 | * This device does not support the extension (in this case |
986 | doesn't have analog audio support at all) */ | 994 | * the device is expecting the snd-usb-audio module or |
995 | * doesn't have analog audio support at all) | ||
996 | */ | ||
987 | return 0; | 997 | return 0; |
988 | } | 998 | } |
989 | 999 | ||
@@ -1005,7 +1015,7 @@ static int em28xx_audio_fini(struct em28xx *dev) | |||
1005 | 1015 | ||
1006 | static int em28xx_audio_suspend(struct em28xx *dev) | 1016 | static int em28xx_audio_suspend(struct em28xx *dev) |
1007 | { | 1017 | { |
1008 | if (dev == NULL) | 1018 | if (!dev) |
1009 | return 0; | 1019 | return 0; |
1010 | 1020 | ||
1011 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) | 1021 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) |
@@ -1019,7 +1029,7 @@ static int em28xx_audio_suspend(struct em28xx *dev) | |||
1019 | 1029 | ||
1020 | static int em28xx_audio_resume(struct em28xx *dev) | 1030 | static int em28xx_audio_resume(struct em28xx *dev) |
1021 | { | 1031 | { |
1022 | if (dev == NULL) | 1032 | if (!dev) |
1023 | return 0; | 1033 | return 0; |
1024 | 1034 | ||
1025 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) | 1035 | if (dev->usb_audio_type != EM28XX_USB_AUDIO_VENDOR) |
@@ -1050,7 +1060,7 @@ static void __exit em28xx_alsa_unregister(void) | |||
1050 | em28xx_unregister_extension(&audio_ops); | 1060 | em28xx_unregister_extension(&audio_ops); |
1051 | } | 1061 | } |
1052 | 1062 | ||
1053 | MODULE_LICENSE("GPL"); | 1063 | MODULE_LICENSE("GPL v2"); |
1054 | MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>"); | 1064 | MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>"); |
1055 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | 1065 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
1056 | MODULE_DESCRIPTION(DRIVER_DESC " - audio interface"); | 1066 | MODULE_DESCRIPTION(DRIVER_DESC " - audio interface"); |
diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index ae87dd3e671f..3c2694a16ed1 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c | |||
@@ -1,23 +1,19 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices | 2 | // |
3 | 3 | // em28xx-camera.c - driver for Empia EM25xx/27xx/28xx USB video capture devices | |
4 | Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | // |
5 | Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> | 5 | // Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> |
6 | 6 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> | |
7 | This program is free software; you can redistribute it and/or modify | 7 | // |
8 | it under the terms of the GNU General Public License as published by | 8 | // This program is free software; you can redistribute it and/or modify |
9 | the Free Software Foundation; either version 2 of the License, or | 9 | // it under the terms of the GNU General Public License as published by |
10 | (at your option) any later version. | 10 | // the Free Software Foundation; either version 2 of the License, or |
11 | 11 | // (at your option) any later version. | |
12 | This program is distributed in the hope that it will be useful, | 12 | // |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | // This program is distributed in the hope that it will be useful, |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | GNU General Public License for more details. | 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | 16 | // GNU General Public License for more details. | |
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | 17 | ||
22 | #include "em28xx.h" | 18 | #include "em28xx.h" |
23 | 19 | ||
@@ -49,7 +45,7 @@ static int em28xx_initialize_mt9m111(struct em28xx *dev) | |||
49 | { 0x0d, 0x00, 0x01, }, /* reset and use defaults */ | 45 | { 0x0d, 0x00, 0x01, }, /* reset and use defaults */ |
50 | { 0x0d, 0x00, 0x00, }, | 46 | { 0x0d, 0x00, 0x00, }, |
51 | { 0x0a, 0x00, 0x21, }, | 47 | { 0x0a, 0x00, 0x21, }, |
52 | { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */ | 48 | { 0x21, 0x04, 0x00, }, /* full readout spd, no row/col skip */ |
53 | }; | 49 | }; |
54 | 50 | ||
55 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 51 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
@@ -157,7 +153,8 @@ static int em28xx_probe_sensor_micron(struct em28xx *dev) | |||
157 | break; | 153 | break; |
158 | default: | 154 | default: |
159 | dev_info(&dev->intf->dev, | 155 | dev_info(&dev->intf->dev, |
160 | "unknown Micron sensor detected: 0x%04x\n", id); | 156 | "unknown Micron sensor detected: 0x%04x\n", |
157 | id); | ||
161 | return 0; | 158 | return 0; |
162 | } | 159 | } |
163 | 160 | ||
@@ -186,8 +183,10 @@ static int em28xx_probe_sensor_omnivision(struct em28xx *dev) | |||
186 | struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; | 183 | struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; |
187 | 184 | ||
188 | dev->em28xx_sensor = EM28XX_NOSENSOR; | 185 | dev->em28xx_sensor = EM28XX_NOSENSOR; |
189 | /* NOTE: these devices have the register auto incrementation disabled | 186 | /* |
190 | * by default, so we have to use single byte reads ! */ | 187 | * NOTE: these devices have the register auto incrementation disabled |
188 | * by default, so we have to use single byte reads ! | ||
189 | */ | ||
191 | for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) { | 190 | for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) { |
192 | client->addr = omnivision_sensor_addrs[i]; | 191 | client->addr = omnivision_sensor_addrs[i]; |
193 | /* Read manufacturer ID from registers 0x1c-0x1d (BE) */ | 192 | /* Read manufacturer ID from registers 0x1c-0x1d (BE) */ |
@@ -397,7 +396,7 @@ int em28xx_init_camera(struct em28xx *dev) | |||
397 | subdev = | 396 | subdev = |
398 | v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, | 397 | v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, |
399 | &ov2640_info, NULL); | 398 | &ov2640_info, NULL); |
400 | if (subdev == NULL) | 399 | if (!subdev) |
401 | return -ENODEV; | 400 | return -ENODEV; |
402 | 401 | ||
403 | format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; | 402 | format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; |
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 34e16f6ab4ac..6e0e67d23876 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
@@ -1,27 +1,23 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB | 2 | // |
3 | video capture devices | 3 | // em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB |
4 | 4 | // video capture devices | |
5 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 5 | // |
6 | Markus Rechberger <mrechberger@gmail.com> | 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
7 | Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | // Markus Rechberger <mrechberger@gmail.com> |
8 | Sascha Sommer <saschasommer@freenet.de> | 8 | // Mauro Carvalho Chehab <mchehab@infradead.org> |
9 | Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 9 | // Sascha Sommer <saschasommer@freenet.de> |
10 | 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | |
11 | This program is free software; you can redistribute it and/or modify | 11 | // |
12 | it under the terms of the GNU General Public License as published by | 12 | // This program is free software; you can redistribute it and/or modify |
13 | the Free Software Foundation; either version 2 of the License, or | 13 | // it under the terms of the GNU General Public License as published by |
14 | (at your option) any later version. | 14 | // the Free Software Foundation; either version 2 of the License, or |
15 | 15 | // (at your option) any later version. | |
16 | This program is distributed in the hope that it will be useful, | 16 | // |
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | // This program is distributed in the hope that it will be useful, |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | GNU General Public License for more details. | 19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | 20 | // GNU General Public License for more details. | |
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | 21 | ||
26 | #include "em28xx.h" | 22 | #include "em28xx.h" |
27 | 23 | ||
@@ -40,7 +36,6 @@ | |||
40 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
41 | #include <sound/ac97_codec.h> | 37 | #include <sound/ac97_codec.h> |
42 | 38 | ||
43 | |||
44 | #define DRIVER_NAME "em28xx" | 39 | #define DRIVER_NAME "em28xx" |
45 | 40 | ||
46 | static int tuner = -1; | 41 | static int tuner = -1; |
@@ -81,26 +76,26 @@ static void em28xx_pre_card_setup(struct em28xx *dev); | |||
81 | */ | 76 | */ |
82 | 77 | ||
83 | /* Reset for the most [analog] boards */ | 78 | /* Reset for the most [analog] boards */ |
84 | static struct em28xx_reg_seq default_analog[] = { | 79 | static const struct em28xx_reg_seq default_analog[] = { |
85 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 80 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
86 | { -1, -1, -1, -1}, | 81 | { -1, -1, -1, -1}, |
87 | }; | 82 | }; |
88 | 83 | ||
89 | /* Reset for the most [digital] boards */ | 84 | /* Reset for the most [digital] boards */ |
90 | static struct em28xx_reg_seq default_digital[] = { | 85 | static const struct em28xx_reg_seq default_digital[] = { |
91 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 86 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
92 | { -1, -1, -1, -1}, | 87 | { -1, -1, -1, -1}, |
93 | }; | 88 | }; |
94 | 89 | ||
95 | /* Board Hauppauge WinTV HVR 900 analog */ | 90 | /* Board Hauppauge WinTV HVR 900 analog */ |
96 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | 91 | static const struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { |
97 | {EM2820_R08_GPIO_CTRL, 0x2d, ~EM_GPIO_4, 10}, | 92 | {EM2820_R08_GPIO_CTRL, 0x2d, ~EM_GPIO_4, 10}, |
98 | { 0x05, 0xff, 0x10, 10}, | 93 | { 0x05, 0xff, 0x10, 10}, |
99 | { -1, -1, -1, -1}, | 94 | { -1, -1, -1, -1}, |
100 | }; | 95 | }; |
101 | 96 | ||
102 | /* Board Hauppauge WinTV HVR 900 digital */ | 97 | /* Board Hauppauge WinTV HVR 900 digital */ |
103 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | 98 | static const struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { |
104 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, | 99 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, |
105 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | 100 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, |
106 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | 101 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, |
@@ -108,25 +103,20 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | |||
108 | }; | 103 | }; |
109 | 104 | ||
110 | /* Board Hauppauge WinTV HVR 900 (R2) digital */ | 105 | /* Board Hauppauge WinTV HVR 900 (R2) digital */ |
111 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { | 106 | static const struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { |
112 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, | 107 | {EM2820_R08_GPIO_CTRL, 0x2e, ~EM_GPIO_4, 10}, |
113 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | 108 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, |
114 | { -1, -1, -1, -1}, | 109 | { -1, -1, -1, -1}, |
115 | }; | 110 | }; |
116 | 111 | ||
117 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | 112 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ |
118 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | 113 | static const struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { |
119 | {EM2820_R08_GPIO_CTRL, 0x69, ~EM_GPIO_4, 10}, | 114 | {EM2820_R08_GPIO_CTRL, 0x69, ~EM_GPIO_4, 10}, |
120 | { -1, -1, -1, -1}, | 115 | { -1, -1, -1, -1}, |
121 | }; | 116 | }; |
122 | 117 | ||
123 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
124 | |||
125 | /* Board - EM2870 Kworld 355u | ||
126 | Analog - No input analog */ | ||
127 | |||
128 | /* Board - EM2882 Kworld 315U digital */ | 118 | /* Board - EM2882 Kworld 315U digital */ |
129 | static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | 119 | static const struct em28xx_reg_seq em2882_kworld_315u_digital[] = { |
130 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, | 120 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, |
131 | {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, | 121 | {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, |
132 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | 122 | {EM2880_R04_GPO, 0x04, 0xff, 10}, |
@@ -135,7 +125,7 @@ static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | |||
135 | { -1, -1, -1, -1}, | 125 | { -1, -1, -1, -1}, |
136 | }; | 126 | }; |
137 | 127 | ||
138 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | 128 | static const struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { |
139 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 129 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
140 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | 130 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, |
141 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 131 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
@@ -143,30 +133,31 @@ static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | |||
143 | { -1, -1, -1, -1}, | 133 | { -1, -1, -1, -1}, |
144 | }; | 134 | }; |
145 | 135 | ||
146 | static struct em28xx_reg_seq kworld_330u_analog[] = { | 136 | static const struct em28xx_reg_seq kworld_330u_analog[] = { |
147 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 137 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
148 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | 138 | {EM2880_R04_GPO, 0x00, 0xff, 10}, |
149 | { -1, -1, -1, -1}, | 139 | { -1, -1, -1, -1}, |
150 | }; | 140 | }; |
151 | 141 | ||
152 | static struct em28xx_reg_seq kworld_330u_digital[] = { | 142 | static const struct em28xx_reg_seq kworld_330u_digital[] = { |
153 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 143 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
154 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 144 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
155 | { -1, -1, -1, -1}, | 145 | { -1, -1, -1, -1}, |
156 | }; | 146 | }; |
157 | 147 | ||
158 | /* Evga inDtube | 148 | /* |
159 | GPIO0 - Enable digital power (s5h1409) - low to enable | 149 | * Evga inDtube |
160 | GPIO1 - Enable analog power (tvp5150/emp202) - low to enable | 150 | * GPIO0 - Enable digital power (s5h1409) - low to enable |
161 | GPIO4 - xc3028 reset | 151 | * GPIO1 - Enable analog power (tvp5150/emp202) - low to enable |
162 | GOP3 - s5h1409 reset | 152 | * GPIO4 - xc3028 reset |
153 | * GOP3 - s5h1409 reset | ||
163 | */ | 154 | */ |
164 | static struct em28xx_reg_seq evga_indtube_analog[] = { | 155 | static const struct em28xx_reg_seq evga_indtube_analog[] = { |
165 | {EM2820_R08_GPIO_CTRL, 0x79, 0xff, 60}, | 156 | {EM2820_R08_GPIO_CTRL, 0x79, 0xff, 60}, |
166 | { -1, -1, -1, -1}, | 157 | { -1, -1, -1, -1}, |
167 | }; | 158 | }; |
168 | 159 | ||
169 | static struct em28xx_reg_seq evga_indtube_digital[] = { | 160 | static const struct em28xx_reg_seq evga_indtube_digital[] = { |
170 | {EM2820_R08_GPIO_CTRL, 0x7a, 0xff, 1}, | 161 | {EM2820_R08_GPIO_CTRL, 0x7a, 0xff, 1}, |
171 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | 162 | {EM2880_R04_GPO, 0x04, 0xff, 10}, |
172 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | 163 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, |
@@ -184,12 +175,12 @@ static struct em28xx_reg_seq evga_indtube_digital[] = { | |||
184 | * EM_GPIO_6 - currently unknown | 175 | * EM_GPIO_6 - currently unknown |
185 | * EM_GPIO_7 - currently unknown | 176 | * EM_GPIO_7 - currently unknown |
186 | */ | 177 | */ |
187 | static struct em28xx_reg_seq kworld_a340_digital[] = { | 178 | static const struct em28xx_reg_seq kworld_a340_digital[] = { |
188 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 179 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
189 | { -1, -1, -1, -1}, | 180 | { -1, -1, -1, -1}, |
190 | }; | 181 | }; |
191 | 182 | ||
192 | static struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { | 183 | static const struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { |
193 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, | 184 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, |
194 | {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 100}, | 185 | {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 100}, |
195 | {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 100}, | 186 | {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 100}, |
@@ -198,45 +189,49 @@ static struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { | |||
198 | }; | 189 | }; |
199 | 190 | ||
200 | /* Pinnacle Hybrid Pro eb1a:2881 */ | 191 | /* Pinnacle Hybrid Pro eb1a:2881 */ |
201 | static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { | 192 | static const struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { |
202 | {EM2820_R08_GPIO_CTRL, 0xfd, ~EM_GPIO_4, 10}, | 193 | {EM2820_R08_GPIO_CTRL, 0xfd, ~EM_GPIO_4, 10}, |
203 | { -1, -1, -1, -1}, | 194 | { -1, -1, -1, -1}, |
204 | }; | 195 | }; |
205 | 196 | ||
206 | static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | 197 | static const struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { |
207 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 198 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
208 | {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ | 199 | {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ |
209 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | 200 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, |
210 | { -1, -1, -1, -1}, | 201 | { -1, -1, -1, -1}, |
211 | }; | 202 | }; |
212 | 203 | ||
213 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { | 204 | static const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { |
214 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, | 205 | {EM2820_R08_GPIO_CTRL, 0x6d, ~EM_GPIO_4, 10}, |
215 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | 206 | {EM2880_R04_GPO, 0x00, 0xff, 10}, |
216 | { -1, -1, -1, -1}, | 207 | { -1, -1, -1, -1}, |
217 | }; | 208 | }; |
218 | 209 | ||
219 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { | 210 | static const struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { |
220 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 211 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
221 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 212 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
222 | { -1, -1, -1, -1}, | 213 | { -1, -1, -1, -1}, |
223 | }; | 214 | }; |
224 | 215 | ||
225 | /* PCTV HD Mini (80e) GPIOs | 216 | /* |
226 | 0-5: not used | 217 | * PCTV HD Mini (80e) GPIOs |
227 | 6: demod reset, active low | 218 | * 0-5: not used |
228 | 7: LED on, active high */ | 219 | * 6: demod reset, active low |
229 | static struct em28xx_reg_seq em2874_pctv_80e_digital[] = { | 220 | * 7: LED on, active high |
221 | */ | ||
222 | static const struct em28xx_reg_seq em2874_pctv_80e_digital[] = { | ||
230 | {EM28XX_R06_I2C_CLK, 0x45, 0xff, 10}, /*400 KHz*/ | 223 | {EM28XX_R06_I2C_CLK, 0x45, 0xff, 10}, /*400 KHz*/ |
231 | {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 100},/*Demod reset*/ | 224 | {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 100},/*Demod reset*/ |
232 | {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 10}, | 225 | {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 10}, |
233 | { -1, -1, -1, -1}, | 226 | { -1, -1, -1, -1}, |
234 | }; | 227 | }; |
235 | 228 | ||
236 | /* eb1a:2868 Reddo DVB-C USB TV Box | 229 | /* |
237 | GPIO4 - CU1216L NIM | 230 | * eb1a:2868 Reddo DVB-C USB TV Box |
238 | Other GPIOs seems to be don't care. */ | 231 | * GPIO4 - CU1216L NIM |
239 | static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { | 232 | * Other GPIOs seems to be don't care. |
233 | */ | ||
234 | static const struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { | ||
240 | {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, | 235 | {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, |
241 | {EM2820_R08_GPIO_CTRL, 0xde, 0xff, 10}, | 236 | {EM2820_R08_GPIO_CTRL, 0xde, 0xff, 10}, |
242 | {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, | 237 | {EM2820_R08_GPIO_CTRL, 0xfe, 0xff, 10}, |
@@ -248,7 +243,7 @@ static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { | |||
248 | }; | 243 | }; |
249 | 244 | ||
250 | /* Callback for the most boards */ | 245 | /* Callback for the most boards */ |
251 | static struct em28xx_reg_seq default_tuner_gpio[] = { | 246 | static const struct em28xx_reg_seq default_tuner_gpio[] = { |
252 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, | 247 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, |
253 | {EM2820_R08_GPIO_CTRL, 0, EM_GPIO_4, 10}, | 248 | {EM2820_R08_GPIO_CTRL, 0, EM_GPIO_4, 10}, |
254 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, | 249 | {EM2820_R08_GPIO_CTRL, EM_GPIO_4, EM_GPIO_4, 10}, |
@@ -256,69 +251,70 @@ static struct em28xx_reg_seq default_tuner_gpio[] = { | |||
256 | }; | 251 | }; |
257 | 252 | ||
258 | /* Mute/unmute */ | 253 | /* Mute/unmute */ |
259 | static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { | 254 | static const struct em28xx_reg_seq compro_unmute_tv_gpio[] = { |
260 | {EM2820_R08_GPIO_CTRL, 5, 7, 10}, | 255 | {EM2820_R08_GPIO_CTRL, 5, 7, 10}, |
261 | { -1, -1, -1, -1}, | 256 | { -1, -1, -1, -1}, |
262 | }; | 257 | }; |
263 | 258 | ||
264 | static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { | 259 | static const struct em28xx_reg_seq compro_unmute_svid_gpio[] = { |
265 | {EM2820_R08_GPIO_CTRL, 4, 7, 10}, | 260 | {EM2820_R08_GPIO_CTRL, 4, 7, 10}, |
266 | { -1, -1, -1, -1}, | 261 | { -1, -1, -1, -1}, |
267 | }; | 262 | }; |
268 | 263 | ||
269 | static struct em28xx_reg_seq compro_mute_gpio[] = { | 264 | static const struct em28xx_reg_seq compro_mute_gpio[] = { |
270 | {EM2820_R08_GPIO_CTRL, 6, 7, 10}, | 265 | {EM2820_R08_GPIO_CTRL, 6, 7, 10}, |
271 | { -1, -1, -1, -1}, | 266 | { -1, -1, -1, -1}, |
272 | }; | 267 | }; |
273 | 268 | ||
274 | /* Terratec AV350 */ | 269 | /* Terratec AV350 */ |
275 | static struct em28xx_reg_seq terratec_av350_mute_gpio[] = { | 270 | static const struct em28xx_reg_seq terratec_av350_mute_gpio[] = { |
276 | {EM2820_R08_GPIO_CTRL, 0xff, 0x7f, 10}, | 271 | {EM2820_R08_GPIO_CTRL, 0xff, 0x7f, 10}, |
277 | { -1, -1, -1, -1}, | 272 | { -1, -1, -1, -1}, |
278 | }; | 273 | }; |
279 | 274 | ||
280 | static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { | 275 | static const struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { |
281 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, | 276 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, |
282 | { -1, -1, -1, -1}, | 277 | { -1, -1, -1, -1}, |
283 | }; | 278 | }; |
284 | 279 | ||
285 | static struct em28xx_reg_seq silvercrest_reg_seq[] = { | 280 | static const struct em28xx_reg_seq silvercrest_reg_seq[] = { |
286 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, | 281 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, |
287 | {EM2820_R08_GPIO_CTRL, 0x01, 0xf7, 10}, | 282 | {EM2820_R08_GPIO_CTRL, 0x01, 0xf7, 10}, |
288 | { -1, -1, -1, -1}, | 283 | { -1, -1, -1, -1}, |
289 | }; | 284 | }; |
290 | 285 | ||
291 | static struct em28xx_reg_seq vc211a_enable[] = { | 286 | static const struct em28xx_reg_seq vc211a_enable[] = { |
292 | {EM2820_R08_GPIO_CTRL, 0xff, 0x07, 10}, | 287 | {EM2820_R08_GPIO_CTRL, 0xff, 0x07, 10}, |
293 | {EM2820_R08_GPIO_CTRL, 0xff, 0x0f, 10}, | 288 | {EM2820_R08_GPIO_CTRL, 0xff, 0x0f, 10}, |
294 | {EM2820_R08_GPIO_CTRL, 0xff, 0x0b, 10}, | 289 | {EM2820_R08_GPIO_CTRL, 0xff, 0x0b, 10}, |
295 | { -1, -1, -1, -1}, | 290 | { -1, -1, -1, -1}, |
296 | }; | 291 | }; |
297 | 292 | ||
298 | static struct em28xx_reg_seq dikom_dk300_digital[] = { | 293 | static const struct em28xx_reg_seq dikom_dk300_digital[] = { |
299 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, | 294 | {EM2820_R08_GPIO_CTRL, 0x6e, ~EM_GPIO_4, 10}, |
300 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | 295 | {EM2880_R04_GPO, 0x08, 0xff, 10}, |
301 | { -1, -1, -1, -1}, | 296 | { -1, -1, -1, -1}, |
302 | }; | 297 | }; |
303 | 298 | ||
304 | /* Reset for the most [digital] boards */ | 299 | /* Reset for the most [digital] boards */ |
305 | static struct em28xx_reg_seq leadership_digital[] = { | 300 | static const struct em28xx_reg_seq leadership_digital[] = { |
306 | {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10}, | 301 | {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10}, |
307 | { -1, -1, -1, -1}, | 302 | { -1, -1, -1, -1}, |
308 | }; | 303 | }; |
309 | 304 | ||
310 | static struct em28xx_reg_seq leadership_reset[] = { | 305 | static const struct em28xx_reg_seq leadership_reset[] = { |
311 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, | 306 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, |
312 | {EM2874_R80_GPIO_P0_CTRL, 0xb0, 0xff, 10}, | 307 | {EM2874_R80_GPIO_P0_CTRL, 0xb0, 0xff, 10}, |
313 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, | 308 | {EM2874_R80_GPIO_P0_CTRL, 0xf0, 0xff, 10}, |
314 | { -1, -1, -1, -1}, | 309 | { -1, -1, -1, -1}, |
315 | }; | 310 | }; |
316 | 311 | ||
317 | /* 2013:024f PCTV nanoStick T2 290e | 312 | /* |
313 | * 2013:024f PCTV nanoStick T2 290e | ||
318 | * GPIO_6 - demod reset | 314 | * GPIO_6 - demod reset |
319 | * GPIO_7 - LED | 315 | * GPIO_7 - LED |
320 | */ | 316 | */ |
321 | static struct em28xx_reg_seq pctv_290e[] = { | 317 | static const struct em28xx_reg_seq pctv_290e[] = { |
322 | {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 80}, | 318 | {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 80}, |
323 | {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ | 319 | {EM2874_R80_GPIO_P0_CTRL, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ |
324 | {EM2874_R80_GPIO_P0_CTRL, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ | 320 | {EM2874_R80_GPIO_P0_CTRL, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ |
@@ -326,7 +322,7 @@ static struct em28xx_reg_seq pctv_290e[] = { | |||
326 | }; | 322 | }; |
327 | 323 | ||
328 | #if 0 | 324 | #if 0 |
329 | static struct em28xx_reg_seq terratec_h5_gpio[] = { | 325 | static const struct em28xx_reg_seq terratec_h5_gpio[] = { |
330 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, | 326 | {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, |
331 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, | 327 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, |
332 | {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, | 328 | {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, |
@@ -334,7 +330,7 @@ static struct em28xx_reg_seq terratec_h5_gpio[] = { | |||
334 | { -1, -1, -1, -1}, | 330 | { -1, -1, -1, -1}, |
335 | }; | 331 | }; |
336 | 332 | ||
337 | static struct em28xx_reg_seq terratec_h5_digital[] = { | 333 | static const struct em28xx_reg_seq terratec_h5_digital[] = { |
338 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, | 334 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, |
339 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 335 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
340 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, | 336 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, |
@@ -342,7 +338,8 @@ static struct em28xx_reg_seq terratec_h5_digital[] = { | |||
342 | }; | 338 | }; |
343 | #endif | 339 | #endif |
344 | 340 | ||
345 | /* 2013:024f PCTV DVB-S2 Stick 460e | 341 | /* |
342 | * 2013:024f PCTV DVB-S2 Stick 460e | ||
346 | * GPIO_0 - POWER_ON | 343 | * GPIO_0 - POWER_ON |
347 | * GPIO_1 - BOOST | 344 | * GPIO_1 - BOOST |
348 | * GPIO_2 - VUV_LNB (red LED) | 345 | * GPIO_2 - VUV_LNB (red LED) |
@@ -352,7 +349,7 @@ static struct em28xx_reg_seq terratec_h5_digital[] = { | |||
352 | * GPIO_6 - RESET_DEM | 349 | * GPIO_6 - RESET_DEM |
353 | * GPIO_7 - LED (green LED) | 350 | * GPIO_7 - LED (green LED) |
354 | */ | 351 | */ |
355 | static struct em28xx_reg_seq pctv_460e[] = { | 352 | static const struct em28xx_reg_seq pctv_460e[] = { |
356 | {EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff, 50}, | 353 | {EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff, 50}, |
357 | { 0x0d, 0xff, 0xff, 50}, | 354 | { 0x0d, 0xff, 0xff, 50}, |
358 | {EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff, 50}, /* GPIO_6=1 */ | 355 | {EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff, 50}, /* GPIO_6=1 */ |
@@ -361,7 +358,7 @@ static struct em28xx_reg_seq pctv_460e[] = { | |||
361 | { -1, -1, -1, -1}, | 358 | { -1, -1, -1, -1}, |
362 | }; | 359 | }; |
363 | 360 | ||
364 | static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { | 361 | static const struct em28xx_reg_seq c3tech_digital_duo_digital[] = { |
365 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 10}, | 362 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 10}, |
366 | {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 10}, /* xc5000 reset */ | 363 | {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 10}, /* xc5000 reset */ |
367 | {EM2874_R80_GPIO_P0_CTRL, 0xf9, 0xff, 35}, | 364 | {EM2874_R80_GPIO_P0_CTRL, 0xf9, 0xff, 35}, |
@@ -384,7 +381,7 @@ static struct em28xx_reg_seq c3tech_digital_duo_digital[] = { | |||
384 | * GPIO 6 = #RESET_DEM | 381 | * GPIO 6 = #RESET_DEM |
385 | * GPIO 7 = P07_LED (green LED) | 382 | * GPIO 7 = P07_LED (green LED) |
386 | */ | 383 | */ |
387 | static struct em28xx_reg_seq pctv_461e[] = { | 384 | static const struct em28xx_reg_seq pctv_461e[] = { |
388 | {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff, 0}, | 385 | {EM2874_R80_GPIO_P0_CTRL, 0x7f, 0xff, 0}, |
389 | {0x0d, 0xff, 0xff, 0}, | 386 | {0x0d, 0xff, 0xff, 0}, |
390 | {EM2874_R80_GPIO_P0_CTRL, 0x3f, 0xff, 100}, /* reset demod */ | 387 | {EM2874_R80_GPIO_P0_CTRL, 0x3f, 0xff, 100}, /* reset demod */ |
@@ -396,7 +393,7 @@ static struct em28xx_reg_seq pctv_461e[] = { | |||
396 | }; | 393 | }; |
397 | 394 | ||
398 | #if 0 | 395 | #if 0 |
399 | static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | 396 | static const struct em28xx_reg_seq hauppauge_930c_gpio[] = { |
400 | {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, | 397 | {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, |
401 | {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, /* xc5000 reset */ | 398 | {EM2874_R80_GPIO_P0_CTRL, 0x4f, 0xff, 10}, /* xc5000 reset */ |
402 | {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, | 399 | {EM2874_R80_GPIO_P0_CTRL, 0x6f, 0xff, 10}, |
@@ -404,7 +401,7 @@ static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | |||
404 | { -1, -1, -1, -1}, | 401 | { -1, -1, -1, -1}, |
405 | }; | 402 | }; |
406 | 403 | ||
407 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { | 404 | static const struct em28xx_reg_seq hauppauge_930c_digital[] = { |
408 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, | 405 | {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 10}, |
409 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, | 406 | {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, |
410 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, | 407 | {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 10}, |
@@ -412,38 +409,41 @@ static struct em28xx_reg_seq hauppauge_930c_digital[] = { | |||
412 | }; | 409 | }; |
413 | #endif | 410 | #endif |
414 | 411 | ||
415 | /* 1b80:e425 MaxMedia UB425-TC | 412 | /* |
413 | * 1b80:e425 MaxMedia UB425-TC | ||
416 | * 1b80:e1cc Delock 61959 | 414 | * 1b80:e1cc Delock 61959 |
417 | * GPIO_6 - demod reset, 0=active | 415 | * GPIO_6 - demod reset, 0=active |
418 | * GPIO_7 - LED, 0=active | 416 | * GPIO_7 - LED, 0=active |
419 | */ | 417 | */ |
420 | static struct em28xx_reg_seq maxmedia_ub425_tc[] = { | 418 | static const struct em28xx_reg_seq maxmedia_ub425_tc[] = { |
421 | {EM2874_R80_GPIO_P0_CTRL, 0x83, 0xff, 100}, | 419 | {EM2874_R80_GPIO_P0_CTRL, 0x83, 0xff, 100}, |
422 | {EM2874_R80_GPIO_P0_CTRL, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ | 420 | {EM2874_R80_GPIO_P0_CTRL, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ |
423 | {EM2874_R80_GPIO_P0_CTRL, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ | 421 | {EM2874_R80_GPIO_P0_CTRL, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ |
424 | { -1, -1, -1, -1}, | 422 | { -1, -1, -1, -1}, |
425 | }; | 423 | }; |
426 | 424 | ||
427 | /* 2304:0242 PCTV QuatroStick (510e) | 425 | /* |
426 | * 2304:0242 PCTV QuatroStick (510e) | ||
428 | * GPIO_2: decoder reset, 0=active | 427 | * GPIO_2: decoder reset, 0=active |
429 | * GPIO_4: decoder suspend, 0=active | 428 | * GPIO_4: decoder suspend, 0=active |
430 | * GPIO_6: demod reset, 0=active | 429 | * GPIO_6: demod reset, 0=active |
431 | * GPIO_7: LED, 1=active | 430 | * GPIO_7: LED, 1=active |
432 | */ | 431 | */ |
433 | static struct em28xx_reg_seq pctv_510e[] = { | 432 | static const struct em28xx_reg_seq pctv_510e[] = { |
434 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, | 433 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, |
435 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | 434 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ |
436 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | 435 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ |
437 | { -1, -1, -1, -1}, | 436 | { -1, -1, -1, -1}, |
438 | }; | 437 | }; |
439 | 438 | ||
440 | /* 2013:0251 PCTV QuatroStick nano (520e) | 439 | /* |
440 | * 2013:0251 PCTV QuatroStick nano (520e) | ||
441 | * GPIO_2: decoder reset, 0=active | 441 | * GPIO_2: decoder reset, 0=active |
442 | * GPIO_4: decoder suspend, 0=active | 442 | * GPIO_4: decoder suspend, 0=active |
443 | * GPIO_6: demod reset, 0=active | 443 | * GPIO_6: demod reset, 0=active |
444 | * GPIO_7: LED, 1=active | 444 | * GPIO_7: LED, 1=active |
445 | */ | 445 | */ |
446 | static struct em28xx_reg_seq pctv_520e[] = { | 446 | static const struct em28xx_reg_seq pctv_520e[] = { |
447 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, | 447 | {EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100}, |
448 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | 448 | {EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ |
449 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | 449 | {EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ |
@@ -451,7 +451,8 @@ static struct em28xx_reg_seq pctv_520e[] = { | |||
451 | { -1, -1, -1, -1}, | 451 | { -1, -1, -1, -1}, |
452 | }; | 452 | }; |
453 | 453 | ||
454 | /* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam | 454 | /* |
455 | * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam | ||
455 | * reg 0x80/0x84: | 456 | * reg 0x80/0x84: |
456 | * GPIO_0: capturing LED, 0=on, 1=off | 457 | * GPIO_0: capturing LED, 0=on, 1=off |
457 | * GPIO_2: AV mute button, 0=pressed, 1=unpressed | 458 | * GPIO_2: AV mute button, 0=pressed, 1=unpressed |
@@ -460,13 +461,13 @@ static struct em28xx_reg_seq pctv_520e[] = { | |||
460 | * reg 0x81/0x85: | 461 | * reg 0x81/0x85: |
461 | * GPIO_7: snapshot button, 0=pressed, 1=unpressed | 462 | * GPIO_7: snapshot button, 0=pressed, 1=unpressed |
462 | */ | 463 | */ |
463 | static struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = { | 464 | static const struct em28xx_reg_seq speedlink_vad_laplace_reg_seq[] = { |
464 | {EM2820_R08_GPIO_CTRL, 0xf7, 0xff, 10}, | 465 | {EM2820_R08_GPIO_CTRL, 0xf7, 0xff, 10}, |
465 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xb2, 10}, | 466 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xb2, 10}, |
466 | { -1, -1, -1, -1}, | 467 | { -1, -1, -1, -1}, |
467 | }; | 468 | }; |
468 | 469 | ||
469 | static struct em28xx_reg_seq pctv_292e[] = { | 470 | static const struct em28xx_reg_seq pctv_292e[] = { |
470 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, | 471 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, |
471 | {0x0d, 0xff, 0xff, 950}, | 472 | {0x0d, 0xff, 0xff, 950}, |
472 | {EM2874_R80_GPIO_P0_CTRL, 0xbd, 0xff, 100}, | 473 | {EM2874_R80_GPIO_P0_CTRL, 0xbd, 0xff, 100}, |
@@ -478,7 +479,7 @@ static struct em28xx_reg_seq pctv_292e[] = { | |||
478 | {-1, -1, -1, -1}, | 479 | {-1, -1, -1, -1}, |
479 | }; | 480 | }; |
480 | 481 | ||
481 | static struct em28xx_reg_seq terratec_t2_stick_hd[] = { | 482 | static const struct em28xx_reg_seq terratec_t2_stick_hd[] = { |
482 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, | 483 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, |
483 | {0x0d, 0xff, 0xff, 600}, | 484 | {0x0d, 0xff, 0xff, 600}, |
484 | {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 10}, | 485 | {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 10}, |
@@ -492,7 +493,7 @@ static struct em28xx_reg_seq terratec_t2_stick_hd[] = { | |||
492 | {-1, -1, -1, -1}, | 493 | {-1, -1, -1, -1}, |
493 | }; | 494 | }; |
494 | 495 | ||
495 | static struct em28xx_reg_seq plex_px_bcud[] = { | 496 | static const struct em28xx_reg_seq plex_px_bcud[] = { |
496 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, | 497 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, |
497 | {0x0d, 0xff, 0xff, 0}, | 498 | {0x0d, 0xff, 0xff, 0}, |
498 | {EM2874_R50_IR_CONFIG, 0x01, 0xff, 0}, | 499 | {EM2874_R50_IR_CONFIG, 0x01, 0xff, 0}, |
@@ -507,8 +508,10 @@ static struct em28xx_reg_seq plex_px_bcud[] = { | |||
507 | }; | 508 | }; |
508 | 509 | ||
509 | /* | 510 | /* |
510 | * 2040:0265 Hauppauge WinTV-dualHD DVB | 511 | * 2040:0265 Hauppauge WinTV-dualHD DVB Isoc |
511 | * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM | 512 | * 2040:8265 Hauppauge WinTV-dualHD DVB Bulk |
513 | * 2040:026d Hauppauge WinTV-dualHD ATSC/QAM Isoc | ||
514 | * 2040:826d Hauppauge WinTV-dualHD ATSC/QAM Bulk | ||
512 | * reg 0x80/0x84: | 515 | * reg 0x80/0x84: |
513 | * GPIO_0: Yellow LED tuner 1, 0=on, 1=off | 516 | * GPIO_0: Yellow LED tuner 1, 0=on, 1=off |
514 | * GPIO_1: Green LED tuner 1, 0=on, 1=off | 517 | * GPIO_1: Green LED tuner 1, 0=on, 1=off |
@@ -517,7 +520,7 @@ static struct em28xx_reg_seq plex_px_bcud[] = { | |||
517 | * GPIO_5: Reset #2, 0=active | 520 | * GPIO_5: Reset #2, 0=active |
518 | * GPIO_6: Reset #1, 0=active | 521 | * GPIO_6: Reset #1, 0=active |
519 | */ | 522 | */ |
520 | static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { | 523 | static const struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { |
521 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, | 524 | {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, |
522 | {0x0d, 0xff, 0xff, 200}, | 525 | {0x0d, 0xff, 0xff, 200}, |
523 | {0x50, 0x04, 0xff, 300}, | 526 | {0x50, 0x04, 0xff, 300}, |
@@ -534,7 +537,7 @@ static struct em28xx_reg_seq hauppauge_dualhd_dvb[] = { | |||
534 | /* | 537 | /* |
535 | * Button definitions | 538 | * Button definitions |
536 | */ | 539 | */ |
537 | static struct em28xx_button std_snapshot_button[] = { | 540 | static const struct em28xx_button std_snapshot_button[] = { |
538 | { | 541 | { |
539 | .role = EM28XX_BUTTON_SNAPSHOT, | 542 | .role = EM28XX_BUTTON_SNAPSHOT, |
540 | .reg_r = EM28XX_R0C_USBSUSP, | 543 | .reg_r = EM28XX_R0C_USBSUSP, |
@@ -545,7 +548,7 @@ static struct em28xx_button std_snapshot_button[] = { | |||
545 | {-1, 0, 0, 0, 0}, | 548 | {-1, 0, 0, 0, 0}, |
546 | }; | 549 | }; |
547 | 550 | ||
548 | static struct em28xx_button speedlink_vad_laplace_buttons[] = { | 551 | static const struct em28xx_button speedlink_vad_laplace_buttons[] = { |
549 | { | 552 | { |
550 | .role = EM28XX_BUTTON_SNAPSHOT, | 553 | .role = EM28XX_BUTTON_SNAPSHOT, |
551 | .reg_r = EM2874_R85_GPIO_P1_STATE, | 554 | .reg_r = EM2874_R85_GPIO_P1_STATE, |
@@ -629,7 +632,7 @@ static struct em28xx_led hauppauge_dualhd_leds[] = { | |||
629 | /* | 632 | /* |
630 | * Board definitions | 633 | * Board definitions |
631 | */ | 634 | */ |
632 | struct em28xx_board em28xx_boards[] = { | 635 | const struct em28xx_board em28xx_boards[] = { |
633 | [EM2750_BOARD_UNKNOWN] = { | 636 | [EM2750_BOARD_UNKNOWN] = { |
634 | .name = "EM2710/EM2750/EM2751 webcam grabber", | 637 | .name = "EM2710/EM2750/EM2751 webcam grabber", |
635 | .xclk = EM28XX_XCLK_FREQUENCY_20MHZ, | 638 | .xclk = EM28XX_XCLK_FREQUENCY_20MHZ, |
@@ -1436,9 +1439,11 @@ struct em28xx_board em28xx_boards[] = { | |||
1436 | .gpio = default_analog, | 1439 | .gpio = default_analog, |
1437 | } }, | 1440 | } }, |
1438 | }, | 1441 | }, |
1439 | /* maybe there's a reason behind it why Terratec sells the Hybrid XS | 1442 | /* |
1440 | as Prodigy XS with a different PID, let's keep it separated for now | 1443 | * maybe there's a reason behind it why Terratec sells the Hybrid XS |
1441 | maybe we'll need it lateron */ | 1444 | * as Prodigy XS with a different PID, let's keep it separated for now |
1445 | * maybe we'll need it later on | ||
1446 | */ | ||
1442 | [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { | 1447 | [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { |
1443 | .name = "Terratec Prodigy XS", | 1448 | .name = "Terratec Prodigy XS", |
1444 | .tuner_type = TUNER_XC2028, | 1449 | .tuner_type = TUNER_XC2028, |
@@ -1782,8 +1787,9 @@ struct em28xx_board em28xx_boards[] = { | |||
1782 | .ir_codes = RC_MAP_KWORLD_315U, | 1787 | .ir_codes = RC_MAP_KWORLD_315U, |
1783 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | 1788 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, |
1784 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, | 1789 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, |
1785 | /* Analog mode - still not ready */ | 1790 | #if 0 |
1786 | /*.input = { { | 1791 | /* FIXME: Analog mode - still not ready */ |
1792 | .input = { { | ||
1787 | .type = EM28XX_VMUX_TELEVISION, | 1793 | .type = EM28XX_VMUX_TELEVISION, |
1788 | .vmux = SAA7115_COMPOSITE2, | 1794 | .vmux = SAA7115_COMPOSITE2, |
1789 | .amux = EM28XX_AMUX_VIDEO, | 1795 | .amux = EM28XX_AMUX_VIDEO, |
@@ -1801,7 +1807,8 @@ struct em28xx_board em28xx_boards[] = { | |||
1801 | .amux = EM28XX_AMUX_LINE_IN, | 1807 | .amux = EM28XX_AMUX_LINE_IN, |
1802 | .gpio = em2882_kworld_315u_analog1, | 1808 | .gpio = em2882_kworld_315u_analog1, |
1803 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | 1809 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, |
1804 | } }, */ | 1810 | } }, |
1811 | #endif | ||
1805 | }, | 1812 | }, |
1806 | [EM2880_BOARD_EMPIRE_DUAL_TV] = { | 1813 | [EM2880_BOARD_EMPIRE_DUAL_TV] = { |
1807 | .name = "Empire dual TV", | 1814 | .name = "Empire dual TV", |
@@ -2162,17 +2169,21 @@ struct em28xx_board em28xx_boards[] = { | |||
2162 | .gpio = evga_indtube_analog, | 2169 | .gpio = evga_indtube_analog, |
2163 | } }, | 2170 | } }, |
2164 | }, | 2171 | }, |
2165 | /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 + | 2172 | /* |
2166 | Infineon TUA6034) */ | 2173 | * eb1a:2868 Empia EM2870 + Philips CU1216L NIM |
2174 | * (Philips TDA10023 + Infineon TUA6034) | ||
2175 | */ | ||
2167 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { | 2176 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { |
2168 | .name = "Reddo DVB-C USB TV Box", | 2177 | .name = "Reddo DVB-C USB TV Box", |
2169 | .tuner_type = TUNER_ABSENT, | 2178 | .tuner_type = TUNER_ABSENT, |
2170 | .tuner_gpio = reddo_dvb_c_usb_box, | 2179 | .tuner_gpio = reddo_dvb_c_usb_box, |
2171 | .has_dvb = 1, | 2180 | .has_dvb = 1, |
2172 | }, | 2181 | }, |
2173 | /* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold | 2182 | /* |
2183 | * 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold | ||
2174 | * initially as the KWorld PlusTV 340U, then as the UB435-Q. | 2184 | * initially as the KWorld PlusTV 340U, then as the UB435-Q. |
2175 | * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */ | 2185 | * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 |
2186 | */ | ||
2176 | [EM2870_BOARD_KWORLD_A340] = { | 2187 | [EM2870_BOARD_KWORLD_A340] = { |
2177 | .name = "KWorld PlusTV 340U or UB435-Q (ATSC)", | 2188 | .name = "KWorld PlusTV 340U or UB435-Q (ATSC)", |
2178 | .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */ | 2189 | .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */ |
@@ -2180,30 +2191,38 @@ struct em28xx_board em28xx_boards[] = { | |||
2180 | .dvb_gpio = kworld_a340_digital, | 2191 | .dvb_gpio = kworld_a340_digital, |
2181 | .tuner_gpio = default_tuner_gpio, | 2192 | .tuner_gpio = default_tuner_gpio, |
2182 | }, | 2193 | }, |
2183 | /* 2013:024f PCTV nanoStick T2 290e. | 2194 | /* |
2184 | * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */ | 2195 | * 2013:024f PCTV nanoStick T2 290e. |
2196 | * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 | ||
2197 | */ | ||
2185 | [EM28174_BOARD_PCTV_290E] = { | 2198 | [EM28174_BOARD_PCTV_290E] = { |
2186 | .name = "PCTV nanoStick T2 290e", | 2199 | .name = "PCTV nanoStick T2 290e", |
2187 | .def_i2c_bus = 1, | 2200 | .def_i2c_bus = 1, |
2188 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, | 2201 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2202 | EM28XX_I2C_FREQ_100_KHZ, | ||
2189 | .tuner_type = TUNER_ABSENT, | 2203 | .tuner_type = TUNER_ABSENT, |
2190 | .tuner_gpio = pctv_290e, | 2204 | .tuner_gpio = pctv_290e, |
2191 | .has_dvb = 1, | 2205 | .has_dvb = 1, |
2192 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | 2206 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, |
2193 | }, | 2207 | }, |
2194 | /* 2013:024f PCTV DVB-S2 Stick 460e | 2208 | /* |
2195 | * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 */ | 2209 | * 2013:024f PCTV DVB-S2 Stick 460e |
2210 | * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 | ||
2211 | */ | ||
2196 | [EM28174_BOARD_PCTV_460E] = { | 2212 | [EM28174_BOARD_PCTV_460E] = { |
2197 | .def_i2c_bus = 1, | 2213 | .def_i2c_bus = 1, |
2198 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | 2214 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2215 | EM28XX_I2C_FREQ_400_KHZ, | ||
2199 | .name = "PCTV DVB-S2 Stick (460e)", | 2216 | .name = "PCTV DVB-S2 Stick (460e)", |
2200 | .tuner_type = TUNER_ABSENT, | 2217 | .tuner_type = TUNER_ABSENT, |
2201 | .tuner_gpio = pctv_460e, | 2218 | .tuner_gpio = pctv_460e, |
2202 | .has_dvb = 1, | 2219 | .has_dvb = 1, |
2203 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | 2220 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, |
2204 | }, | 2221 | }, |
2205 | /* eb1a:5006 Honestech VIDBOX NW03 | 2222 | /* |
2206 | * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner */ | 2223 | * eb1a:5006 Honestech VIDBOX NW03 |
2224 | * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner | ||
2225 | */ | ||
2207 | [EM2860_BOARD_HT_VIDBOX_NW03] = { | 2226 | [EM2860_BOARD_HT_VIDBOX_NW03] = { |
2208 | .name = "Honestech Vidbox NW03", | 2227 | .name = "Honestech Vidbox NW03", |
2209 | .tuner_type = TUNER_ABSENT, | 2228 | .tuner_type = TUNER_ABSENT, |
@@ -2214,12 +2233,14 @@ struct em28xx_board em28xx_boards[] = { | |||
2214 | .amux = EM28XX_AMUX_LINE_IN, | 2233 | .amux = EM28XX_AMUX_LINE_IN, |
2215 | }, { | 2234 | }, { |
2216 | .type = EM28XX_VMUX_SVIDEO, | 2235 | .type = EM28XX_VMUX_SVIDEO, |
2217 | .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs confirming */ | 2236 | .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs check */ |
2218 | .amux = EM28XX_AMUX_LINE_IN, | 2237 | .amux = EM28XX_AMUX_LINE_IN, |
2219 | } }, | 2238 | } }, |
2220 | }, | 2239 | }, |
2221 | /* 1b80:e425 MaxMedia UB425-TC | 2240 | /* |
2222 | * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */ | 2241 | * 1b80:e425 MaxMedia UB425-TC |
2242 | * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 | ||
2243 | */ | ||
2223 | [EM2874_BOARD_MAXMEDIA_UB425_TC] = { | 2244 | [EM2874_BOARD_MAXMEDIA_UB425_TC] = { |
2224 | .name = "MaxMedia UB425-TC", | 2245 | .name = "MaxMedia UB425-TC", |
2225 | .tuner_type = TUNER_ABSENT, | 2246 | .tuner_type = TUNER_ABSENT, |
@@ -2230,8 +2251,10 @@ struct em28xx_board em28xx_boards[] = { | |||
2230 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | 2251 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2231 | EM28XX_I2C_FREQ_400_KHZ, | 2252 | EM28XX_I2C_FREQ_400_KHZ, |
2232 | }, | 2253 | }, |
2233 | /* 2304:0242 PCTV QuatroStick (510e) | 2254 | /* |
2234 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ | 2255 | * 2304:0242 PCTV QuatroStick (510e) |
2256 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 | ||
2257 | */ | ||
2235 | [EM2884_BOARD_PCTV_510E] = { | 2258 | [EM2884_BOARD_PCTV_510E] = { |
2236 | .name = "PCTV QuatroStick (510e)", | 2259 | .name = "PCTV QuatroStick (510e)", |
2237 | .tuner_type = TUNER_ABSENT, | 2260 | .tuner_type = TUNER_ABSENT, |
@@ -2242,8 +2265,10 @@ struct em28xx_board em28xx_boards[] = { | |||
2242 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | 2265 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2243 | EM28XX_I2C_FREQ_400_KHZ, | 2266 | EM28XX_I2C_FREQ_400_KHZ, |
2244 | }, | 2267 | }, |
2245 | /* 2013:0251 PCTV QuatroStick nano (520e) | 2268 | /* |
2246 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ | 2269 | * 2013:0251 PCTV QuatroStick nano (520e) |
2270 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 | ||
2271 | */ | ||
2247 | [EM2884_BOARD_PCTV_520E] = { | 2272 | [EM2884_BOARD_PCTV_520E] = { |
2248 | .name = "PCTV QuatroStick nano (520e)", | 2273 | .name = "PCTV QuatroStick nano (520e)", |
2249 | .tuner_type = TUNER_ABSENT, | 2274 | .tuner_type = TUNER_ABSENT, |
@@ -2263,9 +2288,11 @@ struct em28xx_board em28xx_boards[] = { | |||
2263 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | 2288 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2264 | EM28XX_I2C_FREQ_400_KHZ, | 2289 | EM28XX_I2C_FREQ_400_KHZ, |
2265 | }, | 2290 | }, |
2266 | /* 1b80:e1cc Delock 61959 | 2291 | /* |
2292 | * 1b80:e1cc Delock 61959 | ||
2267 | * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 | 2293 | * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 |
2268 | * mostly the same as MaxMedia UB-425-TC but different remote */ | 2294 | * mostly the same as MaxMedia UB-425-TC but different remote |
2295 | */ | ||
2269 | [EM2874_BOARD_DELOCK_61959] = { | 2296 | [EM2874_BOARD_DELOCK_61959] = { |
2270 | .name = "Delock 61959", | 2297 | .name = "Delock 61959", |
2271 | .tuner_type = TUNER_ABSENT, | 2298 | .tuner_type = TUNER_ABSENT, |
@@ -2311,8 +2338,10 @@ struct em28xx_board em28xx_boards[] = { | |||
2311 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | 2338 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, |
2312 | .leds = pctv_80e_leds, | 2339 | .leds = pctv_80e_leds, |
2313 | }, | 2340 | }, |
2314 | /* 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam | 2341 | /* |
2315 | * Empia EM2765 + OmniVision OV2640 */ | 2342 | * 1ae7:9003/9004 SpeedLink Vicious And Devine Laplace webcam |
2343 | * Empia EM2765 + OmniVision OV2640 | ||
2344 | */ | ||
2316 | [EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = { | 2345 | [EM2765_BOARD_SPEEDLINK_VAD_LAPLACE] = { |
2317 | .name = "SpeedLink Vicious And Devine Laplace webcam", | 2346 | .name = "SpeedLink Vicious And Devine Laplace webcam", |
2318 | .xclk = EM28XX_XCLK_FREQUENCY_24MHZ, | 2347 | .xclk = EM28XX_XCLK_FREQUENCY_24MHZ, |
@@ -2329,23 +2358,29 @@ struct em28xx_board em28xx_boards[] = { | |||
2329 | .buttons = speedlink_vad_laplace_buttons, | 2358 | .buttons = speedlink_vad_laplace_buttons, |
2330 | .leds = speedlink_vad_laplace_leds, | 2359 | .leds = speedlink_vad_laplace_leds, |
2331 | }, | 2360 | }, |
2332 | /* 2013:0258 PCTV DVB-S2 Stick (461e) | 2361 | /* |
2333 | * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293 */ | 2362 | * 2013:0258 PCTV DVB-S2 Stick (461e) |
2363 | * Empia EM28178, Montage M88DS3103, Montage M88TS2022, Allegro A8293 | ||
2364 | */ | ||
2334 | [EM28178_BOARD_PCTV_461E] = { | 2365 | [EM28178_BOARD_PCTV_461E] = { |
2335 | .def_i2c_bus = 1, | 2366 | .def_i2c_bus = 1, |
2336 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | 2367 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2368 | EM28XX_I2C_FREQ_400_KHZ, | ||
2337 | .name = "PCTV DVB-S2 Stick (461e)", | 2369 | .name = "PCTV DVB-S2 Stick (461e)", |
2338 | .tuner_type = TUNER_ABSENT, | 2370 | .tuner_type = TUNER_ABSENT, |
2339 | .tuner_gpio = pctv_461e, | 2371 | .tuner_gpio = pctv_461e, |
2340 | .has_dvb = 1, | 2372 | .has_dvb = 1, |
2341 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | 2373 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, |
2342 | }, | 2374 | }, |
2343 | /* 2013:025f PCTV tripleStick (292e). | 2375 | /* |
2344 | * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157 */ | 2376 | * 2013:025f PCTV tripleStick (292e). |
2377 | * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2157 | ||
2378 | */ | ||
2345 | [EM28178_BOARD_PCTV_292E] = { | 2379 | [EM28178_BOARD_PCTV_292E] = { |
2346 | .name = "PCTV tripleStick (292e)", | 2380 | .name = "PCTV tripleStick (292e)", |
2347 | .def_i2c_bus = 1, | 2381 | .def_i2c_bus = 1, |
2348 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | 2382 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2383 | EM28XX_I2C_FREQ_400_KHZ, | ||
2349 | .tuner_type = TUNER_ABSENT, | 2384 | .tuner_type = TUNER_ABSENT, |
2350 | .tuner_gpio = pctv_292e, | 2385 | .tuner_gpio = pctv_292e, |
2351 | .has_dvb = 1, | 2386 | .has_dvb = 1, |
@@ -2365,12 +2400,15 @@ struct em28xx_board em28xx_boards[] = { | |||
2365 | .amux = EM28XX_AMUX_LINE_IN, | 2400 | .amux = EM28XX_AMUX_LINE_IN, |
2366 | } }, | 2401 | } }, |
2367 | }, | 2402 | }, |
2368 | /* eb1a:8179 Terratec Cinergy T2 Stick HD. | 2403 | /* |
2369 | * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146 */ | 2404 | * eb1a:8179 Terratec Cinergy T2 Stick HD. |
2405 | * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146 | ||
2406 | */ | ||
2370 | [EM28178_BOARD_TERRATEC_T2_STICK_HD] = { | 2407 | [EM28178_BOARD_TERRATEC_T2_STICK_HD] = { |
2371 | .name = "Terratec Cinergy T2 Stick HD", | 2408 | .name = "Terratec Cinergy T2 Stick HD", |
2372 | .def_i2c_bus = 1, | 2409 | .def_i2c_bus = 1, |
2373 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | 2410 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2411 | EM28XX_I2C_FREQ_400_KHZ, | ||
2374 | .tuner_type = TUNER_ABSENT, | 2412 | .tuner_type = TUNER_ABSENT, |
2375 | .tuner_gpio = terratec_t2_stick_hd, | 2413 | .tuner_gpio = terratec_t2_stick_hd, |
2376 | .has_dvb = 1, | 2414 | .has_dvb = 1, |
@@ -2391,7 +2429,8 @@ struct em28xx_board em28xx_boards[] = { | |||
2391 | .has_dvb = 1, | 2429 | .has_dvb = 1, |
2392 | }, | 2430 | }, |
2393 | /* | 2431 | /* |
2394 | * 2040:0265 Hauppauge WinTV-dualHD (DVB version). | 2432 | * 2040:0265 Hauppauge WinTV-dualHD (DVB version) Isoc. |
2433 | * 2040:8265 Hauppauge WinTV-dualHD (DVB version) Bulk. | ||
2395 | * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 | 2434 | * Empia EM28274, 2x Silicon Labs Si2168, 2x Silicon Labs Si2157 |
2396 | */ | 2435 | */ |
2397 | [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = { | 2436 | [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB] = { |
@@ -2402,11 +2441,13 @@ struct em28xx_board em28xx_boards[] = { | |||
2402 | .tuner_type = TUNER_ABSENT, | 2441 | .tuner_type = TUNER_ABSENT, |
2403 | .tuner_gpio = hauppauge_dualhd_dvb, | 2442 | .tuner_gpio = hauppauge_dualhd_dvb, |
2404 | .has_dvb = 1, | 2443 | .has_dvb = 1, |
2444 | .has_dual_ts = 1, | ||
2405 | .ir_codes = RC_MAP_HAUPPAUGE, | 2445 | .ir_codes = RC_MAP_HAUPPAUGE, |
2406 | .leds = hauppauge_dualhd_leds, | 2446 | .leds = hauppauge_dualhd_leds, |
2407 | }, | 2447 | }, |
2408 | /* | 2448 | /* |
2409 | * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM). | 2449 | * 2040:026d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Isoc. |
2450 | * 2040:826d Hauppauge WinTV-dualHD (model 01595 - ATSC/QAM) Bulk. | ||
2410 | * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157 | 2451 | * Empia EM28274, 2x LG LGDT3306A, 2x Silicon Labs Si2157 |
2411 | */ | 2452 | */ |
2412 | [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = { | 2453 | [EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595] = { |
@@ -2417,6 +2458,7 @@ struct em28xx_board em28xx_boards[] = { | |||
2417 | .tuner_type = TUNER_ABSENT, | 2458 | .tuner_type = TUNER_ABSENT, |
2418 | .tuner_gpio = hauppauge_dualhd_dvb, | 2459 | .tuner_gpio = hauppauge_dualhd_dvb, |
2419 | .has_dvb = 1, | 2460 | .has_dvb = 1, |
2461 | .has_dual_ts = 1, | ||
2420 | .ir_codes = RC_MAP_HAUPPAUGE, | 2462 | .ir_codes = RC_MAP_HAUPPAUGE, |
2421 | .leds = hauppauge_dualhd_leds, | 2463 | .leds = hauppauge_dualhd_leds, |
2422 | }, | 2464 | }, |
@@ -2485,10 +2527,10 @@ struct usb_device_id em28xx_id_table[] = { | |||
2485 | .driver_info = EM2870_BOARD_KWORLD_355U }, | 2527 | .driver_info = EM2870_BOARD_KWORLD_355U }, |
2486 | { USB_DEVICE(0xeb1a, 0xe359), | 2528 | { USB_DEVICE(0xeb1a, 0xe359), |
2487 | .driver_info = EM2870_BOARD_KWORLD_355U }, | 2529 | .driver_info = EM2870_BOARD_KWORLD_355U }, |
2488 | { USB_DEVICE(0x1b80, 0xe302), | 2530 | { USB_DEVICE(0x1b80, 0xe302), /* Kaiser Baas Video to DVD maker */ |
2489 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */ | 2531 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, |
2490 | { USB_DEVICE(0x1b80, 0xe304), | 2532 | { USB_DEVICE(0x1b80, 0xe304), /* Kworld DVD Maker 2 */ |
2491 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */ | 2533 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, |
2492 | { USB_DEVICE(0x0ccd, 0x0036), | 2534 | { USB_DEVICE(0x0ccd, 0x0036), |
2493 | .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, | 2535 | .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, |
2494 | { USB_DEVICE(0x0ccd, 0x004c), | 2536 | { USB_DEVICE(0x0ccd, 0x004c), |
@@ -2547,8 +2589,12 @@ struct usb_device_id em28xx_id_table[] = { | |||
2547 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, | 2589 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, |
2548 | { USB_DEVICE(0x2040, 0x0265), | 2590 | { USB_DEVICE(0x2040, 0x0265), |
2549 | .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, | 2591 | .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, |
2592 | { USB_DEVICE(0x2040, 0x8265), | ||
2593 | .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB }, | ||
2550 | { USB_DEVICE(0x2040, 0x026d), | 2594 | { USB_DEVICE(0x2040, 0x026d), |
2551 | .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, | 2595 | .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, |
2596 | { USB_DEVICE(0x2040, 0x826d), | ||
2597 | .driver_info = EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 }, | ||
2552 | { USB_DEVICE(0x0438, 0xb002), | 2598 | { USB_DEVICE(0x0438, 0xb002), |
2553 | .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, | 2599 | .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, |
2554 | { USB_DEVICE(0x2001, 0xf112), | 2600 | { USB_DEVICE(0x2001, 0xf112), |
@@ -2609,7 +2655,13 @@ struct usb_device_id em28xx_id_table[] = { | |||
2609 | .driver_info = EM28178_BOARD_PCTV_461E }, | 2655 | .driver_info = EM28178_BOARD_PCTV_461E }, |
2610 | { USB_DEVICE(0x2013, 0x025f), | 2656 | { USB_DEVICE(0x2013, 0x025f), |
2611 | .driver_info = EM28178_BOARD_PCTV_292E }, | 2657 | .driver_info = EM28178_BOARD_PCTV_292E }, |
2612 | { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD */ | 2658 | { USB_DEVICE(0x2013, 0x0264), /* Hauppauge WinTV-soloHD 292e SE */ |
2659 | .driver_info = EM28178_BOARD_PCTV_292E }, | ||
2660 | { USB_DEVICE(0x2040, 0x0264), /* Hauppauge WinTV-soloHD Isoc */ | ||
2661 | .driver_info = EM28178_BOARD_PCTV_292E }, | ||
2662 | { USB_DEVICE(0x2040, 0x8264), /* Hauppauge OEM Generic WinTV-soloHD Bulk */ | ||
2663 | .driver_info = EM28178_BOARD_PCTV_292E }, | ||
2664 | { USB_DEVICE(0x2040, 0x8268), /* Hauppauge Retail WinTV-soloHD Bulk */ | ||
2613 | .driver_info = EM28178_BOARD_PCTV_292E }, | 2665 | .driver_info = EM28178_BOARD_PCTV_292E }, |
2614 | { USB_DEVICE(0x0413, 0x6f07), | 2666 | { USB_DEVICE(0x0413, 0x6f07), |
2615 | .driver_info = EM2861_BOARD_LEADTEK_VC100 }, | 2667 | .driver_info = EM2861_BOARD_LEADTEK_VC100 }, |
@@ -2626,7 +2678,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); | |||
2626 | /* | 2678 | /* |
2627 | * EEPROM hash table for devices with generic USB IDs | 2679 | * EEPROM hash table for devices with generic USB IDs |
2628 | */ | 2680 | */ |
2629 | static struct em28xx_hash_table em28xx_eeprom_hash[] = { | 2681 | static const struct em28xx_hash_table em28xx_eeprom_hash[] = { |
2630 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ | 2682 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ |
2631 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | 2683 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, |
2632 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, | 2684 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, |
@@ -2639,7 +2691,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = { | |||
2639 | }; | 2691 | }; |
2640 | 2692 | ||
2641 | /* I2C devicelist hash table for devices with generic USB IDs */ | 2693 | /* I2C devicelist hash table for devices with generic USB IDs */ |
2642 | static struct em28xx_hash_table em28xx_i2c_hash[] = { | 2694 | static const struct em28xx_hash_table em28xx_i2c_hash[] = { |
2643 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, | 2695 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, |
2644 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, | 2696 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, |
2645 | {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, | 2697 | {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, |
@@ -2669,26 +2721,46 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) | |||
2669 | } | 2721 | } |
2670 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); | 2722 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); |
2671 | 2723 | ||
2672 | static inline void em28xx_set_model(struct em28xx *dev) | 2724 | static inline void em28xx_set_xclk_i2c_speed(struct em28xx *dev) |
2673 | { | 2725 | { |
2674 | dev->board = em28xx_boards[dev->model]; | 2726 | const struct em28xx_board *board = &em28xx_boards[dev->model]; |
2727 | u8 xclk = board->xclk, i2c_speed = board->i2c_speed; | ||
2675 | 2728 | ||
2676 | /* Those are the default values for the majority of boards | 2729 | /* |
2677 | Use those values if not specified otherwise at boards entry | 2730 | * Those are the default values for the majority of boards |
2731 | * Use those values if not specified otherwise at boards entry | ||
2678 | */ | 2732 | */ |
2679 | if (!dev->board.xclk) | 2733 | if (!xclk) |
2680 | dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE | | 2734 | xclk = EM28XX_XCLK_IR_RC5_MODE | |
2681 | EM28XX_XCLK_FREQUENCY_12MHZ; | 2735 | EM28XX_XCLK_FREQUENCY_12MHZ; |
2736 | |||
2737 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); | ||
2682 | 2738 | ||
2683 | if (!dev->board.i2c_speed) | 2739 | if (!i2c_speed) |
2684 | dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | 2740 | i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | |
2685 | EM28XX_I2C_FREQ_100_KHZ; | 2741 | EM28XX_I2C_FREQ_100_KHZ; |
2742 | |||
2743 | dev->i2c_speed = i2c_speed & 0x03; | ||
2744 | |||
2745 | if (!dev->board.is_em2800) | ||
2746 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, i2c_speed); | ||
2747 | msleep(50); | ||
2748 | } | ||
2749 | |||
2750 | static inline void em28xx_set_model(struct em28xx *dev) | ||
2751 | { | ||
2752 | dev->board = em28xx_boards[dev->model]; | ||
2753 | dev->has_msp34xx = dev->board.has_msp34xx; | ||
2754 | dev->is_webcam = dev->board.is_webcam; | ||
2755 | |||
2756 | em28xx_set_xclk_i2c_speed(dev); | ||
2686 | 2757 | ||
2687 | /* Should be initialized early, for I2C to work */ | 2758 | /* Should be initialized early, for I2C to work */ |
2688 | dev->def_i2c_bus = dev->board.def_i2c_bus; | 2759 | dev->def_i2c_bus = dev->board.def_i2c_bus; |
2689 | } | 2760 | } |
2690 | 2761 | ||
2691 | /* Wait until AC97_RESET reports the expected value reliably before proceeding. | 2762 | /* |
2763 | * Wait until AC97_RESET reports the expected value reliably before proceeding. | ||
2692 | * We also check that two unrelated registers accesses don't return the same | 2764 | * We also check that two unrelated registers accesses don't return the same |
2693 | * value to avoid premature return. | 2765 | * value to avoid premature return. |
2694 | * This procedure helps ensuring AC97 register accesses are reliable. | 2766 | * This procedure helps ensuring AC97 register accesses are reliable. |
@@ -2718,17 +2790,17 @@ static int em28xx_wait_until_ac97_features_equals(struct em28xx *dev, | |||
2718 | return -ETIMEDOUT; | 2790 | return -ETIMEDOUT; |
2719 | } | 2791 | } |
2720 | 2792 | ||
2721 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | 2793 | /* |
2794 | * Since em28xx_pre_card_setup() requires a proper dev->model, | ||
2722 | * this won't work for boards with generic PCI IDs | 2795 | * this won't work for boards with generic PCI IDs |
2723 | */ | 2796 | */ |
2724 | static void em28xx_pre_card_setup(struct em28xx *dev) | 2797 | static void em28xx_pre_card_setup(struct em28xx *dev) |
2725 | { | 2798 | { |
2726 | /* Set the initial XCLK and I2C clock values based on the board | 2799 | /* |
2727 | definition */ | 2800 | * Set the initial XCLK and I2C clock values based on the board |
2728 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); | 2801 | * definition |
2729 | if (!dev->board.is_em2800) | 2802 | */ |
2730 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); | 2803 | em28xx_set_xclk_i2c_speed(dev); |
2731 | msleep(50); | ||
2732 | 2804 | ||
2733 | /* request some modules */ | 2805 | /* request some modules */ |
2734 | switch (dev->model) { | 2806 | switch (dev->model) { |
@@ -2739,17 +2811,19 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2739 | case EM2861_BOARD_KWORLD_PVRTV_300U: | 2811 | case EM2861_BOARD_KWORLD_PVRTV_300U: |
2740 | case EM2880_BOARD_KWORLD_DVB_305U: | 2812 | case EM2880_BOARD_KWORLD_DVB_305U: |
2741 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d); | 2813 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d); |
2742 | msleep(10); | 2814 | usleep_range(10000, 11000); |
2743 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d); | 2815 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d); |
2744 | msleep(10); | 2816 | usleep_range(10000, 11000); |
2745 | break; | 2817 | break; |
2746 | case EM2870_BOARD_COMPRO_VIDEOMATE: | 2818 | case EM2870_BOARD_COMPRO_VIDEOMATE: |
2747 | /* TODO: someone can do some cleanup here... | 2819 | /* |
2748 | not everything's needed */ | 2820 | * TODO: someone can do some cleanup here... |
2821 | * not everything's needed | ||
2822 | */ | ||
2749 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | 2823 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); |
2750 | msleep(10); | 2824 | usleep_range(10000, 11000); |
2751 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x01); | 2825 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x01); |
2752 | msleep(10); | 2826 | usleep_range(10000, 11000); |
2753 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); | 2827 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); |
2754 | mdelay(70); | 2828 | mdelay(70); |
2755 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc); | 2829 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc); |
@@ -2760,8 +2834,10 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2760 | mdelay(70); | 2834 | mdelay(70); |
2761 | break; | 2835 | break; |
2762 | case EM2870_BOARD_TERRATEC_XS_MT2060: | 2836 | case EM2870_BOARD_TERRATEC_XS_MT2060: |
2763 | /* this device needs some gpio writes to get the DVB-T | 2837 | /* |
2764 | demod work */ | 2838 | * this device needs some gpio writes to get the DVB-T |
2839 | * demod work | ||
2840 | */ | ||
2765 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); | 2841 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); |
2766 | mdelay(70); | 2842 | mdelay(70); |
2767 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde); | 2843 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde); |
@@ -2770,8 +2846,10 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2770 | mdelay(70); | 2846 | mdelay(70); |
2771 | break; | 2847 | break; |
2772 | case EM2870_BOARD_PINNACLE_PCTV_DVB: | 2848 | case EM2870_BOARD_PINNACLE_PCTV_DVB: |
2773 | /* this device needs some gpio writes to get the | 2849 | /* |
2774 | DVB-T demod work */ | 2850 | * this device needs some gpio writes to get the |
2851 | * DVB-T demod work | ||
2852 | */ | ||
2775 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); | 2853 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); |
2776 | mdelay(70); | 2854 | mdelay(70); |
2777 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde); | 2855 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde); |
@@ -2787,13 +2865,13 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2787 | 2865 | ||
2788 | case EM2882_BOARD_KWORLD_ATSC_315U: | 2866 | case EM2882_BOARD_KWORLD_ATSC_315U: |
2789 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); | 2867 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); |
2790 | msleep(10); | 2868 | usleep_range(10000, 11000); |
2791 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); | 2869 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); |
2792 | msleep(10); | 2870 | usleep_range(10000, 11000); |
2793 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | 2871 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); |
2794 | msleep(10); | 2872 | usleep_range(10000, 11000); |
2795 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); | 2873 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); |
2796 | msleep(10); | 2874 | usleep_range(10000, 11000); |
2797 | break; | 2875 | break; |
2798 | 2876 | ||
2799 | case EM2860_BOARD_KAIOMY_TVNPC_U2: | 2877 | case EM2860_BOARD_KAIOMY_TVNPC_U2: |
@@ -2801,11 +2879,11 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2801 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | 2879 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); |
2802 | em28xx_write_regs(dev, 0x0d, "\x42", 1); | 2880 | em28xx_write_regs(dev, 0x0d, "\x42", 1); |
2803 | em28xx_write_regs(dev, 0x08, "\xfd", 1); | 2881 | em28xx_write_regs(dev, 0x08, "\xfd", 1); |
2804 | msleep(10); | 2882 | usleep_range(10000, 11000); |
2805 | em28xx_write_regs(dev, 0x08, "\xff", 1); | 2883 | em28xx_write_regs(dev, 0x08, "\xff", 1); |
2806 | msleep(10); | 2884 | usleep_range(10000, 11000); |
2807 | em28xx_write_regs(dev, 0x08, "\x7f", 1); | 2885 | em28xx_write_regs(dev, 0x08, "\x7f", 1); |
2808 | msleep(10); | 2886 | usleep_range(10000, 11000); |
2809 | em28xx_write_regs(dev, 0x08, "\x6b", 1); | 2887 | em28xx_write_regs(dev, 0x08, "\x6b", 1); |
2810 | 2888 | ||
2811 | break; | 2889 | break; |
@@ -2817,7 +2895,7 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2817 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); | 2895 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); |
2818 | msleep(70); | 2896 | msleep(70); |
2819 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); | 2897 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); |
2820 | msleep(10); | 2898 | usleep_range(10000, 11000); |
2821 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); | 2899 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe); |
2822 | msleep(70); | 2900 | msleep(70); |
2823 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); | 2901 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); |
@@ -2825,7 +2903,8 @@ static void em28xx_pre_card_setup(struct em28xx *dev) | |||
2825 | break; | 2903 | break; |
2826 | 2904 | ||
2827 | case EM2860_BOARD_TERRATEC_GRABBY: | 2905 | case EM2860_BOARD_TERRATEC_GRABBY: |
2828 | /* HACK?: Ensure AC97 register reading is reliable before | 2906 | /* |
2907 | * HACK?: Ensure AC97 register reading is reliable before | ||
2829 | * proceeding. In practice, this will wait about 1.6 seconds. | 2908 | * proceeding. In practice, this will wait about 1.6 seconds. |
2830 | */ | 2909 | */ |
2831 | em28xx_wait_until_ac97_features_equals(dev, 0x6a90); | 2910 | em28xx_wait_until_ac97_features_equals(dev, 0x6a90); |
@@ -2843,7 +2922,7 @@ static int em28xx_hint_board(struct em28xx *dev) | |||
2843 | { | 2922 | { |
2844 | int i; | 2923 | int i; |
2845 | 2924 | ||
2846 | if (dev->board.is_webcam) { | 2925 | if (dev->is_webcam) { |
2847 | if (dev->em28xx_sensor == EM28XX_MT9V011) { | 2926 | if (dev->em28xx_sensor == EM28XX_MT9V011) { |
2848 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | 2927 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; |
2849 | } else if (dev->em28xx_sensor == EM28XX_MT9M001 || | 2928 | } else if (dev->em28xx_sensor == EM28XX_MT9M001 || |
@@ -2855,7 +2934,8 @@ static int em28xx_hint_board(struct em28xx *dev) | |||
2855 | return 0; | 2934 | return 0; |
2856 | } | 2935 | } |
2857 | 2936 | ||
2858 | /* HINT method: EEPROM | 2937 | /* |
2938 | * HINT method: EEPROM | ||
2859 | * | 2939 | * |
2860 | * This method works only for boards with eeprom. | 2940 | * This method works only for boards with eeprom. |
2861 | * Uses a hash of all eeprom bytes. The hash should be | 2941 | * Uses a hash of all eeprom bytes. The hash should be |
@@ -2881,7 +2961,8 @@ static int em28xx_hint_board(struct em28xx *dev) | |||
2881 | } | 2961 | } |
2882 | } | 2962 | } |
2883 | 2963 | ||
2884 | /* HINT method: I2C attached devices | 2964 | /* |
2965 | * HINT method: I2C attached devices | ||
2885 | * | 2966 | * |
2886 | * This method works for all boards. | 2967 | * This method works for all boards. |
2887 | * Uses a hash of i2c scanned devices. | 2968 | * Uses a hash of i2c scanned devices. |
@@ -2935,11 +3016,11 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
2935 | * If the device can be a webcam, seek for a sensor. | 3016 | * If the device can be a webcam, seek for a sensor. |
2936 | * If sensor is not found, then it isn't a webcam. | 3017 | * If sensor is not found, then it isn't a webcam. |
2937 | */ | 3018 | */ |
2938 | if (dev->board.is_webcam) { | 3019 | if (dev->is_webcam) { |
2939 | em28xx_detect_sensor(dev); | 3020 | em28xx_detect_sensor(dev); |
2940 | if (dev->em28xx_sensor == EM28XX_NOSENSOR) | 3021 | if (dev->em28xx_sensor == EM28XX_NOSENSOR) |
2941 | /* NOTE: error/unknown sensor/no sensor */ | 3022 | /* NOTE: error/unknown sensor/no sensor */ |
2942 | dev->board.is_webcam = 0; | 3023 | dev->is_webcam = 0; |
2943 | } | 3024 | } |
2944 | 3025 | ||
2945 | switch (dev->model) { | 3026 | switch (dev->model) { |
@@ -2959,9 +3040,9 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
2959 | * This solution is only valid if they do not share eeprom | 3040 | * This solution is only valid if they do not share eeprom |
2960 | * hash identities which has not been determined as yet. | 3041 | * hash identities which has not been determined as yet. |
2961 | */ | 3042 | */ |
2962 | if (em28xx_hint_board(dev) < 0) | 3043 | if (em28xx_hint_board(dev) < 0) { |
2963 | dev_err(&dev->intf->dev, "Board not discovered\n"); | 3044 | dev_err(&dev->intf->dev, "Board not discovered\n"); |
2964 | else { | 3045 | } else { |
2965 | em28xx_set_model(dev); | 3046 | em28xx_set_model(dev); |
2966 | em28xx_pre_card_setup(dev); | 3047 | em28xx_pre_card_setup(dev); |
2967 | } | 3048 | } |
@@ -2971,7 +3052,7 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
2971 | } | 3052 | } |
2972 | 3053 | ||
2973 | dev_info(&dev->intf->dev, "Identified as %s (card=%d)\n", | 3054 | dev_info(&dev->intf->dev, "Identified as %s (card=%d)\n", |
2974 | dev->board.name, dev->model); | 3055 | dev->board.name, dev->model); |
2975 | 3056 | ||
2976 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; | 3057 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; |
2977 | 3058 | ||
@@ -2988,7 +3069,7 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
2988 | { | 3069 | { |
2989 | struct tveeprom tv; | 3070 | struct tveeprom tv; |
2990 | 3071 | ||
2991 | if (dev->eedata == NULL) | 3072 | if (!dev->eedata) |
2992 | break; | 3073 | break; |
2993 | #if defined(CONFIG_MODULES) && defined(MODULE) | 3074 | #if defined(CONFIG_MODULES) && defined(MODULE) |
2994 | request_module("tveeprom"); | 3075 | request_module("tveeprom"); |
@@ -3001,15 +3082,15 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
3001 | 3082 | ||
3002 | if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) { | 3083 | if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) { |
3003 | dev->i2s_speed = 2048000; | 3084 | dev->i2s_speed = 2048000; |
3004 | dev->board.has_msp34xx = 1; | 3085 | dev->has_msp34xx = 1; |
3005 | } | 3086 | } |
3006 | break; | 3087 | break; |
3007 | } | 3088 | } |
3008 | case EM2882_BOARD_KWORLD_ATSC_315U: | 3089 | case EM2882_BOARD_KWORLD_ATSC_315U: |
3009 | em28xx_write_reg(dev, 0x0d, 0x42); | 3090 | em28xx_write_reg(dev, 0x0d, 0x42); |
3010 | msleep(10); | 3091 | usleep_range(10000, 11000); |
3011 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); | 3092 | em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd); |
3012 | msleep(10); | 3093 | usleep_range(10000, 11000); |
3013 | break; | 3094 | break; |
3014 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | 3095 | case EM2820_BOARD_KWORLD_PVRTV2800RF: |
3015 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ | 3096 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ |
@@ -3034,10 +3115,12 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
3034 | if (!em28xx_hint_board(dev)) | 3115 | if (!em28xx_hint_board(dev)) |
3035 | em28xx_set_model(dev); | 3116 | em28xx_set_model(dev); |
3036 | 3117 | ||
3037 | /* In cases where we had to use a board hint, the call to | 3118 | /* |
3038 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | 3119 | * In cases where we had to use a board hint, the call to |
3039 | so make the call now so the analog GPIOs are set properly | 3120 | * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, |
3040 | before probing the i2c bus. */ | 3121 | * so make the call now so the analog GPIOs are set properly |
3122 | * before probing the i2c bus. | ||
3123 | */ | ||
3041 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | 3124 | em28xx_gpio_set(dev, dev->board.tuner_gpio); |
3042 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 3125 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
3043 | break; | 3126 | break; |
@@ -3059,10 +3142,12 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
3059 | if (!em28xx_hint_board(dev)) | 3142 | if (!em28xx_hint_board(dev)) |
3060 | em28xx_set_model(dev); | 3143 | em28xx_set_model(dev); |
3061 | 3144 | ||
3062 | /* In cases where we had to use a board hint, the call to | 3145 | /* |
3063 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | 3146 | * In cases where we had to use a board hint, the call to |
3064 | so make the call now so the analog GPIOs are set properly | 3147 | * em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, |
3065 | before probing the i2c bus. */ | 3148 | * so make the call now so the analog GPIOs are set properly |
3149 | * before probing the i2c bus. | ||
3150 | */ | ||
3066 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | 3151 | em28xx_gpio_set(dev, dev->board.tuner_gpio); |
3067 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 3152 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
3068 | break; | 3153 | break; |
@@ -3147,8 +3232,8 @@ static void request_module_async(struct work_struct *work) | |||
3147 | */ | 3232 | */ |
3148 | 3233 | ||
3149 | /* | 3234 | /* |
3150 | * Devicdes with an audio-only interface also have a V4L/DVB/RC | 3235 | * Devices with an audio-only intf also have a V4L/DVB/RC |
3151 | * interface. Don't register extensions twice on those devices. | 3236 | * intf. Don't register extensions twice on those devices. |
3152 | */ | 3237 | */ |
3153 | if (dev->is_audio_only) { | 3238 | if (dev->is_audio_only) { |
3154 | #if defined(CONFIG_MODULES) && defined(MODULE) | 3239 | #if defined(CONFIG_MODULES) && defined(MODULE) |
@@ -3209,7 +3294,6 @@ static int em28xx_media_device_init(struct em28xx *dev, | |||
3209 | 3294 | ||
3210 | static void em28xx_unregister_media_device(struct em28xx *dev) | 3295 | static void em28xx_unregister_media_device(struct em28xx *dev) |
3211 | { | 3296 | { |
3212 | |||
3213 | #ifdef CONFIG_MEDIA_CONTROLLER | 3297 | #ifdef CONFIG_MEDIA_CONTROLLER |
3214 | if (dev->media_dev) { | 3298 | if (dev->media_dev) { |
3215 | media_device_unregister(dev->media_dev); | 3299 | media_device_unregister(dev->media_dev); |
@@ -3224,7 +3308,7 @@ static void em28xx_unregister_media_device(struct em28xx *dev) | |||
3224 | * em28xx_release_resources() | 3308 | * em28xx_release_resources() |
3225 | * unregisters the v4l2,i2c and usb devices | 3309 | * unregisters the v4l2,i2c and usb devices |
3226 | * called when the device gets disconnected or at module unload | 3310 | * called when the device gets disconnected or at module unload |
3227 | */ | 3311 | */ |
3228 | static void em28xx_release_resources(struct em28xx *dev) | 3312 | static void em28xx_release_resources(struct em28xx *dev) |
3229 | { | 3313 | { |
3230 | struct usb_device *udev = interface_to_usbdev(dev->intf); | 3314 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
@@ -3239,7 +3323,8 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
3239 | em28xx_i2c_unregister(dev, 1); | 3323 | em28xx_i2c_unregister(dev, 1); |
3240 | em28xx_i2c_unregister(dev, 0); | 3324 | em28xx_i2c_unregister(dev, 0); |
3241 | 3325 | ||
3242 | usb_put_dev(udev); | 3326 | if (dev->ts == PRIMARY_TS) |
3327 | usb_put_dev(udev); | ||
3243 | 3328 | ||
3244 | /* Mark device as unused */ | 3329 | /* Mark device as unused */ |
3245 | clear_bit(dev->devno, em28xx_devused); | 3330 | clear_bit(dev->devno, em28xx_devused); |
@@ -3273,13 +3358,13 @@ EXPORT_SYMBOL_GPL(em28xx_free_device); | |||
3273 | * allocates and inits the device structs, registers i2c bus and v4l device | 3358 | * allocates and inits the device structs, registers i2c bus and v4l device |
3274 | */ | 3359 | */ |
3275 | static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | 3360 | static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, |
3276 | struct usb_interface *interface, | 3361 | struct usb_interface *intf, |
3277 | int minor) | 3362 | int minor) |
3278 | { | 3363 | { |
3279 | int retval; | 3364 | int retval; |
3280 | const char *chip_name = NULL; | 3365 | const char *chip_name = NULL; |
3281 | 3366 | ||
3282 | dev->intf = interface; | 3367 | dev->intf = intf; |
3283 | mutex_init(&dev->ctrl_urb_lock); | 3368 | mutex_init(&dev->ctrl_urb_lock); |
3284 | spin_lock_init(&dev->slock); | 3369 | spin_lock_init(&dev->slock); |
3285 | 3370 | ||
@@ -3382,17 +3467,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | |||
3382 | 3467 | ||
3383 | em28xx_pre_card_setup(dev); | 3468 | em28xx_pre_card_setup(dev); |
3384 | 3469 | ||
3385 | if (!dev->board.is_em2800) { | ||
3386 | /* Resets I2C speed */ | ||
3387 | retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); | ||
3388 | if (retval < 0) { | ||
3389 | dev_err(&dev->intf->dev, | ||
3390 | "%s: em28xx_write_reg failed! retval [%d]\n", | ||
3391 | __func__, retval); | ||
3392 | return retval; | ||
3393 | } | ||
3394 | } | ||
3395 | |||
3396 | rt_mutex_init(&dev->i2c_bus_lock); | 3470 | rt_mutex_init(&dev->i2c_bus_lock); |
3397 | 3471 | ||
3398 | /* register i2c bus 0 */ | 3472 | /* register i2c bus 0 */ |
@@ -3417,8 +3491,8 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | |||
3417 | EM28XX_I2C_ALGO_EM28XX); | 3491 | EM28XX_I2C_ALGO_EM28XX); |
3418 | if (retval < 0) { | 3492 | if (retval < 0) { |
3419 | dev_err(&dev->intf->dev, | 3493 | dev_err(&dev->intf->dev, |
3420 | "%s: em28xx_i2c_register bus 1 - error [%d]!\n", | 3494 | "%s: em28xx_i2c_register bus 1 - error [%d]!\n", |
3421 | __func__, retval); | 3495 | __func__, retval); |
3422 | 3496 | ||
3423 | em28xx_i2c_unregister(dev, 0); | 3497 | em28xx_i2c_unregister(dev, 0); |
3424 | 3498 | ||
@@ -3432,14 +3506,147 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | |||
3432 | return 0; | 3506 | return 0; |
3433 | } | 3507 | } |
3434 | 3508 | ||
3509 | static int em28xx_duplicate_dev(struct em28xx *dev) | ||
3510 | { | ||
3511 | int nr; | ||
3512 | struct em28xx *sec_dev = kzalloc(sizeof(*sec_dev), GFP_KERNEL); | ||
3513 | |||
3514 | if (!sec_dev) { | ||
3515 | dev->dev_next = NULL; | ||
3516 | return -ENOMEM; | ||
3517 | } | ||
3518 | memcpy(sec_dev, dev, sizeof(*sec_dev)); | ||
3519 | /* Check to see next free device and mark as used */ | ||
3520 | do { | ||
3521 | nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); | ||
3522 | if (nr >= EM28XX_MAXBOARDS) { | ||
3523 | /* No free device slots */ | ||
3524 | dev_warn(&dev->intf->dev, ": Supports only %i em28xx boards.\n", | ||
3525 | EM28XX_MAXBOARDS); | ||
3526 | kfree(sec_dev); | ||
3527 | dev->dev_next = NULL; | ||
3528 | return -ENOMEM; | ||
3529 | } | ||
3530 | } while (test_and_set_bit(nr, em28xx_devused)); | ||
3531 | sec_dev->devno = nr; | ||
3532 | snprintf(sec_dev->name, 28, "em28xx #%d", nr); | ||
3533 | sec_dev->dev_next = NULL; | ||
3534 | dev->dev_next = sec_dev; | ||
3535 | return 0; | ||
3536 | } | ||
3537 | |||
3435 | /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ | 3538 | /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ |
3436 | #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) | 3539 | #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) |
3437 | 3540 | ||
3541 | static void em28xx_check_usb_descriptor(struct em28xx *dev, | ||
3542 | struct usb_device *udev, | ||
3543 | struct usb_interface *intf, | ||
3544 | int alt, int ep, | ||
3545 | bool *has_vendor_audio, | ||
3546 | bool *has_video, | ||
3547 | bool *has_dvb) | ||
3548 | { | ||
3549 | const struct usb_endpoint_descriptor *e; | ||
3550 | int sizedescr, size; | ||
3551 | |||
3552 | /* | ||
3553 | * NOTE: | ||
3554 | * | ||
3555 | * Old logic with support for isoc transfers only was: | ||
3556 | * 0x82 isoc => analog | ||
3557 | * 0x83 isoc => audio | ||
3558 | * 0x84 isoc => digital | ||
3559 | * | ||
3560 | * New logic with support for bulk transfers | ||
3561 | * 0x82 isoc => analog | ||
3562 | * 0x82 bulk => analog | ||
3563 | * 0x83 isoc* => audio | ||
3564 | * 0x84 isoc => digital | ||
3565 | * 0x84 bulk => analog or digital** | ||
3566 | * 0x85 isoc => digital TS2 | ||
3567 | * 0x85 bulk => digital TS2 | ||
3568 | * (*: audio should always be isoc) | ||
3569 | * (**: analog, if ep 0x82 is isoc, otherwise digital) | ||
3570 | * | ||
3571 | * The new logic preserves backwards compatibility and | ||
3572 | * reflects the endpoint configurations we have seen | ||
3573 | * so far. But there might be devices for which this | ||
3574 | * logic is not sufficient... | ||
3575 | */ | ||
3576 | |||
3577 | e = &intf->altsetting[alt].endpoint[ep].desc; | ||
3578 | |||
3579 | if (!usb_endpoint_dir_in(e)) | ||
3580 | return; | ||
3581 | |||
3582 | sizedescr = le16_to_cpu(e->wMaxPacketSize); | ||
3583 | size = sizedescr & 0x7ff; | ||
3584 | |||
3585 | if (udev->speed == USB_SPEED_HIGH) | ||
3586 | size = size * hb_mult(sizedescr); | ||
3587 | |||
3588 | /* Only inspect input endpoints */ | ||
3589 | |||
3590 | switch (e->bEndpointAddress) { | ||
3591 | case 0x82: | ||
3592 | *has_video = true; | ||
3593 | if (usb_endpoint_xfer_isoc(e)) { | ||
3594 | dev->analog_ep_isoc = e->bEndpointAddress; | ||
3595 | dev->alt_max_pkt_size_isoc[alt] = size; | ||
3596 | } else if (usb_endpoint_xfer_bulk(e)) { | ||
3597 | dev->analog_ep_bulk = e->bEndpointAddress; | ||
3598 | } | ||
3599 | return; | ||
3600 | case 0x83: | ||
3601 | if (usb_endpoint_xfer_isoc(e)) | ||
3602 | *has_vendor_audio = true; | ||
3603 | else | ||
3604 | dev_err(&intf->dev, | ||
3605 | "error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); | ||
3606 | return; | ||
3607 | case 0x84: | ||
3608 | if (*has_video && (usb_endpoint_xfer_bulk(e))) { | ||
3609 | dev->analog_ep_bulk = e->bEndpointAddress; | ||
3610 | } else { | ||
3611 | if (usb_endpoint_xfer_isoc(e)) { | ||
3612 | if (size > dev->dvb_max_pkt_size_isoc) { | ||
3613 | /* | ||
3614 | * 2) some manufacturers (e.g. Terratec) | ||
3615 | * disable endpoints by setting | ||
3616 | * wMaxPacketSize to 0 bytes for all | ||
3617 | * alt settings. So far, we've seen | ||
3618 | * this for DVB isoc endpoints only. | ||
3619 | */ | ||
3620 | *has_dvb = true; | ||
3621 | dev->dvb_ep_isoc = e->bEndpointAddress; | ||
3622 | dev->dvb_max_pkt_size_isoc = size; | ||
3623 | dev->dvb_alt_isoc = alt; | ||
3624 | } | ||
3625 | } else { | ||
3626 | *has_dvb = true; | ||
3627 | dev->dvb_ep_bulk = e->bEndpointAddress; | ||
3628 | } | ||
3629 | } | ||
3630 | return; | ||
3631 | case 0x85: | ||
3632 | if (usb_endpoint_xfer_isoc(e)) { | ||
3633 | if (size > dev->dvb_max_pkt_size_isoc_ts2) { | ||
3634 | dev->dvb_ep_isoc_ts2 = e->bEndpointAddress; | ||
3635 | dev->dvb_max_pkt_size_isoc_ts2 = size; | ||
3636 | dev->dvb_alt_isoc = alt; | ||
3637 | } | ||
3638 | } else { | ||
3639 | dev->dvb_ep_bulk_ts2 = e->bEndpointAddress; | ||
3640 | } | ||
3641 | return; | ||
3642 | } | ||
3643 | } | ||
3644 | |||
3438 | /* | 3645 | /* |
3439 | * em28xx_usb_probe() | 3646 | * em28xx_usb_probe() |
3440 | * checks for supported devices | 3647 | * checks for supported devices |
3441 | */ | 3648 | */ |
3442 | static int em28xx_usb_probe(struct usb_interface *interface, | 3649 | static int em28xx_usb_probe(struct usb_interface *intf, |
3443 | const struct usb_device_id *id) | 3650 | const struct usb_device_id *id) |
3444 | { | 3651 | { |
3445 | struct usb_device *udev; | 3652 | struct usb_device *udev; |
@@ -3447,17 +3654,17 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3447 | int retval; | 3654 | int retval; |
3448 | bool has_vendor_audio = false, has_video = false, has_dvb = false; | 3655 | bool has_vendor_audio = false, has_video = false, has_dvb = false; |
3449 | int i, nr, try_bulk; | 3656 | int i, nr, try_bulk; |
3450 | const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; | 3657 | const int ifnum = intf->altsetting[0].desc.bInterfaceNumber; |
3451 | char *speed; | 3658 | char *speed; |
3452 | 3659 | ||
3453 | udev = usb_get_dev(interface_to_usbdev(interface)); | 3660 | udev = usb_get_dev(interface_to_usbdev(intf)); |
3454 | 3661 | ||
3455 | /* Check to see next free device and mark as used */ | 3662 | /* Check to see next free device and mark as used */ |
3456 | do { | 3663 | do { |
3457 | nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); | 3664 | nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); |
3458 | if (nr >= EM28XX_MAXBOARDS) { | 3665 | if (nr >= EM28XX_MAXBOARDS) { |
3459 | /* No free device slots */ | 3666 | /* No free device slots */ |
3460 | dev_err(&interface->dev, | 3667 | dev_err(&intf->dev, |
3461 | "Driver supports up to %i em28xx boards.\n", | 3668 | "Driver supports up to %i em28xx boards.\n", |
3462 | EM28XX_MAXBOARDS); | 3669 | EM28XX_MAXBOARDS); |
3463 | retval = -ENOMEM; | 3670 | retval = -ENOMEM; |
@@ -3466,13 +3673,13 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3466 | } while (test_and_set_bit(nr, em28xx_devused)); | 3673 | } while (test_and_set_bit(nr, em28xx_devused)); |
3467 | 3674 | ||
3468 | /* Don't register audio interfaces */ | 3675 | /* Don't register audio interfaces */ |
3469 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | 3676 | if (intf->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { |
3470 | dev_err(&interface->dev, | 3677 | dev_err(&intf->dev, |
3471 | "audio device (%04x:%04x): interface %i, class %i\n", | 3678 | "audio device (%04x:%04x): interface %i, class %i\n", |
3472 | le16_to_cpu(udev->descriptor.idVendor), | 3679 | le16_to_cpu(udev->descriptor.idVendor), |
3473 | le16_to_cpu(udev->descriptor.idProduct), | 3680 | le16_to_cpu(udev->descriptor.idProduct), |
3474 | ifnum, | 3681 | ifnum, |
3475 | interface->altsetting[0].desc.bInterfaceClass); | 3682 | intf->altsetting[0].desc.bInterfaceClass); |
3476 | 3683 | ||
3477 | retval = -ENODEV; | 3684 | retval = -ENODEV; |
3478 | goto err; | 3685 | goto err; |
@@ -3480,106 +3687,33 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3480 | 3687 | ||
3481 | /* allocate memory for our device state and initialize it */ | 3688 | /* allocate memory for our device state and initialize it */ |
3482 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 3689 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
3483 | if (dev == NULL) { | 3690 | if (!dev) { |
3484 | retval = -ENOMEM; | 3691 | retval = -ENOMEM; |
3485 | goto err; | 3692 | goto err; |
3486 | } | 3693 | } |
3487 | 3694 | ||
3488 | /* compute alternate max packet sizes */ | 3695 | /* compute alternate max packet sizes */ |
3489 | dev->alt_max_pkt_size_isoc = | 3696 | dev->alt_max_pkt_size_isoc = kcalloc(intf->num_altsetting, |
3490 | kmalloc(sizeof(dev->alt_max_pkt_size_isoc[0]) * | 3697 | sizeof(dev->alt_max_pkt_size_isoc[0]), |
3491 | interface->num_altsetting, GFP_KERNEL); | 3698 | GFP_KERNEL); |
3492 | if (dev->alt_max_pkt_size_isoc == NULL) { | 3699 | if (!dev->alt_max_pkt_size_isoc) { |
3493 | kfree(dev); | 3700 | kfree(dev); |
3494 | retval = -ENOMEM; | 3701 | retval = -ENOMEM; |
3495 | goto err; | 3702 | goto err; |
3496 | } | 3703 | } |
3497 | 3704 | ||
3498 | /* Get endpoints */ | 3705 | /* Get endpoints */ |
3499 | for (i = 0; i < interface->num_altsetting; i++) { | 3706 | for (i = 0; i < intf->num_altsetting; i++) { |
3500 | int ep; | 3707 | int ep; |
3501 | 3708 | ||
3502 | for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) { | 3709 | for (ep = 0; |
3503 | const struct usb_endpoint_descriptor *e; | 3710 | ep < intf->altsetting[i].desc.bNumEndpoints; |
3504 | int sizedescr, size; | 3711 | ep++) |
3505 | 3712 | em28xx_check_usb_descriptor(dev, udev, intf, | |
3506 | e = &interface->altsetting[i].endpoint[ep].desc; | 3713 | i, ep, |
3507 | 3714 | &has_vendor_audio, | |
3508 | sizedescr = le16_to_cpu(e->wMaxPacketSize); | 3715 | &has_video, |
3509 | size = sizedescr & 0x7ff; | 3716 | &has_dvb); |
3510 | |||
3511 | if (udev->speed == USB_SPEED_HIGH) | ||
3512 | size = size * hb_mult(sizedescr); | ||
3513 | |||
3514 | if (usb_endpoint_dir_in(e)) { | ||
3515 | switch (e->bEndpointAddress) { | ||
3516 | case 0x82: | ||
3517 | has_video = true; | ||
3518 | if (usb_endpoint_xfer_isoc(e)) { | ||
3519 | dev->analog_ep_isoc = | ||
3520 | e->bEndpointAddress; | ||
3521 | dev->alt_max_pkt_size_isoc[i] = size; | ||
3522 | } else if (usb_endpoint_xfer_bulk(e)) { | ||
3523 | dev->analog_ep_bulk = | ||
3524 | e->bEndpointAddress; | ||
3525 | } | ||
3526 | break; | ||
3527 | case 0x83: | ||
3528 | if (usb_endpoint_xfer_isoc(e)) { | ||
3529 | has_vendor_audio = true; | ||
3530 | } else { | ||
3531 | dev_err(&interface->dev, | ||
3532 | "error: skipping audio endpoint 0x83, because it uses bulk transfers !\n"); | ||
3533 | } | ||
3534 | break; | ||
3535 | case 0x84: | ||
3536 | if (has_video && | ||
3537 | (usb_endpoint_xfer_bulk(e))) { | ||
3538 | dev->analog_ep_bulk = | ||
3539 | e->bEndpointAddress; | ||
3540 | } else { | ||
3541 | if (usb_endpoint_xfer_isoc(e)) { | ||
3542 | if (size > dev->dvb_max_pkt_size_isoc) { | ||
3543 | has_dvb = true; /* see NOTE (~) */ | ||
3544 | dev->dvb_ep_isoc = e->bEndpointAddress; | ||
3545 | dev->dvb_max_pkt_size_isoc = size; | ||
3546 | dev->dvb_alt_isoc = i; | ||
3547 | } | ||
3548 | } else { | ||
3549 | has_dvb = true; | ||
3550 | dev->dvb_ep_bulk = e->bEndpointAddress; | ||
3551 | } | ||
3552 | } | ||
3553 | break; | ||
3554 | } | ||
3555 | } | ||
3556 | /* NOTE: | ||
3557 | * Old logic with support for isoc transfers only was: | ||
3558 | * 0x82 isoc => analog | ||
3559 | * 0x83 isoc => audio | ||
3560 | * 0x84 isoc => digital | ||
3561 | * | ||
3562 | * New logic with support for bulk transfers | ||
3563 | * 0x82 isoc => analog | ||
3564 | * 0x82 bulk => analog | ||
3565 | * 0x83 isoc* => audio | ||
3566 | * 0x84 isoc => digital | ||
3567 | * 0x84 bulk => analog or digital** | ||
3568 | * (*: audio should always be isoc) | ||
3569 | * (**: analog, if ep 0x82 is isoc, otherwise digital) | ||
3570 | * | ||
3571 | * The new logic preserves backwards compatibility and | ||
3572 | * reflects the endpoint configurations we have seen | ||
3573 | * so far. But there might be devices for which this | ||
3574 | * logic is not sufficient... | ||
3575 | */ | ||
3576 | /* | ||
3577 | * NOTE (~): some manufacturers (e.g. Terratec) disable | ||
3578 | * endpoints by setting wMaxPacketSize to 0 bytes for | ||
3579 | * all alt settings. So far, we've seen this for | ||
3580 | * DVB isoc endpoints only. | ||
3581 | */ | ||
3582 | } | ||
3583 | } | 3717 | } |
3584 | 3718 | ||
3585 | if (!(has_vendor_audio || has_video || has_dvb)) { | 3719 | if (!(has_vendor_audio || has_video || has_dvb)) { |
@@ -3602,7 +3736,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3602 | speed = "unknown"; | 3736 | speed = "unknown"; |
3603 | } | 3737 | } |
3604 | 3738 | ||
3605 | dev_err(&interface->dev, | 3739 | dev_err(&intf->dev, |
3606 | "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", | 3740 | "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n", |
3607 | udev->manufacturer ? udev->manufacturer : "", | 3741 | udev->manufacturer ? udev->manufacturer : "", |
3608 | udev->product ? udev->product : "", | 3742 | udev->product ? udev->product : "", |
@@ -3610,7 +3744,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3610 | le16_to_cpu(udev->descriptor.idVendor), | 3744 | le16_to_cpu(udev->descriptor.idVendor), |
3611 | le16_to_cpu(udev->descriptor.idProduct), | 3745 | le16_to_cpu(udev->descriptor.idProduct), |
3612 | ifnum, | 3746 | ifnum, |
3613 | interface->altsetting->desc.bInterfaceNumber); | 3747 | intf->altsetting->desc.bInterfaceNumber); |
3614 | 3748 | ||
3615 | /* | 3749 | /* |
3616 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | 3750 | * Make sure we have 480 Mbps of bandwidth, otherwise things like |
@@ -3618,8 +3752,8 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3618 | * not enough even for most Digital TV streams. | 3752 | * not enough even for most Digital TV streams. |
3619 | */ | 3753 | */ |
3620 | if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | 3754 | if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { |
3621 | dev_err(&interface->dev, "Device initialization failed.\n"); | 3755 | dev_err(&intf->dev, "Device initialization failed.\n"); |
3622 | dev_err(&interface->dev, | 3756 | dev_err(&intf->dev, |
3623 | "Device must be connected to a high-speed USB 2.0 port.\n"); | 3757 | "Device must be connected to a high-speed USB 2.0 port.\n"); |
3624 | retval = -ENODEV; | 3758 | retval = -ENODEV; |
3625 | goto err_free; | 3759 | goto err_free; |
@@ -3632,53 +3766,56 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3632 | dev->has_video = has_video; | 3766 | dev->has_video = has_video; |
3633 | dev->ifnum = ifnum; | 3767 | dev->ifnum = ifnum; |
3634 | 3768 | ||
3769 | dev->ts = PRIMARY_TS; | ||
3770 | snprintf(dev->name, 28, "em28xx"); | ||
3771 | dev->dev_next = NULL; | ||
3772 | |||
3635 | if (has_vendor_audio) { | 3773 | if (has_vendor_audio) { |
3636 | dev_err(&interface->dev, | 3774 | dev_err(&intf->dev, |
3637 | "Audio interface %i found (Vendor Class)\n", ifnum); | 3775 | "Audio interface %i found (Vendor Class)\n", ifnum); |
3638 | dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR; | 3776 | dev->usb_audio_type = EM28XX_USB_AUDIO_VENDOR; |
3639 | } | 3777 | } |
3640 | /* Checks if audio is provided by a USB Audio Class interface */ | 3778 | /* Checks if audio is provided by a USB Audio Class intf */ |
3641 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | 3779 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { |
3642 | struct usb_interface *uif = udev->config->interface[i]; | 3780 | struct usb_interface *uif = udev->config->interface[i]; |
3643 | 3781 | ||
3644 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | 3782 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { |
3645 | if (has_vendor_audio) | 3783 | if (has_vendor_audio) |
3646 | dev_err(&interface->dev, | 3784 | dev_err(&intf->dev, |
3647 | "em28xx: device seems to have vendor AND usb audio class interfaces !\n" | 3785 | "em28xx: device seems to have vendor AND usb audio class interfaces !\n" |
3648 | "\t\tThe vendor interface will be ignored. Please contact the developers <linux-media@vger.kernel.org>\n"); | 3786 | "\t\tThe vendor interface will be ignored. Please contact the developers <linux-media@vger.kernel.org>\n"); |
3649 | dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; | 3787 | dev->usb_audio_type = EM28XX_USB_AUDIO_CLASS; |
3650 | break; | 3788 | break; |
3651 | } | 3789 | } |
3652 | } | 3790 | } |
3653 | 3791 | ||
3654 | if (has_video) | 3792 | if (has_video) |
3655 | dev_err(&interface->dev, "Video interface %i found:%s%s\n", | 3793 | dev_err(&intf->dev, "Video interface %i found:%s%s\n", |
3656 | ifnum, | 3794 | ifnum, |
3657 | dev->analog_ep_bulk ? " bulk" : "", | 3795 | dev->analog_ep_bulk ? " bulk" : "", |
3658 | dev->analog_ep_isoc ? " isoc" : ""); | 3796 | dev->analog_ep_isoc ? " isoc" : ""); |
3659 | if (has_dvb) | 3797 | if (has_dvb) |
3660 | dev_err(&interface->dev, "DVB interface %i found:%s%s\n", | 3798 | dev_err(&intf->dev, "DVB interface %i found:%s%s\n", |
3661 | ifnum, | 3799 | ifnum, |
3662 | dev->dvb_ep_bulk ? " bulk" : "", | 3800 | dev->dvb_ep_bulk ? " bulk" : "", |
3663 | dev->dvb_ep_isoc ? " isoc" : ""); | 3801 | dev->dvb_ep_isoc ? " isoc" : ""); |
3664 | 3802 | ||
3665 | dev->num_alt = interface->num_altsetting; | 3803 | dev->num_alt = intf->num_altsetting; |
3666 | 3804 | ||
3667 | if ((unsigned)card[nr] < em28xx_bcount) | 3805 | if ((unsigned int)card[nr] < em28xx_bcount) |
3668 | dev->model = card[nr]; | 3806 | dev->model = card[nr]; |
3669 | 3807 | ||
3670 | /* save our data pointer in this interface device */ | 3808 | /* save our data pointer in this intf device */ |
3671 | usb_set_intfdata(interface, dev); | 3809 | usb_set_intfdata(intf, dev); |
3672 | 3810 | ||
3673 | /* allocate device struct and check if the device is a webcam */ | 3811 | /* allocate device struct and check if the device is a webcam */ |
3674 | mutex_init(&dev->lock); | 3812 | mutex_init(&dev->lock); |
3675 | retval = em28xx_init_dev(dev, udev, interface, nr); | 3813 | retval = em28xx_init_dev(dev, udev, intf, nr); |
3676 | if (retval) { | 3814 | if (retval) |
3677 | goto err_free; | 3815 | goto err_free; |
3678 | } | ||
3679 | 3816 | ||
3680 | if (usb_xfer_mode < 0) { | 3817 | if (usb_xfer_mode < 0) { |
3681 | if (dev->board.is_webcam) | 3818 | if (dev->is_webcam) |
3682 | try_bulk = 1; | 3819 | try_bulk = 1; |
3683 | else | 3820 | else |
3684 | try_bulk = 0; | 3821 | try_bulk = 0; |
@@ -3690,8 +3827,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3690 | if (has_video && | 3827 | if (has_video && |
3691 | dev->board.decoder == EM28XX_NODECODER && | 3828 | dev->board.decoder == EM28XX_NODECODER && |
3692 | dev->em28xx_sensor == EM28XX_NOSENSOR) { | 3829 | dev->em28xx_sensor == EM28XX_NOSENSOR) { |
3693 | 3830 | dev_err(&intf->dev, | |
3694 | dev_err(&interface->dev, | ||
3695 | "Currently, V4L2 is not supported on this model\n"); | 3831 | "Currently, V4L2 is not supported on this model\n"); |
3696 | has_video = false; | 3832 | has_video = false; |
3697 | dev->has_video = false; | 3833 | dev->has_video = false; |
@@ -3701,16 +3837,75 @@ static int em28xx_usb_probe(struct usb_interface *interface, | |||
3701 | if (has_video) { | 3837 | if (has_video) { |
3702 | if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) | 3838 | if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk)) |
3703 | dev->analog_xfer_bulk = 1; | 3839 | dev->analog_xfer_bulk = 1; |
3704 | dev_err(&interface->dev, "analog set to %s mode.\n", | 3840 | dev_err(&intf->dev, "analog set to %s mode.\n", |
3705 | dev->analog_xfer_bulk ? "bulk" : "isoc"); | 3841 | dev->analog_xfer_bulk ? "bulk" : "isoc"); |
3706 | } | 3842 | } |
3707 | if (has_dvb) { | 3843 | if (has_dvb) { |
3708 | if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) | 3844 | if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk)) |
3709 | dev->dvb_xfer_bulk = 1; | 3845 | dev->dvb_xfer_bulk = 1; |
3710 | dev_err(&interface->dev, "dvb set to %s mode.\n", | 3846 | dev_err(&intf->dev, "dvb set to %s mode.\n", |
3711 | dev->dvb_xfer_bulk ? "bulk" : "isoc"); | 3847 | dev->dvb_xfer_bulk ? "bulk" : "isoc"); |
3712 | } | 3848 | } |
3713 | 3849 | ||
3850 | if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) { | ||
3851 | dev->dev_next->ts = SECONDARY_TS; | ||
3852 | dev->dev_next->alt = -1; | ||
3853 | dev->dev_next->is_audio_only = has_vendor_audio && | ||
3854 | !(has_video || has_dvb); | ||
3855 | dev->dev_next->has_video = false; | ||
3856 | dev->dev_next->ifnum = ifnum; | ||
3857 | dev->dev_next->model = id->driver_info; | ||
3858 | |||
3859 | mutex_init(&dev->dev_next->lock); | ||
3860 | retval = em28xx_init_dev(dev->dev_next, udev, intf, | ||
3861 | dev->dev_next->devno); | ||
3862 | if (retval) | ||
3863 | goto err_free; | ||
3864 | |||
3865 | dev->dev_next->board.ir_codes = NULL; /* No IR for 2nd tuner */ | ||
3866 | dev->dev_next->board.has_ir_i2c = 0; /* No IR for 2nd tuner */ | ||
3867 | |||
3868 | if (usb_xfer_mode < 0) { | ||
3869 | if (dev->dev_next->is_webcam) | ||
3870 | try_bulk = 1; | ||
3871 | else | ||
3872 | try_bulk = 0; | ||
3873 | } else { | ||
3874 | try_bulk = usb_xfer_mode > 0; | ||
3875 | } | ||
3876 | |||
3877 | /* Select USB transfer types to use */ | ||
3878 | if (has_dvb) { | ||
3879 | if (!dev->dvb_ep_isoc_ts2 || | ||
3880 | (try_bulk && dev->dvb_ep_bulk_ts2)) | ||
3881 | dev->dev_next->dvb_xfer_bulk = 1; | ||
3882 | dev_info(&dev->intf->dev, "dvb ts2 set to %s mode.\n", | ||
3883 | dev->dev_next->dvb_xfer_bulk ? "bulk" : "isoc"); | ||
3884 | } | ||
3885 | |||
3886 | dev->dev_next->dvb_ep_isoc = dev->dvb_ep_isoc_ts2; | ||
3887 | dev->dev_next->dvb_ep_bulk = dev->dvb_ep_bulk_ts2; | ||
3888 | dev->dev_next->dvb_max_pkt_size_isoc = dev->dvb_max_pkt_size_isoc_ts2; | ||
3889 | dev->dev_next->dvb_alt_isoc = dev->dvb_alt_isoc; | ||
3890 | |||
3891 | /* Configuare hardware to support TS2*/ | ||
3892 | if (dev->dvb_xfer_bulk) { | ||
3893 | /* The ep4 and ep5 are configuared for BULK */ | ||
3894 | em28xx_write_reg(dev, 0x0b, 0x96); | ||
3895 | mdelay(100); | ||
3896 | em28xx_write_reg(dev, 0x0b, 0x80); | ||
3897 | mdelay(100); | ||
3898 | } else { | ||
3899 | /* The ep4 and ep5 are configuared for ISO */ | ||
3900 | em28xx_write_reg(dev, 0x0b, 0x96); | ||
3901 | mdelay(100); | ||
3902 | em28xx_write_reg(dev, 0x0b, 0x82); | ||
3903 | mdelay(100); | ||
3904 | } | ||
3905 | |||
3906 | kref_init(&dev->dev_next->ref); | ||
3907 | } | ||
3908 | |||
3714 | kref_init(&dev->ref); | 3909 | kref_init(&dev->ref); |
3715 | 3910 | ||
3716 | request_modules(dev); | 3911 | request_modules(dev); |
@@ -3743,45 +3938,59 @@ err_no_slot: | |||
3743 | * called when the device gets disconnected | 3938 | * called when the device gets disconnected |
3744 | * video device will be unregistered on v4l2_close in case it is still open | 3939 | * video device will be unregistered on v4l2_close in case it is still open |
3745 | */ | 3940 | */ |
3746 | static void em28xx_usb_disconnect(struct usb_interface *interface) | 3941 | static void em28xx_usb_disconnect(struct usb_interface *intf) |
3747 | { | 3942 | { |
3748 | struct em28xx *dev; | 3943 | struct em28xx *dev; |
3749 | 3944 | ||
3750 | dev = usb_get_intfdata(interface); | 3945 | dev = usb_get_intfdata(intf); |
3751 | usb_set_intfdata(interface, NULL); | 3946 | usb_set_intfdata(intf, NULL); |
3752 | 3947 | ||
3753 | if (!dev) | 3948 | if (!dev) |
3754 | return; | 3949 | return; |
3755 | 3950 | ||
3951 | if (dev->dev_next) { | ||
3952 | dev->dev_next->disconnected = 1; | ||
3953 | dev_info(&dev->intf->dev, "Disconnecting %s\n", | ||
3954 | dev->dev_next->name); | ||
3955 | flush_request_modules(dev->dev_next); | ||
3956 | } | ||
3957 | |||
3756 | dev->disconnected = 1; | 3958 | dev->disconnected = 1; |
3757 | 3959 | ||
3758 | dev_err(&dev->intf->dev, "Disconnecting\n"); | 3960 | dev_err(&dev->intf->dev, "Disconnecting %s\n", dev->name); |
3759 | 3961 | ||
3760 | flush_request_modules(dev); | 3962 | flush_request_modules(dev); |
3761 | 3963 | ||
3762 | em28xx_close_extension(dev); | 3964 | em28xx_close_extension(dev); |
3763 | 3965 | ||
3966 | if (dev->dev_next) | ||
3967 | em28xx_release_resources(dev->dev_next); | ||
3764 | em28xx_release_resources(dev); | 3968 | em28xx_release_resources(dev); |
3969 | |||
3970 | if (dev->dev_next) { | ||
3971 | kref_put(&dev->dev_next->ref, em28xx_free_device); | ||
3972 | dev->dev_next = NULL; | ||
3973 | } | ||
3765 | kref_put(&dev->ref, em28xx_free_device); | 3974 | kref_put(&dev->ref, em28xx_free_device); |
3766 | } | 3975 | } |
3767 | 3976 | ||
3768 | static int em28xx_usb_suspend(struct usb_interface *interface, | 3977 | static int em28xx_usb_suspend(struct usb_interface *intf, |
3769 | pm_message_t message) | 3978 | pm_message_t message) |
3770 | { | 3979 | { |
3771 | struct em28xx *dev; | 3980 | struct em28xx *dev; |
3772 | 3981 | ||
3773 | dev = usb_get_intfdata(interface); | 3982 | dev = usb_get_intfdata(intf); |
3774 | if (!dev) | 3983 | if (!dev) |
3775 | return 0; | 3984 | return 0; |
3776 | em28xx_suspend_extension(dev); | 3985 | em28xx_suspend_extension(dev); |
3777 | return 0; | 3986 | return 0; |
3778 | } | 3987 | } |
3779 | 3988 | ||
3780 | static int em28xx_usb_resume(struct usb_interface *interface) | 3989 | static int em28xx_usb_resume(struct usb_interface *intf) |
3781 | { | 3990 | { |
3782 | struct em28xx *dev; | 3991 | struct em28xx *dev; |
3783 | 3992 | ||
3784 | dev = usb_get_intfdata(interface); | 3993 | dev = usb_get_intfdata(intf); |
3785 | if (!dev) | 3994 | if (!dev) |
3786 | return 0; | 3995 | return 0; |
3787 | em28xx_resume_extension(dev); | 3996 | em28xx_resume_extension(dev); |
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 1d0d8cc06103..36d341fb65dd 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c | |||
@@ -1,26 +1,22 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | 2 | // |
3 | 3 | // em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | |
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | // |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | 6 | // Markus Rechberger <mrechberger@gmail.com> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | // Mauro Carvalho Chehab <mchehab@infradead.org> |
8 | Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 8 | // Sascha Sommer <saschasommer@freenet.de> |
9 | 9 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | |
10 | This program is free software; you can redistribute it and/or modify | 10 | // |
11 | it under the terms of the GNU General Public License as published by | 11 | // This program is free software; you can redistribute it and/or modify |
12 | the Free Software Foundation; either version 2 of the License, or | 12 | // it under the terms of the GNU General Public License as published by |
13 | (at your option) any later version. | 13 | // the Free Software Foundation; either version 2 of the License, or |
14 | 14 | // (at your option) any later version. | |
15 | This program is distributed in the hope that it will be useful, | 15 | // |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | // This program is distributed in the hope that it will be useful, |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | GNU General Public License for more details. | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | 19 | // GNU General Public License for more details. | |
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | 20 | ||
25 | #include "em28xx.h" | 21 | #include "em28xx.h" |
26 | 22 | ||
@@ -41,7 +37,7 @@ | |||
41 | 37 | ||
42 | MODULE_AUTHOR(DRIVER_AUTHOR); | 38 | MODULE_AUTHOR(DRIVER_AUTHOR); |
43 | MODULE_DESCRIPTION(DRIVER_DESC); | 39 | MODULE_DESCRIPTION(DRIVER_DESC); |
44 | MODULE_LICENSE("GPL"); | 40 | MODULE_LICENSE("GPL v2"); |
45 | MODULE_VERSION(EM28XX_VERSION); | 41 | MODULE_VERSION(EM28XX_VERSION); |
46 | 42 | ||
47 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ | 43 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ |
@@ -60,7 +56,6 @@ static unsigned int reg_debug; | |||
60 | module_param(reg_debug, int, 0644); | 56 | module_param(reg_debug, int, 0644); |
61 | MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); | 57 | MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); |
62 | 58 | ||
63 | |||
64 | #define em28xx_regdbg(fmt, arg...) do { \ | 59 | #define em28xx_regdbg(fmt, arg...) do { \ |
65 | if (reg_debug) \ | 60 | if (reg_debug) \ |
66 | dev_printk(KERN_DEBUG, &dev->intf->dev, \ | 61 | dev_printk(KERN_DEBUG, &dev->intf->dev, \ |
@@ -97,10 +92,11 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
97 | 0x0000, reg, dev->urb_buf, len, HZ); | 92 | 0x0000, reg, dev->urb_buf, len, HZ); |
98 | if (ret < 0) { | 93 | if (ret < 0) { |
99 | em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", | 94 | em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", |
100 | pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 95 | pipe, |
101 | req, 0, 0, | 96 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
102 | reg & 0xff, reg >> 8, | 97 | req, 0, 0, |
103 | len & 0xff, len >> 8, ret); | 98 | reg & 0xff, reg >> 8, |
99 | len & 0xff, len >> 8, ret); | ||
104 | mutex_unlock(&dev->ctrl_urb_lock); | 100 | mutex_unlock(&dev->ctrl_urb_lock); |
105 | return usb_translate_errors(ret); | 101 | return usb_translate_errors(ret); |
106 | } | 102 | } |
@@ -111,10 +107,10 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
111 | mutex_unlock(&dev->ctrl_urb_lock); | 107 | mutex_unlock(&dev->ctrl_urb_lock); |
112 | 108 | ||
113 | em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x <<< %*ph\n", | 109 | em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x <<< %*ph\n", |
114 | pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 110 | pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
115 | req, 0, 0, | 111 | req, 0, 0, |
116 | reg & 0xff, reg >> 8, | 112 | reg & 0xff, reg >> 8, |
117 | len & 0xff, len >> 8, len, buf); | 113 | len & 0xff, len >> 8, len, buf); |
118 | 114 | ||
119 | return ret; | 115 | return ret; |
120 | } | 116 | } |
@@ -155,7 +151,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
155 | if (dev->disconnected) | 151 | if (dev->disconnected) |
156 | return -ENODEV; | 152 | return -ENODEV; |
157 | 153 | ||
158 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) | 154 | if (len < 1 || len > URB_MAX_CTRL_SIZE) |
159 | return -EINVAL; | 155 | return -EINVAL; |
160 | 156 | ||
161 | mutex_lock(&dev->ctrl_urb_lock); | 157 | mutex_lock(&dev->ctrl_urb_lock); |
@@ -341,8 +337,9 @@ static int set_ac97_input(struct em28xx *dev) | |||
341 | int ret, i; | 337 | int ret, i; |
342 | enum em28xx_amux amux = dev->ctl_ainput; | 338 | enum em28xx_amux amux = dev->ctl_ainput; |
343 | 339 | ||
344 | /* EM28XX_AMUX_VIDEO2 is a special case used to indicate that | 340 | /* |
345 | em28xx should point to LINE IN, while AC97 should use VIDEO | 341 | * EM28XX_AMUX_VIDEO2 is a special case used to indicate that |
342 | * em28xx should point to LINE IN, while AC97 should use VIDEO | ||
346 | */ | 343 | */ |
347 | if (amux == EM28XX_AMUX_VIDEO2) | 344 | if (amux == EM28XX_AMUX_VIDEO2) |
348 | amux = EM28XX_AMUX_VIDEO; | 345 | amux = EM28XX_AMUX_VIDEO; |
@@ -378,9 +375,9 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
378 | return ret; | 375 | return ret; |
379 | } | 376 | } |
380 | 377 | ||
381 | if (dev->board.has_msp34xx) | 378 | if (dev->has_msp34xx) { |
382 | input = EM28XX_AUDIO_SRC_TUNER; | 379 | input = EM28XX_AUDIO_SRC_TUNER; |
383 | else { | 380 | } else { |
384 | switch (dev->ctl_ainput) { | 381 | switch (dev->ctl_ainput) { |
385 | case EM28XX_AMUX_VIDEO: | 382 | case EM28XX_AMUX_VIDEO: |
386 | input = EM28XX_AUDIO_SRC_TUNER; | 383 | input = EM28XX_AUDIO_SRC_TUNER; |
@@ -399,7 +396,7 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
399 | ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); | 396 | ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); |
400 | if (ret < 0) | 397 | if (ret < 0) |
401 | return ret; | 398 | return ret; |
402 | msleep(5); | 399 | usleep_range(10000, 11000); |
403 | 400 | ||
404 | switch (dev->audio_mode.ac97) { | 401 | switch (dev->audio_mode.ac97) { |
405 | case EM28XX_NO_AC97: | 402 | case EM28XX_NO_AC97: |
@@ -432,8 +429,9 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
432 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) | 429 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) |
433 | return 0; | 430 | return 0; |
434 | 431 | ||
435 | /* It is assumed that all devices use master volume for output. | 432 | /* |
436 | It would be possible to use also line output. | 433 | * It is assumed that all devices use master volume for output. |
434 | * It would be possible to use also line output. | ||
437 | */ | 435 | */ |
438 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | 436 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
439 | /* Mute all outputs */ | 437 | /* Mute all outputs */ |
@@ -453,7 +451,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
453 | ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); | 451 | ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); |
454 | if (ret < 0) | 452 | if (ret < 0) |
455 | return ret; | 453 | return ret; |
456 | msleep(10); | 454 | usleep_range(10000, 11000); |
457 | 455 | ||
458 | /* Selects the proper audio input */ | 456 | /* Selects the proper audio input */ |
459 | ret = em28xx_set_audio_source(dev); | 457 | ret = em28xx_set_audio_source(dev); |
@@ -487,8 +485,10 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
487 | if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { | 485 | if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { |
488 | int sel = ac97_return_record_select(dev->ctl_aoutput); | 486 | int sel = ac97_return_record_select(dev->ctl_aoutput); |
489 | 487 | ||
490 | /* Use the same input for both left and right | 488 | /* |
491 | channels */ | 489 | * Use the same input for both left and right |
490 | * channels | ||
491 | */ | ||
492 | sel |= (sel << 8); | 492 | sel |= (sel << 8); |
493 | 493 | ||
494 | em28xx_write_ac97(dev, AC97_REC_SEL, sel); | 494 | em28xx_write_ac97(dev, AC97_REC_SEL, sel); |
@@ -539,7 +539,7 @@ int em28xx_audio_setup(struct em28xx *dev) | |||
539 | else | 539 | else |
540 | i2s_samplerates = 3; | 540 | i2s_samplerates = 3; |
541 | dev_info(&dev->intf->dev, "I2S Audio (%d sample rate(s))\n", | 541 | dev_info(&dev->intf->dev, "I2S Audio (%d sample rate(s))\n", |
542 | i2s_samplerates); | 542 | i2s_samplerates); |
543 | /* Skip the code that does AC97 vendor detection */ | 543 | /* Skip the code that does AC97 vendor detection */ |
544 | dev->audio_mode.ac97 = EM28XX_NO_AC97; | 544 | dev->audio_mode.ac97 = EM28XX_NO_AC97; |
545 | goto init_audio; | 545 | goto init_audio; |
@@ -579,7 +579,7 @@ int em28xx_audio_setup(struct em28xx *dev) | |||
579 | dev_warn(&dev->intf->dev, "AC97 features = 0x%04x\n", feat); | 579 | dev_warn(&dev->intf->dev, "AC97 features = 0x%04x\n", feat); |
580 | 580 | ||
581 | /* Try to identify what audio processor we have */ | 581 | /* Try to identify what audio processor we have */ |
582 | if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90)) | 582 | if ((vid == 0xffffffff || vid == 0x83847650) && feat == 0x6a90) |
583 | dev->audio_mode.ac97 = EM28XX_AC97_EM202; | 583 | dev->audio_mode.ac97 = EM28XX_AC97_EM202; |
584 | else if ((vid >> 8) == 0x838476) | 584 | else if ((vid >> 8) == 0x838476) |
585 | dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL; | 585 | dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL; |
@@ -638,10 +638,29 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
638 | dev->chip_id == CHIP_ID_EM28174 || | 638 | dev->chip_id == CHIP_ID_EM28174 || |
639 | dev->chip_id == CHIP_ID_EM28178) { | 639 | dev->chip_id == CHIP_ID_EM28178) { |
640 | /* The Transport Stream Enable Register moved in em2874 */ | 640 | /* The Transport Stream Enable Register moved in em2874 */ |
641 | rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, | 641 | if (dev->dvb_xfer_bulk) { |
642 | start ? | 642 | /* Max Tx Size = 188 * 256 = 48128 - LCM(188,512) * 2 */ |
643 | EM2874_TS1_CAPTURE_ENABLE : 0x00, | 643 | em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? |
644 | EM2874_TS1_CAPTURE_ENABLE); | 644 | EM2874_R5D_TS1_PKT_SIZE : |
645 | EM2874_R5E_TS2_PKT_SIZE, | ||
646 | 0xff); | ||
647 | } else { | ||
648 | /* ISOC Maximum Transfer Size = 188 * 5 */ | ||
649 | em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? | ||
650 | EM2874_R5D_TS1_PKT_SIZE : | ||
651 | EM2874_R5E_TS2_PKT_SIZE, | ||
652 | dev->dvb_max_pkt_size_isoc / 188); | ||
653 | } | ||
654 | if (dev->ts == PRIMARY_TS) | ||
655 | rc = em28xx_write_reg_bits(dev, | ||
656 | EM2874_R5F_TS_ENABLE, | ||
657 | start ? EM2874_TS1_CAPTURE_ENABLE : 0x00, | ||
658 | EM2874_TS1_CAPTURE_ENABLE); | ||
659 | else | ||
660 | rc = em28xx_write_reg_bits(dev, | ||
661 | EM2874_R5F_TS_ENABLE, | ||
662 | start ? EM2874_TS2_CAPTURE_ENABLE : 0x00, | ||
663 | EM2874_TS2_CAPTURE_ENABLE); | ||
645 | } else { | 664 | } else { |
646 | /* FIXME: which is the best order? */ | 665 | /* FIXME: which is the best order? */ |
647 | /* video registers are sampled by VREF */ | 666 | /* video registers are sampled by VREF */ |
@@ -651,7 +670,7 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
651 | return rc; | 670 | return rc; |
652 | 671 | ||
653 | if (start) { | 672 | if (start) { |
654 | if (dev->board.is_webcam) | 673 | if (dev->is_webcam) |
655 | rc = em28xx_write_reg(dev, 0x13, 0x0c); | 674 | rc = em28xx_write_reg(dev, 0x13, 0x0c); |
656 | 675 | ||
657 | /* Enable video capture */ | 676 | /* Enable video capture */ |
@@ -670,7 +689,7 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
670 | if (rc < 0) | 689 | if (rc < 0) |
671 | return rc; | 690 | return rc; |
672 | 691 | ||
673 | msleep(6); | 692 | usleep_range(10000, 11000); |
674 | } else { | 693 | } else { |
675 | /* disable video capture */ | 694 | /* disable video capture */ |
676 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); | 695 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); |
@@ -691,7 +710,7 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
691 | return rc; | 710 | return rc; |
692 | } | 711 | } |
693 | 712 | ||
694 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) | 713 | int em28xx_gpio_set(struct em28xx *dev, const struct em28xx_reg_seq *gpio) |
695 | { | 714 | { |
696 | int rc = 0; | 715 | int rc = 0; |
697 | 716 | ||
@@ -704,7 +723,7 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) | |||
704 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); | 723 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); |
705 | else | 724 | else |
706 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); | 725 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); |
707 | msleep(6); | 726 | usleep_range(10000, 11000); |
708 | } | 727 | } |
709 | 728 | ||
710 | /* Send GPIO reset sequences specified at board entry */ | 729 | /* Send GPIO reset sequences specified at board entry */ |
@@ -748,9 +767,9 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) | |||
748 | } | 767 | } |
749 | EXPORT_SYMBOL_GPL(em28xx_set_mode); | 768 | EXPORT_SYMBOL_GPL(em28xx_set_mode); |
750 | 769 | ||
751 | /* ------------------------------------------------------------------ | 770 | /* |
752 | URB control | 771 | *URB control |
753 | ------------------------------------------------------------------*/ | 772 | */ |
754 | 773 | ||
755 | /* | 774 | /* |
756 | * URB completion handler for isoc/bulk transfers | 775 | * URB completion handler for isoc/bulk transfers |
@@ -769,7 +788,7 @@ static void em28xx_irq_callback(struct urb *urb) | |||
769 | case -ESHUTDOWN: | 788 | case -ESHUTDOWN: |
770 | return; | 789 | return; |
771 | default: /* error */ | 790 | default: /* error */ |
772 | em28xx_isocdbg("urb completition error %d.\n", urb->status); | 791 | em28xx_isocdbg("urb completion error %d.\n", urb->status); |
773 | break; | 792 | break; |
774 | } | 793 | } |
775 | 794 | ||
@@ -800,11 +819,9 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) | |||
800 | { | 819 | { |
801 | struct urb *urb; | 820 | struct urb *urb; |
802 | struct em28xx_usb_bufs *usb_bufs; | 821 | struct em28xx_usb_bufs *usb_bufs; |
803 | struct usb_device *udev = interface_to_usbdev(dev->intf); | ||
804 | int i; | 822 | int i; |
805 | 823 | ||
806 | em28xx_isocdbg("em28xx: called em28xx_uninit_usb_xfer in mode %d\n", | 824 | em28xx_isocdbg("called %s in mode %d\n", __func__, mode); |
807 | mode); | ||
808 | 825 | ||
809 | if (mode == EM28XX_DIGITAL_MODE) | 826 | if (mode == EM28XX_DIGITAL_MODE) |
810 | usb_bufs = &dev->usb_ctl.digital_bufs; | 827 | usb_bufs = &dev->usb_ctl.digital_bufs; |
@@ -819,23 +836,16 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) | |||
819 | else | 836 | else |
820 | usb_unlink_urb(urb); | 837 | usb_unlink_urb(urb); |
821 | 838 | ||
822 | if (usb_bufs->transfer_buffer[i]) { | ||
823 | usb_free_coherent(udev, | ||
824 | urb->transfer_buffer_length, | ||
825 | usb_bufs->transfer_buffer[i], | ||
826 | urb->transfer_dma); | ||
827 | } | ||
828 | usb_free_urb(urb); | 839 | usb_free_urb(urb); |
829 | usb_bufs->urb[i] = NULL; | 840 | usb_bufs->urb[i] = NULL; |
830 | } | 841 | } |
831 | usb_bufs->transfer_buffer[i] = NULL; | ||
832 | } | 842 | } |
833 | 843 | ||
834 | kfree(usb_bufs->urb); | 844 | kfree(usb_bufs->urb); |
835 | kfree(usb_bufs->transfer_buffer); | 845 | kfree(usb_bufs->buf); |
836 | 846 | ||
837 | usb_bufs->urb = NULL; | 847 | usb_bufs->urb = NULL; |
838 | usb_bufs->transfer_buffer = NULL; | 848 | usb_bufs->buf = NULL; |
839 | usb_bufs->num_bufs = 0; | 849 | usb_bufs->num_bufs = 0; |
840 | 850 | ||
841 | em28xx_capture_start(dev, 0); | 851 | em28xx_capture_start(dev, 0); |
@@ -851,7 +861,7 @@ void em28xx_stop_urbs(struct em28xx *dev) | |||
851 | struct urb *urb; | 861 | struct urb *urb; |
852 | struct em28xx_usb_bufs *isoc_bufs = &dev->usb_ctl.digital_bufs; | 862 | struct em28xx_usb_bufs *isoc_bufs = &dev->usb_ctl.digital_bufs; |
853 | 863 | ||
854 | em28xx_isocdbg("em28xx: called em28xx_stop_urbs\n"); | 864 | em28xx_isocdbg("called %s\n", __func__); |
855 | 865 | ||
856 | for (i = 0; i < isoc_bufs->num_bufs; i++) { | 866 | for (i = 0; i < isoc_bufs->num_bufs; i++) { |
857 | urb = isoc_bufs->urb[i]; | 867 | urb = isoc_bufs->urb[i]; |
@@ -880,10 +890,12 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, | |||
880 | int sb_size, pipe; | 890 | int sb_size, pipe; |
881 | int j, k; | 891 | int j, k; |
882 | 892 | ||
883 | em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode); | 893 | em28xx_isocdbg("em28xx: called %s in mode %d\n", __func__, mode); |
884 | 894 | ||
885 | /* Check mode and if we have an endpoint for the selected | 895 | /* |
886 | transfer type, select buffer */ | 896 | * Check mode and if we have an endpoint for the selected |
897 | * transfer type, select buffer | ||
898 | */ | ||
887 | if (mode == EM28XX_DIGITAL_MODE) { | 899 | if (mode == EM28XX_DIGITAL_MODE) { |
888 | if ((xfer_bulk && !dev->dvb_ep_bulk) || | 900 | if ((xfer_bulk && !dev->dvb_ep_bulk) || |
889 | (!xfer_bulk && !dev->dvb_ep_isoc)) { | 901 | (!xfer_bulk && !dev->dvb_ep_isoc)) { |
@@ -912,14 +924,13 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, | |||
912 | 924 | ||
913 | usb_bufs->num_bufs = num_bufs; | 925 | usb_bufs->num_bufs = num_bufs; |
914 | 926 | ||
915 | usb_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); | 927 | usb_bufs->urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); |
916 | if (!usb_bufs->urb) | 928 | if (!usb_bufs->urb) |
917 | return -ENOMEM; | 929 | return -ENOMEM; |
918 | 930 | ||
919 | usb_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | 931 | usb_bufs->buf = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); |
920 | GFP_KERNEL); | 932 | if (!usb_bufs->buf) { |
921 | if (!usb_bufs->transfer_buffer) { | 933 | kfree(usb_bufs->buf); |
922 | kfree(usb_bufs->urb); | ||
923 | return -ENOMEM; | 934 | return -ENOMEM; |
924 | } | 935 | } |
925 | 936 | ||
@@ -942,37 +953,36 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, | |||
942 | } | 953 | } |
943 | usb_bufs->urb[i] = urb; | 954 | usb_bufs->urb[i] = urb; |
944 | 955 | ||
945 | usb_bufs->transfer_buffer[i] = usb_alloc_coherent(udev, | 956 | usb_bufs->buf[i] = kzalloc(sb_size, GFP_KERNEL); |
946 | sb_size, GFP_KERNEL, &urb->transfer_dma); | 957 | if (!usb_bufs->buf[i]) { |
947 | if (!usb_bufs->transfer_buffer[i]) { | ||
948 | dev_err(&dev->intf->dev, | ||
949 | "unable to allocate %i bytes for transfer buffer %i%s\n", | ||
950 | sb_size, i, | ||
951 | in_interrupt() ? " while in int" : ""); | ||
952 | em28xx_uninit_usb_xfer(dev, mode); | 958 | em28xx_uninit_usb_xfer(dev, mode); |
959 | |||
960 | for (i--; i >= 0; i--) | ||
961 | kfree(usb_bufs->buf[i]); | ||
962 | |||
963 | kfree(usb_bufs->buf); | ||
964 | usb_bufs->buf = NULL; | ||
965 | |||
953 | return -ENOMEM; | 966 | return -ENOMEM; |
954 | } | 967 | } |
955 | memset(usb_bufs->transfer_buffer[i], 0, sb_size); | 968 | |
969 | urb->transfer_flags = URB_FREE_BUFFER; | ||
956 | 970 | ||
957 | if (xfer_bulk) { /* bulk */ | 971 | if (xfer_bulk) { /* bulk */ |
958 | pipe = usb_rcvbulkpipe(udev, | 972 | pipe = usb_rcvbulkpipe(udev, |
959 | mode == EM28XX_ANALOG_MODE ? | 973 | mode == EM28XX_ANALOG_MODE ? |
960 | dev->analog_ep_bulk : | 974 | dev->analog_ep_bulk : |
961 | dev->dvb_ep_bulk); | 975 | dev->dvb_ep_bulk); |
962 | usb_fill_bulk_urb(urb, udev, pipe, | 976 | usb_fill_bulk_urb(urb, udev, pipe, usb_bufs->buf[i], |
963 | usb_bufs->transfer_buffer[i], sb_size, | 977 | sb_size, em28xx_irq_callback, dev); |
964 | em28xx_irq_callback, dev); | ||
965 | urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | ||
966 | } else { /* isoc */ | 978 | } else { /* isoc */ |
967 | pipe = usb_rcvisocpipe(udev, | 979 | pipe = usb_rcvisocpipe(udev, |
968 | mode == EM28XX_ANALOG_MODE ? | 980 | mode == EM28XX_ANALOG_MODE ? |
969 | dev->analog_ep_isoc : | 981 | dev->analog_ep_isoc : |
970 | dev->dvb_ep_isoc); | 982 | dev->dvb_ep_isoc); |
971 | usb_fill_int_urb(urb, udev, pipe, | 983 | usb_fill_int_urb(urb, udev, pipe, usb_bufs->buf[i], |
972 | usb_bufs->transfer_buffer[i], sb_size, | 984 | sb_size, em28xx_irq_callback, dev, 1); |
973 | em28xx_irq_callback, dev, 1); | 985 | urb->transfer_flags |= URB_ISO_ASAP; |
974 | urb->transfer_flags = URB_ISO_ASAP | | ||
975 | URB_NO_TRANSFER_DMA_MAP; | ||
976 | k = 0; | 986 | k = 0; |
977 | for (j = 0; j < usb_bufs->num_packets; j++) { | 987 | for (j = 0; j < usb_bufs->num_packets; j++) { |
978 | urb->iso_frame_desc[j].offset = k; | 988 | urb->iso_frame_desc[j].offset = k; |
@@ -1005,8 +1015,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, | |||
1005 | int rc; | 1015 | int rc; |
1006 | int alloc; | 1016 | int alloc; |
1007 | 1017 | ||
1008 | em28xx_isocdbg("em28xx: called em28xx_init_usb_xfer in mode %d\n", | 1018 | em28xx_isocdbg("em28xx: called %s in mode %d\n", __func__, mode); |
1009 | mode); | ||
1010 | 1019 | ||
1011 | dev->usb_ctl.urb_data_copy = urb_data_copy; | 1020 | dev->usb_ctl.urb_data_copy = urb_data_copy; |
1012 | 1021 | ||
@@ -1077,7 +1086,11 @@ int em28xx_register_extension(struct em28xx_ops *ops) | |||
1077 | mutex_lock(&em28xx_devlist_mutex); | 1086 | mutex_lock(&em28xx_devlist_mutex); |
1078 | list_add_tail(&ops->next, &em28xx_extension_devlist); | 1087 | list_add_tail(&ops->next, &em28xx_extension_devlist); |
1079 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | 1088 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
1080 | ops->init(dev); | 1089 | if (ops->init) { |
1090 | ops->init(dev); | ||
1091 | if (dev->dev_next) | ||
1092 | ops->init(dev->dev_next); | ||
1093 | } | ||
1081 | } | 1094 | } |
1082 | mutex_unlock(&em28xx_devlist_mutex); | 1095 | mutex_unlock(&em28xx_devlist_mutex); |
1083 | pr_info("em28xx: Registered (%s) extension\n", ops->name); | 1096 | pr_info("em28xx: Registered (%s) extension\n", ops->name); |
@@ -1091,7 +1104,11 @@ void em28xx_unregister_extension(struct em28xx_ops *ops) | |||
1091 | 1104 | ||
1092 | mutex_lock(&em28xx_devlist_mutex); | 1105 | mutex_lock(&em28xx_devlist_mutex); |
1093 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | 1106 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
1094 | ops->fini(dev); | 1107 | if (ops->fini) { |
1108 | if (dev->dev_next) | ||
1109 | ops->fini(dev->dev_next); | ||
1110 | ops->fini(dev); | ||
1111 | } | ||
1095 | } | 1112 | } |
1096 | list_del(&ops->next); | 1113 | list_del(&ops->next); |
1097 | mutex_unlock(&em28xx_devlist_mutex); | 1114 | mutex_unlock(&em28xx_devlist_mutex); |
@@ -1106,8 +1123,11 @@ void em28xx_init_extension(struct em28xx *dev) | |||
1106 | mutex_lock(&em28xx_devlist_mutex); | 1123 | mutex_lock(&em28xx_devlist_mutex); |
1107 | list_add_tail(&dev->devlist, &em28xx_devlist); | 1124 | list_add_tail(&dev->devlist, &em28xx_devlist); |
1108 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | 1125 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1109 | if (ops->init) | 1126 | if (ops->init) { |
1110 | ops->init(dev); | 1127 | ops->init(dev); |
1128 | if (dev->dev_next) | ||
1129 | ops->init(dev->dev_next); | ||
1130 | } | ||
1111 | } | 1131 | } |
1112 | mutex_unlock(&em28xx_devlist_mutex); | 1132 | mutex_unlock(&em28xx_devlist_mutex); |
1113 | } | 1133 | } |
@@ -1118,8 +1138,11 @@ void em28xx_close_extension(struct em28xx *dev) | |||
1118 | 1138 | ||
1119 | mutex_lock(&em28xx_devlist_mutex); | 1139 | mutex_lock(&em28xx_devlist_mutex); |
1120 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | 1140 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1121 | if (ops->fini) | 1141 | if (ops->fini) { |
1142 | if (dev->dev_next) | ||
1143 | ops->fini(dev->dev_next); | ||
1122 | ops->fini(dev); | 1144 | ops->fini(dev); |
1145 | } | ||
1123 | } | 1146 | } |
1124 | list_del(&dev->devlist); | 1147 | list_del(&dev->devlist); |
1125 | mutex_unlock(&em28xx_devlist_mutex); | 1148 | mutex_unlock(&em28xx_devlist_mutex); |
@@ -1134,6 +1157,8 @@ int em28xx_suspend_extension(struct em28xx *dev) | |||
1134 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | 1157 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1135 | if (ops->suspend) | 1158 | if (ops->suspend) |
1136 | ops->suspend(dev); | 1159 | ops->suspend(dev); |
1160 | if (dev->dev_next) | ||
1161 | ops->suspend(dev->dev_next); | ||
1137 | } | 1162 | } |
1138 | mutex_unlock(&em28xx_devlist_mutex); | 1163 | mutex_unlock(&em28xx_devlist_mutex); |
1139 | return 0; | 1164 | return 0; |
@@ -1148,6 +1173,8 @@ int em28xx_resume_extension(struct em28xx *dev) | |||
1148 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | 1173 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1149 | if (ops->resume) | 1174 | if (ops->resume) |
1150 | ops->resume(dev); | 1175 | ops->resume(dev); |
1176 | if (dev->dev_next) | ||
1177 | ops->resume(dev->dev_next); | ||
1151 | } | 1178 | } |
1152 | mutex_unlock(&em28xx_devlist_mutex); | 1179 | mutex_unlock(&em28xx_devlist_mutex); |
1153 | return 0; | 1180 | return 0; |
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 8a81c94a8a27..a54cb8dc52c9 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
@@ -1,25 +1,25 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | DVB device driver for em28xx | 2 | // |
3 | 3 | // DVB device driver for em28xx | |
4 | (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> | 4 | // |
5 | 5 | // (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> | |
6 | (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> | 6 | // |
7 | - Fixes for the driver to properly work with HVR-950 | 7 | // (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> |
8 | - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick | 8 | // - Fixes for the driver to properly work with HVR-950 |
9 | - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 | 9 | // - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick |
10 | 10 | // - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 | |
11 | (c) 2008 Aidan Thornton <makosoft@googlemail.com> | 11 | // |
12 | 12 | // (c) 2008 Aidan Thornton <makosoft@googlemail.com> | |
13 | (c) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 13 | // |
14 | 14 | // (c) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | |
15 | Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: | 15 | // |
16 | (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> | 16 | // Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: |
17 | (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | 17 | // (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> |
18 | 18 | // (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | |
19 | This program is free software; you can redistribute it and/or modify | 19 | // |
20 | it under the terms of the GNU General Public License as published by | 20 | // This program is free software; you can redistribute it and/or modify |
21 | the Free Software Foundation; either version 2 of the License. | 21 | // it under the terms of the GNU General Public License as published by |
22 | */ | 22 | // the Free Software Foundation version 2 of the License. |
23 | 23 | ||
24 | #include "em28xx.h" | 24 | #include "em28xx.h" |
25 | 25 | ||
@@ -64,7 +64,7 @@ | |||
64 | #include "qm1d1c0042.h" | 64 | #include "qm1d1c0042.h" |
65 | 65 | ||
66 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | 66 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); |
67 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL v2"); |
68 | MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); | 68 | MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); |
69 | MODULE_VERSION(EM28XX_VERSION); | 69 | MODULE_VERSION(EM28XX_VERSION); |
70 | 70 | ||
@@ -96,7 +96,7 @@ struct em28xx_dvb { | |||
96 | struct dvb_net net; | 96 | struct dvb_net net; |
97 | 97 | ||
98 | /* Due to DRX-K - probably need changes */ | 98 | /* Due to DRX-K - probably need changes */ |
99 | int (*gate_ctrl)(struct dvb_frontend *, int); | 99 | int (*gate_ctrl)(struct dvb_frontend *fe, int gate); |
100 | struct semaphore pll_mutex; | 100 | struct semaphore pll_mutex; |
101 | bool dont_attach_fe1; | 101 | bool dont_attach_fe1; |
102 | int lna_gpio; | 102 | int lna_gpio; |
@@ -199,7 +199,6 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) | |||
199 | int rc; | 199 | int rc; |
200 | struct em28xx_i2c_bus *i2c_bus = dvb->adapter.priv; | 200 | struct em28xx_i2c_bus *i2c_bus = dvb->adapter.priv; |
201 | struct em28xx *dev = i2c_bus->dev; | 201 | struct em28xx *dev = i2c_bus->dev; |
202 | struct usb_device *udev = interface_to_usbdev(dev->intf); | ||
203 | int dvb_max_packet_size, packet_multiplier, dvb_alt; | 202 | int dvb_max_packet_size, packet_multiplier, dvb_alt; |
204 | 203 | ||
205 | if (dev->dvb_xfer_bulk) { | 204 | if (dev->dvb_xfer_bulk) { |
@@ -218,7 +217,6 @@ static int em28xx_start_streaming(struct em28xx_dvb *dvb) | |||
218 | dvb_alt = dev->dvb_alt_isoc; | 217 | dvb_alt = dev->dvb_alt_isoc; |
219 | } | 218 | } |
220 | 219 | ||
221 | usb_set_interface(udev, dev->ifnum, dvb_alt); | ||
222 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | 220 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
223 | if (rc < 0) | 221 | if (rc < 0) |
224 | return rc; | 222 | return rc; |
@@ -278,14 +276,13 @@ static int em28xx_stop_feed(struct dvb_demux_feed *feed) | |||
278 | mutex_lock(&dvb->lock); | 276 | mutex_lock(&dvb->lock); |
279 | dvb->nfeeds--; | 277 | dvb->nfeeds--; |
280 | 278 | ||
281 | if (0 == dvb->nfeeds) | 279 | if (!dvb->nfeeds) |
282 | err = em28xx_stop_streaming(dvb); | 280 | err = em28xx_stop_streaming(dvb); |
283 | 281 | ||
284 | mutex_unlock(&dvb->lock); | 282 | mutex_unlock(&dvb->lock); |
285 | return err; | 283 | return err; |
286 | } | 284 | } |
287 | 285 | ||
288 | |||
289 | /* ------------------------------------------------------------------ */ | 286 | /* ------------------------------------------------------------------ */ |
290 | static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | 287 | static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) |
291 | { | 288 | { |
@@ -358,7 +355,7 @@ static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | |||
358 | .gpio = S5H1409_GPIO_OFF, | 355 | .gpio = S5H1409_GPIO_OFF, |
359 | .inversion = S5H1409_INVERSION_OFF, | 356 | .inversion = S5H1409_INVERSION_OFF, |
360 | .status_mode = S5H1409_DEMODLOCKING, | 357 | .status_mode = S5H1409_DEMODLOCKING, |
361 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | 358 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINUOUS_NONINVERTING_CLOCK |
362 | }; | 359 | }; |
363 | 360 | ||
364 | static struct tda18271_std_map kworld_a340_std_map = { | 361 | static struct tda18271_std_map kworld_a340_std_map = { |
@@ -514,14 +511,15 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) | |||
514 | 511 | ||
515 | em28xx_gpio_set(dev, hauppauge_hvr930c_init); | 512 | em28xx_gpio_set(dev, hauppauge_hvr930c_init); |
516 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | 513 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); |
517 | msleep(10); | 514 | usleep_range(10000, 11000); |
518 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | 515 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); |
519 | msleep(10); | 516 | usleep_range(10000, 11000); |
520 | 517 | ||
521 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; | 518 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; |
522 | 519 | ||
523 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 520 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
524 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); | 521 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], |
522 | regs[i].r, regs[i].len); | ||
525 | em28xx_gpio_set(dev, hauppauge_hvr930c_end); | 523 | em28xx_gpio_set(dev, hauppauge_hvr930c_end); |
526 | 524 | ||
527 | msleep(100); | 525 | msleep(100); |
@@ -530,8 +528,7 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) | |||
530 | msleep(30); | 528 | msleep(30); |
531 | 529 | ||
532 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | 530 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); |
533 | msleep(10); | 531 | usleep_range(10000, 11000); |
534 | |||
535 | } | 532 | } |
536 | 533 | ||
537 | static void terratec_h5_init(struct em28xx *dev) | 534 | static void terratec_h5_init(struct em28xx *dev) |
@@ -571,14 +568,15 @@ static void terratec_h5_init(struct em28xx *dev) | |||
571 | 568 | ||
572 | em28xx_gpio_set(dev, terratec_h5_init); | 569 | em28xx_gpio_set(dev, terratec_h5_init); |
573 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | 570 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); |
574 | msleep(10); | 571 | usleep_range(10000, 11000); |
575 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | 572 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); |
576 | msleep(10); | 573 | usleep_range(10000, 11000); |
577 | 574 | ||
578 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; | 575 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; |
579 | 576 | ||
580 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 577 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
581 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); | 578 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], |
579 | regs[i].r, regs[i].len); | ||
582 | em28xx_gpio_set(dev, terratec_h5_end); | 580 | em28xx_gpio_set(dev, terratec_h5_end); |
583 | }; | 581 | }; |
584 | 582 | ||
@@ -624,14 +622,15 @@ static void terratec_htc_stick_init(struct em28xx *dev) | |||
624 | em28xx_gpio_set(dev, terratec_htc_stick_init); | 622 | em28xx_gpio_set(dev, terratec_htc_stick_init); |
625 | 623 | ||
626 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | 624 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); |
627 | msleep(10); | 625 | usleep_range(10000, 11000); |
628 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | 626 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); |
629 | msleep(10); | 627 | usleep_range(10000, 11000); |
630 | 628 | ||
631 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; | 629 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; |
632 | 630 | ||
633 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 631 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
634 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); | 632 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], |
633 | regs[i].r, regs[i].len); | ||
635 | 634 | ||
636 | em28xx_gpio_set(dev, terratec_htc_stick_end); | 635 | em28xx_gpio_set(dev, terratec_htc_stick_end); |
637 | }; | 636 | }; |
@@ -682,14 +681,15 @@ static void terratec_htc_usb_xs_init(struct em28xx *dev) | |||
682 | em28xx_gpio_set(dev, terratec_htc_usb_xs_init); | 681 | em28xx_gpio_set(dev, terratec_htc_usb_xs_init); |
683 | 682 | ||
684 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | 683 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); |
685 | msleep(10); | 684 | usleep_range(10000, 11000); |
686 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | 685 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); |
687 | msleep(10); | 686 | usleep_range(10000, 11000); |
688 | 687 | ||
689 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; | 688 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; |
690 | 689 | ||
691 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 690 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
692 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); | 691 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], |
692 | regs[i].r, regs[i].len); | ||
693 | 693 | ||
694 | em28xx_gpio_set(dev, terratec_htc_usb_xs_end); | 694 | em28xx_gpio_set(dev, terratec_htc_usb_xs_end); |
695 | }; | 695 | }; |
@@ -718,7 +718,8 @@ static void pctv_520e_init(struct em28xx *dev) | |||
718 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; /* 0x41 */ | 718 | dev->i2c_client[dev->def_i2c_bus].addr = 0x82 >> 1; /* 0x41 */ |
719 | 719 | ||
720 | for (i = 0; i < ARRAY_SIZE(regs); i++) | 720 | for (i = 0; i < ARRAY_SIZE(regs); i++) |
721 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], regs[i].r, regs[i].len); | 721 | i2c_master_send(&dev->i2c_client[dev->def_i2c_bus], |
722 | regs[i].r, regs[i].len); | ||
722 | }; | 723 | }; |
723 | 724 | ||
724 | static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) | 725 | static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) |
@@ -780,7 +781,7 @@ static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) | |||
780 | static u8 tuner_go[] = { TUNER_GO, 0x01}; | 781 | static u8 tuner_go[] = { TUNER_GO, 0x01}; |
781 | 782 | ||
782 | mt352_write(fe, clock_config, sizeof(clock_config)); | 783 | mt352_write(fe, clock_config, sizeof(clock_config)); |
783 | udelay(200); | 784 | usleep_range(200, 250); |
784 | mt352_write(fe, reset, sizeof(reset)); | 785 | mt352_write(fe, reset, sizeof(reset)); |
785 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | 786 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); |
786 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | 787 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); |
@@ -840,8 +841,8 @@ static void px_bcud_init(struct em28xx *dev) | |||
840 | /* sleeping ISDB-T */ | 841 | /* sleeping ISDB-T */ |
841 | dev->dvb->i2c_client_demod->addr = 0x14; | 842 | dev->dvb->i2c_client_demod->addr = 0x14; |
842 | for (i = 0; i < ARRAY_SIZE(regs1); i++) | 843 | for (i = 0; i < ARRAY_SIZE(regs1); i++) |
843 | i2c_master_send(dev->dvb->i2c_client_demod, regs1[i].r, | 844 | i2c_master_send(dev->dvb->i2c_client_demod, |
844 | regs1[i].len); | 845 | regs1[i].r, regs1[i].len); |
845 | /* sleeping ISDB-S */ | 846 | /* sleeping ISDB-S */ |
846 | dev->dvb->i2c_client_demod->addr = 0x15; | 847 | dev->dvb->i2c_client_demod->addr = 0x15; |
847 | for (i = 0; i < ARRAY_SIZE(regs2); i++) | 848 | for (i = 0; i < ARRAY_SIZE(regs2); i++) |
@@ -934,7 +935,7 @@ static struct lgdt3306a_config hauppauge_01595_lgdt3306a_config = { | |||
934 | 935 | ||
935 | /* ------------------------------------------------------------------ */ | 936 | /* ------------------------------------------------------------------ */ |
936 | 937 | ||
937 | static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) | 938 | static noinline_for_stack int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) |
938 | { | 939 | { |
939 | struct dvb_frontend *fe; | 940 | struct dvb_frontend *fe; |
940 | struct xc2028_config cfg; | 941 | struct xc2028_config cfg; |
@@ -1077,7 +1078,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, | |||
1077 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | 1078 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); |
1078 | 1079 | ||
1079 | /* If the analog part won't create RF connectors, DVB will do it */ | 1080 | /* If the analog part won't create RF connectors, DVB will do it */ |
1080 | if (!dev->has_video || (dev->tuner_type == TUNER_ABSENT)) | 1081 | if (!dev->has_video || dev->tuner_type == TUNER_ABSENT) |
1081 | create_rf_connector = true; | 1082 | create_rf_connector = true; |
1082 | 1083 | ||
1083 | result = dvb_create_media_graph(&dvb->adapter, create_rf_connector); | 1084 | result = dvb_create_media_graph(&dvb->adapter, create_rf_connector); |
@@ -1126,10 +1127,285 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) | |||
1126 | dvb_unregister_adapter(&dvb->adapter); | 1127 | dvb_unregister_adapter(&dvb->adapter); |
1127 | } | 1128 | } |
1128 | 1129 | ||
1130 | static int em28174_dvb_init_pctv_460e(struct em28xx *dev) | ||
1131 | { | ||
1132 | struct em28xx_dvb *dvb = dev->dvb; | ||
1133 | struct tda10071_platform_data tda10071_pdata = {}; | ||
1134 | struct a8293_platform_data a8293_pdata = {}; | ||
1135 | |||
1136 | /* attach demod + tuner combo */ | ||
1137 | tda10071_pdata.clk = 40444000; /* 40.444 MHz */ | ||
1138 | tda10071_pdata.i2c_wr_max = 64; | ||
1139 | tda10071_pdata.ts_mode = TDA10071_TS_SERIAL; | ||
1140 | tda10071_pdata.pll_multiplier = 20; | ||
1141 | tda10071_pdata.tuner_i2c_addr = 0x14; | ||
1142 | |||
1143 | dvb->i2c_client_demod = dvb_module_probe("tda10071", "tda10071_cx24118", | ||
1144 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1145 | 0x55, &tda10071_pdata); | ||
1146 | if (!dvb->i2c_client_demod) | ||
1147 | return -ENODEV; | ||
1148 | |||
1149 | dvb->fe[0] = tda10071_pdata.get_dvb_frontend(dvb->i2c_client_demod); | ||
1150 | |||
1151 | /* attach SEC */ | ||
1152 | a8293_pdata.dvb_frontend = dvb->fe[0]; | ||
1153 | |||
1154 | dvb->i2c_client_sec = dvb_module_probe("a8293", NULL, | ||
1155 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1156 | 0x08, &a8293_pdata); | ||
1157 | if (!dvb->i2c_client_sec) { | ||
1158 | dvb_module_release(dvb->i2c_client_demod); | ||
1159 | return -ENODEV; | ||
1160 | } | ||
1161 | |||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | static int em28178_dvb_init_pctv_461e(struct em28xx *dev) | ||
1166 | { | ||
1167 | struct em28xx_dvb *dvb = dev->dvb; | ||
1168 | struct i2c_adapter *i2c_adapter; | ||
1169 | struct m88ds3103_platform_data m88ds3103_pdata = {}; | ||
1170 | struct ts2020_config ts2020_config = {}; | ||
1171 | struct a8293_platform_data a8293_pdata = {}; | ||
1172 | |||
1173 | /* attach demod */ | ||
1174 | m88ds3103_pdata.clk = 27000000; | ||
1175 | m88ds3103_pdata.i2c_wr_max = 33; | ||
1176 | m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; | ||
1177 | m88ds3103_pdata.ts_clk = 16000; | ||
1178 | m88ds3103_pdata.ts_clk_pol = 1; | ||
1179 | m88ds3103_pdata.agc = 0x99; | ||
1180 | |||
1181 | dvb->i2c_client_demod = dvb_module_probe("m88ds3103", NULL, | ||
1182 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1183 | 0x68, &m88ds3103_pdata); | ||
1184 | if (!dvb->i2c_client_demod) | ||
1185 | return -ENODEV; | ||
1186 | |||
1187 | dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(dvb->i2c_client_demod); | ||
1188 | i2c_adapter = m88ds3103_pdata.get_i2c_adapter(dvb->i2c_client_demod); | ||
1189 | |||
1190 | /* attach tuner */ | ||
1191 | ts2020_config.fe = dvb->fe[0]; | ||
1192 | |||
1193 | dvb->i2c_client_tuner = dvb_module_probe("ts2020", "ts2022", | ||
1194 | i2c_adapter, | ||
1195 | 0x60, &ts2020_config); | ||
1196 | if (!dvb->i2c_client_tuner) { | ||
1197 | dvb_module_release(dvb->i2c_client_demod); | ||
1198 | return -ENODEV; | ||
1199 | } | ||
1200 | |||
1201 | /* delegate signal strength measurement to tuner */ | ||
1202 | dvb->fe[0]->ops.read_signal_strength = | ||
1203 | dvb->fe[0]->ops.tuner_ops.get_rf_strength; | ||
1204 | |||
1205 | /* attach SEC */ | ||
1206 | a8293_pdata.dvb_frontend = dvb->fe[0]; | ||
1207 | dvb->i2c_client_sec = dvb_module_probe("a8293", NULL, | ||
1208 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1209 | 0x08, &a8293_pdata); | ||
1210 | if (!dvb->i2c_client_sec) { | ||
1211 | dvb_module_release(dvb->i2c_client_tuner); | ||
1212 | dvb_module_release(dvb->i2c_client_demod); | ||
1213 | return -ENODEV; | ||
1214 | } | ||
1215 | |||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | static int em28178_dvb_init_pctv_292e(struct em28xx *dev) | ||
1220 | { | ||
1221 | struct em28xx_dvb *dvb = dev->dvb; | ||
1222 | struct i2c_adapter *adapter; | ||
1223 | struct si2168_config si2168_config = {}; | ||
1224 | struct si2157_config si2157_config = {}; | ||
1225 | |||
1226 | /* attach demod */ | ||
1227 | si2168_config.i2c_adapter = &adapter; | ||
1228 | si2168_config.fe = &dvb->fe[0]; | ||
1229 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | ||
1230 | si2168_config.spectral_inversion = true; | ||
1231 | |||
1232 | dvb->i2c_client_demod = dvb_module_probe("si2168", NULL, | ||
1233 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1234 | 0x64, &si2168_config); | ||
1235 | if (!dvb->i2c_client_demod) | ||
1236 | return -ENODEV; | ||
1237 | |||
1238 | /* attach tuner */ | ||
1239 | si2157_config.fe = dvb->fe[0]; | ||
1240 | si2157_config.if_port = 1; | ||
1241 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1242 | si2157_config.mdev = dev->media_dev; | ||
1243 | #endif | ||
1244 | dvb->i2c_client_tuner = dvb_module_probe("si2157", NULL, | ||
1245 | adapter, | ||
1246 | 0x60, &si2157_config); | ||
1247 | if (!dvb->i2c_client_tuner) { | ||
1248 | dvb_module_release(dvb->i2c_client_demod); | ||
1249 | return -ENODEV; | ||
1250 | } | ||
1251 | dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; | ||
1252 | |||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | static int em28178_dvb_init_terratec_t2_stick_hd(struct em28xx *dev) | ||
1257 | { | ||
1258 | struct em28xx_dvb *dvb = dev->dvb; | ||
1259 | struct i2c_adapter *adapter; | ||
1260 | struct si2168_config si2168_config = {}; | ||
1261 | struct si2157_config si2157_config = {}; | ||
1262 | |||
1263 | /* attach demod */ | ||
1264 | si2168_config.i2c_adapter = &adapter; | ||
1265 | si2168_config.fe = &dvb->fe[0]; | ||
1266 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | ||
1267 | |||
1268 | dvb->i2c_client_demod = dvb_module_probe("si2168", NULL, | ||
1269 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1270 | 0x64, &si2168_config); | ||
1271 | if (!dvb->i2c_client_demod) | ||
1272 | return -ENODEV; | ||
1273 | |||
1274 | /* attach tuner */ | ||
1275 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
1276 | si2157_config.fe = dvb->fe[0]; | ||
1277 | si2157_config.if_port = 0; | ||
1278 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1279 | si2157_config.mdev = dev->media_dev; | ||
1280 | #endif | ||
1281 | dvb->i2c_client_tuner = dvb_module_probe("si2157", "si2146", | ||
1282 | adapter, | ||
1283 | 0x60, &si2157_config); | ||
1284 | if (!dvb->i2c_client_tuner) { | ||
1285 | dvb_module_release(dvb->i2c_client_demod); | ||
1286 | return -ENODEV; | ||
1287 | } | ||
1288 | |||
1289 | return 0; | ||
1290 | } | ||
1291 | |||
1292 | static int em28178_dvb_init_plex_px_bcud(struct em28xx *dev) | ||
1293 | { | ||
1294 | struct em28xx_dvb *dvb = dev->dvb; | ||
1295 | struct tc90522_config tc90522_config = {}; | ||
1296 | struct qm1d1c0042_config qm1d1c0042_config = {}; | ||
1297 | |||
1298 | /* attach demod */ | ||
1299 | dvb->i2c_client_demod = dvb_module_probe("tc90522", "tc90522sat", | ||
1300 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1301 | 0x15, &tc90522_config); | ||
1302 | if (!dvb->i2c_client_demod) | ||
1303 | return -ENODEV; | ||
1304 | |||
1305 | /* attach tuner */ | ||
1306 | qm1d1c0042_config.fe = tc90522_config.fe; | ||
1307 | qm1d1c0042_config.lpf = 1; | ||
1308 | |||
1309 | dvb->i2c_client_tuner = dvb_module_probe("qm1d1c0042", NULL, | ||
1310 | tc90522_config.tuner_i2c, | ||
1311 | 0x61, &qm1d1c0042_config); | ||
1312 | if (!dvb->i2c_client_tuner) { | ||
1313 | dvb_module_release(dvb->i2c_client_demod); | ||
1314 | return -ENODEV; | ||
1315 | } | ||
1316 | |||
1317 | dvb->fe[0] = tc90522_config.fe; | ||
1318 | px_bcud_init(dev); | ||
1319 | |||
1320 | return 0; | ||
1321 | } | ||
1322 | |||
1323 | static int em28174_dvb_init_hauppauge_wintv_dualhd_dvb(struct em28xx *dev) | ||
1324 | { | ||
1325 | struct em28xx_dvb *dvb = dev->dvb; | ||
1326 | struct i2c_adapter *adapter; | ||
1327 | struct si2168_config si2168_config = {}; | ||
1328 | struct si2157_config si2157_config = {}; | ||
1329 | unsigned char addr; | ||
1330 | |||
1331 | /* attach demod */ | ||
1332 | si2168_config.i2c_adapter = &adapter; | ||
1333 | si2168_config.fe = &dvb->fe[0]; | ||
1334 | si2168_config.ts_mode = SI2168_TS_SERIAL; | ||
1335 | si2168_config.spectral_inversion = true; | ||
1336 | addr = (dev->ts == PRIMARY_TS) ? 0x64 : 0x67; | ||
1337 | |||
1338 | dvb->i2c_client_demod = dvb_module_probe("si2168", NULL, | ||
1339 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1340 | addr, &si2168_config); | ||
1341 | if (!dvb->i2c_client_demod) | ||
1342 | return -ENODEV; | ||
1343 | |||
1344 | /* attach tuner */ | ||
1345 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
1346 | si2157_config.fe = dvb->fe[0]; | ||
1347 | si2157_config.if_port = 1; | ||
1348 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1349 | si2157_config.mdev = dev->media_dev; | ||
1350 | #endif | ||
1351 | addr = (dev->ts == PRIMARY_TS) ? 0x60 : 0x63; | ||
1352 | |||
1353 | dvb->i2c_client_tuner = dvb_module_probe("si2157", NULL, | ||
1354 | adapter, | ||
1355 | addr, &si2157_config); | ||
1356 | if (!dvb->i2c_client_tuner) { | ||
1357 | dvb_module_release(dvb->i2c_client_demod); | ||
1358 | return -ENODEV; | ||
1359 | } | ||
1360 | |||
1361 | return 0; | ||
1362 | } | ||
1363 | |||
1364 | static int em28174_dvb_init_hauppauge_wintv_dualhd_01595(struct em28xx *dev) | ||
1365 | { | ||
1366 | struct em28xx_dvb *dvb = dev->dvb; | ||
1367 | struct i2c_adapter *adapter; | ||
1368 | struct lgdt3306a_config lgdt3306a_config = {}; | ||
1369 | struct si2157_config si2157_config = {}; | ||
1370 | unsigned char addr; | ||
1371 | |||
1372 | /* attach demod */ | ||
1373 | lgdt3306a_config = hauppauge_01595_lgdt3306a_config; | ||
1374 | lgdt3306a_config.fe = &dvb->fe[0]; | ||
1375 | lgdt3306a_config.i2c_adapter = &adapter; | ||
1376 | addr = (dev->ts == PRIMARY_TS) ? 0x59 : 0x0e; | ||
1377 | |||
1378 | dvb->i2c_client_demod = dvb_module_probe("lgdt3306a", NULL, | ||
1379 | &dev->i2c_adap[dev->def_i2c_bus], | ||
1380 | addr, &lgdt3306a_config); | ||
1381 | if (!dvb->i2c_client_demod) | ||
1382 | return -ENODEV; | ||
1383 | |||
1384 | /* attach tuner */ | ||
1385 | si2157_config.fe = dvb->fe[0]; | ||
1386 | si2157_config.if_port = 1; | ||
1387 | si2157_config.inversion = 1; | ||
1388 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1389 | si2157_config.mdev = dev->media_dev; | ||
1390 | #endif | ||
1391 | addr = (dev->ts == PRIMARY_TS) ? 0x60 : 0x62; | ||
1392 | |||
1393 | dvb->i2c_client_tuner = dvb_module_probe("si2157", NULL, | ||
1394 | adapter, | ||
1395 | 0x60, &si2157_config); | ||
1396 | if (!dvb->i2c_client_tuner) { | ||
1397 | dvb_module_release(dvb->i2c_client_demod); | ||
1398 | return -ENODEV; | ||
1399 | } | ||
1400 | |||
1401 | return 0; | ||
1402 | } | ||
1403 | |||
1129 | static int em28xx_dvb_init(struct em28xx *dev) | 1404 | static int em28xx_dvb_init(struct em28xx *dev) |
1130 | { | 1405 | { |
1131 | int result = 0; | 1406 | int result = 0, dvb_alt = 0; |
1132 | struct em28xx_dvb *dvb; | 1407 | struct em28xx_dvb *dvb; |
1408 | struct usb_device *udev; | ||
1133 | 1409 | ||
1134 | if (dev->is_audio_only) { | 1410 | if (dev->is_audio_only) { |
1135 | /* Shouldn't initialize IR for this interface */ | 1411 | /* Shouldn't initialize IR for this interface */ |
@@ -1143,12 +1419,13 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1143 | 1419 | ||
1144 | dev_info(&dev->intf->dev, "Binding DVB extension\n"); | 1420 | dev_info(&dev->intf->dev, "Binding DVB extension\n"); |
1145 | 1421 | ||
1146 | dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); | 1422 | dvb = kzalloc(sizeof(*dvb), GFP_KERNEL); |
1147 | if (!dvb) | 1423 | if (!dvb) |
1148 | return -ENOMEM; | 1424 | return -ENOMEM; |
1149 | 1425 | ||
1150 | dev->dvb = dvb; | 1426 | dev->dvb = dvb; |
1151 | dvb->fe[0] = dvb->fe[1] = NULL; | 1427 | dvb->fe[0] = NULL; |
1428 | dvb->fe[1] = NULL; | ||
1152 | 1429 | ||
1153 | /* pre-allocate DVB usb transfer buffers */ | 1430 | /* pre-allocate DVB usb transfer buffers */ |
1154 | if (dev->dvb_xfer_bulk) { | 1431 | if (dev->dvb_xfer_bulk) { |
@@ -1178,7 +1455,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1178 | switch (dev->model) { | 1455 | switch (dev->model) { |
1179 | case EM2874_BOARD_LEADERSHIP_ISDBT: | 1456 | case EM2874_BOARD_LEADERSHIP_ISDBT: |
1180 | dvb->fe[0] = dvb_attach(s921_attach, | 1457 | dvb->fe[0] = dvb_attach(s921_attach, |
1181 | &sharp_isdbt, &dev->i2c_adap[dev->def_i2c_bus]); | 1458 | &sharp_isdbt, |
1459 | &dev->i2c_adap[dev->def_i2c_bus]); | ||
1182 | 1460 | ||
1183 | if (!dvb->fe[0]) { | 1461 | if (!dvb->fe[0]) { |
1184 | result = -EINVAL; | 1462 | result = -EINVAL; |
@@ -1191,8 +1469,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1191 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | 1469 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: |
1192 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | 1470 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: |
1193 | dvb->fe[0] = dvb_attach(lgdt330x_attach, | 1471 | dvb->fe[0] = dvb_attach(lgdt330x_attach, |
1194 | &em2880_lgdt3303_dev, | 1472 | &em2880_lgdt3303_dev, |
1195 | &dev->i2c_adap[dev->def_i2c_bus]); | 1473 | &dev->i2c_adap[dev->def_i2c_bus]); |
1196 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | 1474 | if (em28xx_attach_xc3028(0x61, dev) < 0) { |
1197 | result = -EINVAL; | 1475 | result = -EINVAL; |
1198 | goto out_free; | 1476 | goto out_free; |
@@ -1200,8 +1478,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1200 | break; | 1478 | break; |
1201 | case EM2880_BOARD_KWORLD_DVB_310U: | 1479 | case EM2880_BOARD_KWORLD_DVB_310U: |
1202 | dvb->fe[0] = dvb_attach(zl10353_attach, | 1480 | dvb->fe[0] = dvb_attach(zl10353_attach, |
1203 | &em28xx_zl10353_with_xc3028, | 1481 | &em28xx_zl10353_with_xc3028, |
1204 | &dev->i2c_adap[dev->def_i2c_bus]); | 1482 | &dev->i2c_adap[dev->def_i2c_bus]); |
1205 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | 1483 | if (em28xx_attach_xc3028(0x61, dev) < 0) { |
1206 | result = -EINVAL; | 1484 | result = -EINVAL; |
1207 | goto out_free; | 1485 | goto out_free; |
@@ -1211,8 +1489,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1211 | case EM2882_BOARD_TERRATEC_HYBRID_XS: | 1489 | case EM2882_BOARD_TERRATEC_HYBRID_XS: |
1212 | case EM2880_BOARD_EMPIRE_DUAL_TV: | 1490 | case EM2880_BOARD_EMPIRE_DUAL_TV: |
1213 | dvb->fe[0] = dvb_attach(zl10353_attach, | 1491 | dvb->fe[0] = dvb_attach(zl10353_attach, |
1214 | &em28xx_zl10353_xc3028_no_i2c_gate, | 1492 | &em28xx_zl10353_xc3028_no_i2c_gate, |
1215 | &dev->i2c_adap[dev->def_i2c_bus]); | 1493 | &dev->i2c_adap[dev->def_i2c_bus]); |
1216 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | 1494 | if (em28xx_attach_xc3028(0x61, dev) < 0) { |
1217 | result = -EINVAL; | 1495 | result = -EINVAL; |
1218 | goto out_free; | 1496 | goto out_free; |
@@ -1223,16 +1501,17 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1223 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | 1501 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: |
1224 | case EM2882_BOARD_DIKOM_DK300: | 1502 | case EM2882_BOARD_DIKOM_DK300: |
1225 | case EM2882_BOARD_KWORLD_VS_DVBT: | 1503 | case EM2882_BOARD_KWORLD_VS_DVBT: |
1504 | /* | ||
1505 | * Those boards could have either a zl10353 or a mt352. | ||
1506 | * If the chip id isn't for zl10353, try mt352. | ||
1507 | */ | ||
1226 | dvb->fe[0] = dvb_attach(zl10353_attach, | 1508 | dvb->fe[0] = dvb_attach(zl10353_attach, |
1227 | &em28xx_zl10353_xc3028_no_i2c_gate, | 1509 | &em28xx_zl10353_xc3028_no_i2c_gate, |
1228 | &dev->i2c_adap[dev->def_i2c_bus]); | 1510 | &dev->i2c_adap[dev->def_i2c_bus]); |
1229 | if (dvb->fe[0] == NULL) { | 1511 | if (!dvb->fe[0]) |
1230 | /* This board could have either a zl10353 or a mt352. | ||
1231 | If the chip id isn't for zl10353, try mt352 */ | ||
1232 | dvb->fe[0] = dvb_attach(mt352_attach, | 1512 | dvb->fe[0] = dvb_attach(mt352_attach, |
1233 | &terratec_xs_mt352_cfg, | 1513 | &terratec_xs_mt352_cfg, |
1234 | &dev->i2c_adap[dev->def_i2c_bus]); | 1514 | &dev->i2c_adap[dev->def_i2c_bus]); |
1235 | } | ||
1236 | 1515 | ||
1237 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | 1516 | if (em28xx_attach_xc3028(0x61, dev) < 0) { |
1238 | result = -EINVAL; | 1517 | result = -EINVAL; |
@@ -1241,27 +1520,28 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1241 | break; | 1520 | break; |
1242 | case EM2870_BOARD_TERRATEC_XS_MT2060: | 1521 | case EM2870_BOARD_TERRATEC_XS_MT2060: |
1243 | dvb->fe[0] = dvb_attach(zl10353_attach, | 1522 | dvb->fe[0] = dvb_attach(zl10353_attach, |
1244 | &em28xx_zl10353_no_i2c_gate_dev, | 1523 | &em28xx_zl10353_no_i2c_gate_dev, |
1245 | &dev->i2c_adap[dev->def_i2c_bus]); | 1524 | &dev->i2c_adap[dev->def_i2c_bus]); |
1246 | if (dvb->fe[0] != NULL) { | 1525 | if (dvb->fe[0]) { |
1247 | dvb_attach(mt2060_attach, dvb->fe[0], | 1526 | dvb_attach(mt2060_attach, dvb->fe[0], |
1248 | &dev->i2c_adap[dev->def_i2c_bus], | 1527 | &dev->i2c_adap[dev->def_i2c_bus], |
1249 | &em28xx_mt2060_config, 1220); | 1528 | &em28xx_mt2060_config, 1220); |
1250 | } | 1529 | } |
1251 | break; | 1530 | break; |
1252 | case EM2870_BOARD_KWORLD_355U: | 1531 | case EM2870_BOARD_KWORLD_355U: |
1253 | dvb->fe[0] = dvb_attach(zl10353_attach, | 1532 | dvb->fe[0] = dvb_attach(zl10353_attach, |
1254 | &em28xx_zl10353_no_i2c_gate_dev, | 1533 | &em28xx_zl10353_no_i2c_gate_dev, |
1255 | &dev->i2c_adap[dev->def_i2c_bus]); | 1534 | &dev->i2c_adap[dev->def_i2c_bus]); |
1256 | if (dvb->fe[0] != NULL) | 1535 | if (dvb->fe[0]) |
1257 | dvb_attach(qt1010_attach, dvb->fe[0], | 1536 | dvb_attach(qt1010_attach, dvb->fe[0], |
1258 | &dev->i2c_adap[dev->def_i2c_bus], &em28xx_qt1010_config); | 1537 | &dev->i2c_adap[dev->def_i2c_bus], |
1538 | &em28xx_qt1010_config); | ||
1259 | break; | 1539 | break; |
1260 | case EM2883_BOARD_KWORLD_HYBRID_330U: | 1540 | case EM2883_BOARD_KWORLD_HYBRID_330U: |
1261 | case EM2882_BOARD_EVGA_INDTUBE: | 1541 | case EM2882_BOARD_EVGA_INDTUBE: |
1262 | dvb->fe[0] = dvb_attach(s5h1409_attach, | 1542 | dvb->fe[0] = dvb_attach(s5h1409_attach, |
1263 | &em28xx_s5h1409_with_xc3028, | 1543 | &em28xx_s5h1409_with_xc3028, |
1264 | &dev->i2c_adap[dev->def_i2c_bus]); | 1544 | &dev->i2c_adap[dev->def_i2c_bus]); |
1265 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | 1545 | if (em28xx_attach_xc3028(0x61, dev) < 0) { |
1266 | result = -EINVAL; | 1546 | result = -EINVAL; |
1267 | goto out_free; | 1547 | goto out_free; |
@@ -1269,9 +1549,9 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1269 | break; | 1549 | break; |
1270 | case EM2882_BOARD_KWORLD_ATSC_315U: | 1550 | case EM2882_BOARD_KWORLD_ATSC_315U: |
1271 | dvb->fe[0] = dvb_attach(lgdt330x_attach, | 1551 | dvb->fe[0] = dvb_attach(lgdt330x_attach, |
1272 | &em2880_lgdt3303_dev, | 1552 | &em2880_lgdt3303_dev, |
1273 | &dev->i2c_adap[dev->def_i2c_bus]); | 1553 | &dev->i2c_adap[dev->def_i2c_bus]); |
1274 | if (dvb->fe[0] != NULL) { | 1554 | if (dvb->fe[0]) { |
1275 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], | 1555 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], |
1276 | &dev->i2c_adap[dev->def_i2c_bus], | 1556 | &dev->i2c_adap[dev->def_i2c_bus], |
1277 | 0x61, TUNER_THOMSON_DTT761X)) { | 1557 | 0x61, TUNER_THOMSON_DTT761X)) { |
@@ -1293,8 +1573,9 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1293 | case EM2870_BOARD_REDDO_DVB_C_USB_BOX: | 1573 | case EM2870_BOARD_REDDO_DVB_C_USB_BOX: |
1294 | /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ | 1574 | /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ |
1295 | dvb->fe[0] = dvb_attach(tda10023_attach, | 1575 | dvb->fe[0] = dvb_attach(tda10023_attach, |
1296 | &em28xx_tda10023_config, | 1576 | &em28xx_tda10023_config, |
1297 | &dev->i2c_adap[dev->def_i2c_bus], 0x48); | 1577 | &dev->i2c_adap[dev->def_i2c_bus], |
1578 | 0x48); | ||
1298 | if (dvb->fe[0]) { | 1579 | if (dvb->fe[0]) { |
1299 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], | 1580 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], |
1300 | &dev->i2c_adap[dev->def_i2c_bus], | 1581 | &dev->i2c_adap[dev->def_i2c_bus], |
@@ -1306,18 +1587,18 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1306 | break; | 1587 | break; |
1307 | case EM2870_BOARD_KWORLD_A340: | 1588 | case EM2870_BOARD_KWORLD_A340: |
1308 | dvb->fe[0] = dvb_attach(lgdt3305_attach, | 1589 | dvb->fe[0] = dvb_attach(lgdt3305_attach, |
1309 | &em2870_lgdt3304_dev, | 1590 | &em2870_lgdt3304_dev, |
1310 | &dev->i2c_adap[dev->def_i2c_bus]); | 1591 | &dev->i2c_adap[dev->def_i2c_bus]); |
1311 | if (!dvb->fe[0]) { | 1592 | if (!dvb->fe[0]) { |
1312 | result = -EINVAL; | 1593 | result = -EINVAL; |
1313 | goto out_free; | 1594 | goto out_free; |
1314 | } | 1595 | } |
1315 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | 1596 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, |
1316 | &dev->i2c_adap[dev->def_i2c_bus], | 1597 | &dev->i2c_adap[dev->def_i2c_bus], |
1317 | &kworld_a340_config)) { | 1598 | &kworld_a340_config)) { |
1318 | dvb_frontend_detach(dvb->fe[0]); | 1599 | dvb_frontend_detach(dvb->fe[0]); |
1319 | result = -EINVAL; | 1600 | result = -EINVAL; |
1320 | goto out_free; | 1601 | goto out_free; |
1321 | } | 1602 | } |
1322 | break; | 1603 | break; |
1323 | case EM28174_BOARD_PCTV_290E: | 1604 | case EM28174_BOARD_PCTV_290E: |
@@ -1335,7 +1616,6 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1335 | 0x60, | 1616 | 0x60, |
1336 | &dev->i2c_adap[dev->def_i2c_bus], | 1617 | &dev->i2c_adap[dev->def_i2c_bus], |
1337 | &em28xx_cxd2820r_tda18271_config)) { | 1618 | &em28xx_cxd2820r_tda18271_config)) { |
1338 | |||
1339 | dvb_frontend_detach(dvb->fe[0]); | 1619 | dvb_frontend_detach(dvb->fe[0]); |
1340 | result = -EINVAL; | 1620 | result = -EINVAL; |
1341 | goto out_free; | 1621 | goto out_free; |
@@ -1360,12 +1640,13 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1360 | break; | 1640 | break; |
1361 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: | 1641 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: |
1362 | { | 1642 | { |
1363 | struct xc5000_config cfg; | 1643 | struct xc5000_config cfg = {}; |
1364 | 1644 | ||
1365 | hauppauge_hvr930c_init(dev); | 1645 | hauppauge_hvr930c_init(dev); |
1366 | 1646 | ||
1367 | dvb->fe[0] = dvb_attach(drxk_attach, | 1647 | dvb->fe[0] = dvb_attach(drxk_attach, |
1368 | &hauppauge_930c_drxk, &dev->i2c_adap[dev->def_i2c_bus]); | 1648 | &hauppauge_930c_drxk, |
1649 | &dev->i2c_adap[dev->def_i2c_bus]); | ||
1369 | if (!dvb->fe[0]) { | 1650 | if (!dvb->fe[0]) { |
1370 | result = -EINVAL; | 1651 | result = -EINVAL; |
1371 | goto out_free; | 1652 | goto out_free; |
@@ -1377,14 +1658,13 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1377 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | 1658 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; |
1378 | 1659 | ||
1379 | /* Attach xc5000 */ | 1660 | /* Attach xc5000 */ |
1380 | memset(&cfg, 0, sizeof(cfg)); | ||
1381 | cfg.i2c_address = 0x61; | 1661 | cfg.i2c_address = 0x61; |
1382 | cfg.if_khz = 4000; | 1662 | cfg.if_khz = 4000; |
1383 | 1663 | ||
1384 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | 1664 | if (dvb->fe[0]->ops.i2c_gate_ctrl) |
1385 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | 1665 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); |
1386 | if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], | 1666 | if (!dvb_attach(xc5000_attach, dvb->fe[0], |
1387 | &cfg)) { | 1667 | &dev->i2c_adap[dev->def_i2c_bus], &cfg)) { |
1388 | result = -EINVAL; | 1668 | result = -EINVAL; |
1389 | goto out_free; | 1669 | goto out_free; |
1390 | } | 1670 | } |
@@ -1396,7 +1676,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1396 | case EM2884_BOARD_TERRATEC_H5: | 1676 | case EM2884_BOARD_TERRATEC_H5: |
1397 | terratec_h5_init(dev); | 1677 | terratec_h5_init(dev); |
1398 | 1678 | ||
1399 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap[dev->def_i2c_bus]); | 1679 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, |
1680 | &dev->i2c_adap[dev->def_i2c_bus]); | ||
1400 | if (!dvb->fe[0]) { | 1681 | if (!dvb->fe[0]) { |
1401 | result = -EINVAL; | 1682 | result = -EINVAL; |
1402 | goto out_free; | 1683 | goto out_free; |
@@ -1410,7 +1691,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1410 | /* Attach tda18271 to DVB-C frontend */ | 1691 | /* Attach tda18271 to DVB-C frontend */ |
1411 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | 1692 | if (dvb->fe[0]->ops.i2c_gate_ctrl) |
1412 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | 1693 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); |
1413 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { | 1694 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], |
1695 | &dev->i2c_adap[dev->def_i2c_bus], 0x60)) { | ||
1414 | result = -EINVAL; | 1696 | result = -EINVAL; |
1415 | goto out_free; | 1697 | goto out_free; |
1416 | } | 1698 | } |
@@ -1420,72 +1702,23 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1420 | break; | 1702 | break; |
1421 | case EM2884_BOARD_C3TECH_DIGITAL_DUO: | 1703 | case EM2884_BOARD_C3TECH_DIGITAL_DUO: |
1422 | dvb->fe[0] = dvb_attach(mb86a20s_attach, | 1704 | dvb->fe[0] = dvb_attach(mb86a20s_attach, |
1423 | &c3tech_duo_mb86a20s_config, | 1705 | &c3tech_duo_mb86a20s_config, |
1424 | &dev->i2c_adap[dev->def_i2c_bus]); | 1706 | &dev->i2c_adap[dev->def_i2c_bus]); |
1425 | if (dvb->fe[0] != NULL) | 1707 | if (dvb->fe[0]) |
1426 | dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | 1708 | dvb_attach(tda18271_attach, dvb->fe[0], 0x60, |
1427 | &dev->i2c_adap[dev->def_i2c_bus], | 1709 | &dev->i2c_adap[dev->def_i2c_bus], |
1428 | &c3tech_duo_tda18271_config); | 1710 | &c3tech_duo_tda18271_config); |
1429 | break; | 1711 | break; |
1430 | case EM28174_BOARD_PCTV_460E: { | 1712 | case EM28174_BOARD_PCTV_460E: |
1431 | struct i2c_client *client; | 1713 | result = em28174_dvb_init_pctv_460e(dev); |
1432 | struct i2c_board_info board_info; | 1714 | if (result) |
1433 | struct tda10071_platform_data tda10071_pdata = {}; | ||
1434 | struct a8293_platform_data a8293_pdata = {}; | ||
1435 | |||
1436 | /* attach demod + tuner combo */ | ||
1437 | tda10071_pdata.clk = 40444000, /* 40.444 MHz */ | ||
1438 | tda10071_pdata.i2c_wr_max = 64, | ||
1439 | tda10071_pdata.ts_mode = TDA10071_TS_SERIAL, | ||
1440 | tda10071_pdata.pll_multiplier = 20, | ||
1441 | tda10071_pdata.tuner_i2c_addr = 0x14, | ||
1442 | memset(&board_info, 0, sizeof(board_info)); | ||
1443 | strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE); | ||
1444 | board_info.addr = 0x55; | ||
1445 | board_info.platform_data = &tda10071_pdata; | ||
1446 | request_module("tda10071"); | ||
1447 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); | ||
1448 | if (client == NULL || client->dev.driver == NULL) { | ||
1449 | result = -ENODEV; | ||
1450 | goto out_free; | 1715 | goto out_free; |
1451 | } | ||
1452 | if (!try_module_get(client->dev.driver->owner)) { | ||
1453 | i2c_unregister_device(client); | ||
1454 | result = -ENODEV; | ||
1455 | goto out_free; | ||
1456 | } | ||
1457 | dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client); | ||
1458 | dvb->i2c_client_demod = client; | ||
1459 | |||
1460 | /* attach SEC */ | ||
1461 | a8293_pdata.dvb_frontend = dvb->fe[0]; | ||
1462 | memset(&board_info, 0, sizeof(board_info)); | ||
1463 | strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); | ||
1464 | board_info.addr = 0x08; | ||
1465 | board_info.platform_data = &a8293_pdata; | ||
1466 | request_module("a8293"); | ||
1467 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); | ||
1468 | if (client == NULL || client->dev.driver == NULL) { | ||
1469 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1470 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1471 | result = -ENODEV; | ||
1472 | goto out_free; | ||
1473 | } | ||
1474 | if (!try_module_get(client->dev.driver->owner)) { | ||
1475 | i2c_unregister_device(client); | ||
1476 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1477 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1478 | result = -ENODEV; | ||
1479 | goto out_free; | ||
1480 | } | ||
1481 | dvb->i2c_client_sec = client; | ||
1482 | break; | 1716 | break; |
1483 | } | ||
1484 | case EM2874_BOARD_DELOCK_61959: | 1717 | case EM2874_BOARD_DELOCK_61959: |
1485 | case EM2874_BOARD_MAXMEDIA_UB425_TC: | 1718 | case EM2874_BOARD_MAXMEDIA_UB425_TC: |
1486 | /* attach demodulator */ | 1719 | /* attach demodulator */ |
1487 | dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, | 1720 | dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, |
1488 | &dev->i2c_adap[dev->def_i2c_bus]); | 1721 | &dev->i2c_adap[dev->def_i2c_bus]); |
1489 | 1722 | ||
1490 | if (dvb->fe[0]) { | 1723 | if (dvb->fe[0]) { |
1491 | /* disable I2C-gate */ | 1724 | /* disable I2C-gate */ |
@@ -1507,7 +1740,7 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1507 | 1740 | ||
1508 | /* attach demodulator */ | 1741 | /* attach demodulator */ |
1509 | dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, | 1742 | dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, |
1510 | &dev->i2c_adap[dev->def_i2c_bus]); | 1743 | &dev->i2c_adap[dev->def_i2c_bus]); |
1511 | 1744 | ||
1512 | if (dvb->fe[0]) { | 1745 | if (dvb->fe[0]) { |
1513 | /* attach tuner */ | 1746 | /* attach tuner */ |
@@ -1579,13 +1812,7 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1579 | break; | 1812 | break; |
1580 | case EM2874_BOARD_KWORLD_UB435Q_V3: | 1813 | case EM2874_BOARD_KWORLD_UB435Q_V3: |
1581 | { | 1814 | { |
1582 | struct i2c_client *client; | ||
1583 | struct i2c_adapter *adapter = &dev->i2c_adap[dev->def_i2c_bus]; | 1815 | struct i2c_adapter *adapter = &dev->i2c_adap[dev->def_i2c_bus]; |
1584 | struct i2c_board_info board_info = { | ||
1585 | .type = "tda18212", | ||
1586 | .addr = 0x60, | ||
1587 | .platform_data = &kworld_ub435q_v3_config, | ||
1588 | }; | ||
1589 | 1816 | ||
1590 | dvb->fe[0] = dvb_attach(lgdt3305_attach, | 1817 | dvb->fe[0] = dvb_attach(lgdt3305_attach, |
1591 | &em2874_lgdt3305_nogate_dev, | 1818 | &em2874_lgdt3305_nogate_dev, |
@@ -1597,28 +1824,23 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1597 | 1824 | ||
1598 | /* attach tuner */ | 1825 | /* attach tuner */ |
1599 | kworld_ub435q_v3_config.fe = dvb->fe[0]; | 1826 | kworld_ub435q_v3_config.fe = dvb->fe[0]; |
1600 | request_module("tda18212"); | ||
1601 | client = i2c_new_device(adapter, &board_info); | ||
1602 | if (client == NULL || client->dev.driver == NULL) { | ||
1603 | dvb_frontend_detach(dvb->fe[0]); | ||
1604 | result = -ENODEV; | ||
1605 | goto out_free; | ||
1606 | } | ||
1607 | 1827 | ||
1608 | if (!try_module_get(client->dev.driver->owner)) { | 1828 | dvb->i2c_client_tuner = dvb_module_probe("tda18212", NULL, |
1609 | i2c_unregister_device(client); | 1829 | adapter, 0x60, |
1830 | &kworld_ub435q_v3_config); | ||
1831 | if (!dvb->i2c_client_tuner) { | ||
1610 | dvb_frontend_detach(dvb->fe[0]); | 1832 | dvb_frontend_detach(dvb->fe[0]); |
1611 | result = -ENODEV; | 1833 | result = -ENODEV; |
1612 | goto out_free; | 1834 | goto out_free; |
1613 | } | 1835 | } |
1614 | |||
1615 | dvb->i2c_client_tuner = client; | ||
1616 | break; | 1836 | break; |
1617 | } | 1837 | } |
1618 | case EM2874_BOARD_PCTV_HD_MINI_80E: | 1838 | case EM2874_BOARD_PCTV_HD_MINI_80E: |
1619 | dvb->fe[0] = dvb_attach(drx39xxj_attach, &dev->i2c_adap[dev->def_i2c_bus]); | 1839 | dvb->fe[0] = dvb_attach(drx39xxj_attach, |
1620 | if (dvb->fe[0] != NULL) { | 1840 | &dev->i2c_adap[dev->def_i2c_bus]); |
1621 | dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | 1841 | if (dvb->fe[0]) { |
1842 | dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], | ||
1843 | 0x60, | ||
1622 | &dev->i2c_adap[dev->def_i2c_bus], | 1844 | &dev->i2c_adap[dev->def_i2c_bus], |
1623 | &pinnacle_80e_dvb_config); | 1845 | &pinnacle_80e_dvb_config); |
1624 | if (!dvb->fe[0]) { | 1846 | if (!dvb->fe[0]) { |
@@ -1627,410 +1849,42 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
1627 | } | 1849 | } |
1628 | } | 1850 | } |
1629 | break; | 1851 | break; |
1630 | case EM28178_BOARD_PCTV_461E: { | 1852 | case EM28178_BOARD_PCTV_461E: |
1631 | struct i2c_client *client; | 1853 | result = em28178_dvb_init_pctv_461e(dev); |
1632 | struct i2c_adapter *i2c_adapter; | 1854 | if (result) |
1633 | struct i2c_board_info board_info; | ||
1634 | struct m88ds3103_platform_data m88ds3103_pdata = {}; | ||
1635 | struct ts2020_config ts2020_config = {}; | ||
1636 | struct a8293_platform_data a8293_pdata = {}; | ||
1637 | |||
1638 | /* attach demod */ | ||
1639 | m88ds3103_pdata.clk = 27000000; | ||
1640 | m88ds3103_pdata.i2c_wr_max = 33; | ||
1641 | m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; | ||
1642 | m88ds3103_pdata.ts_clk = 16000; | ||
1643 | m88ds3103_pdata.ts_clk_pol = 1; | ||
1644 | m88ds3103_pdata.agc = 0x99; | ||
1645 | memset(&board_info, 0, sizeof(board_info)); | ||
1646 | strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); | ||
1647 | board_info.addr = 0x68; | ||
1648 | board_info.platform_data = &m88ds3103_pdata; | ||
1649 | request_module("m88ds3103"); | ||
1650 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); | ||
1651 | if (client == NULL || client->dev.driver == NULL) { | ||
1652 | result = -ENODEV; | ||
1653 | goto out_free; | ||
1654 | } | ||
1655 | if (!try_module_get(client->dev.driver->owner)) { | ||
1656 | i2c_unregister_device(client); | ||
1657 | result = -ENODEV; | ||
1658 | goto out_free; | ||
1659 | } | ||
1660 | dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client); | ||
1661 | i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); | ||
1662 | dvb->i2c_client_demod = client; | ||
1663 | |||
1664 | /* attach tuner */ | ||
1665 | ts2020_config.fe = dvb->fe[0]; | ||
1666 | memset(&board_info, 0, sizeof(board_info)); | ||
1667 | strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE); | ||
1668 | board_info.addr = 0x60; | ||
1669 | board_info.platform_data = &ts2020_config; | ||
1670 | request_module("ts2020"); | ||
1671 | client = i2c_new_device(i2c_adapter, &board_info); | ||
1672 | if (client == NULL || client->dev.driver == NULL) { | ||
1673 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1674 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1675 | result = -ENODEV; | ||
1676 | goto out_free; | ||
1677 | } | ||
1678 | if (!try_module_get(client->dev.driver->owner)) { | ||
1679 | i2c_unregister_device(client); | ||
1680 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1681 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1682 | result = -ENODEV; | ||
1683 | goto out_free; | ||
1684 | } | ||
1685 | dvb->i2c_client_tuner = client; | ||
1686 | /* delegate signal strength measurement to tuner */ | ||
1687 | dvb->fe[0]->ops.read_signal_strength = | ||
1688 | dvb->fe[0]->ops.tuner_ops.get_rf_strength; | ||
1689 | |||
1690 | /* attach SEC */ | ||
1691 | a8293_pdata.dvb_frontend = dvb->fe[0]; | ||
1692 | memset(&board_info, 0, sizeof(board_info)); | ||
1693 | strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); | ||
1694 | board_info.addr = 0x08; | ||
1695 | board_info.platform_data = &a8293_pdata; | ||
1696 | request_module("a8293"); | ||
1697 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); | ||
1698 | if (client == NULL || client->dev.driver == NULL) { | ||
1699 | module_put(dvb->i2c_client_tuner->dev.driver->owner); | ||
1700 | i2c_unregister_device(dvb->i2c_client_tuner); | ||
1701 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1702 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1703 | result = -ENODEV; | ||
1704 | goto out_free; | ||
1705 | } | ||
1706 | if (!try_module_get(client->dev.driver->owner)) { | ||
1707 | i2c_unregister_device(client); | ||
1708 | module_put(dvb->i2c_client_tuner->dev.driver->owner); | ||
1709 | i2c_unregister_device(dvb->i2c_client_tuner); | ||
1710 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1711 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1712 | result = -ENODEV; | ||
1713 | goto out_free; | 1855 | goto out_free; |
1714 | } | ||
1715 | dvb->i2c_client_sec = client; | ||
1716 | break; | 1856 | break; |
1717 | } | ||
1718 | case EM28178_BOARD_PCTV_292E: | 1857 | case EM28178_BOARD_PCTV_292E: |
1719 | { | 1858 | result = em28178_dvb_init_pctv_292e(dev); |
1720 | struct i2c_adapter *adapter; | 1859 | if (result) |
1721 | struct i2c_client *client; | 1860 | goto out_free; |
1722 | struct i2c_board_info info; | ||
1723 | struct si2168_config si2168_config; | ||
1724 | struct si2157_config si2157_config; | ||
1725 | |||
1726 | /* attach demod */ | ||
1727 | memset(&si2168_config, 0, sizeof(si2168_config)); | ||
1728 | si2168_config.i2c_adapter = &adapter; | ||
1729 | si2168_config.fe = &dvb->fe[0]; | ||
1730 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | ||
1731 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1732 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | ||
1733 | info.addr = 0x64; | ||
1734 | info.platform_data = &si2168_config; | ||
1735 | request_module(info.type); | ||
1736 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); | ||
1737 | if (client == NULL || client->dev.driver == NULL) { | ||
1738 | result = -ENODEV; | ||
1739 | goto out_free; | ||
1740 | } | ||
1741 | |||
1742 | if (!try_module_get(client->dev.driver->owner)) { | ||
1743 | i2c_unregister_device(client); | ||
1744 | result = -ENODEV; | ||
1745 | goto out_free; | ||
1746 | } | ||
1747 | |||
1748 | dvb->i2c_client_demod = client; | ||
1749 | |||
1750 | /* attach tuner */ | ||
1751 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
1752 | si2157_config.fe = dvb->fe[0]; | ||
1753 | si2157_config.if_port = 1; | ||
1754 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1755 | si2157_config.mdev = dev->media_dev; | ||
1756 | #endif | ||
1757 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1758 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
1759 | info.addr = 0x60; | ||
1760 | info.platform_data = &si2157_config; | ||
1761 | request_module(info.type); | ||
1762 | client = i2c_new_device(adapter, &info); | ||
1763 | if (client == NULL || client->dev.driver == NULL) { | ||
1764 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1765 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1766 | result = -ENODEV; | ||
1767 | goto out_free; | ||
1768 | } | ||
1769 | |||
1770 | if (!try_module_get(client->dev.driver->owner)) { | ||
1771 | i2c_unregister_device(client); | ||
1772 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1773 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1774 | result = -ENODEV; | ||
1775 | goto out_free; | ||
1776 | } | ||
1777 | |||
1778 | dvb->i2c_client_tuner = client; | ||
1779 | dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; | ||
1780 | } | ||
1781 | break; | 1861 | break; |
1782 | case EM28178_BOARD_TERRATEC_T2_STICK_HD: | 1862 | case EM28178_BOARD_TERRATEC_T2_STICK_HD: |
1783 | { | 1863 | result = em28178_dvb_init_terratec_t2_stick_hd(dev); |
1784 | struct i2c_adapter *adapter; | 1864 | if (result) |
1785 | struct i2c_client *client; | 1865 | goto out_free; |
1786 | struct i2c_board_info info; | ||
1787 | struct si2168_config si2168_config; | ||
1788 | struct si2157_config si2157_config; | ||
1789 | |||
1790 | /* attach demod */ | ||
1791 | memset(&si2168_config, 0, sizeof(si2168_config)); | ||
1792 | si2168_config.i2c_adapter = &adapter; | ||
1793 | si2168_config.fe = &dvb->fe[0]; | ||
1794 | si2168_config.ts_mode = SI2168_TS_PARALLEL; | ||
1795 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1796 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | ||
1797 | info.addr = 0x64; | ||
1798 | info.platform_data = &si2168_config; | ||
1799 | request_module(info.type); | ||
1800 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); | ||
1801 | if (client == NULL || client->dev.driver == NULL) { | ||
1802 | result = -ENODEV; | ||
1803 | goto out_free; | ||
1804 | } | ||
1805 | |||
1806 | if (!try_module_get(client->dev.driver->owner)) { | ||
1807 | i2c_unregister_device(client); | ||
1808 | result = -ENODEV; | ||
1809 | goto out_free; | ||
1810 | } | ||
1811 | |||
1812 | dvb->i2c_client_demod = client; | ||
1813 | |||
1814 | /* attach tuner */ | ||
1815 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
1816 | si2157_config.fe = dvb->fe[0]; | ||
1817 | si2157_config.if_port = 0; | ||
1818 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1819 | si2157_config.mdev = dev->media_dev; | ||
1820 | #endif | ||
1821 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1822 | strlcpy(info.type, "si2146", I2C_NAME_SIZE); | ||
1823 | info.addr = 0x60; | ||
1824 | info.platform_data = &si2157_config; | ||
1825 | request_module("si2157"); | ||
1826 | client = i2c_new_device(adapter, &info); | ||
1827 | if (client == NULL || client->dev.driver == NULL) { | ||
1828 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1829 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1830 | result = -ENODEV; | ||
1831 | goto out_free; | ||
1832 | } | ||
1833 | |||
1834 | if (!try_module_get(client->dev.driver->owner)) { | ||
1835 | i2c_unregister_device(client); | ||
1836 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1837 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1838 | result = -ENODEV; | ||
1839 | goto out_free; | ||
1840 | } | ||
1841 | |||
1842 | dvb->i2c_client_tuner = client; | ||
1843 | } | ||
1844 | break; | 1866 | break; |
1845 | |||
1846 | case EM28178_BOARD_PLEX_PX_BCUD: | 1867 | case EM28178_BOARD_PLEX_PX_BCUD: |
1847 | { | 1868 | result = em28178_dvb_init_plex_px_bcud(dev); |
1848 | struct i2c_client *client; | 1869 | if (result) |
1849 | struct i2c_board_info info; | 1870 | goto out_free; |
1850 | struct tc90522_config tc90522_config; | ||
1851 | struct qm1d1c0042_config qm1d1c0042_config; | ||
1852 | |||
1853 | /* attach demod */ | ||
1854 | memset(&tc90522_config, 0, sizeof(tc90522_config)); | ||
1855 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1856 | strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE); | ||
1857 | info.addr = 0x15; | ||
1858 | info.platform_data = &tc90522_config; | ||
1859 | request_module("tc90522"); | ||
1860 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); | ||
1861 | if (client == NULL || client->dev.driver == NULL) { | ||
1862 | result = -ENODEV; | ||
1863 | goto out_free; | ||
1864 | } | ||
1865 | dvb->i2c_client_demod = client; | ||
1866 | if (!try_module_get(client->dev.driver->owner)) { | ||
1867 | i2c_unregister_device(client); | ||
1868 | result = -ENODEV; | ||
1869 | goto out_free; | ||
1870 | } | ||
1871 | |||
1872 | /* attach tuner */ | ||
1873 | memset(&qm1d1c0042_config, 0, | ||
1874 | sizeof(qm1d1c0042_config)); | ||
1875 | qm1d1c0042_config.fe = tc90522_config.fe; | ||
1876 | qm1d1c0042_config.lpf = 1; | ||
1877 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1878 | strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE); | ||
1879 | info.addr = 0x61; | ||
1880 | info.platform_data = &qm1d1c0042_config; | ||
1881 | request_module(info.type); | ||
1882 | client = i2c_new_device(tc90522_config.tuner_i2c, | ||
1883 | &info); | ||
1884 | if (client == NULL || client->dev.driver == NULL) { | ||
1885 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1886 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1887 | result = -ENODEV; | ||
1888 | goto out_free; | ||
1889 | } | ||
1890 | dvb->i2c_client_tuner = client; | ||
1891 | if (!try_module_get(client->dev.driver->owner)) { | ||
1892 | i2c_unregister_device(client); | ||
1893 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1894 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1895 | result = -ENODEV; | ||
1896 | goto out_free; | ||
1897 | } | ||
1898 | dvb->fe[0] = tc90522_config.fe; | ||
1899 | px_bcud_init(dev); | ||
1900 | } | ||
1901 | break; | 1871 | break; |
1902 | case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: | 1872 | case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: |
1903 | { | 1873 | result = em28174_dvb_init_hauppauge_wintv_dualhd_dvb(dev); |
1904 | struct i2c_adapter *adapter; | 1874 | if (result) |
1905 | struct i2c_client *client; | 1875 | goto out_free; |
1906 | struct i2c_board_info info; | ||
1907 | struct si2168_config si2168_config; | ||
1908 | struct si2157_config si2157_config; | ||
1909 | |||
1910 | /* attach demod */ | ||
1911 | memset(&si2168_config, 0, sizeof(si2168_config)); | ||
1912 | si2168_config.i2c_adapter = &adapter; | ||
1913 | si2168_config.fe = &dvb->fe[0]; | ||
1914 | si2168_config.ts_mode = SI2168_TS_SERIAL; | ||
1915 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1916 | strlcpy(info.type, "si2168", I2C_NAME_SIZE); | ||
1917 | info.addr = 0x64; | ||
1918 | info.platform_data = &si2168_config; | ||
1919 | request_module(info.type); | ||
1920 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); | ||
1921 | if (client == NULL || client->dev.driver == NULL) { | ||
1922 | result = -ENODEV; | ||
1923 | goto out_free; | ||
1924 | } | ||
1925 | |||
1926 | if (!try_module_get(client->dev.driver->owner)) { | ||
1927 | i2c_unregister_device(client); | ||
1928 | result = -ENODEV; | ||
1929 | goto out_free; | ||
1930 | } | ||
1931 | |||
1932 | dvb->i2c_client_demod = client; | ||
1933 | |||
1934 | /* attach tuner */ | ||
1935 | memset(&si2157_config, 0, sizeof(si2157_config)); | ||
1936 | si2157_config.fe = dvb->fe[0]; | ||
1937 | si2157_config.if_port = 1; | ||
1938 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
1939 | si2157_config.mdev = dev->media_dev; | ||
1940 | #endif | ||
1941 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1942 | strlcpy(info.type, "si2157", I2C_NAME_SIZE); | ||
1943 | info.addr = 0x60; | ||
1944 | info.platform_data = &si2157_config; | ||
1945 | request_module(info.type); | ||
1946 | client = i2c_new_device(adapter, &info); | ||
1947 | if (client == NULL || client->dev.driver == NULL) { | ||
1948 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1949 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1950 | result = -ENODEV; | ||
1951 | goto out_free; | ||
1952 | } | ||
1953 | |||
1954 | if (!try_module_get(client->dev.driver->owner)) { | ||
1955 | i2c_unregister_device(client); | ||
1956 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
1957 | i2c_unregister_device(dvb->i2c_client_demod); | ||
1958 | result = -ENODEV; | ||
1959 | goto out_free; | ||
1960 | } | ||
1961 | |||
1962 | dvb->i2c_client_tuner = client; | ||
1963 | |||
1964 | } | ||
1965 | break; | 1876 | break; |
1966 | case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595: | 1877 | case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595: |
1967 | { | 1878 | result = em28174_dvb_init_hauppauge_wintv_dualhd_01595(dev); |
1968 | struct i2c_adapter *adapter; | 1879 | if (result) |
1969 | struct i2c_client *client; | 1880 | goto out_free; |
1970 | struct i2c_board_info info = {}; | ||
1971 | struct lgdt3306a_config lgdt3306a_config; | ||
1972 | struct si2157_config si2157_config = {}; | ||
1973 | |||
1974 | /* attach demod */ | ||
1975 | lgdt3306a_config = hauppauge_01595_lgdt3306a_config; | ||
1976 | lgdt3306a_config.fe = &dvb->fe[0]; | ||
1977 | lgdt3306a_config.i2c_adapter = &adapter; | ||
1978 | strlcpy(info.type, "lgdt3306a", sizeof(info.type)); | ||
1979 | info.addr = 0x59; | ||
1980 | info.platform_data = &lgdt3306a_config; | ||
1981 | request_module(info.type); | ||
1982 | client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], | ||
1983 | &info); | ||
1984 | if (client == NULL || client->dev.driver == NULL) { | ||
1985 | result = -ENODEV; | ||
1986 | goto out_free; | ||
1987 | } | ||
1988 | |||
1989 | if (!try_module_get(client->dev.driver->owner)) { | ||
1990 | i2c_unregister_device(client); | ||
1991 | result = -ENODEV; | ||
1992 | goto out_free; | ||
1993 | } | ||
1994 | |||
1995 | dvb->i2c_client_demod = client; | ||
1996 | |||
1997 | /* attach tuner */ | ||
1998 | si2157_config.fe = dvb->fe[0]; | ||
1999 | si2157_config.if_port = 1; | ||
2000 | si2157_config.inversion = 1; | ||
2001 | #ifdef CONFIG_MEDIA_CONTROLLER_DVB | ||
2002 | si2157_config.mdev = dev->media_dev; | ||
2003 | #endif | ||
2004 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
2005 | strlcpy(info.type, "si2157", sizeof(info.type)); | ||
2006 | info.addr = 0x60; | ||
2007 | info.platform_data = &si2157_config; | ||
2008 | request_module(info.type); | ||
2009 | |||
2010 | client = i2c_new_device(adapter, &info); | ||
2011 | if (client == NULL || client->dev.driver == NULL) { | ||
2012 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
2013 | i2c_unregister_device(dvb->i2c_client_demod); | ||
2014 | result = -ENODEV; | ||
2015 | goto out_free; | ||
2016 | } | ||
2017 | if (!try_module_get(client->dev.driver->owner)) { | ||
2018 | i2c_unregister_device(client); | ||
2019 | module_put(dvb->i2c_client_demod->dev.driver->owner); | ||
2020 | i2c_unregister_device(dvb->i2c_client_demod); | ||
2021 | result = -ENODEV; | ||
2022 | goto out_free; | ||
2023 | } | ||
2024 | |||
2025 | dvb->i2c_client_tuner = client; | ||
2026 | } | ||
2027 | break; | 1881 | break; |
2028 | default: | 1882 | default: |
2029 | dev_err(&dev->intf->dev, | 1883 | dev_err(&dev->intf->dev, |
2030 | "The frontend of your DVB/ATSC card isn't supported yet\n"); | 1884 | "The frontend of your DVB/ATSC card isn't supported yet\n"); |
2031 | break; | 1885 | break; |
2032 | } | 1886 | } |
2033 | if (NULL == dvb->fe[0]) { | 1887 | if (!dvb->fe[0]) { |
2034 | dev_err(&dev->intf->dev, "frontend initialization failed\n"); | 1888 | dev_err(&dev->intf->dev, "frontend initialization failed\n"); |
2035 | result = -EINVAL; | 1889 | result = -EINVAL; |
2036 | goto out_free; | 1890 | goto out_free; |
@@ -2046,6 +1900,14 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
2046 | if (result < 0) | 1900 | if (result < 0) |
2047 | goto out_free; | 1901 | goto out_free; |
2048 | 1902 | ||
1903 | if (dev->dvb_xfer_bulk) { | ||
1904 | dvb_alt = 0; | ||
1905 | } else { /* isoc */ | ||
1906 | dvb_alt = dev->dvb_alt_isoc; | ||
1907 | } | ||
1908 | |||
1909 | udev = interface_to_usbdev(dev->intf); | ||
1910 | usb_set_interface(udev, dev->ifnum, dvb_alt); | ||
2049 | dev_info(&dev->intf->dev, "DVB extension successfully initialized\n"); | 1911 | dev_info(&dev->intf->dev, "DVB extension successfully initialized\n"); |
2050 | 1912 | ||
2051 | kref_get(&dev->ref); | 1913 | kref_get(&dev->ref); |
@@ -2071,7 +1933,6 @@ static inline void prevent_sleep(struct dvb_frontend_ops *ops) | |||
2071 | static int em28xx_dvb_fini(struct em28xx *dev) | 1933 | static int em28xx_dvb_fini(struct em28xx *dev) |
2072 | { | 1934 | { |
2073 | struct em28xx_dvb *dvb; | 1935 | struct em28xx_dvb *dvb; |
2074 | struct i2c_client *client; | ||
2075 | 1936 | ||
2076 | if (dev->is_audio_only) { | 1937 | if (dev->is_audio_only) { |
2077 | /* Shouldn't initialize IR for this interface */ | 1938 | /* Shouldn't initialize IR for this interface */ |
@@ -2093,8 +1954,10 @@ static int em28xx_dvb_fini(struct em28xx *dev) | |||
2093 | em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); | 1954 | em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); |
2094 | 1955 | ||
2095 | if (dev->disconnected) { | 1956 | if (dev->disconnected) { |
2096 | /* We cannot tell the device to sleep | 1957 | /* |
2097 | * once it has been unplugged. */ | 1958 | * We cannot tell the device to sleep |
1959 | * once it has been unplugged. | ||
1960 | */ | ||
2098 | if (dvb->fe[0]) { | 1961 | if (dvb->fe[0]) { |
2099 | prevent_sleep(&dvb->fe[0]->ops); | 1962 | prevent_sleep(&dvb->fe[0]->ops); |
2100 | dvb->fe[0]->exit = DVB_FE_DEVICE_REMOVED; | 1963 | dvb->fe[0]->exit = DVB_FE_DEVICE_REMOVED; |
@@ -2107,26 +1970,10 @@ static int em28xx_dvb_fini(struct em28xx *dev) | |||
2107 | 1970 | ||
2108 | em28xx_unregister_dvb(dvb); | 1971 | em28xx_unregister_dvb(dvb); |
2109 | 1972 | ||
2110 | /* remove I2C SEC */ | 1973 | /* release I2C module bindings */ |
2111 | client = dvb->i2c_client_sec; | 1974 | dvb_module_release(dvb->i2c_client_sec); |
2112 | if (client) { | 1975 | dvb_module_release(dvb->i2c_client_tuner); |
2113 | module_put(client->dev.driver->owner); | 1976 | dvb_module_release(dvb->i2c_client_demod); |
2114 | i2c_unregister_device(client); | ||
2115 | } | ||
2116 | |||
2117 | /* remove I2C tuner */ | ||
2118 | client = dvb->i2c_client_tuner; | ||
2119 | if (client) { | ||
2120 | module_put(client->dev.driver->owner); | ||
2121 | i2c_unregister_device(client); | ||
2122 | } | ||
2123 | |||
2124 | /* remove I2C demod */ | ||
2125 | client = dvb->i2c_client_demod; | ||
2126 | if (client) { | ||
2127 | module_put(client->dev.driver->owner); | ||
2128 | i2c_unregister_device(client); | ||
2129 | } | ||
2130 | 1977 | ||
2131 | kfree(dvb); | 1978 | kfree(dvb); |
2132 | dev->dvb = NULL; | 1979 | dev->dvb = NULL; |
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 9bf49d666e5a..9151bccd859a 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c | |||
@@ -1,26 +1,22 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | 2 | // |
3 | 3 | // em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | |
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | // |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | 6 | // Markus Rechberger <mrechberger@gmail.com> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | // Mauro Carvalho Chehab <mchehab@infradead.org> |
8 | Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> | 8 | // Sascha Sommer <saschasommer@freenet.de> |
9 | 9 | // Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> | |
10 | This program is free software; you can redistribute it and/or modify | 10 | // |
11 | it under the terms of the GNU General Public License as published by | 11 | // This program is free software; you can redistribute it and/or modify |
12 | the Free Software Foundation; either version 2 of the License, or | 12 | // it under the terms of the GNU General Public License as published by |
13 | (at your option) any later version. | 13 | // the Free Software Foundation; either version 2 of the License, or |
14 | 14 | // (at your option) any later version. | |
15 | This program is distributed in the hope that it will be useful, | 15 | // |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | // This program is distributed in the hope that it will be useful, |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | GNU General Public License for more details. | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | 19 | // GNU General Public License for more details. | |
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | 20 | ||
25 | #include "em28xx.h" | 21 | #include "em28xx.h" |
26 | 22 | ||
@@ -50,6 +46,35 @@ MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I | |||
50 | "i2c: %s: " fmt, __func__, ## arg); \ | 46 | "i2c: %s: " fmt, __func__, ## arg); \ |
51 | } while (0) | 47 | } while (0) |
52 | 48 | ||
49 | /* | ||
50 | * Time in msecs to wait for i2c xfers to finish. | ||
51 | * 35ms is the maximum time a SMBUS device could wait when | ||
52 | * clock stretching is used. As the transfer itself will take | ||
53 | * some time to happen, set it to 35 ms. | ||
54 | * | ||
55 | * Ok, I2C doesn't specify any limit. So, eventually, we may need | ||
56 | * to increase this timeout. | ||
57 | */ | ||
58 | #define EM28XX_I2C_XFER_TIMEOUT 35 /* ms */ | ||
59 | |||
60 | static int em28xx_i2c_timeout(struct em28xx *dev) | ||
61 | { | ||
62 | int time = EM28XX_I2C_XFER_TIMEOUT; | ||
63 | |||
64 | switch (dev->i2c_speed & 0x03) { | ||
65 | case EM28XX_I2C_FREQ_25_KHZ: | ||
66 | time += 4; /* Assume 4 ms for transfers */ | ||
67 | break; | ||
68 | case EM28XX_I2C_FREQ_100_KHZ: | ||
69 | case EM28XX_I2C_FREQ_400_KHZ: | ||
70 | time += 1; /* Assume 1 ms for transfers */ | ||
71 | break; | ||
72 | default: /* EM28XX_I2C_FREQ_1_5_MHZ */ | ||
73 | break; | ||
74 | } | ||
75 | |||
76 | return msecs_to_jiffies(time); | ||
77 | } | ||
53 | 78 | ||
54 | /* | 79 | /* |
55 | * em2800_i2c_send_bytes() | 80 | * em2800_i2c_send_bytes() |
@@ -57,14 +82,13 @@ MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I | |||
57 | */ | 82 | */ |
58 | static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | 83 | static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) |
59 | { | 84 | { |
60 | unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); | 85 | unsigned long timeout = jiffies + em28xx_i2c_timeout(dev); |
61 | int ret; | 86 | int ret; |
62 | u8 b2[6]; | 87 | u8 b2[6]; |
63 | 88 | ||
64 | if (len < 1 || len > 4) | 89 | if (len < 1 || len > 4) |
65 | return -EOPNOTSUPP; | 90 | return -EOPNOTSUPP; |
66 | 91 | ||
67 | BUG_ON(len < 1 || len > 4); | ||
68 | b2[5] = 0x80 + len - 1; | 92 | b2[5] = 0x80 + len - 1; |
69 | b2[4] = addr; | 93 | b2[4] = addr; |
70 | b2[3] = buf[0]; | 94 | b2[3] = buf[0]; |
@@ -98,7 +122,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | |||
98 | ret); | 122 | ret); |
99 | return ret; | 123 | return ret; |
100 | } | 124 | } |
101 | msleep(5); | 125 | usleep_range(5000, 6000); |
102 | } | 126 | } |
103 | dprintk(0, "write to i2c device at 0x%x timed out\n", addr); | 127 | dprintk(0, "write to i2c device at 0x%x timed out\n", addr); |
104 | return -ETIMEDOUT; | 128 | return -ETIMEDOUT; |
@@ -110,7 +134,7 @@ static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | |||
110 | */ | 134 | */ |
111 | static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | 135 | static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) |
112 | { | 136 | { |
113 | unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); | 137 | unsigned long timeout = jiffies + em28xx_i2c_timeout(dev); |
114 | u8 buf2[4]; | 138 | u8 buf2[4]; |
115 | int ret; | 139 | int ret; |
116 | int i; | 140 | int i; |
@@ -145,14 +169,13 @@ static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) | |||
145 | ret); | 169 | ret); |
146 | return ret; | 170 | return ret; |
147 | } | 171 | } |
148 | msleep(5); | 172 | usleep_range(5000, 6000); |
149 | } | 173 | } |
150 | if (ret != 0x84 + len - 1) { | 174 | if (ret != 0x84 + len - 1) |
151 | dprintk(0, "read from i2c device at 0x%x timed out\n", addr); | 175 | dprintk(0, "read from i2c device at 0x%x timed out\n", addr); |
152 | } | ||
153 | 176 | ||
154 | /* get the received message */ | 177 | /* get the received message */ |
155 | ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); | 178 | ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4 - len, buf2, len); |
156 | if (ret != len) { | 179 | if (ret != len) { |
157 | dev_warn(&dev->intf->dev, | 180 | dev_warn(&dev->intf->dev, |
158 | "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", | 181 | "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", |
@@ -186,7 +209,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) | |||
186 | static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | 209 | static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, |
187 | u16 len, int stop) | 210 | u16 len, int stop) |
188 | { | 211 | { |
189 | unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); | 212 | unsigned long timeout = jiffies + em28xx_i2c_timeout(dev); |
190 | int ret; | 213 | int ret; |
191 | 214 | ||
192 | if (len < 1 || len > 64) | 215 | if (len < 1 || len > 64) |
@@ -204,12 +227,11 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
204 | "writing to i2c device at 0x%x failed (error=%i)\n", | 227 | "writing to i2c device at 0x%x failed (error=%i)\n", |
205 | addr, ret); | 228 | addr, ret); |
206 | return ret; | 229 | return ret; |
207 | } else { | ||
208 | dev_warn(&dev->intf->dev, | ||
209 | "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", | ||
210 | len, addr, ret); | ||
211 | return -EIO; | ||
212 | } | 230 | } |
231 | dev_warn(&dev->intf->dev, | ||
232 | "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", | ||
233 | len, addr, ret); | ||
234 | return -EIO; | ||
213 | } | 235 | } |
214 | 236 | ||
215 | /* wait for completion */ | 237 | /* wait for completion */ |
@@ -228,7 +250,7 @@ static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
228 | ret); | 250 | ret); |
229 | return ret; | 251 | return ret; |
230 | } | 252 | } |
231 | msleep(5); | 253 | usleep_range(5000, 6000); |
232 | /* | 254 | /* |
233 | * NOTE: do we really have to wait for success ? | 255 | * NOTE: do we really have to wait for success ? |
234 | * Never seen anything else than 0x00 or 0x10 | 256 | * Never seen anything else than 0x00 or 0x10 |
@@ -351,12 +373,12 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
351 | "writing to i2c device at 0x%x failed (error=%i)\n", | 373 | "writing to i2c device at 0x%x failed (error=%i)\n", |
352 | addr, ret); | 374 | addr, ret); |
353 | return ret; | 375 | return ret; |
354 | } else { | ||
355 | dev_warn(&dev->intf->dev, | ||
356 | "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", | ||
357 | len, addr, ret); | ||
358 | return -EIO; | ||
359 | } | 376 | } |
377 | |||
378 | dev_warn(&dev->intf->dev, | ||
379 | "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", | ||
380 | len, addr, ret); | ||
381 | return -EIO; | ||
360 | } | 382 | } |
361 | /* Check success */ | 383 | /* Check success */ |
362 | ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); | 384 | ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); |
@@ -366,7 +388,8 @@ static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
366 | */ | 388 | */ |
367 | if (!ret) | 389 | if (!ret) |
368 | return len; | 390 | return len; |
369 | else if (ret > 0) { | 391 | |
392 | if (ret > 0) { | ||
370 | dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); | 393 | dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); |
371 | return -ENXIO; | 394 | return -ENXIO; |
372 | } | 395 | } |
@@ -420,7 +443,8 @@ static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, | |||
420 | */ | 443 | */ |
421 | if (!ret) | 444 | if (!ret) |
422 | return len; | 445 | return len; |
423 | else if (ret > 0) { | 446 | |
447 | if (ret > 0) { | ||
424 | dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); | 448 | dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); |
425 | return -ENXIO; | 449 | return -ENXIO; |
426 | } | 450 | } |
@@ -508,13 +532,15 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
508 | { | 532 | { |
509 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; | 533 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; |
510 | struct em28xx *dev = i2c_bus->dev; | 534 | struct em28xx *dev = i2c_bus->dev; |
511 | unsigned bus = i2c_bus->bus; | 535 | unsigned int bus = i2c_bus->bus; |
512 | int addr, rc, i; | 536 | int addr, rc, i; |
513 | u8 reg; | 537 | u8 reg; |
514 | 538 | ||
515 | /* prevent i2c xfer attempts after device is disconnected | 539 | /* |
516 | some fe's try to do i2c writes/reads from their release | 540 | * prevent i2c xfer attempts after device is disconnected |
517 | interfaces when called in disconnect path */ | 541 | * some fe's try to do i2c writes/reads from their release |
542 | * interfaces when called in disconnect path | ||
543 | */ | ||
518 | if (dev->disconnected) | 544 | if (dev->disconnected) |
519 | return -ENODEV; | 545 | return -ENODEV; |
520 | 546 | ||
@@ -597,12 +623,13 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) | |||
597 | if (len == length) { | 623 | if (len == length) { |
598 | c = (char)len; | 624 | c = (char)len; |
599 | len = -1; | 625 | len = -1; |
600 | } else | 626 | } else { |
601 | c = *buf++; | 627 | c = *buf++; |
628 | } | ||
602 | l = (l << 8) | c; | 629 | l = (l << 8) | c; |
603 | len++; | 630 | len++; |
604 | if ((len & (32 / 8 - 1)) == 0) | 631 | if ((len & (32 / 8 - 1)) == 0) |
605 | hash = ((hash^l) * 0x9e370001UL); | 632 | hash = ((hash ^ l) * 0x9e370001UL); |
606 | } while (len); | 633 | } while (len); |
607 | 634 | ||
608 | return (hash >> (32 - bits)) & 0xffffffffUL; | 635 | return (hash >> (32 - bits)) & 0xffffffffUL; |
@@ -612,7 +639,7 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) | |||
612 | * Helper function to read data blocks from i2c clients with 8 or 16 bit | 639 | * Helper function to read data blocks from i2c clients with 8 or 16 bit |
613 | * address width, 8 bit register width and auto incrementation been activated | 640 | * address width, 8 bit register width and auto incrementation been activated |
614 | */ | 641 | */ |
615 | static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, | 642 | static int em28xx_i2c_read_block(struct em28xx *dev, unsigned int bus, u16 addr, |
616 | bool addr_w16, u16 len, u8 *data) | 643 | bool addr_w16, u16 len, u8 *data) |
617 | { | 644 | { |
618 | int remain = len, rsize, rsize_max, ret; | 645 | int remain = len, rsize, rsize_max, ret; |
@@ -624,7 +651,8 @@ static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, | |||
624 | /* Select address */ | 651 | /* Select address */ |
625 | buf[0] = addr >> 8; | 652 | buf[0] = addr >> 8; |
626 | buf[1] = addr & 0xff; | 653 | buf[1] = addr & 0xff; |
627 | ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); | 654 | ret = i2c_master_send(&dev->i2c_client[bus], |
655 | buf + !addr_w16, 1 + addr_w16); | ||
628 | if (ret < 0) | 656 | if (ret < 0) |
629 | return ret; | 657 | return ret; |
630 | /* Read data */ | 658 | /* Read data */ |
@@ -649,7 +677,7 @@ static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, | |||
649 | return len; | 677 | return len; |
650 | } | 678 | } |
651 | 679 | ||
652 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, | 680 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned int bus, |
653 | u8 **eedata, u16 *eedata_len) | 681 | u8 **eedata, u16 *eedata_len) |
654 | { | 682 | { |
655 | const u16 len = 256; | 683 | const u16 len = 256; |
@@ -677,7 +705,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, | |||
677 | } | 705 | } |
678 | 706 | ||
679 | data = kzalloc(len, GFP_KERNEL); | 707 | data = kzalloc(len, GFP_KERNEL); |
680 | if (data == NULL) | 708 | if (!data) |
681 | return -ENOMEM; | 709 | return -ENOMEM; |
682 | 710 | ||
683 | /* Read EEPROM content */ | 711 | /* Read EEPROM content */ |
@@ -710,8 +738,8 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, | |||
710 | mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ | 738 | mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ |
711 | 739 | ||
712 | dev_info(&dev->intf->dev, | 740 | dev_info(&dev->intf->dev, |
713 | "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", | 741 | "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n", |
714 | data[0], data[1], data[2], data[3], dev->hash); | 742 | data, dev->hash); |
715 | dev_info(&dev->intf->dev, | 743 | dev_info(&dev->intf->dev, |
716 | "EEPROM info:\n"); | 744 | "EEPROM info:\n"); |
717 | dev_info(&dev->intf->dev, | 745 | dev_info(&dev->intf->dev, |
@@ -769,15 +797,18 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, | |||
769 | return 0; | 797 | return 0; |
770 | } | 798 | } |
771 | 799 | ||
772 | /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ | 800 | /* |
801 | * TODO: decrypt eeprom data for camera bridges | ||
802 | * (em25xx, em276x+) | ||
803 | */ | ||
773 | 804 | ||
774 | } else if (!dev->eeprom_addrwidth_16bit && | 805 | } else if (!dev->eeprom_addrwidth_16bit && |
775 | data[0] == 0x1a && data[1] == 0xeb && | 806 | data[0] == 0x1a && data[1] == 0xeb && |
776 | data[2] == 0x67 && data[3] == 0x95) { | 807 | data[2] == 0x67 && data[3] == 0x95) { |
777 | dev->hash = em28xx_hash_mem(data, len, 32); | 808 | dev->hash = em28xx_hash_mem(data, len, 32); |
778 | dev_info(&dev->intf->dev, | 809 | dev_info(&dev->intf->dev, |
779 | "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", | 810 | "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n", |
780 | data[0], data[1], data[2], data[3], dev->hash); | 811 | data, dev->hash); |
781 | dev_info(&dev->intf->dev, | 812 | dev_info(&dev->intf->dev, |
782 | "EEPROM info:\n"); | 813 | "EEPROM info:\n"); |
783 | } else { | 814 | } else { |
@@ -859,8 +890,8 @@ static u32 functionality(struct i2c_adapter *i2c_adap) | |||
859 | { | 890 | { |
860 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; | 891 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; |
861 | 892 | ||
862 | if ((i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) || | 893 | if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX || |
863 | (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)) { | 894 | i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) { |
864 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 895 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
865 | } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) { | 896 | } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) { |
866 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) & | 897 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) & |
@@ -893,7 +924,7 @@ static const struct i2c_client em28xx_client_template = { | |||
893 | * incomplete list of known devices | 924 | * incomplete list of known devices |
894 | */ | 925 | */ |
895 | static char *i2c_devs[128] = { | 926 | static char *i2c_devs[128] = { |
896 | [0x1c >> 1] = "lgdt330x", | 927 | [0x1c >> 1] = "lgdt330x", |
897 | [0x3e >> 1] = "remote IR sensor", | 928 | [0x3e >> 1] = "remote IR sensor", |
898 | [0x4a >> 1] = "saa7113h", | 929 | [0x4a >> 1] = "saa7113h", |
899 | [0x52 >> 1] = "drxk", | 930 | [0x52 >> 1] = "drxk", |
@@ -916,7 +947,7 @@ static char *i2c_devs[128] = { | |||
916 | * do_i2c_scan() | 947 | * do_i2c_scan() |
917 | * check i2c address range for devices | 948 | * check i2c address range for devices |
918 | */ | 949 | */ |
919 | void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) | 950 | void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus) |
920 | { | 951 | { |
921 | u8 i2c_devicelist[128]; | 952 | u8 i2c_devicelist[128]; |
922 | unsigned char buf; | 953 | unsigned char buf; |
@@ -944,13 +975,14 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) | |||
944 | * em28xx_i2c_register() | 975 | * em28xx_i2c_register() |
945 | * register i2c bus | 976 | * register i2c bus |
946 | */ | 977 | */ |
947 | int em28xx_i2c_register(struct em28xx *dev, unsigned bus, | 978 | int em28xx_i2c_register(struct em28xx *dev, unsigned int bus, |
948 | enum em28xx_i2c_algo_type algo_type) | 979 | enum em28xx_i2c_algo_type algo_type) |
949 | { | 980 | { |
950 | int retval; | 981 | int retval; |
951 | 982 | ||
952 | BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); | 983 | if (WARN_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg || |
953 | BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); | 984 | !dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req)) |
985 | return -ENODEV; | ||
954 | 986 | ||
955 | if (bus >= NUM_I2C_BUSES) | 987 | if (bus >= NUM_I2C_BUSES) |
956 | return -ENODEV; | 988 | return -ENODEV; |
@@ -977,8 +1009,9 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, | |||
977 | 1009 | ||
978 | /* Up to now, all eeproms are at bus 0 */ | 1010 | /* Up to now, all eeproms are at bus 0 */ |
979 | if (!bus) { | 1011 | if (!bus) { |
980 | retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); | 1012 | retval = em28xx_i2c_eeprom(dev, bus, |
981 | if ((retval < 0) && (retval != -ENODEV)) { | 1013 | &dev->eedata, &dev->eedata_len); |
1014 | if (retval < 0 && retval != -ENODEV) { | ||
982 | dev_err(&dev->intf->dev, | 1015 | dev_err(&dev->intf->dev, |
983 | "%s: em28xx_i2_eeprom failed! retval [%d]\n", | 1016 | "%s: em28xx_i2_eeprom failed! retval [%d]\n", |
984 | __func__, retval); | 1017 | __func__, retval); |
@@ -995,7 +1028,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, | |||
995 | * em28xx_i2c_unregister() | 1028 | * em28xx_i2c_unregister() |
996 | * unregister i2c_bus | 1029 | * unregister i2c_bus |
997 | */ | 1030 | */ |
998 | int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) | 1031 | int em28xx_i2c_unregister(struct em28xx *dev, unsigned int bus) |
999 | { | 1032 | { |
1000 | if (bus >= NUM_I2C_BUSES) | 1033 | if (bus >= NUM_I2C_BUSES) |
1001 | return -ENODEV; | 1034 | return -ENODEV; |
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 046223de1e91..2dc1be00b8b8 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c | |||
@@ -1,25 +1,21 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | handle em28xx IR remotes via linux kernel input layer. | 2 | // |
3 | 3 | // handle em28xx IR remotes via linux kernel input layer. | |
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 4 | // |
5 | Markus Rechberger <mrechberger@gmail.com> | 5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | 6 | // Markus Rechberger <mrechberger@gmail.com> |
7 | Sascha Sommer <saschasommer@freenet.de> | 7 | // Mauro Carvalho Chehab <mchehab@infradead.org> |
8 | 8 | // Sascha Sommer <saschasommer@freenet.de> | |
9 | This program is free software; you can redistribute it and/or modify | 9 | // |
10 | it under the terms of the GNU General Public License as published by | 10 | // This program is free software; you can redistribute it and/or modify |
11 | the Free Software Foundation; either version 2 of the License, or | 11 | // it under the terms of the GNU General Public License as published by |
12 | (at your option) any later version. | 12 | // the Free Software Foundation; either version 2 of the License, or |
13 | 13 | // (at your option) any later version. | |
14 | This program is distributed in the hope that it will be useful, | 14 | // |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | // This program is distributed in the hope that it will be useful, |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | GNU General Public License for more details. | 17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | 18 | // GNU General Public License for more details. | |
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | 19 | ||
24 | #include "em28xx.h" | 20 | #include "em28xx.h" |
25 | 21 | ||
@@ -41,15 +37,15 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | |||
41 | 37 | ||
42 | #define MODULE_NAME "em28xx" | 38 | #define MODULE_NAME "em28xx" |
43 | 39 | ||
44 | #define dprintk( fmt, arg...) do { \ | 40 | #define dprintk(fmt, arg...) do { \ |
45 | if (ir_debug) \ | 41 | if (ir_debug) \ |
46 | dev_printk(KERN_DEBUG, &ir->dev->intf->dev, \ | 42 | dev_printk(KERN_DEBUG, &ir->dev->intf->dev, \ |
47 | "input: %s: " fmt, __func__, ## arg); \ | 43 | "input: %s: " fmt, __func__, ## arg); \ |
48 | } while (0) | 44 | } while (0) |
49 | 45 | ||
50 | /********************************************************** | 46 | /* |
51 | Polling structure used by em28xx IR's | 47 | * Polling structure used by em28xx IR's |
52 | **********************************************************/ | 48 | */ |
53 | 49 | ||
54 | struct em28xx_ir_poll_result { | 50 | struct em28xx_ir_poll_result { |
55 | unsigned int toggle_bit:1; | 51 | unsigned int toggle_bit:1; |
@@ -76,24 +72,31 @@ struct em28xx_IR { | |||
76 | 72 | ||
77 | int (*get_key_i2c)(struct i2c_client *ir, enum rc_proto *protocol, | 73 | int (*get_key_i2c)(struct i2c_client *ir, enum rc_proto *protocol, |
78 | u32 *scancode); | 74 | u32 *scancode); |
79 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); | 75 | int (*get_key)(struct em28xx_IR *ir, struct em28xx_ir_poll_result *r); |
80 | }; | 76 | }; |
81 | 77 | ||
82 | /********************************************************** | 78 | /* |
83 | I2C IR based get keycodes - should be used with ir-kbd-i2c | 79 | * I2C IR based get keycodes - should be used with ir-kbd-i2c |
84 | **********************************************************/ | 80 | */ |
85 | 81 | ||
86 | static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, | 82 | static int em28xx_get_key_terratec(struct i2c_client *i2c_dev, |
87 | enum rc_proto *protocol, u32 *scancode) | 83 | enum rc_proto *protocol, u32 *scancode) |
88 | { | 84 | { |
85 | int rc; | ||
89 | unsigned char b; | 86 | unsigned char b; |
90 | 87 | ||
91 | /* poll IR chip */ | 88 | /* poll IR chip */ |
92 | if (1 != i2c_master_recv(i2c_dev, &b, 1)) | 89 | rc = i2c_master_recv(i2c_dev, &b, 1); |
90 | if (rc != 1) { | ||
91 | if (rc < 0) | ||
92 | return rc; | ||
93 | return -EIO; | 93 | return -EIO; |
94 | } | ||
94 | 95 | ||
95 | /* it seems that 0xFE indicates that a button is still hold | 96 | /* |
96 | down, while 0xff indicates that no button is hold down. */ | 97 | * it seems that 0xFE indicates that a button is still hold |
98 | * down, while 0xff indicates that no button is hold down. | ||
99 | */ | ||
97 | 100 | ||
98 | if (b == 0xff) | 101 | if (b == 0xff) |
99 | return 0; | 102 | return 0; |
@@ -145,7 +148,7 @@ static int em28xx_get_key_pinnacle_usb_grey(struct i2c_client *i2c_dev, | |||
145 | 148 | ||
146 | /* poll IR chip */ | 149 | /* poll IR chip */ |
147 | 150 | ||
148 | if (3 != i2c_master_recv(i2c_dev, buf, 3)) | 151 | if (i2c_master_recv(i2c_dev, buf, 3) != 3) |
149 | return -EIO; | 152 | return -EIO; |
150 | 153 | ||
151 | if (buf[0] != 0x00) | 154 | if (buf[0] != 0x00) |
@@ -162,18 +165,28 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, | |||
162 | { | 165 | { |
163 | unsigned char subaddr, keydetect, key; | 166 | unsigned char subaddr, keydetect, key; |
164 | 167 | ||
165 | struct i2c_msg msg[] = { { .addr = i2c_dev->addr, .flags = 0, .buf = &subaddr, .len = 1}, | 168 | struct i2c_msg msg[] = { |
166 | { .addr = i2c_dev->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} }; | 169 | { |
170 | .addr = i2c_dev->addr, | ||
171 | .flags = 0, | ||
172 | .buf = &subaddr, .len = 1 | ||
173 | }, { | ||
174 | .addr = i2c_dev->addr, | ||
175 | .flags = I2C_M_RD, | ||
176 | .buf = &keydetect, | ||
177 | .len = 1 | ||
178 | } | ||
179 | }; | ||
167 | 180 | ||
168 | subaddr = 0x10; | 181 | subaddr = 0x10; |
169 | if (2 != i2c_transfer(i2c_dev->adapter, msg, 2)) | 182 | if (i2c_transfer(i2c_dev->adapter, msg, 2) != 2) |
170 | return -EIO; | 183 | return -EIO; |
171 | if (keydetect == 0x00) | 184 | if (keydetect == 0x00) |
172 | return 0; | 185 | return 0; |
173 | 186 | ||
174 | subaddr = 0x00; | 187 | subaddr = 0x00; |
175 | msg[1].buf = &key; | 188 | msg[1].buf = &key; |
176 | if (2 != i2c_transfer(i2c_dev->adapter, msg, 2)) | 189 | if (i2c_transfer(i2c_dev->adapter, msg, 2) != 2) |
177 | return -EIO; | 190 | return -EIO; |
178 | if (key == 0x00) | 191 | if (key == 0x00) |
179 | return 0; | 192 | return 0; |
@@ -183,9 +196,9 @@ static int em28xx_get_key_winfast_usbii_deluxe(struct i2c_client *i2c_dev, | |||
183 | return 1; | 196 | return 1; |
184 | } | 197 | } |
185 | 198 | ||
186 | /********************************************************** | 199 | /* |
187 | Poll based get keycode functions | 200 | * Poll based get keycode functions |
188 | **********************************************************/ | 201 | */ |
189 | 202 | ||
190 | /* This is for the em2860/em2880 */ | 203 | /* This is for the em2860/em2880 */ |
191 | static int default_polling_getkey(struct em28xx_IR *ir, | 204 | static int default_polling_getkey(struct em28xx_IR *ir, |
@@ -195,8 +208,9 @@ static int default_polling_getkey(struct em28xx_IR *ir, | |||
195 | int rc; | 208 | int rc; |
196 | u8 msg[3] = { 0, 0, 0 }; | 209 | u8 msg[3] = { 0, 0, 0 }; |
197 | 210 | ||
198 | /* Read key toggle, brand, and key code | 211 | /* |
199 | on registers 0x45, 0x46 and 0x47 | 212 | * Read key toggle, brand, and key code |
213 | * on registers 0x45, 0x46 and 0x47 | ||
200 | */ | 214 | */ |
201 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR, | 215 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR, |
202 | msg, sizeof(msg)); | 216 | msg, sizeof(msg)); |
@@ -237,8 +251,9 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, | |||
237 | int rc; | 251 | int rc; |
238 | u8 msg[5] = { 0, 0, 0, 0, 0 }; | 252 | u8 msg[5] = { 0, 0, 0, 0, 0 }; |
239 | 253 | ||
240 | /* Read key toggle, brand, and key code | 254 | /* |
241 | on registers 0x51-55 | 255 | * Read key toggle, brand, and key code |
256 | * on registers 0x51-55 | ||
242 | */ | 257 | */ |
243 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR, | 258 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR, |
244 | msg, sizeof(msg)); | 259 | msg, sizeof(msg)); |
@@ -294,9 +309,9 @@ static int em2874_polling_getkey(struct em28xx_IR *ir, | |||
294 | return 0; | 309 | return 0; |
295 | } | 310 | } |
296 | 311 | ||
297 | /********************************************************** | 312 | /* |
298 | Polling code for em28xx | 313 | * Polling code for em28xx |
299 | **********************************************************/ | 314 | */ |
300 | 315 | ||
301 | static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) | 316 | static int em28xx_i2c_ir_handle_key(struct em28xx_IR *ir) |
302 | { | 317 | { |
@@ -347,11 +362,14 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir) | |||
347 | 362 | ||
348 | if (ir->dev->chip_id == CHIP_ID_EM2874 || | 363 | if (ir->dev->chip_id == CHIP_ID_EM2874 || |
349 | ir->dev->chip_id == CHIP_ID_EM2884) | 364 | ir->dev->chip_id == CHIP_ID_EM2884) |
350 | /* The em2874 clears the readcount field every time the | 365 | /* |
351 | register is read. The em2860/2880 datasheet says that it | 366 | * The em2874 clears the readcount field every time the |
352 | is supposed to clear the readcount, but it doesn't. So with | 367 | * register is read. The em2860/2880 datasheet says |
353 | the em2874, we are looking for a non-zero read count as | 368 | * that it is supposed to clear the readcount, but it |
354 | opposed to a readcount that is incrementing */ | 369 | * doesn't. So with the em2874, we are looking for a |
370 | * non-zero read count as opposed to a readcount | ||
371 | * that is incrementing | ||
372 | */ | ||
355 | ir->last_readcount = 0; | 373 | ir->last_readcount = 0; |
356 | else | 374 | else |
357 | ir->last_readcount = poll_result.read_count; | 375 | ir->last_readcount = poll_result.read_count; |
@@ -476,15 +494,18 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_proto) | |||
476 | static int em28xx_probe_i2c_ir(struct em28xx *dev) | 494 | static int em28xx_probe_i2c_ir(struct em28xx *dev) |
477 | { | 495 | { |
478 | int i = 0; | 496 | int i = 0; |
479 | /* Leadtek winfast tv USBII deluxe can find a non working IR-device */ | 497 | /* |
480 | /* at address 0x18, so if that address is needed for another board in */ | 498 | * Leadtek winfast tv USBII deluxe can find a non working IR-device |
481 | /* the future, please put it after 0x1f. */ | 499 | * at address 0x18, so if that address is needed for another board in |
500 | * the future, please put it after 0x1f. | ||
501 | */ | ||
482 | const unsigned short addr_list[] = { | 502 | const unsigned short addr_list[] = { |
483 | 0x1f, 0x30, 0x47, I2C_CLIENT_END | 503 | 0x1f, 0x30, 0x47, I2C_CLIENT_END |
484 | }; | 504 | }; |
485 | 505 | ||
486 | while (addr_list[i] != I2C_CLIENT_END) { | 506 | while (addr_list[i] != I2C_CLIENT_END) { |
487 | if (i2c_probe_func_quick_read(&dev->i2c_adap[dev->def_i2c_bus], addr_list[i]) == 1) | 507 | if (i2c_probe_func_quick_read(&dev->i2c_adap[dev->def_i2c_bus], |
508 | addr_list[i]) == 1) | ||
488 | return addr_list[i]; | 509 | return addr_list[i]; |
489 | i++; | 510 | i++; |
490 | } | 511 | } |
@@ -492,9 +513,9 @@ static int em28xx_probe_i2c_ir(struct em28xx *dev) | |||
492 | return -ENODEV; | 513 | return -ENODEV; |
493 | } | 514 | } |
494 | 515 | ||
495 | /********************************************************** | 516 | /* |
496 | Handle buttons | 517 | * Handle buttons |
497 | **********************************************************/ | 518 | */ |
498 | 519 | ||
499 | static void em28xx_query_buttons(struct work_struct *work) | 520 | static void em28xx_query_buttons(struct work_struct *work) |
500 | { | 521 | { |
@@ -515,7 +536,10 @@ static void em28xx_query_buttons(struct work_struct *work) | |||
515 | j = 0; | 536 | j = 0; |
516 | while (dev->board.buttons[j].role >= 0 && | 537 | while (dev->board.buttons[j].role >= 0 && |
517 | dev->board.buttons[j].role < EM28XX_NUM_BUTTON_ROLES) { | 538 | dev->board.buttons[j].role < EM28XX_NUM_BUTTON_ROLES) { |
518 | struct em28xx_button *button = &dev->board.buttons[j]; | 539 | const struct em28xx_button *button; |
540 | |||
541 | button = &dev->board.buttons[j]; | ||
542 | |||
519 | /* Check if button uses the current address */ | 543 | /* Check if button uses the current address */ |
520 | if (button->reg_r != dev->button_polling_addresses[i]) { | 544 | if (button->reg_r != dev->button_polling_addresses[i]) { |
521 | j++; | 545 | j++; |
@@ -618,7 +642,8 @@ static void em28xx_init_buttons(struct em28xx *dev) | |||
618 | dev->button_polling_interval = EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL; | 642 | dev->button_polling_interval = EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL; |
619 | while (dev->board.buttons[i].role >= 0 && | 643 | while (dev->board.buttons[i].role >= 0 && |
620 | dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) { | 644 | dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) { |
621 | struct em28xx_button *button = &dev->board.buttons[i]; | 645 | const struct em28xx_button *button = &dev->board.buttons[i]; |
646 | |||
622 | /* Check if polling address is already on the list */ | 647 | /* Check if polling address is already on the list */ |
623 | addr_new = true; | 648 | addr_new = true; |
624 | for (j = 0; j < dev->num_button_polling_addresses; j++) { | 649 | for (j = 0; j < dev->num_button_polling_addresses; j++) { |
@@ -649,6 +674,7 @@ static void em28xx_init_buttons(struct em28xx *dev) | |||
649 | /* Add read address to list of polling addresses */ | 674 | /* Add read address to list of polling addresses */ |
650 | if (addr_new) { | 675 | if (addr_new) { |
651 | unsigned int index = dev->num_button_polling_addresses; | 676 | unsigned int index = dev->num_button_polling_addresses; |
677 | |||
652 | dev->button_polling_addresses[index] = button->reg_r; | 678 | dev->button_polling_addresses[index] = button->reg_r; |
653 | dev->num_button_polling_addresses++; | 679 | dev->num_button_polling_addresses++; |
654 | } | 680 | } |
@@ -677,7 +703,7 @@ static void em28xx_shutdown_buttons(struct em28xx *dev) | |||
677 | /* Clear polling addresses list */ | 703 | /* Clear polling addresses list */ |
678 | dev->num_button_polling_addresses = 0; | 704 | dev->num_button_polling_addresses = 0; |
679 | /* Deregister input devices */ | 705 | /* Deregister input devices */ |
680 | if (dev->sbutton_input_dev != NULL) { | 706 | if (dev->sbutton_input_dev) { |
681 | dev_info(&dev->intf->dev, "Deregistering snapshot button\n"); | 707 | dev_info(&dev->intf->dev, "Deregistering snapshot button\n"); |
682 | input_unregister_device(dev->sbutton_input_dev); | 708 | input_unregister_device(dev->sbutton_input_dev); |
683 | dev->sbutton_input_dev = NULL; | 709 | dev->sbutton_input_dev = NULL; |
@@ -714,7 +740,7 @@ static int em28xx_ir_init(struct em28xx *dev) | |||
714 | } | 740 | } |
715 | } | 741 | } |
716 | 742 | ||
717 | if (dev->board.ir_codes == NULL && !dev->board.has_ir_i2c) { | 743 | if (!dev->board.ir_codes && !dev->board.has_ir_i2c) { |
718 | /* No remote control support */ | 744 | /* No remote control support */ |
719 | dev_warn(&dev->intf->dev, | 745 | dev_warn(&dev->intf->dev, |
720 | "Remote control support is not available for this card.\n"); | 746 | "Remote control support is not available for this card.\n"); |
@@ -764,7 +790,7 @@ static int em28xx_ir_init(struct em28xx *dev) | |||
764 | goto error; | 790 | goto error; |
765 | } | 791 | } |
766 | 792 | ||
767 | ir->i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 793 | ir->i2c_client = kzalloc(sizeof(*ir->i2c_client), GFP_KERNEL); |
768 | if (!ir->i2c_client) | 794 | if (!ir->i2c_client) |
769 | goto error; | 795 | goto error; |
770 | ir->i2c_client->adapter = &ir->dev->i2c_adap[dev->def_i2c_bus]; | 796 | ir->i2c_client->adapter = &ir->dev->i2c_adap[dev->def_i2c_bus]; |
@@ -881,9 +907,11 @@ static int em28xx_ir_suspend(struct em28xx *dev) | |||
881 | if (ir) | 907 | if (ir) |
882 | cancel_delayed_work_sync(&ir->work); | 908 | cancel_delayed_work_sync(&ir->work); |
883 | cancel_delayed_work_sync(&dev->buttons_query_work); | 909 | cancel_delayed_work_sync(&dev->buttons_query_work); |
884 | /* is canceling delayed work sufficient or does the rc event | 910 | /* |
885 | kthread needs stopping? kthread is stopped in | 911 | * is canceling delayed work sufficient or does the rc event |
886 | ir_raw_event_unregister() */ | 912 | * kthread needs stopping? kthread is stopped in |
913 | * ir_raw_event_unregister() | ||
914 | */ | ||
887 | return 0; | 915 | return 0; |
888 | } | 916 | } |
889 | 917 | ||
@@ -895,8 +923,10 @@ static int em28xx_ir_resume(struct em28xx *dev) | |||
895 | return 0; | 923 | return 0; |
896 | 924 | ||
897 | dev_info(&dev->intf->dev, "Resuming input extension\n"); | 925 | dev_info(&dev->intf->dev, "Resuming input extension\n"); |
898 | /* if suspend calls ir_raw_event_unregister(), the should call | 926 | /* |
899 | ir_raw_event_register() */ | 927 | * if suspend calls ir_raw_event_unregister(), the should call |
928 | * ir_raw_event_register() | ||
929 | */ | ||
900 | if (ir) | 930 | if (ir) |
901 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); | 931 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); |
902 | if (dev->num_button_polling_addresses) | 932 | if (dev->num_button_polling_addresses) |
@@ -924,7 +954,7 @@ static void __exit em28xx_rc_unregister(void) | |||
924 | em28xx_unregister_extension(&rc_ops); | 954 | em28xx_unregister_extension(&rc_ops); |
925 | } | 955 | } |
926 | 956 | ||
927 | MODULE_LICENSE("GPL"); | 957 | MODULE_LICENSE("GPL v2"); |
928 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | 958 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
929 | MODULE_DESCRIPTION(DRIVER_DESC " - input interface"); | 959 | MODULE_DESCRIPTION(DRIVER_DESC " - input interface"); |
930 | MODULE_VERSION(EM28XX_VERSION); | 960 | MODULE_VERSION(EM28XX_VERSION); |
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 9e5cdfb25a73..f53afe18e92d 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h | |||
@@ -1,17 +1,22 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #define EM_GPIO_0 (1 << 0) | 2 | |
3 | #define EM_GPIO_1 (1 << 1) | 3 | /* |
4 | #define EM_GPIO_2 (1 << 2) | 4 | * em28xx-reg.h - Register definitions for em28xx driver |
5 | #define EM_GPIO_3 (1 << 3) | 5 | */ |
6 | #define EM_GPIO_4 (1 << 4) | 6 | |
7 | #define EM_GPIO_5 (1 << 5) | 7 | #define EM_GPIO_0 ((unsigned char)BIT(0)) |
8 | #define EM_GPIO_6 (1 << 6) | 8 | #define EM_GPIO_1 ((unsigned char)BIT(1)) |
9 | #define EM_GPIO_7 (1 << 7) | 9 | #define EM_GPIO_2 ((unsigned char)BIT(2)) |
10 | 10 | #define EM_GPIO_3 ((unsigned char)BIT(3)) | |
11 | #define EM_GPO_0 (1 << 0) | 11 | #define EM_GPIO_4 ((unsigned char)BIT(4)) |
12 | #define EM_GPO_1 (1 << 1) | 12 | #define EM_GPIO_5 ((unsigned char)BIT(5)) |
13 | #define EM_GPO_2 (1 << 2) | 13 | #define EM_GPIO_6 ((unsigned char)BIT(6)) |
14 | #define EM_GPO_3 (1 << 3) | 14 | #define EM_GPIO_7 ((unsigned char)BIT(7)) |
15 | |||
16 | #define EM_GPO_0 ((unsigned char)BIT(0)) | ||
17 | #define EM_GPO_1 ((unsigned char)BIT(1)) | ||
18 | #define EM_GPO_2 ((unsigned char)BIT(2)) | ||
19 | #define EM_GPO_3 ((unsigned char)BIT(3)) | ||
15 | 20 | ||
16 | /* em28xx endpoints */ | 21 | /* em28xx endpoints */ |
17 | /* 0x82: (always ?) analog */ | 22 | /* 0x82: (always ?) analog */ |
@@ -203,10 +208,11 @@ | |||
203 | #define EM28XX_R43_AC97BUSY 0x43 | 208 | #define EM28XX_R43_AC97BUSY 0x43 |
204 | 209 | ||
205 | #define EM28XX_R45_IR 0x45 | 210 | #define EM28XX_R45_IR 0x45 |
206 | /* 0x45 bit 7 - parity bit | 211 | /* |
207 | bits 6-0 - count | 212 | * 0x45 bit 7 - parity bit |
208 | 0x46 IR brand | 213 | * bits 6-0 - count |
209 | 0x47 IR data | 214 | * 0x46 IR brand |
215 | * 0x47 IR data | ||
210 | */ | 216 | */ |
211 | 217 | ||
212 | /* em2874 registers */ | 218 | /* em2874 registers */ |
@@ -249,12 +255,12 @@ | |||
249 | #define EM2874_IR_RC6_MODE_6A 0x0b | 255 | #define EM2874_IR_RC6_MODE_6A 0x0b |
250 | 256 | ||
251 | /* em2874 Transport Stream Enable Register (0x5f) */ | 257 | /* em2874 Transport Stream Enable Register (0x5f) */ |
252 | #define EM2874_TS1_CAPTURE_ENABLE (1 << 0) | 258 | #define EM2874_TS1_CAPTURE_ENABLE ((unsigned char)BIT(0)) |
253 | #define EM2874_TS1_FILTER_ENABLE (1 << 1) | 259 | #define EM2874_TS1_FILTER_ENABLE ((unsigned char)BIT(1)) |
254 | #define EM2874_TS1_NULL_DISCARD (1 << 2) | 260 | #define EM2874_TS1_NULL_DISCARD ((unsigned char)BIT(2)) |
255 | #define EM2874_TS2_CAPTURE_ENABLE (1 << 4) | 261 | #define EM2874_TS2_CAPTURE_ENABLE ((unsigned char)BIT(4)) |
256 | #define EM2874_TS2_FILTER_ENABLE (1 << 5) | 262 | #define EM2874_TS2_FILTER_ENABLE ((unsigned char)BIT(5)) |
257 | #define EM2874_TS2_NULL_DISCARD (1 << 6) | 263 | #define EM2874_TS2_NULL_DISCARD ((unsigned char)BIT(6)) |
258 | 264 | ||
259 | /* register settings */ | 265 | /* register settings */ |
260 | #define EM2800_AUDIO_SRC_TUNER 0x0d | 266 | #define EM2800_AUDIO_SRC_TUNER 0x0d |
diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h index 9c411aac3878..1788dbf9024a 100644 --- a/drivers/media/usb/em28xx/em28xx-v4l.h +++ b/drivers/media/usb/em28xx/em28xx-v4l.h | |||
@@ -1,17 +1,18 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB | 3 | * em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB |
3 | video capture devices | 4 | * video capture devices |
4 | 5 | * | |
5 | Copyright (C) 2013-2014 Mauro Carvalho Chehab <m.chehab@samsung.com> | 6 | * Copyright (C) 2013-2014 Mauro Carvalho Chehab <m.chehab@samsung.com> |
6 | 7 | * | |
7 | This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation version 2 of the License. | 10 | * the Free Software Foundation version 2 of the License. |
10 | 11 | * | |
11 | This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
15 | */ | 16 | */ |
16 | 17 | ||
17 | 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); |
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index f5123651ef30..63c48361d3f2 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c | |||
@@ -1,25 +1,20 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | em28xx-vbi.c - VBI driver for em28xx | 2 | // |
3 | 3 | // em28xx-vbi.c - VBI driver for em28xx | |
4 | Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | 4 | // |
5 | 5 | // Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | |
6 | This work was sponsored by EyeMagnet Limited. | 6 | // |
7 | 7 | // This work was sponsored by EyeMagnet Limited. | |
8 | This program is free software; you can redistribute it and/or modify | 8 | // |
9 | it under the terms of the GNU General Public License as published by | 9 | // This program is free software; you can redistribute it and/or modify |
10 | the Free Software Foundation; either version 2 of the License, or | 10 | // it under the terms of the GNU General Public License as published by |
11 | (at your option) any later version. | 11 | // the Free Software Foundation; either version 2 of the License, or |
12 | 12 | // (at your option) any later version. | |
13 | This program is distributed in the hope that it will be useful, | 13 | // |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | // This program is distributed in the hope that it will be useful, |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | GNU General Public License for more details. | 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | 17 | // GNU General Public License for more details. | |
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
21 | 02110-1301, USA. | ||
22 | */ | ||
23 | 18 | ||
24 | #include "em28xx.h" | 19 | #include "em28xx.h" |
25 | 20 | ||
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index a2ba2d905952..d70ee13cc52e 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c | |||
@@ -1,30 +1,26 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB | 2 | // |
3 | video capture devices | 3 | // em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB |
4 | 4 | // video capture devices | |
5 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | 5 | // |
6 | Markus Rechberger <mrechberger@gmail.com> | 6 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
7 | Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | // Markus Rechberger <mrechberger@gmail.com> |
8 | Sascha Sommer <saschasommer@freenet.de> | 8 | // Mauro Carvalho Chehab <mchehab@infradead.org> |
9 | Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 9 | // Sascha Sommer <saschasommer@freenet.de> |
10 | 10 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | |
11 | Some parts based on SN9C10x PC Camera Controllers GPL driver made | 11 | // |
12 | by Luca Risolia <luca.risolia@studio.unibo.it> | 12 | // Some parts based on SN9C10x PC Camera Controllers GPL driver made |
13 | 13 | // by Luca Risolia <luca.risolia@studio.unibo.it> | |
14 | This program is free software; you can redistribute it and/or modify | 14 | // |
15 | it under the terms of the GNU General Public License as published by | 15 | // This program is free software; you can redistribute it and/or modify |
16 | the Free Software Foundation; either version 2 of the License, or | 16 | // it under the terms of the GNU General Public License as published by |
17 | (at your option) any later version. | 17 | // the Free Software Foundation; either version 2 of the License, or |
18 | 18 | // (at your option) any later version. | |
19 | This program is distributed in the hope that it will be useful, | 19 | // |
20 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 20 | // This program is distributed in the hope that it will be useful, |
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | GNU General Public License for more details. | 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | 23 | // GNU General Public License for more details. | |
24 | You should have received a copy of the GNU General Public License | ||
25 | along with this program; if not, write to the Free Software | ||
26 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | 24 | ||
29 | #include "em28xx.h" | 25 | #include "em28xx.h" |
30 | 26 | ||
@@ -77,7 +73,7 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | |||
77 | 73 | ||
78 | MODULE_AUTHOR(DRIVER_AUTHOR); | 74 | MODULE_AUTHOR(DRIVER_AUTHOR); |
79 | MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface"); | 75 | MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface"); |
80 | MODULE_LICENSE("GPL"); | 76 | MODULE_LICENSE("GPL v2"); |
81 | MODULE_VERSION(EM28XX_VERSION); | 77 | MODULE_VERSION(EM28XX_VERSION); |
82 | 78 | ||
83 | #define EM25XX_FRMDATAHDR_BYTE1 0x02 | 79 | #define EM25XX_FRMDATAHDR_BYTE1 0x02 |
@@ -148,7 +144,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev) | |||
148 | { | 144 | { |
149 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 145 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
150 | 146 | ||
151 | if (dev->board.is_webcam) | 147 | if (dev->is_webcam) |
152 | return v4l2->sensor_xres; | 148 | return v4l2->sensor_xres; |
153 | 149 | ||
154 | if (dev->board.max_range_640_480) | 150 | if (dev->board.max_range_640_480) |
@@ -161,7 +157,7 @@ static inline unsigned int norm_maxh(struct em28xx *dev) | |||
161 | { | 157 | { |
162 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 158 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
163 | 159 | ||
164 | if (dev->board.is_webcam) | 160 | if (dev->is_webcam) |
165 | return v4l2->sensor_yres; | 161 | return v4l2->sensor_yres; |
166 | 162 | ||
167 | if (dev->board.max_range_640_480) | 163 | if (dev->board.max_range_640_480) |
@@ -176,7 +172,7 @@ static int em28xx_vbi_supported(struct em28xx *dev) | |||
176 | if (disable_vbi == 1) | 172 | if (disable_vbi == 1) |
177 | return 0; | 173 | return 0; |
178 | 174 | ||
179 | if (dev->board.is_webcam) | 175 | if (dev->is_webcam) |
180 | return 0; | 176 | return 0; |
181 | 177 | ||
182 | /* FIXME: check subdevices for VBI support */ | 178 | /* FIXME: check subdevices for VBI support */ |
@@ -250,7 +246,8 @@ static int em28xx_set_outfmt(struct em28xx *dev) | |||
250 | if (em28xx_vbi_supported(dev) == 1) { | 246 | if (em28xx_vbi_supported(dev) == 1) { |
251 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; | 247 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; |
252 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); | 248 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); |
253 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, v4l2->vbi_width/4); | 249 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, |
250 | v4l2->vbi_width / 4); | ||
254 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, v4l2->vbi_height); | 251 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, v4l2->vbi_height); |
255 | if (v4l2->norm & V4L2_STD_525_60) { | 252 | if (v4l2->norm & V4L2_STD_525_60) { |
256 | /* NTSC */ | 253 | /* NTSC */ |
@@ -320,8 +317,10 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
320 | buf[0] = v; | 317 | buf[0] = v; |
321 | buf[1] = v >> 8; | 318 | buf[1] = v >> 8; |
322 | em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); | 319 | em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); |
323 | /* it seems that both H and V scalers must be active | 320 | /* |
324 | to work correctly */ | 321 | * it seems that both H and V scalers must be active |
322 | * to work correctly | ||
323 | */ | ||
325 | mode = (h || v) ? 0x30 : 0x00; | 324 | mode = (h || v) ? 0x30 : 0x00; |
326 | } | 325 | } |
327 | return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode); | 326 | return em28xx_write_reg(dev, EM28XX_R26_COMPR, mode); |
@@ -345,13 +344,15 @@ static int em28xx_resolution_set(struct em28xx *dev) | |||
345 | 344 | ||
346 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); | 345 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); |
347 | 346 | ||
348 | /* If we don't set the start position to 2 in VBI mode, we end up | 347 | /* |
349 | with line 20/21 being YUYV encoded instead of being in 8-bit | 348 | * If we don't set the start position to 2 in VBI mode, we end up |
350 | greyscale. The core of the issue is that line 21 (and line 23 for | 349 | * with line 20/21 being YUYV encoded instead of being in 8-bit |
351 | PAL WSS) are inside of active video region, and as a result they | 350 | * greyscale. The core of the issue is that line 21 (and line 23 for |
352 | get the pixelformatting associated with that area. So by cropping | 351 | * PAL WSS) are inside of active video region, and as a result they |
353 | it out, we end up with the same format as the rest of the VBI | 352 | * get the pixelformatting associated with that area. So by cropping |
354 | region */ | 353 | * it out, we end up with the same format as the rest of the VBI |
354 | * region | ||
355 | */ | ||
355 | if (em28xx_vbi_supported(dev) == 1) | 356 | if (em28xx_vbi_supported(dev) == 1) |
356 | em28xx_capture_area_set(dev, 0, 2, width, height); | 357 | em28xx_capture_area_set(dev, 0, 2, width, height); |
357 | else | 358 | else |
@@ -365,14 +366,16 @@ static int em28xx_set_alternate(struct em28xx *dev) | |||
365 | { | 366 | { |
366 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 367 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
367 | struct usb_device *udev = interface_to_usbdev(dev->intf); | 368 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
368 | int errCode; | 369 | int err; |
369 | int i; | 370 | int i; |
370 | unsigned int min_pkt_size = v4l2->width * 2 + 4; | 371 | unsigned int min_pkt_size = v4l2->width * 2 + 4; |
371 | 372 | ||
372 | /* NOTE: for isoc transfers, only alt settings > 0 are allowed | 373 | /* |
373 | bulk transfers seem to work only with alt=0 ! */ | 374 | * NOTE: for isoc transfers, only alt settings > 0 are allowed |
375 | * bulk transfers seem to work only with alt=0 ! | ||
376 | */ | ||
374 | dev->alt = 0; | 377 | dev->alt = 0; |
375 | if ((alt > 0) && (alt < dev->num_alt)) { | 378 | if (alt > 0 && alt < dev->num_alt) { |
376 | em28xx_videodbg("alternate forced to %d\n", dev->alt); | 379 | em28xx_videodbg("alternate forced to %d\n", dev->alt); |
377 | dev->alt = alt; | 380 | dev->alt = alt; |
378 | goto set_alt; | 381 | goto set_alt; |
@@ -380,9 +383,10 @@ static int em28xx_set_alternate(struct em28xx *dev) | |||
380 | if (dev->analog_xfer_bulk) | 383 | if (dev->analog_xfer_bulk) |
381 | goto set_alt; | 384 | goto set_alt; |
382 | 385 | ||
383 | /* When image size is bigger than a certain value, | 386 | /* |
384 | the frame size should be increased, otherwise, only | 387 | * When image size is bigger than a certain value, |
385 | green screen will be received. | 388 | * the frame size should be increased, otherwise, only |
389 | * green screen will be received. | ||
386 | */ | 390 | */ |
387 | if (v4l2->width * 2 * v4l2->height > 720 * 240 * 2) | 391 | if (v4l2->width * 2 * v4l2->height > 720 * 240 * 2) |
388 | min_pkt_size *= 2; | 392 | min_pkt_size *= 2; |
@@ -392,18 +396,22 @@ static int em28xx_set_alternate(struct em28xx *dev) | |||
392 | if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) { | 396 | if (dev->alt_max_pkt_size_isoc[i] >= min_pkt_size) { |
393 | dev->alt = i; | 397 | dev->alt = i; |
394 | break; | 398 | break; |
395 | /* otherwise make sure that we end up with the maximum bandwidth | 399 | /* |
396 | because the min_pkt_size equation might be wrong... | 400 | * otherwise make sure that we end up with the maximum |
397 | */ | 401 | * bandwidth because the min_pkt_size equation might be wrong. |
402 | * | ||
403 | */ | ||
398 | } else if (dev->alt_max_pkt_size_isoc[i] > | 404 | } else if (dev->alt_max_pkt_size_isoc[i] > |
399 | dev->alt_max_pkt_size_isoc[dev->alt]) | 405 | dev->alt_max_pkt_size_isoc[dev->alt]) |
400 | dev->alt = i; | 406 | dev->alt = i; |
401 | } | 407 | } |
402 | 408 | ||
403 | set_alt: | 409 | set_alt: |
404 | /* NOTE: for bulk transfers, we need to call usb_set_interface() | 410 | /* |
411 | * NOTE: for bulk transfers, we need to call usb_set_interface() | ||
405 | * even if the previous settings were the same. Otherwise streaming | 412 | * even if the previous settings were the same. Otherwise streaming |
406 | * fails with all urbs having status = -EOVERFLOW ! */ | 413 | * fails with all urbs having status = -EOVERFLOW ! |
414 | */ | ||
407 | if (dev->analog_xfer_bulk) { | 415 | if (dev->analog_xfer_bulk) { |
408 | dev->max_pkt_size = 512; /* USB 2.0 spec */ | 416 | dev->max_pkt_size = 512; /* USB 2.0 spec */ |
409 | dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER; | 417 | dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER; |
@@ -416,19 +424,19 @@ set_alt: | |||
416 | } | 424 | } |
417 | em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n", | 425 | em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n", |
418 | dev->alt, dev->max_pkt_size); | 426 | dev->alt, dev->max_pkt_size); |
419 | errCode = usb_set_interface(udev, dev->ifnum, dev->alt); | 427 | err = usb_set_interface(udev, dev->ifnum, dev->alt); |
420 | if (errCode < 0) { | 428 | if (err < 0) { |
421 | dev_err(&dev->intf->dev, | 429 | dev_err(&dev->intf->dev, |
422 | "cannot change alternate number to %d (error=%i)\n", | 430 | "cannot change alternate number to %d (error=%i)\n", |
423 | dev->alt, errCode); | 431 | dev->alt, err); |
424 | return errCode; | 432 | return err; |
425 | } | 433 | } |
426 | return 0; | 434 | return 0; |
427 | } | 435 | } |
428 | 436 | ||
429 | /* ------------------------------------------------------------------ | 437 | /* |
430 | DMA and thread functions | 438 | * DMA and thread functions |
431 | ------------------------------------------------------------------*/ | 439 | */ |
432 | 440 | ||
433 | /* | 441 | /* |
434 | * Finish the current buffer | 442 | * Finish the current buffer |
@@ -514,8 +522,9 @@ static void em28xx_copy_video(struct em28xx *dev, | |||
514 | em28xx_isocdbg("Overflow of %zu bytes past buffer end(2)\n", | 522 | em28xx_isocdbg("Overflow of %zu bytes past buffer end(2)\n", |
515 | ((char *)startwrite + lencopy) - | 523 | ((char *)startwrite + lencopy) - |
516 | ((char *)buf->vb_buf + buf->length)); | 524 | ((char *)buf->vb_buf + buf->length)); |
517 | lencopy = remain = (char *)buf->vb_buf + buf->length - | 525 | remain = (char *)buf->vb_buf + buf->length - |
518 | (char *)startwrite; | 526 | (char *)startwrite; |
527 | lencopy = remain; | ||
519 | } | 528 | } |
520 | if (lencopy <= 0) | 529 | if (lencopy <= 0) |
521 | break; | 530 | break; |
@@ -623,11 +632,11 @@ finish_field_prepare_next(struct em28xx *dev, | |||
623 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 632 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
624 | 633 | ||
625 | if (v4l2->progressive || v4l2->top_field) { /* Brand new frame */ | 634 | if (v4l2->progressive || v4l2->top_field) { /* Brand new frame */ |
626 | if (buf != NULL) | 635 | if (buf) |
627 | finish_buffer(dev, buf); | 636 | finish_buffer(dev, buf); |
628 | buf = get_next_buf(dev, dma_q); | 637 | buf = get_next_buf(dev, dma_q); |
629 | } | 638 | } |
630 | if (buf != NULL) { | 639 | if (buf) { |
631 | buf->top_field = v4l2->top_field; | 640 | buf->top_field = v4l2->top_field; |
632 | buf->pos = 0; | 641 | buf->pos = 0; |
633 | } | 642 | } |
@@ -648,13 +657,17 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
648 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 657 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
649 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; | 658 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; |
650 | 659 | ||
651 | /* capture type 0 = vbi start | 660 | /* |
652 | capture type 1 = vbi in progress | 661 | * capture type 0 = vbi start |
653 | capture type 2 = video start | 662 | * capture type 1 = vbi in progress |
654 | capture type 3 = video in progress */ | 663 | * capture type 2 = video start |
664 | * capture type 3 = video in progress | ||
665 | */ | ||
655 | if (data_len >= 4) { | 666 | if (data_len >= 4) { |
656 | /* NOTE: Headers are always 4 bytes and | 667 | /* |
657 | * never split across packets */ | 668 | * NOTE: Headers are always 4 bytes and |
669 | * never split across packets | ||
670 | */ | ||
658 | if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 && | 671 | if (data_pkt[0] == 0x88 && data_pkt[1] == 0x88 && |
659 | data_pkt[2] == 0x88 && data_pkt[3] == 0x88) { | 672 | data_pkt[2] == 0x88 && data_pkt[3] == 0x88) { |
660 | /* Continuation */ | 673 | /* Continuation */ |
@@ -677,8 +690,10 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
677 | data_len -= 4; | 690 | data_len -= 4; |
678 | } | 691 | } |
679 | } | 692 | } |
680 | /* NOTE: With bulk transfers, intermediate data packets | 693 | /* |
681 | * have no continuation header */ | 694 | * NOTE: With bulk transfers, intermediate data packets |
695 | * have no continuation header | ||
696 | */ | ||
682 | 697 | ||
683 | if (v4l2->capture_type == 0) { | 698 | if (v4l2->capture_type == 0) { |
684 | vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); | 699 | vbi_buf = finish_field_prepare_next(dev, vbi_buf, vbi_dma_q); |
@@ -692,7 +707,7 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
692 | (vbi_size - v4l2->vbi_read) : data_len; | 707 | (vbi_size - v4l2->vbi_read) : data_len; |
693 | 708 | ||
694 | /* Copy VBI data */ | 709 | /* Copy VBI data */ |
695 | if (vbi_buf != NULL) | 710 | if (vbi_buf) |
696 | em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len); | 711 | em28xx_copy_vbi(dev, vbi_buf, data_pkt, vbi_data_len); |
697 | v4l2->vbi_read += vbi_data_len; | 712 | v4l2->vbi_read += vbi_data_len; |
698 | 713 | ||
@@ -710,7 +725,7 @@ static inline void process_frame_data_em28xx(struct em28xx *dev, | |||
710 | v4l2->capture_type = 3; | 725 | v4l2->capture_type = 3; |
711 | } | 726 | } |
712 | 727 | ||
713 | if (v4l2->capture_type == 3 && buf != NULL && data_len > 0) | 728 | if (v4l2->capture_type == 3 && buf && data_len > 0) |
714 | em28xx_copy_video(dev, buf, data_pkt, data_len); | 729 | em28xx_copy_video(dev, buf, data_pkt, data_len); |
715 | } | 730 | } |
716 | 731 | ||
@@ -727,8 +742,10 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, | |||
727 | bool frame_end = false; | 742 | bool frame_end = false; |
728 | 743 | ||
729 | /* Check for header */ | 744 | /* Check for header */ |
730 | /* NOTE: at least with bulk transfers, only the first packet | 745 | /* |
731 | * has a header and has always set the FRAME_END bit */ | 746 | * NOTE: at least with bulk transfers, only the first packet |
747 | * has a header and has always set the FRAME_END bit | ||
748 | */ | ||
732 | if (data_len >= 2) { /* em25xx header is only 2 bytes long */ | 749 | if (data_len >= 2) { /* em25xx header is only 2 bytes long */ |
733 | if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) && | 750 | if ((data_pkt[0] == EM25XX_FRMDATAHDR_BYTE1) && |
734 | ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) { | 751 | ((data_pkt[1] & ~EM25XX_FRMDATAHDR_BYTE2_MASK) == 0x00)) { |
@@ -745,14 +762,15 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, | |||
745 | buf = finish_field_prepare_next(dev, buf, dmaq); | 762 | buf = finish_field_prepare_next(dev, buf, dmaq); |
746 | dev->usb_ctl.vid_buf = buf; | 763 | dev->usb_ctl.vid_buf = buf; |
747 | } | 764 | } |
748 | /* NOTE: in ISOC mode when a new frame starts and buf==NULL, | 765 | /* |
766 | * NOTE: in ISOC mode when a new frame starts and buf==NULL, | ||
749 | * we COULD already prepare a buffer here to avoid skipping the | 767 | * we COULD already prepare a buffer here to avoid skipping the |
750 | * first frame. | 768 | * first frame. |
751 | */ | 769 | */ |
752 | } | 770 | } |
753 | 771 | ||
754 | /* Copy data */ | 772 | /* Copy data */ |
755 | if (buf != NULL && data_len > 0) | 773 | if (buf && data_len > 0) |
756 | em28xx_copy_video(dev, buf, data_pkt, data_len); | 774 | em28xx_copy_video(dev, buf, data_pkt, data_len); |
757 | 775 | ||
758 | /* Finish frame (ISOC only) => avoids lag of 1 frame */ | 776 | /* Finish frame (ISOC only) => avoids lag of 1 frame */ |
@@ -761,14 +779,17 @@ static inline void process_frame_data_em25xx(struct em28xx *dev, | |||
761 | dev->usb_ctl.vid_buf = buf; | 779 | dev->usb_ctl.vid_buf = buf; |
762 | } | 780 | } |
763 | 781 | ||
764 | /* NOTE: Tested with USB bulk transfers only ! | 782 | /* |
783 | * NOTES: | ||
784 | * | ||
785 | * 1) Tested with USB bulk transfers only ! | ||
765 | * The wording in the datasheet suggests that isoc might work different. | 786 | * The wording in the datasheet suggests that isoc might work different. |
766 | * The current code assumes that with isoc transfers each packet has a | 787 | * The current code assumes that with isoc transfers each packet has a |
767 | * header like with the other em28xx devices. | 788 | * header like with the other em28xx devices. |
789 | * | ||
790 | * 2) Support for interlaced mode is pure theory. It has not been | ||
791 | * tested and it is unknown if these devices actually support it. | ||
768 | */ | 792 | */ |
769 | /* NOTE: Support for interlaced mode is pure theory. It has not been | ||
770 | * tested and it is unknown if these devices actually support it. */ | ||
771 | /* NOTE: No VBI support yet (these chips likely do not support VBI). */ | ||
772 | } | 793 | } |
773 | 794 | ||
774 | /* Processes and copies the URB data content (video and VBI data) */ | 795 | /* Processes and copies the URB data content (video and VBI data) */ |
@@ -829,12 +850,11 @@ static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) | |||
829 | else | 850 | else |
830 | process_frame_data_em28xx(dev, | 851 | process_frame_data_em28xx(dev, |
831 | usb_data_pkt, usb_data_len); | 852 | usb_data_pkt, usb_data_len); |
832 | |||
833 | } | 853 | } |
834 | return 1; | 854 | return 1; |
835 | } | 855 | } |
836 | 856 | ||
837 | static int get_ressource(enum v4l2_buf_type f_type) | 857 | static int get_resource(enum v4l2_buf_type f_type) |
838 | { | 858 | { |
839 | switch (f_type) { | 859 | switch (f_type) { |
840 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 860 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
@@ -842,14 +862,15 @@ static int get_ressource(enum v4l2_buf_type f_type) | |||
842 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 862 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
843 | return EM28XX_RESOURCE_VBI; | 863 | return EM28XX_RESOURCE_VBI; |
844 | default: | 864 | default: |
845 | BUG(); | 865 | WARN_ON(1); |
866 | return -1; /* Indicate that device is busy */ | ||
846 | } | 867 | } |
847 | } | 868 | } |
848 | 869 | ||
849 | /* Usage lock check functions */ | 870 | /* Usage lock check functions */ |
850 | static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type) | 871 | static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type) |
851 | { | 872 | { |
852 | int res_type = get_ressource(f_type); | 873 | int res_type = get_resource(f_type); |
853 | 874 | ||
854 | /* is it free? */ | 875 | /* is it free? */ |
855 | if (dev->resources & res_type) { | 876 | if (dev->resources & res_type) { |
@@ -865,7 +886,7 @@ static int res_get(struct em28xx *dev, enum v4l2_buf_type f_type) | |||
865 | 886 | ||
866 | static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type) | 887 | static void res_free(struct em28xx *dev, enum v4l2_buf_type f_type) |
867 | { | 888 | { |
868 | int res_type = get_ressource(f_type); | 889 | int res_type = get_resource(f_type); |
869 | 890 | ||
870 | dev->resources &= ~res_type; | 891 | dev->resources &= ~res_type; |
871 | em28xx_videodbg("res: put %d\n", res_type); | 892 | em28xx_videodbg("res: put %d\n", res_type); |
@@ -937,10 +958,11 @@ static int em28xx_enable_analog_tuner(struct em28xx *dev) | |||
937 | flags ? "enabled" : "disabled", | 958 | flags ? "enabled" : "disabled", |
938 | ret); | 959 | ret); |
939 | return ret; | 960 | return ret; |
940 | } else | 961 | } |
941 | em28xx_videodbg("link %s->%s was %s\n", | 962 | |
942 | source->name, sink->name, | 963 | em28xx_videodbg("link %s->%s was %s\n", |
943 | flags ? "ENABLED" : "disabled"); | 964 | source->name, sink->name, |
965 | flags ? "ENABLED" : "disabled"); | ||
944 | } | 966 | } |
945 | #endif | 967 | #endif |
946 | return 0; | 968 | return 0; |
@@ -976,7 +998,7 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) | |||
976 | } | 998 | } |
977 | 999 | ||
978 | /* Webcams don't have input connectors */ | 1000 | /* Webcams don't have input connectors */ |
979 | if (dev->board.is_webcam) | 1001 | if (dev->is_webcam) |
980 | return; | 1002 | return; |
981 | 1003 | ||
982 | /* Create entities for each input connector */ | 1004 | /* Create entities for each input connector */ |
@@ -1016,10 +1038,9 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev) | |||
1016 | #endif | 1038 | #endif |
1017 | } | 1039 | } |
1018 | 1040 | ||
1019 | 1041 | /* | |
1020 | /* ------------------------------------------------------------------ | 1042 | * Videobuf2 operations |
1021 | Videobuf2 operations | 1043 | */ |
1022 | ------------------------------------------------------------------*/ | ||
1023 | 1044 | ||
1024 | static int queue_setup(struct vb2_queue *vq, | 1045 | static int queue_setup(struct vb2_queue *vq, |
1025 | unsigned int *nbuffers, unsigned int *nplanes, | 1046 | unsigned int *nbuffers, unsigned int *nplanes, |
@@ -1072,8 +1093,10 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
1072 | 1093 | ||
1073 | em28xx_videodbg("%s\n", __func__); | 1094 | em28xx_videodbg("%s\n", __func__); |
1074 | 1095 | ||
1075 | /* Make sure streaming is not already in progress for this type | 1096 | /* |
1076 | of filehandle (e.g. video, vbi) */ | 1097 | * Make sure streaming is not already in progress for this type |
1098 | * of filehandle (e.g. video, vbi) | ||
1099 | */ | ||
1077 | rc = res_get(dev, vq->type); | 1100 | rc = res_get(dev, vq->type); |
1078 | if (rc) | 1101 | if (rc) |
1079 | return rc; | 1102 | return rc; |
@@ -1084,9 +1107,10 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
1084 | /* Allocate the USB bandwidth */ | 1107 | /* Allocate the USB bandwidth */ |
1085 | em28xx_set_alternate(dev); | 1108 | em28xx_set_alternate(dev); |
1086 | 1109 | ||
1087 | /* Needed, since GPIO might have disabled power of | 1110 | /* |
1088 | some i2c device | 1111 | * Needed, since GPIO might have disabled power of |
1089 | */ | 1112 | * some i2c device |
1113 | */ | ||
1090 | em28xx_wake_i2c(dev); | 1114 | em28xx_wake_i2c(dev); |
1091 | 1115 | ||
1092 | v4l2->capture_type = -1; | 1116 | v4l2->capture_type = -1; |
@@ -1145,7 +1169,7 @@ static void em28xx_stop_streaming(struct vb2_queue *vq) | |||
1145 | } | 1169 | } |
1146 | 1170 | ||
1147 | spin_lock_irqsave(&dev->slock, flags); | 1171 | spin_lock_irqsave(&dev->slock, flags); |
1148 | if (dev->usb_ctl.vid_buf != NULL) { | 1172 | if (dev->usb_ctl.vid_buf) { |
1149 | vb2_buffer_done(&dev->usb_ctl.vid_buf->vb.vb2_buf, | 1173 | vb2_buffer_done(&dev->usb_ctl.vid_buf->vb.vb2_buf, |
1150 | VB2_BUF_STATE_ERROR); | 1174 | VB2_BUF_STATE_ERROR); |
1151 | dev->usb_ctl.vid_buf = NULL; | 1175 | dev->usb_ctl.vid_buf = NULL; |
@@ -1180,7 +1204,7 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq) | |||
1180 | } | 1204 | } |
1181 | 1205 | ||
1182 | spin_lock_irqsave(&dev->slock, flags); | 1206 | spin_lock_irqsave(&dev->slock, flags); |
1183 | if (dev->usb_ctl.vbi_buf != NULL) { | 1207 | if (dev->usb_ctl.vbi_buf) { |
1184 | vb2_buffer_done(&dev->usb_ctl.vbi_buf->vb.vb2_buf, | 1208 | vb2_buffer_done(&dev->usb_ctl.vbi_buf->vb.vb2_buf, |
1185 | VB2_BUF_STATE_ERROR); | 1209 | VB2_BUF_STATE_ERROR); |
1186 | dev->usb_ctl.vbi_buf = NULL; | 1210 | dev->usb_ctl.vbi_buf = NULL; |
@@ -1261,7 +1285,9 @@ static int em28xx_vb2_setup(struct em28xx *dev) | |||
1261 | return 0; | 1285 | return 0; |
1262 | } | 1286 | } |
1263 | 1287 | ||
1264 | /********************* v4l2 interface **************************************/ | 1288 | /* |
1289 | * v4l2 interface | ||
1290 | */ | ||
1265 | 1291 | ||
1266 | static void video_mux(struct em28xx *dev, int index) | 1292 | static void video_mux(struct em28xx *dev, int index) |
1267 | { | 1293 | { |
@@ -1277,7 +1303,7 @@ static void video_mux(struct em28xx *dev, int index) | |||
1277 | v4l2_device_call_all(v4l2_dev, 0, video, s_routing, | 1303 | v4l2_device_call_all(v4l2_dev, 0, video, s_routing, |
1278 | INPUT(index)->vmux, 0, 0); | 1304 | INPUT(index)->vmux, 0, 0); |
1279 | 1305 | ||
1280 | if (dev->board.has_msp34xx) { | 1306 | if (dev->has_msp34xx) { |
1281 | if (dev->i2s_speed) { | 1307 | if (dev->i2s_speed) { |
1282 | v4l2_device_call_all(v4l2_dev, 0, audio, | 1308 | v4l2_device_call_all(v4l2_dev, 0, audio, |
1283 | s_i2s_clock_freq, dev->i2s_speed); | 1309 | s_i2s_clock_freq, dev->i2s_speed); |
@@ -1394,9 +1420,9 @@ static void scale_to_size(struct em28xx *dev, | |||
1394 | *height = 1; | 1420 | *height = 1; |
1395 | } | 1421 | } |
1396 | 1422 | ||
1397 | /* ------------------------------------------------------------------ | 1423 | /* |
1398 | IOCTL vidioc handling | 1424 | * IOCTL vidioc handling |
1399 | ------------------------------------------------------------------*/ | 1425 | */ |
1400 | 1426 | ||
1401 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | 1427 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, |
1402 | struct v4l2_format *f) | 1428 | struct v4l2_format *f) |
@@ -1462,8 +1488,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
1462 | if (width == maxw && height == maxh) | 1488 | if (width == maxw && height == maxh) |
1463 | width /= 2; | 1489 | width /= 2; |
1464 | } else { | 1490 | } else { |
1465 | /* width must even because of the YUYV format | 1491 | /* |
1466 | height must be even because of interlacing */ | 1492 | * width must even because of the YUYV format |
1493 | * height must be even because of interlacing | ||
1494 | */ | ||
1467 | v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, | 1495 | v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, |
1468 | 1, 0); | 1496 | 1, 0); |
1469 | } | 1497 | } |
@@ -1493,7 +1521,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
1493 | } | 1521 | } |
1494 | 1522 | ||
1495 | static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | 1523 | static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, |
1496 | unsigned width, unsigned height) | 1524 | unsigned int width, unsigned int height) |
1497 | { | 1525 | { |
1498 | struct em28xx_fmt *fmt; | 1526 | struct em28xx_fmt *fmt; |
1499 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 1527 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
@@ -1582,17 +1610,26 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) | |||
1582 | static int vidioc_g_parm(struct file *file, void *priv, | 1610 | static int vidioc_g_parm(struct file *file, void *priv, |
1583 | struct v4l2_streamparm *p) | 1611 | struct v4l2_streamparm *p) |
1584 | { | 1612 | { |
1613 | struct v4l2_subdev_frame_interval ival = { 0 }; | ||
1585 | struct em28xx *dev = video_drvdata(file); | 1614 | struct em28xx *dev = video_drvdata(file); |
1586 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 1615 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
1587 | int rc = 0; | 1616 | int rc = 0; |
1588 | 1617 | ||
1618 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
1619 | p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
1620 | return -EINVAL; | ||
1621 | |||
1589 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; | 1622 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; |
1590 | if (dev->board.is_webcam) | 1623 | p->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; |
1624 | if (dev->is_webcam) { | ||
1591 | rc = v4l2_device_call_until_err(&v4l2->v4l2_dev, 0, | 1625 | rc = v4l2_device_call_until_err(&v4l2->v4l2_dev, 0, |
1592 | video, g_parm, p); | 1626 | video, g_frame_interval, &ival); |
1593 | else | 1627 | if (!rc) |
1628 | p->parm.capture.timeperframe = ival.interval; | ||
1629 | } else { | ||
1594 | v4l2_video_std_frame_period(v4l2->norm, | 1630 | v4l2_video_std_frame_period(v4l2->norm, |
1595 | &p->parm.capture.timeperframe); | 1631 | &p->parm.capture.timeperframe); |
1632 | } | ||
1596 | 1633 | ||
1597 | return rc; | 1634 | return rc; |
1598 | } | 1635 | } |
@@ -1601,10 +1638,27 @@ static int vidioc_s_parm(struct file *file, void *priv, | |||
1601 | struct v4l2_streamparm *p) | 1638 | struct v4l2_streamparm *p) |
1602 | { | 1639 | { |
1603 | struct em28xx *dev = video_drvdata(file); | 1640 | struct em28xx *dev = video_drvdata(file); |
1641 | struct v4l2_subdev_frame_interval ival = { | ||
1642 | 0, | ||
1643 | p->parm.capture.timeperframe | ||
1644 | }; | ||
1645 | int rc = 0; | ||
1646 | |||
1647 | if (!dev->is_webcam) | ||
1648 | return -ENOTTY; | ||
1649 | |||
1650 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
1651 | p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
1652 | return -EINVAL; | ||
1604 | 1653 | ||
1654 | memset(&p->parm, 0, sizeof(p->parm)); | ||
1605 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; | 1655 | p->parm.capture.readbuffers = EM28XX_MIN_BUF; |
1606 | return v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, | 1656 | p->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; |
1607 | 0, video, s_parm, p); | 1657 | rc = v4l2_device_call_until_err(&dev->v4l2->v4l2_dev, 0, |
1658 | video, s_frame_interval, &ival); | ||
1659 | if (!rc) | ||
1660 | p->parm.capture.timeperframe = ival.interval; | ||
1661 | return rc; | ||
1608 | } | 1662 | } |
1609 | 1663 | ||
1610 | static int vidioc_enum_input(struct file *file, void *priv, | 1664 | static int vidioc_enum_input(struct file *file, void *priv, |
@@ -1616,20 +1670,19 @@ static int vidioc_enum_input(struct file *file, void *priv, | |||
1616 | n = i->index; | 1670 | n = i->index; |
1617 | if (n >= MAX_EM28XX_INPUT) | 1671 | if (n >= MAX_EM28XX_INPUT) |
1618 | return -EINVAL; | 1672 | return -EINVAL; |
1619 | if (0 == INPUT(n)->type) | 1673 | if (!INPUT(n)->type) |
1620 | return -EINVAL; | 1674 | return -EINVAL; |
1621 | 1675 | ||
1622 | i->index = n; | ||
1623 | i->type = V4L2_INPUT_TYPE_CAMERA; | 1676 | i->type = V4L2_INPUT_TYPE_CAMERA; |
1624 | 1677 | ||
1625 | strcpy(i->name, iname[INPUT(n)->type]); | 1678 | strcpy(i->name, iname[INPUT(n)->type]); |
1626 | 1679 | ||
1627 | if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type)) | 1680 | if (INPUT(n)->type == EM28XX_VMUX_TELEVISION) |
1628 | i->type = V4L2_INPUT_TYPE_TUNER; | 1681 | i->type = V4L2_INPUT_TYPE_TUNER; |
1629 | 1682 | ||
1630 | i->std = dev->v4l2->vdev.tvnorms; | 1683 | i->std = dev->v4l2->vdev.tvnorms; |
1631 | /* webcams do not have the STD API */ | 1684 | /* webcams do not have the STD API */ |
1632 | if (dev->board.is_webcam) | 1685 | if (dev->is_webcam) |
1633 | i->capabilities = 0; | 1686 | i->capabilities = 0; |
1634 | 1687 | ||
1635 | return 0; | 1688 | return 0; |
@@ -1650,7 +1703,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
1650 | 1703 | ||
1651 | if (i >= MAX_EM28XX_INPUT) | 1704 | if (i >= MAX_EM28XX_INPUT) |
1652 | return -EINVAL; | 1705 | return -EINVAL; |
1653 | if (0 == INPUT(i)->type) | 1706 | if (!INPUT(i)->type) |
1654 | return -EINVAL; | 1707 | return -EINVAL; |
1655 | 1708 | ||
1656 | video_mux(dev, i); | 1709 | video_mux(dev, i); |
@@ -1696,13 +1749,14 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
1696 | return 0; | 1749 | return 0; |
1697 | } | 1750 | } |
1698 | 1751 | ||
1699 | static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a) | 1752 | static int vidioc_s_audio(struct file *file, void *priv, |
1753 | const struct v4l2_audio *a) | ||
1700 | { | 1754 | { |
1701 | struct em28xx *dev = video_drvdata(file); | 1755 | struct em28xx *dev = video_drvdata(file); |
1702 | 1756 | ||
1703 | if (a->index >= MAX_EM28XX_INPUT) | 1757 | if (a->index >= MAX_EM28XX_INPUT) |
1704 | return -EINVAL; | 1758 | return -EINVAL; |
1705 | if (0 == INPUT(a->index)->type) | 1759 | if (!INPUT(a->index)->type) |
1706 | return -EINVAL; | 1760 | return -EINVAL; |
1707 | 1761 | ||
1708 | dev->ctl_ainput = INPUT(a->index)->amux; | 1762 | dev->ctl_ainput = INPUT(a->index)->amux; |
@@ -1719,7 +1773,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
1719 | { | 1773 | { |
1720 | struct em28xx *dev = video_drvdata(file); | 1774 | struct em28xx *dev = video_drvdata(file); |
1721 | 1775 | ||
1722 | if (0 != t->index) | 1776 | if (t->index != 0) |
1723 | return -EINVAL; | 1777 | return -EINVAL; |
1724 | 1778 | ||
1725 | strcpy(t->name, "Tuner"); | 1779 | strcpy(t->name, "Tuner"); |
@@ -1733,7 +1787,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
1733 | { | 1787 | { |
1734 | struct em28xx *dev = video_drvdata(file); | 1788 | struct em28xx *dev = video_drvdata(file); |
1735 | 1789 | ||
1736 | if (0 != t->index) | 1790 | if (t->index != 0) |
1737 | return -EINVAL; | 1791 | return -EINVAL; |
1738 | 1792 | ||
1739 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); | 1793 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); |
@@ -1746,7 +1800,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
1746 | struct em28xx *dev = video_drvdata(file); | 1800 | struct em28xx *dev = video_drvdata(file); |
1747 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 1801 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
1748 | 1802 | ||
1749 | if (0 != f->tuner) | 1803 | if (f->tuner != 0) |
1750 | return -EINVAL; | 1804 | return -EINVAL; |
1751 | 1805 | ||
1752 | f->frequency = v4l2->frequency; | 1806 | f->frequency = v4l2->frequency; |
@@ -1760,7 +1814,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1760 | struct em28xx *dev = video_drvdata(file); | 1814 | struct em28xx *dev = video_drvdata(file); |
1761 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 1815 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
1762 | 1816 | ||
1763 | if (0 != f->tuner) | 1817 | if (f->tuner != 0) |
1764 | return -EINVAL; | 1818 | return -EINVAL; |
1765 | 1819 | ||
1766 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_frequency, f); | 1820 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_frequency, f); |
@@ -1884,8 +1938,9 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1884 | if (dev->tuner_type != TUNER_ABSENT) | 1938 | if (dev->tuner_type != TUNER_ABSENT) |
1885 | cap->device_caps |= V4L2_CAP_TUNER; | 1939 | cap->device_caps |= V4L2_CAP_TUNER; |
1886 | 1940 | ||
1887 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS | | 1941 | cap->capabilities = cap->device_caps | |
1888 | V4L2_CAP_READWRITE | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1942 | V4L2_CAP_DEVICE_CAPS | V4L2_CAP_READWRITE | |
1943 | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | ||
1889 | if (video_is_registered(&v4l2->vbi_dev)) | 1944 | if (video_is_registered(&v4l2->vbi_dev)) |
1890 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; | 1945 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; |
1891 | if (video_is_registered(&v4l2->radio_dev)) | 1946 | if (video_is_registered(&v4l2->radio_dev)) |
@@ -1978,9 +2033,9 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | |||
1978 | return 0; | 2033 | return 0; |
1979 | } | 2034 | } |
1980 | 2035 | ||
1981 | /* ----------------------------------------------------------- */ | 2036 | /* |
1982 | /* RADIO ESPECIFIC IOCTLS */ | 2037 | * RADIO ESPECIFIC IOCTLS |
1983 | /* ----------------------------------------------------------- */ | 2038 | */ |
1984 | 2039 | ||
1985 | static int radio_g_tuner(struct file *file, void *priv, | 2040 | static int radio_g_tuner(struct file *file, void *priv, |
1986 | struct v4l2_tuner *t) | 2041 | struct v4l2_tuner *t) |
@@ -2002,7 +2057,7 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
2002 | { | 2057 | { |
2003 | struct em28xx *dev = video_drvdata(file); | 2058 | struct em28xx *dev = video_drvdata(file); |
2004 | 2059 | ||
2005 | if (0 != t->index) | 2060 | if (t->index != 0) |
2006 | return -EINVAL; | 2061 | return -EINVAL; |
2007 | 2062 | ||
2008 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); | 2063 | v4l2_device_call_all(&dev->v4l2->v4l2_dev, 0, tuner, s_tuner, t); |
@@ -2097,7 +2152,7 @@ static int em28xx_v4l2_open(struct file *filp) | |||
2097 | * em28xx_v4l2_fini() | 2152 | * em28xx_v4l2_fini() |
2098 | * unregisters the v4l2,i2c and usb devices | 2153 | * unregisters the v4l2,i2c and usb devices |
2099 | * called when the device gets disconected or at module unload | 2154 | * called when the device gets disconected or at module unload |
2100 | */ | 2155 | */ |
2101 | static int em28xx_v4l2_fini(struct em28xx *dev) | 2156 | static int em28xx_v4l2_fini(struct em28xx *dev) |
2102 | { | 2157 | { |
2103 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 2158 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
@@ -2112,7 +2167,7 @@ static int em28xx_v4l2_fini(struct em28xx *dev) | |||
2112 | return 0; | 2167 | return 0; |
2113 | } | 2168 | } |
2114 | 2169 | ||
2115 | if (v4l2 == NULL) | 2170 | if (!v4l2) |
2116 | return 0; | 2171 | return 0; |
2117 | 2172 | ||
2118 | dev_info(&dev->intf->dev, "Closing video extension\n"); | 2173 | dev_info(&dev->intf->dev, "Closing video extension\n"); |
@@ -2127,17 +2182,17 @@ static int em28xx_v4l2_fini(struct em28xx *dev) | |||
2127 | 2182 | ||
2128 | if (video_is_registered(&v4l2->radio_dev)) { | 2183 | if (video_is_registered(&v4l2->radio_dev)) { |
2129 | dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", | 2184 | dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", |
2130 | video_device_node_name(&v4l2->radio_dev)); | 2185 | video_device_node_name(&v4l2->radio_dev)); |
2131 | video_unregister_device(&v4l2->radio_dev); | 2186 | video_unregister_device(&v4l2->radio_dev); |
2132 | } | 2187 | } |
2133 | if (video_is_registered(&v4l2->vbi_dev)) { | 2188 | if (video_is_registered(&v4l2->vbi_dev)) { |
2134 | dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", | 2189 | dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", |
2135 | video_device_node_name(&v4l2->vbi_dev)); | 2190 | video_device_node_name(&v4l2->vbi_dev)); |
2136 | video_unregister_device(&v4l2->vbi_dev); | 2191 | video_unregister_device(&v4l2->vbi_dev); |
2137 | } | 2192 | } |
2138 | if (video_is_registered(&v4l2->vdev)) { | 2193 | if (video_is_registered(&v4l2->vdev)) { |
2139 | dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", | 2194 | dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n", |
2140 | video_device_node_name(&v4l2->vdev)); | 2195 | video_device_node_name(&v4l2->vdev)); |
2141 | video_unregister_device(&v4l2->vdev); | 2196 | video_unregister_device(&v4l2->vdev); |
2142 | } | 2197 | } |
2143 | 2198 | ||
@@ -2189,7 +2244,7 @@ static int em28xx_v4l2_close(struct file *filp) | |||
2189 | struct em28xx *dev = video_drvdata(filp); | 2244 | struct em28xx *dev = video_drvdata(filp); |
2190 | struct em28xx_v4l2 *v4l2 = dev->v4l2; | 2245 | struct em28xx_v4l2 *v4l2 = dev->v4l2; |
2191 | struct usb_device *udev = interface_to_usbdev(dev->intf); | 2246 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
2192 | int errCode; | 2247 | int err; |
2193 | 2248 | ||
2194 | em28xx_videodbg("users=%d\n", v4l2->users); | 2249 | em28xx_videodbg("users=%d\n", v4l2->users); |
2195 | 2250 | ||
@@ -2202,7 +2257,7 @@ static int em28xx_v4l2_close(struct file *filp) | |||
2202 | goto exit; | 2257 | goto exit; |
2203 | 2258 | ||
2204 | /* Save some power by putting tuner to sleep */ | 2259 | /* Save some power by putting tuner to sleep */ |
2205 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); | 2260 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, standby); |
2206 | 2261 | ||
2207 | /* do this before setting alternate! */ | 2262 | /* do this before setting alternate! */ |
2208 | em28xx_set_mode(dev, EM28XX_SUSPEND); | 2263 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
@@ -2210,11 +2265,11 @@ static int em28xx_v4l2_close(struct file *filp) | |||
2210 | /* set alternate 0 */ | 2265 | /* set alternate 0 */ |
2211 | dev->alt = 0; | 2266 | dev->alt = 0; |
2212 | em28xx_videodbg("setting alternate 0\n"); | 2267 | em28xx_videodbg("setting alternate 0\n"); |
2213 | errCode = usb_set_interface(udev, 0, 0); | 2268 | err = usb_set_interface(udev, 0, 0); |
2214 | if (errCode < 0) { | 2269 | if (err < 0) { |
2215 | dev_err(&dev->intf->dev, | 2270 | dev_err(&dev->intf->dev, |
2216 | "cannot change alternate number to 0 (error=%i)\n", | 2271 | "cannot change alternate number to 0 (error=%i)\n", |
2217 | errCode); | 2272 | err); |
2218 | } | 2273 | } |
2219 | } | 2274 | } |
2220 | 2275 | ||
@@ -2343,7 +2398,7 @@ static void em28xx_vdev_init(struct em28xx *dev, | |||
2343 | *vfd = *template; | 2398 | *vfd = *template; |
2344 | vfd->v4l2_dev = &dev->v4l2->v4l2_dev; | 2399 | vfd->v4l2_dev = &dev->v4l2->v4l2_dev; |
2345 | vfd->lock = &dev->lock; | 2400 | vfd->lock = &dev->lock; |
2346 | if (dev->board.is_webcam) | 2401 | if (dev->is_webcam) |
2347 | vfd->tvnorms = 0; | 2402 | vfd->tvnorms = 0; |
2348 | 2403 | ||
2349 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", | 2404 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", |
@@ -2372,7 +2427,7 @@ static void em28xx_tuner_setup(struct em28xx *dev, unsigned short tuner_addr) | |||
2372 | 0, tuner, s_type_addr, &tun_setup); | 2427 | 0, tuner, s_type_addr, &tun_setup); |
2373 | } | 2428 | } |
2374 | 2429 | ||
2375 | if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) { | 2430 | if (dev->tuner_type != TUNER_ABSENT && dev->tuner_type) { |
2376 | tun_setup.type = dev->tuner_type; | 2431 | tun_setup.type = dev->tuner_type; |
2377 | tun_setup.addr = tuner_addr; | 2432 | tun_setup.addr = tuner_addr; |
2378 | 2433 | ||
@@ -2435,7 +2490,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2435 | 2490 | ||
2436 | mutex_lock(&dev->lock); | 2491 | mutex_lock(&dev->lock); |
2437 | 2492 | ||
2438 | v4l2 = kzalloc(sizeof(struct em28xx_v4l2), GFP_KERNEL); | 2493 | v4l2 = kzalloc(sizeof(*v4l2), GFP_KERNEL); |
2439 | if (!v4l2) { | 2494 | if (!v4l2) { |
2440 | mutex_unlock(&dev->lock); | 2495 | mutex_unlock(&dev->lock); |
2441 | return -ENOMEM; | 2496 | return -ENOMEM; |
@@ -2458,7 +2513,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2458 | v4l2_ctrl_handler_init(hdl, 8); | 2513 | v4l2_ctrl_handler_init(hdl, 8); |
2459 | v4l2->v4l2_dev.ctrl_handler = hdl; | 2514 | v4l2->v4l2_dev.ctrl_handler = hdl; |
2460 | 2515 | ||
2461 | if (dev->board.is_webcam) | 2516 | if (dev->is_webcam) |
2462 | v4l2->progressive = true; | 2517 | v4l2->progressive = true; |
2463 | 2518 | ||
2464 | /* | 2519 | /* |
@@ -2470,7 +2525,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2470 | 2525 | ||
2471 | /* request some modules */ | 2526 | /* request some modules */ |
2472 | 2527 | ||
2473 | if (dev->board.has_msp34xx) | 2528 | if (dev->has_msp34xx) |
2474 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, | 2529 | v4l2_i2c_new_subdev(&v4l2->v4l2_dev, |
2475 | &dev->i2c_adap[dev->def_i2c_bus], | 2530 | &dev->i2c_adap[dev->def_i2c_bus], |
2476 | "msp3400", 0, msp3400_addrs); | 2531 | "msp3400", 0, msp3400_addrs); |
@@ -2559,7 +2614,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2559 | INIT_LIST_HEAD(&dev->vidq.active); | 2614 | INIT_LIST_HEAD(&dev->vidq.active); |
2560 | INIT_LIST_HEAD(&dev->vbiq.active); | 2615 | INIT_LIST_HEAD(&dev->vbiq.active); |
2561 | 2616 | ||
2562 | if (dev->board.has_msp34xx) { | 2617 | if (dev->has_msp34xx) { |
2563 | /* Send a reset to other chips via gpio */ | 2618 | /* Send a reset to other chips via gpio */ |
2564 | ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); | 2619 | ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7); |
2565 | if (ret < 0) { | 2620 | if (ret < 0) { |
@@ -2568,7 +2623,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2568 | __func__, ret); | 2623 | __func__, ret); |
2569 | goto unregister_dev; | 2624 | goto unregister_dev; |
2570 | } | 2625 | } |
2571 | msleep(3); | 2626 | usleep_range(10000, 11000); |
2572 | 2627 | ||
2573 | ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); | 2628 | ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff); |
2574 | if (ret < 0) { | 2629 | if (ret < 0) { |
@@ -2577,7 +2632,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2577 | __func__, ret); | 2632 | __func__, ret); |
2578 | goto unregister_dev; | 2633 | goto unregister_dev; |
2579 | } | 2634 | } |
2580 | msleep(3); | 2635 | usleep_range(10000, 11000); |
2581 | } | 2636 | } |
2582 | 2637 | ||
2583 | /* set default norm */ | 2638 | /* set default norm */ |
@@ -2589,8 +2644,10 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2589 | v4l2->format = &format[0]; | 2644 | v4l2->format = &format[0]; |
2590 | 2645 | ||
2591 | maxw = norm_maxw(dev); | 2646 | maxw = norm_maxw(dev); |
2592 | /* MaxPacketSize for em2800 is too small to capture at full resolution | 2647 | /* |
2593 | * use half of maxw as the scaler can only scale to 50% */ | 2648 | * MaxPacketSize for em2800 is too small to capture at full resolution |
2649 | * use half of maxw as the scaler can only scale to 50% | ||
2650 | */ | ||
2594 | if (dev->board.is_em2800) | 2651 | if (dev->board.is_em2800) |
2595 | maxw /= 2; | 2652 | maxw /= 2; |
2596 | 2653 | ||
@@ -2611,29 +2668,33 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2611 | em28xx_set_outfmt(dev); | 2668 | em28xx_set_outfmt(dev); |
2612 | 2669 | ||
2613 | /* Add image controls */ | 2670 | /* Add image controls */ |
2614 | /* NOTE: at this point, the subdevices are already registered, so bridge | 2671 | |
2615 | * controls are only added/enabled when no subdevice provides them */ | 2672 | /* |
2616 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST)) | 2673 | * NOTE: at this point, the subdevices are already registered, so |
2674 | * bridge controls are only added/enabled when no subdevice provides | ||
2675 | * them | ||
2676 | */ | ||
2677 | if (!v4l2_ctrl_find(hdl, V4L2_CID_CONTRAST)) | ||
2617 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, | 2678 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
2618 | V4L2_CID_CONTRAST, | 2679 | V4L2_CID_CONTRAST, |
2619 | 0, 0x1f, 1, CONTRAST_DEFAULT); | 2680 | 0, 0x1f, 1, CONTRAST_DEFAULT); |
2620 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS)) | 2681 | if (!v4l2_ctrl_find(hdl, V4L2_CID_BRIGHTNESS)) |
2621 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, | 2682 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
2622 | V4L2_CID_BRIGHTNESS, | 2683 | V4L2_CID_BRIGHTNESS, |
2623 | -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); | 2684 | -0x80, 0x7f, 1, BRIGHTNESS_DEFAULT); |
2624 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SATURATION)) | 2685 | if (!v4l2_ctrl_find(hdl, V4L2_CID_SATURATION)) |
2625 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, | 2686 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
2626 | V4L2_CID_SATURATION, | 2687 | V4L2_CID_SATURATION, |
2627 | 0, 0x1f, 1, SATURATION_DEFAULT); | 2688 | 0, 0x1f, 1, SATURATION_DEFAULT); |
2628 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE)) | 2689 | if (!v4l2_ctrl_find(hdl, V4L2_CID_BLUE_BALANCE)) |
2629 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, | 2690 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
2630 | V4L2_CID_BLUE_BALANCE, | 2691 | V4L2_CID_BLUE_BALANCE, |
2631 | -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); | 2692 | -0x30, 0x30, 1, BLUE_BALANCE_DEFAULT); |
2632 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE)) | 2693 | if (!v4l2_ctrl_find(hdl, V4L2_CID_RED_BALANCE)) |
2633 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, | 2694 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
2634 | V4L2_CID_RED_BALANCE, | 2695 | V4L2_CID_RED_BALANCE, |
2635 | -0x30, 0x30, 1, RED_BALANCE_DEFAULT); | 2696 | -0x30, 0x30, 1, RED_BALANCE_DEFAULT); |
2636 | if (NULL == v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS)) | 2697 | if (!v4l2_ctrl_find(hdl, V4L2_CID_SHARPNESS)) |
2637 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, | 2698 | v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, |
2638 | V4L2_CID_SHARPNESS, | 2699 | V4L2_CID_SHARPNESS, |
2639 | 0, 0x0f, 1, SHARPNESS_DEFAULT); | 2700 | 0, 0x0f, 1, SHARPNESS_DEFAULT); |
@@ -2653,7 +2714,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2653 | v4l2->vdev.queue->lock = &v4l2->vb_queue_lock; | 2714 | v4l2->vdev.queue->lock = &v4l2->vb_queue_lock; |
2654 | 2715 | ||
2655 | /* disable inapplicable ioctls */ | 2716 | /* disable inapplicable ioctls */ |
2656 | if (dev->board.is_webcam) { | 2717 | if (dev->is_webcam) { |
2657 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_QUERYSTD); | 2718 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_QUERYSTD); |
2658 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_STD); | 2719 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_G_STD); |
2659 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_STD); | 2720 | v4l2_disable_ioctl(&v4l2->vdev, VIDIOC_S_STD); |
@@ -2683,7 +2744,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2683 | /* Allocate and fill vbi video_device struct */ | 2744 | /* Allocate and fill vbi video_device struct */ |
2684 | if (em28xx_vbi_supported(dev) == 1) { | 2745 | if (em28xx_vbi_supported(dev) == 1) { |
2685 | em28xx_vdev_init(dev, &v4l2->vbi_dev, &em28xx_video_template, | 2746 | em28xx_vdev_init(dev, &v4l2->vbi_dev, &em28xx_video_template, |
2686 | "vbi"); | 2747 | "vbi"); |
2687 | 2748 | ||
2688 | v4l2->vbi_dev.queue = &v4l2->vb_vbiq; | 2749 | v4l2->vbi_dev.queue = &v4l2->vb_vbiq; |
2689 | v4l2->vbi_dev.queue->lock = &v4l2->vb_vbi_queue_lock; | 2750 | v4l2->vbi_dev.queue->lock = &v4l2->vb_vbi_queue_lock; |
@@ -2713,7 +2774,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2713 | 2774 | ||
2714 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | 2775 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { |
2715 | em28xx_vdev_init(dev, &v4l2->radio_dev, &em28xx_radio_template, | 2776 | em28xx_vdev_init(dev, &v4l2->radio_dev, &em28xx_radio_template, |
2716 | "radio"); | 2777 | "radio"); |
2717 | ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, | 2778 | ret = video_register_device(&v4l2->radio_dev, VFL_TYPE_RADIO, |
2718 | radio_nr[dev->devno]); | 2779 | radio_nr[dev->devno]); |
2719 | if (ret < 0) { | 2780 | if (ret < 0) { |
@@ -2749,7 +2810,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) | |||
2749 | video_device_node_name(&v4l2->vbi_dev)); | 2810 | video_device_node_name(&v4l2->vbi_dev)); |
2750 | 2811 | ||
2751 | /* Save some power by putting tuner to sleep */ | 2812 | /* Save some power by putting tuner to sleep */ |
2752 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, core, s_power, 0); | 2813 | v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, standby); |
2753 | 2814 | ||
2754 | /* initialize videobuf2 stuff */ | 2815 | /* initialize videobuf2 stuff */ |
2755 | em28xx_vb2_setup(dev); | 2816 | em28xx_vb2_setup(dev); |
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 88084f24f033..63c7c6124707 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h | |||
@@ -1,31 +1,30 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
1 | /* | 2 | /* |
2 | em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices | 3 | * em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices |
3 | 4 | * | |
4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | 5 | * Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> |
5 | Ludovico Cavedon <cavedon@sssup.it> | 6 | * Ludovico Cavedon <cavedon@sssup.it> |
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | 7 | * Mauro Carvalho Chehab <mchehab@infradead.org> |
7 | Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> | 8 | * Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
8 | 9 | * | |
9 | Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> | 10 | * Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> |
10 | 11 | * | |
11 | This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
13 | the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
14 | (at your option) any later version. | 15 | * (at your option) any later version. |
15 | 16 | * | |
16 | This program is distributed in the hope that it will be useful, | 17 | * This program is distributed in the hope that it will be useful, |
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | GNU General Public License for more details. | 20 | * GNU General Public License for more details. |
20 | |||
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | 21 | */ |
25 | 22 | ||
26 | #ifndef _EM28XX_H | 23 | #ifndef _EM28XX_H |
27 | #define _EM28XX_H | 24 | #define _EM28XX_H |
28 | 25 | ||
26 | #include <linux/bitfield.h> | ||
27 | |||
29 | #define EM28XX_VERSION "0.2.2" | 28 | #define EM28XX_VERSION "0.2.2" |
30 | #define DRIVER_DESC "Empia em28xx device driver" | 29 | #define DRIVER_DESC "Empia em28xx device driver" |
31 | 30 | ||
@@ -166,7 +165,7 @@ | |||
166 | #define EM28XX_STOP_AUDIO 0 | 165 | #define EM28XX_STOP_AUDIO 0 |
167 | 166 | ||
168 | /* maximum number of em28xx boards */ | 167 | /* maximum number of em28xx boards */ |
169 | #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ | 168 | #define EM28XX_MAXBOARDS DVB_MAX_ADAPTERS /* All adapters could be em28xx */ |
170 | 169 | ||
171 | /* maximum number of frames that can be queued */ | 170 | /* maximum number of frames that can be queued */ |
172 | #define EM28XX_NUM_FRAMES 5 | 171 | #define EM28XX_NUM_FRAMES 5 |
@@ -180,43 +179,32 @@ | |||
180 | /* max number of I2C buses on em28xx devices */ | 179 | /* max number of I2C buses on em28xx devices */ |
181 | #define NUM_I2C_BUSES 2 | 180 | #define NUM_I2C_BUSES 2 |
182 | 181 | ||
183 | /* isoc transfers: number of packets for each buffer | 182 | /* |
184 | windows requests only 64 packets .. so we better do the same | 183 | * isoc transfers: number of packets for each buffer |
185 | this is what I found out for all alternate numbers there! | 184 | * windows requests only 64 packets .. so we better do the same |
185 | * this is what I found out for all alternate numbers there! | ||
186 | */ | 186 | */ |
187 | #define EM28XX_NUM_ISOC_PACKETS 64 | 187 | #define EM28XX_NUM_ISOC_PACKETS 64 |
188 | #define EM28XX_DVB_NUM_ISOC_PACKETS 64 | 188 | #define EM28XX_DVB_NUM_ISOC_PACKETS 64 |
189 | 189 | ||
190 | /* bulk transfers: transfer buffer size = packet size * packet multiplier | 190 | /* |
191 | USB 2.0 spec says bulk packet size is always 512 bytes | 191 | * bulk transfers: transfer buffer size = packet size * packet multiplier |
192 | * USB 2.0 spec says bulk packet size is always 512 bytes | ||
192 | */ | 193 | */ |
193 | #define EM28XX_BULK_PACKET_MULTIPLIER 384 | 194 | #define EM28XX_BULK_PACKET_MULTIPLIER 384 |
194 | #define EM28XX_DVB_BULK_PACKET_MULTIPLIER 384 | 195 | #define EM28XX_DVB_BULK_PACKET_MULTIPLIER 94 |
195 | 196 | ||
196 | #define EM28XX_INTERLACED_DEFAULT 1 | 197 | #define EM28XX_INTERLACED_DEFAULT 1 |
197 | 198 | ||
198 | /* | ||
199 | * Time in msecs to wait for i2c xfers to finish. | ||
200 | * 35ms is the maximum time a SMBUS device could wait when | ||
201 | * clock stretching is used. As the transfer itself will take | ||
202 | * some time to happen, set it to 35 ms. | ||
203 | * | ||
204 | * Ok, I2C doesn't specify any limit. So, eventually, we may need | ||
205 | * to increase this timeout. | ||
206 | * | ||
207 | * FIXME: this assumes that an I2C message is not longer than 1ms. | ||
208 | * This is actually dependent on the I2C bus speed, although most | ||
209 | * devices use a 100kHz clock. So, this assumtion is true most of | ||
210 | * the time. | ||
211 | */ | ||
212 | #define EM28XX_I2C_XFER_TIMEOUT 36 | ||
213 | |||
214 | /* time in msecs to wait for AC97 xfers to finish */ | 199 | /* time in msecs to wait for AC97 xfers to finish */ |
215 | #define EM28XX_AC97_XFER_TIMEOUT 100 | 200 | #define EM28XX_AC97_XFER_TIMEOUT 100 |
216 | 201 | ||
217 | /* max. number of button state polling addresses */ | 202 | /* max. number of button state polling addresses */ |
218 | #define EM28XX_NUM_BUTTON_ADDRESSES_MAX 5 | 203 | #define EM28XX_NUM_BUTTON_ADDRESSES_MAX 5 |
219 | 204 | ||
205 | #define PRIMARY_TS 0 | ||
206 | #define SECONDARY_TS 1 | ||
207 | |||
220 | enum em28xx_mode { | 208 | enum em28xx_mode { |
221 | EM28XX_SUSPEND, | 209 | EM28XX_SUSPEND, |
222 | EM28XX_ANALOG_MODE, | 210 | EM28XX_ANALOG_MODE, |
@@ -225,64 +213,83 @@ enum em28xx_mode { | |||
225 | 213 | ||
226 | struct em28xx; | 214 | struct em28xx; |
227 | 215 | ||
216 | /** | ||
217 | * struct em28xx_usb_bufs - Contains URB-related buffer data | ||
218 | * | ||
219 | * @max_pkt_size: max packet size of isoc transaction | ||
220 | * @num_packets: number of packets in each buffer | ||
221 | * @num_bufs: number of allocated urb | ||
222 | * @urb: urb for isoc/bulk transfers | ||
223 | * @buf: transfer buffers for isoc/bulk transfer | ||
224 | */ | ||
228 | struct em28xx_usb_bufs { | 225 | struct em28xx_usb_bufs { |
229 | /* max packet size of isoc transaction */ | ||
230 | int max_pkt_size; | 226 | int max_pkt_size; |
231 | |||
232 | /* number of packets in each buffer */ | ||
233 | int num_packets; | 227 | int num_packets; |
234 | |||
235 | /* number of allocated urbs */ | ||
236 | int num_bufs; | 228 | int num_bufs; |
237 | |||
238 | /* urb for isoc/bulk transfers */ | ||
239 | struct urb **urb; | 229 | struct urb **urb; |
240 | 230 | char **buf; | |
241 | /* transfer buffers for isoc/bulk transfer */ | ||
242 | char **transfer_buffer; | ||
243 | }; | 231 | }; |
244 | 232 | ||
233 | /** | ||
234 | * struct em28xx_usb_ctl - Contains URB-related buffer data | ||
235 | * | ||
236 | * @analog_bufs: isoc/bulk transfer buffers for analog mode | ||
237 | * @digital_bufs: isoc/bulk transfer buffers for digital mode | ||
238 | * @vid_buf: Stores already requested video buffers | ||
239 | * @vbi_buf: Stores already requested VBI buffers | ||
240 | * @urb_data_copy: copy data from URB | ||
241 | */ | ||
245 | struct em28xx_usb_ctl { | 242 | struct em28xx_usb_ctl { |
246 | /* isoc/bulk transfer buffers for analog mode */ | ||
247 | struct em28xx_usb_bufs analog_bufs; | 243 | struct em28xx_usb_bufs analog_bufs; |
248 | |||
249 | /* isoc/bulk transfer buffers for digital mode */ | ||
250 | struct em28xx_usb_bufs digital_bufs; | 244 | struct em28xx_usb_bufs digital_bufs; |
251 | |||
252 | /* Stores already requested buffers */ | ||
253 | struct em28xx_buffer *vid_buf; | 245 | struct em28xx_buffer *vid_buf; |
254 | struct em28xx_buffer *vbi_buf; | 246 | struct em28xx_buffer *vbi_buf; |
255 | |||
256 | /* copy data from URB */ | ||
257 | int (*urb_data_copy)(struct em28xx *dev, struct urb *urb); | 247 | int (*urb_data_copy)(struct em28xx *dev, struct urb *urb); |
258 | |||
259 | }; | 248 | }; |
260 | 249 | ||
261 | /* Struct to enumberate video formats */ | 250 | /** |
251 | * struct em28xx_fmt - Struct to enumberate video formats | ||
252 | * | ||
253 | * @name: Name for the video standard | ||
254 | * @fourcc: v4l2 format id | ||
255 | * @depth: mean number of bits to represent a pixel | ||
256 | * @reg: em28xx register value to set it | ||
257 | */ | ||
262 | struct em28xx_fmt { | 258 | struct em28xx_fmt { |
263 | char *name; | 259 | char *name; |
264 | u32 fourcc; /* v4l2 format id */ | 260 | u32 fourcc; |
265 | int depth; | 261 | int depth; |
266 | int reg; | 262 | int reg; |
267 | }; | 263 | }; |
268 | 264 | ||
269 | /* buffer for one video frame */ | 265 | /** |
266 | * struct em28xx_buffer- buffer for storing one video frame | ||
267 | * | ||
268 | * @vb: common v4l buffer stuff | ||
269 | * @list: List to associate it with the other buffers | ||
270 | * @mem: pointer to the buffer, as returned by vb2_plane_vaddr() | ||
271 | * @length: length of the buffer, as returned by vb2_plane_size() | ||
272 | * @top_field: If non-zero, indicate that the buffer is the top field | ||
273 | * @pos: Indicate the next position of the buffer to be filled. | ||
274 | * @vb_buf: pointer to vmalloc memory address in vb | ||
275 | * | ||
276 | * .. note:: | ||
277 | * | ||
278 | * in interlaced mode, @pos is reset to zero at the start of each new | ||
279 | * field (not frame !) | ||
280 | */ | ||
270 | struct em28xx_buffer { | 281 | struct em28xx_buffer { |
271 | /* common v4l buffer stuff -- must be first */ | 282 | struct vb2_v4l2_buffer vb; /* must be first */ |
272 | struct vb2_v4l2_buffer vb; | ||
273 | struct list_head list; | ||
274 | 283 | ||
275 | void *mem; | 284 | struct list_head list; |
276 | unsigned int length; | ||
277 | int top_field; | ||
278 | 285 | ||
279 | /* counter to control buffer fill */ | 286 | void *mem; |
280 | unsigned int pos; | 287 | unsigned int length; |
281 | /* NOTE; in interlaced mode, this value is reset to zero at | 288 | int top_field; |
282 | * the start of each new field (not frame !) */ | ||
283 | 289 | ||
284 | /* pointer to vmalloc memory address in vb */ | 290 | unsigned int pos; |
285 | char *vb_buf; | 291 | |
292 | char *vb_buf; | ||
286 | }; | 293 | }; |
287 | 294 | ||
288 | struct em28xx_dmaqueue { | 295 | struct em28xx_dmaqueue { |
@@ -324,20 +331,48 @@ enum em28xx_usb_audio_type { | |||
324 | EM28XX_USB_AUDIO_VENDOR, | 331 | EM28XX_USB_AUDIO_VENDOR, |
325 | }; | 332 | }; |
326 | 333 | ||
327 | /* em28xx has two audio inputs: tuner and line in. | 334 | /** |
328 | However, on most devices, an auxiliary AC97 codec device is used. | 335 | * em28xx_amux - describes the type of audio input used by em28xx |
329 | The AC97 device may have several different inputs and outputs, | 336 | * |
330 | depending on their model. So, it is possible to use AC97 mixer to | 337 | * @EM28XX_AMUX_VIDEO: |
331 | address more than two different entries. | 338 | * On devices without AC97, this is the only value that it is currently |
339 | * allowed. | ||
340 | * On devices with AC97, it corresponds to the AC97 mixer "Video" control. | ||
341 | * @EM28XX_AMUX_LINE_IN: | ||
342 | * Only for devices with AC97. Corresponds to AC97 mixer "Line In". | ||
343 | * @EM28XX_AMUX_VIDEO2: | ||
344 | * Only for devices with AC97. It means that em28xx should use "Line In" | ||
345 | * And AC97 should use the "Video" mixer control. | ||
346 | * @EM28XX_AMUX_PHONE: | ||
347 | * Only for devices with AC97. Corresponds to AC97 mixer "Phone". | ||
348 | * @EM28XX_AMUX_MIC: | ||
349 | * Only for devices with AC97. Corresponds to AC97 mixer "Mic". | ||
350 | * @EM28XX_AMUX_CD: | ||
351 | * Only for devices with AC97. Corresponds to AC97 mixer "CD". | ||
352 | * @EM28XX_AMUX_AUX: | ||
353 | * Only for devices with AC97. Corresponds to AC97 mixer "Aux". | ||
354 | * @EM28XX_AMUX_PCM_OUT: | ||
355 | * Only for devices with AC97. Corresponds to AC97 mixer "PCM out". | ||
356 | * | ||
357 | * The em28xx chip itself has only two audio inputs: tuner and line in. | ||
358 | * On almost all devices, only the tuner input is used. | ||
359 | * | ||
360 | * However, on most devices, an auxiliary AC97 codec device is used, | ||
361 | * usually connected to the em28xx tuner input (except for | ||
362 | * @EM28XX_AMUX_LINE_IN). | ||
363 | * | ||
364 | * The AC97 device typically have several different inputs and outputs. | ||
365 | * The exact number and description depends on their model. | ||
366 | * | ||
367 | * It is possible to AC97 to mixer more than one different entries at the | ||
368 | * same time, via the alsa mux. | ||
332 | */ | 369 | */ |
333 | enum em28xx_amux { | 370 | enum em28xx_amux { |
334 | /* This is the only entry for em28xx tuner input */ | 371 | EM28XX_AMUX_VIDEO, |
335 | EM28XX_AMUX_VIDEO, /* em28xx tuner, AC97 mixer Video */ | 372 | EM28XX_AMUX_LINE_IN, |
336 | |||
337 | EM28XX_AMUX_LINE_IN, /* AC97 mixer Line In */ | ||
338 | 373 | ||
339 | /* Some less-common mixer setups */ | 374 | /* Some less-common mixer setups */ |
340 | EM28XX_AMUX_VIDEO2, /* em28xx Line in, AC97 mixer Video */ | 375 | EM28XX_AMUX_VIDEO2, |
341 | EM28XX_AMUX_PHONE, | 376 | EM28XX_AMUX_PHONE, |
342 | EM28XX_AMUX_MIC, | 377 | EM28XX_AMUX_MIC, |
343 | EM28XX_AMUX_CD, | 378 | EM28XX_AMUX_CD, |
@@ -347,14 +382,14 @@ enum em28xx_amux { | |||
347 | 382 | ||
348 | enum em28xx_aout { | 383 | enum em28xx_aout { |
349 | /* AC97 outputs */ | 384 | /* AC97 outputs */ |
350 | EM28XX_AOUT_MASTER = 1 << 0, | 385 | EM28XX_AOUT_MASTER = BIT(0), |
351 | EM28XX_AOUT_LINE = 1 << 1, | 386 | EM28XX_AOUT_LINE = BIT(1), |
352 | EM28XX_AOUT_MONO = 1 << 2, | 387 | EM28XX_AOUT_MONO = BIT(2), |
353 | EM28XX_AOUT_LFE = 1 << 3, | 388 | EM28XX_AOUT_LFE = BIT(3), |
354 | EM28XX_AOUT_SURR = 1 << 4, | 389 | EM28XX_AOUT_SURR = BIT(4), |
355 | 390 | ||
356 | /* PCM IN Mixer - used by AC97_RECORD_SELECT register */ | 391 | /* PCM IN Mixer - used by AC97_RECORD_SELECT register */ |
357 | EM28XX_AOUT_PCM_IN = 1 << 7, | 392 | EM28XX_AOUT_PCM_IN = BIT(7), |
358 | 393 | ||
359 | /* Bits 10-8 are used to indicate the PCM IN record select */ | 394 | /* Bits 10-8 are used to indicate the PCM IN record select */ |
360 | EM28XX_AOUT_PCM_MIC_PCM = 0 << 8, | 395 | EM28XX_AOUT_PCM_MIC_PCM = 0 << 8, |
@@ -383,7 +418,7 @@ struct em28xx_input { | |||
383 | unsigned int vmux; | 418 | unsigned int vmux; |
384 | enum em28xx_amux amux; | 419 | enum em28xx_amux amux; |
385 | enum em28xx_aout aout; | 420 | enum em28xx_aout aout; |
386 | struct em28xx_reg_seq *gpio; | 421 | const struct em28xx_reg_seq *gpio; |
387 | }; | 422 | }; |
388 | 423 | ||
389 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) | 424 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) |
@@ -441,22 +476,23 @@ struct em28xx_board { | |||
441 | int vchannels; | 476 | int vchannels; |
442 | int tuner_type; | 477 | int tuner_type; |
443 | int tuner_addr; | 478 | int tuner_addr; |
444 | unsigned def_i2c_bus; /* Default I2C bus */ | 479 | unsigned int def_i2c_bus; /* Default I2C bus */ |
445 | 480 | ||
446 | /* i2c flags */ | 481 | /* i2c flags */ |
447 | unsigned int tda9887_conf; | 482 | unsigned int tda9887_conf; |
448 | 483 | ||
449 | /* GPIO sequences */ | 484 | /* GPIO sequences */ |
450 | struct em28xx_reg_seq *dvb_gpio; | 485 | const struct em28xx_reg_seq *dvb_gpio; |
451 | struct em28xx_reg_seq *suspend_gpio; | 486 | const struct em28xx_reg_seq *suspend_gpio; |
452 | struct em28xx_reg_seq *tuner_gpio; | 487 | const struct em28xx_reg_seq *tuner_gpio; |
453 | struct em28xx_reg_seq *mute_gpio; | 488 | const struct em28xx_reg_seq *mute_gpio; |
454 | 489 | ||
455 | unsigned int is_em2800:1; | 490 | unsigned int is_em2800:1; |
456 | unsigned int has_msp34xx:1; | 491 | unsigned int has_msp34xx:1; |
457 | unsigned int mts_firmware:1; | 492 | unsigned int mts_firmware:1; |
458 | unsigned int max_range_640_480:1; | 493 | unsigned int max_range_640_480:1; |
459 | unsigned int has_dvb:1; | 494 | unsigned int has_dvb:1; |
495 | unsigned int has_dual_ts:1; | ||
460 | unsigned int is_webcam:1; | 496 | unsigned int is_webcam:1; |
461 | unsigned int valid:1; | 497 | unsigned int valid:1; |
462 | unsigned int has_ir_i2c:1; | 498 | unsigned int has_ir_i2c:1; |
@@ -476,7 +512,7 @@ struct em28xx_board { | |||
476 | struct em28xx_led *leds; | 512 | struct em28xx_led *leds; |
477 | 513 | ||
478 | /* Buttons */ | 514 | /* Buttons */ |
479 | struct em28xx_button *buttons; | 515 | const struct em28xx_button *buttons; |
480 | }; | 516 | }; |
481 | 517 | ||
482 | struct em28xx_eeprom { | 518 | struct em28xx_eeprom { |
@@ -519,8 +555,8 @@ struct em28xx_v4l2 { | |||
519 | /* Videobuf2 */ | 555 | /* Videobuf2 */ |
520 | struct vb2_queue vb_vidq; | 556 | struct vb2_queue vb_vidq; |
521 | struct vb2_queue vb_vbiq; | 557 | struct vb2_queue vb_vbiq; |
522 | struct mutex vb_queue_lock; | 558 | struct mutex vb_queue_lock; /* Protects vb_vidq */ |
523 | struct mutex vb_vbi_queue_lock; | 559 | struct mutex vb_vbi_queue_lock; /* Protects vb_vbiq */ |
524 | 560 | ||
525 | u8 vinmode; | 561 | u8 vinmode; |
526 | u8 vinctl; | 562 | u8 vinctl; |
@@ -546,8 +582,8 @@ struct em28xx_v4l2 { | |||
546 | /* Frame properties */ | 582 | /* Frame properties */ |
547 | int width; /* current frame width */ | 583 | int width; /* current frame width */ |
548 | int height; /* current frame height */ | 584 | int height; /* current frame height */ |
549 | unsigned hscale; /* horizontal scale factor (see datasheet) */ | 585 | unsigned int hscale; /* horizontal scale factor (see datasheet) */ |
550 | unsigned vscale; /* vertical scale factor (see datasheet) */ | 586 | unsigned int vscale; /* vertical scale factor (see datasheet) */ |
551 | unsigned int vbi_width; | 587 | unsigned int vbi_width; |
552 | unsigned int vbi_height; /* lines per field */ | 588 | unsigned int vbi_height; /* lines per field */ |
553 | 589 | ||
@@ -565,7 +601,7 @@ struct em28xx_v4l2 { | |||
565 | 601 | ||
566 | struct em28xx_audio { | 602 | struct em28xx_audio { |
567 | char name[50]; | 603 | char name[50]; |
568 | unsigned num_urb; | 604 | unsigned int num_urb; |
569 | char **transfer_buffer; | 605 | char **transfer_buffer; |
570 | struct urb **urb; | 606 | struct urb **urb; |
571 | struct usb_device *udev; | 607 | struct usb_device *udev; |
@@ -578,7 +614,7 @@ struct em28xx_audio { | |||
578 | size_t period; | 614 | size_t period; |
579 | 615 | ||
580 | int users; | 616 | int users; |
581 | spinlock_t slock; | 617 | spinlock_t slock; /* Protects struct em28xx_audio */ |
582 | 618 | ||
583 | /* Controls streaming */ | 619 | /* Controls streaming */ |
584 | struct work_struct wq_trigger; /* trigger to start/stop audio */ | 620 | struct work_struct wq_trigger; /* trigger to start/stop audio */ |
@@ -596,7 +632,7 @@ enum em28xx_i2c_algo_type { | |||
596 | struct em28xx_i2c_bus { | 632 | struct em28xx_i2c_bus { |
597 | struct em28xx *dev; | 633 | struct em28xx *dev; |
598 | 634 | ||
599 | unsigned bus; | 635 | unsigned int bus; |
600 | enum em28xx_i2c_algo_type algo_type; | 636 | enum em28xx_i2c_algo_type algo_type; |
601 | }; | 637 | }; |
602 | 638 | ||
@@ -604,102 +640,111 @@ struct em28xx_i2c_bus { | |||
604 | struct em28xx { | 640 | struct em28xx { |
605 | struct kref ref; | 641 | struct kref ref; |
606 | 642 | ||
607 | /* Sub-module data */ | 643 | // Sub-module data |
608 | struct em28xx_v4l2 *v4l2; | 644 | struct em28xx_v4l2 *v4l2; |
609 | struct em28xx_dvb *dvb; | 645 | struct em28xx_dvb *dvb; |
610 | struct em28xx_audio adev; | 646 | struct em28xx_audio adev; |
611 | struct em28xx_IR *ir; | 647 | struct em28xx_IR *ir; |
612 | 648 | ||
613 | /* generic device properties */ | 649 | // generic device properties |
614 | int model; /* index in the device_data struct */ | 650 | int model; // index in the device_data struct |
615 | int devno; /* marks the number of this device */ | 651 | int devno; // marks the number of this device |
616 | enum em28xx_chip_id chip_id; | 652 | enum em28xx_chip_id chip_id; |
617 | 653 | ||
618 | unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */ | 654 | unsigned int is_em25xx:1; // em25xx/em276x/7x/8x family bridge |
619 | unsigned char disconnected:1; /* device has been diconnected */ | 655 | unsigned int disconnected:1; // device has been diconnected |
620 | unsigned int has_video:1; | 656 | unsigned int has_video:1; |
621 | unsigned int is_audio_only:1; | 657 | unsigned int is_audio_only:1; |
658 | unsigned int is_webcam:1; | ||
659 | unsigned int has_msp34xx:1; | ||
660 | unsigned int i2c_speed:2; | ||
622 | enum em28xx_int_audio_type int_audio_type; | 661 | enum em28xx_int_audio_type int_audio_type; |
623 | enum em28xx_usb_audio_type usb_audio_type; | 662 | enum em28xx_usb_audio_type usb_audio_type; |
663 | unsigned char name[32]; | ||
624 | 664 | ||
625 | struct em28xx_board board; | 665 | struct em28xx_board board; |
626 | 666 | ||
627 | enum em28xx_sensor em28xx_sensor; /* camera specific */ | 667 | enum em28xx_sensor em28xx_sensor; // camera specific |
628 | 668 | ||
629 | /* Some older em28xx chips needs a waiting time after writing */ | 669 | // Some older em28xx chips needs a waiting time after writing |
630 | unsigned int wait_after_write; | 670 | unsigned int wait_after_write; |
631 | 671 | ||
632 | struct list_head devlist; | 672 | struct list_head devlist; |
633 | 673 | ||
634 | u32 i2s_speed; /* I2S speed for audio digital stream */ | 674 | u32 i2s_speed; // I2S speed for audio digital stream |
635 | 675 | ||
636 | struct em28xx_audio_mode audio_mode; | 676 | struct em28xx_audio_mode audio_mode; |
637 | 677 | ||
638 | int tuner_type; /* type of the tuner */ | 678 | int tuner_type; // type of the tuner |
639 | 679 | ||
640 | /* i2c i/o */ | 680 | // i2c i/o |
641 | struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; | 681 | struct i2c_adapter i2c_adap[NUM_I2C_BUSES]; |
642 | struct i2c_client i2c_client[NUM_I2C_BUSES]; | 682 | struct i2c_client i2c_client[NUM_I2C_BUSES]; |
643 | struct em28xx_i2c_bus i2c_bus[NUM_I2C_BUSES]; | 683 | struct em28xx_i2c_bus i2c_bus[NUM_I2C_BUSES]; |
644 | 684 | ||
645 | unsigned char eeprom_addrwidth_16bit:1; | 685 | unsigned char eeprom_addrwidth_16bit:1; |
646 | unsigned def_i2c_bus; /* Default I2C bus */ | 686 | unsigned int def_i2c_bus; // Default I2C bus |
647 | unsigned cur_i2c_bus; /* Current I2C bus */ | 687 | unsigned int cur_i2c_bus; // Current I2C bus |
648 | struct rt_mutex i2c_bus_lock; | 688 | struct rt_mutex i2c_bus_lock; |
649 | 689 | ||
650 | /* video for linux */ | 690 | // video for linux |
651 | unsigned int ctl_input; /* selected input */ | 691 | unsigned int ctl_input; // selected input |
652 | unsigned int ctl_ainput;/* selected audio input */ | 692 | unsigned int ctl_ainput;// selected audio input |
653 | unsigned int ctl_aoutput;/* selected audio output */ | 693 | unsigned int ctl_aoutput;// selected audio output |
654 | int mute; | 694 | int mute; |
655 | int volume; | 695 | int volume; |
656 | 696 | ||
657 | unsigned long hash; /* eeprom hash - for boards with generic ID */ | 697 | unsigned long hash; // eeprom hash - for boards with generic ID |
658 | unsigned long i2c_hash; /* i2c devicelist hash - | 698 | unsigned long i2c_hash; // i2c devicelist hash - |
659 | for boards with generic ID */ | 699 | // for boards with generic ID |
660 | 700 | ||
661 | struct work_struct request_module_wk; | 701 | struct work_struct request_module_wk; |
662 | 702 | ||
663 | /* locks */ | 703 | // locks |
664 | struct mutex lock; | 704 | struct mutex lock; /* protects em28xx struct */ |
665 | struct mutex ctrl_urb_lock; /* protects urb_buf */ | 705 | struct mutex ctrl_urb_lock; /* protects urb_buf */ |
666 | 706 | ||
667 | /* resources in use */ | 707 | // resources in use |
668 | unsigned int resources; | 708 | unsigned int resources; |
669 | 709 | ||
670 | /* eeprom content */ | 710 | // eeprom content |
671 | u8 *eedata; | 711 | u8 *eedata; |
672 | u16 eedata_len; | 712 | u16 eedata_len; |
673 | 713 | ||
674 | /* Isoc control struct */ | 714 | // Isoc control struct |
675 | struct em28xx_dmaqueue vidq; | 715 | struct em28xx_dmaqueue vidq; |
676 | struct em28xx_dmaqueue vbiq; | 716 | struct em28xx_dmaqueue vbiq; |
677 | struct em28xx_usb_ctl usb_ctl; | 717 | struct em28xx_usb_ctl usb_ctl; |
678 | spinlock_t slock; | 718 | |
679 | 719 | spinlock_t slock; /* Protects em28xx video/vbi/dvb IRQ stream data */ | |
680 | /* usb transfer */ | 720 | |
681 | struct usb_interface *intf; /* the usb interface */ | 721 | // usb transfer |
682 | u8 ifnum; /* number of the assigned usb interface */ | 722 | struct usb_interface *intf; // the usb interface |
683 | u8 analog_ep_isoc; /* address of isoc endpoint for analog */ | 723 | u8 ifnum; // number of the assigned usb interface |
684 | u8 analog_ep_bulk; /* address of bulk endpoint for analog */ | 724 | u8 analog_ep_isoc; // address of isoc endpoint for analog |
685 | u8 dvb_ep_isoc; /* address of isoc endpoint for DVB */ | 725 | u8 analog_ep_bulk; // address of bulk endpoint for analog |
686 | u8 dvb_ep_bulk; /* address of bulk endpoint for DVB */ | 726 | u8 dvb_ep_isoc_ts2; // address of isoc endpoint for DVB TS2 |
687 | int alt; /* alternate setting */ | 727 | u8 dvb_ep_bulk_ts2; // address of bulk endpoint for DVB TS2 |
688 | int max_pkt_size; /* max packet size of the selected ep at alt */ | 728 | u8 dvb_ep_isoc; // address of isoc endpoint for DVB |
689 | int packet_multiplier; /* multiplier for wMaxPacketSize, used for | 729 | u8 dvb_ep_bulk; // address of bulk endpoint for DVB |
690 | URB buffer size definition */ | 730 | int alt; // alternate setting |
691 | int num_alt; /* number of alternative settings */ | 731 | int max_pkt_size; // max packet size of the selected ep at alt |
692 | unsigned int *alt_max_pkt_size_isoc; /* array of isoc wMaxPacketSize */ | 732 | int packet_multiplier; // multiplier for wMaxPacketSize, used for |
693 | unsigned int analog_xfer_bulk:1; /* use bulk instead of isoc | 733 | // URB buffer size definition |
694 | transfers for analog */ | 734 | int num_alt; // number of alternative settings |
695 | int dvb_alt_isoc; /* alternate setting for DVB isoc transfers */ | 735 | unsigned int *alt_max_pkt_size_isoc; // array of isoc wMaxPacketSize |
696 | unsigned int dvb_max_pkt_size_isoc; /* isoc max packet size of the | 736 | unsigned int analog_xfer_bulk:1; // use bulk instead of isoc |
697 | selected DVB ep at dvb_alt */ | 737 | // transfers for analog |
698 | unsigned int dvb_xfer_bulk:1; /* use bulk instead of isoc | 738 | int dvb_alt_isoc; // alternate setting for DVB isoc transfers |
699 | transfers for DVB */ | 739 | unsigned int dvb_max_pkt_size_isoc; // isoc max packet size of the |
700 | char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ | 740 | // selected DVB ep at dvb_alt |
701 | 741 | unsigned int dvb_max_pkt_size_isoc_ts2; // isoc max packet size of the | |
702 | /* helper funcs that call usb_control_msg */ | 742 | // selected DVB ep at dvb_alt |
743 | unsigned int dvb_xfer_bulk:1; // use bulk instead of isoc | ||
744 | // transfers for DVB | ||
745 | char urb_buf[URB_MAX_CTRL_SIZE]; // urb control msg buffer | ||
746 | |||
747 | // helper funcs that call usb_control_msg | ||
703 | int (*em28xx_write_regs)(struct em28xx *dev, u16 reg, | 748 | int (*em28xx_write_regs)(struct em28xx *dev, u16 reg, |
704 | char *buf, int len); | 749 | char *buf, int len); |
705 | int (*em28xx_read_reg)(struct em28xx *dev, u16 reg); | 750 | int (*em28xx_read_reg)(struct em28xx *dev, u16 reg); |
@@ -711,14 +756,14 @@ struct em28xx { | |||
711 | 756 | ||
712 | enum em28xx_mode mode; | 757 | enum em28xx_mode mode; |
713 | 758 | ||
714 | /* Button state polling */ | 759 | // Button state polling |
715 | struct delayed_work buttons_query_work; | 760 | struct delayed_work buttons_query_work; |
716 | u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; | 761 | u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; |
717 | u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; | 762 | u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; |
718 | u8 num_button_polling_addresses; | 763 | u8 num_button_polling_addresses; |
719 | u16 button_polling_interval; /* [ms] */ | 764 | u16 button_polling_interval; // [ms] |
720 | /* Snapshot button input device */ | 765 | // Snapshot button input device |
721 | char snapshot_button_path[30]; /* path of the input dev */ | 766 | char snapshot_button_path[30]; // path of the input dev |
722 | struct input_dev *sbutton_input_dev; | 767 | struct input_dev *sbutton_input_dev; |
723 | 768 | ||
724 | #ifdef CONFIG_MEDIA_CONTROLLER | 769 | #ifdef CONFIG_MEDIA_CONTROLLER |
@@ -726,6 +771,9 @@ struct em28xx { | |||
726 | struct media_entity input_ent[MAX_EM28XX_INPUT]; | 771 | struct media_entity input_ent[MAX_EM28XX_INPUT]; |
727 | struct media_pad input_pad[MAX_EM28XX_INPUT]; | 772 | struct media_pad input_pad[MAX_EM28XX_INPUT]; |
728 | #endif | 773 | #endif |
774 | |||
775 | struct em28xx *dev_next; | ||
776 | int ts; | ||
729 | }; | 777 | }; |
730 | 778 | ||
731 | #define kref_to_dev(d) container_of(d, struct em28xx, ref) | 779 | #define kref_to_dev(d) container_of(d, struct em28xx, ref) |
@@ -734,17 +782,17 @@ struct em28xx_ops { | |||
734 | struct list_head next; | 782 | struct list_head next; |
735 | char *name; | 783 | char *name; |
736 | int id; | 784 | int id; |
737 | int (*init)(struct em28xx *); | 785 | int (*init)(struct em28xx *dev); |
738 | int (*fini)(struct em28xx *); | 786 | int (*fini)(struct em28xx *dev); |
739 | int (*suspend)(struct em28xx *); | 787 | int (*suspend)(struct em28xx *dev); |
740 | int (*resume)(struct em28xx *); | 788 | int (*resume)(struct em28xx *dev); |
741 | }; | 789 | }; |
742 | 790 | ||
743 | /* Provided by em28xx-i2c.c */ | 791 | /* Provided by em28xx-i2c.c */ |
744 | void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus); | 792 | void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus); |
745 | int em28xx_i2c_register(struct em28xx *dev, unsigned bus, | 793 | int em28xx_i2c_register(struct em28xx *dev, unsigned int bus, |
746 | enum em28xx_i2c_algo_type algo_type); | 794 | enum em28xx_i2c_algo_type algo_type); |
747 | int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus); | 795 | int em28xx_i2c_unregister(struct em28xx *dev, unsigned int bus); |
748 | 796 | ||
749 | /* Provided by em28xx-core.c */ | 797 | /* Provided by em28xx-core.c */ |
750 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | 798 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, |
@@ -778,7 +826,7 @@ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, | |||
778 | void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode); | 826 | void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode); |
779 | void em28xx_stop_urbs(struct em28xx *dev); | 827 | void em28xx_stop_urbs(struct em28xx *dev); |
780 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | 828 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); |
781 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | 829 | int em28xx_gpio_set(struct em28xx *dev, const struct em28xx_reg_seq *gpio); |
782 | int em28xx_register_extension(struct em28xx_ops *dev); | 830 | int em28xx_register_extension(struct em28xx_ops *dev); |
783 | void em28xx_unregister_extension(struct em28xx_ops *dev); | 831 | void em28xx_unregister_extension(struct em28xx_ops *dev); |
784 | void em28xx_init_extension(struct em28xx *dev); | 832 | void em28xx_init_extension(struct em28xx *dev); |
@@ -787,7 +835,7 @@ int em28xx_suspend_extension(struct em28xx *dev); | |||
787 | int em28xx_resume_extension(struct em28xx *dev); | 835 | int em28xx_resume_extension(struct em28xx *dev); |
788 | 836 | ||
789 | /* Provided by em28xx-cards.c */ | 837 | /* Provided by em28xx-cards.c */ |
790 | extern struct em28xx_board em28xx_boards[]; | 838 | extern const struct em28xx_board em28xx_boards[]; |
791 | extern struct usb_device_id em28xx_id_table[]; | 839 | extern struct usb_device_id em28xx_id_table[]; |
792 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); | 840 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); |
793 | void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl); | 841 | void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl); |
diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index c618764480c6..f84a2130f033 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c | |||
@@ -227,7 +227,7 @@ int go7007_snd_init(struct go7007 *go) | |||
227 | { | 227 | { |
228 | static int dev; | 228 | static int dev; |
229 | struct go7007_snd *gosnd; | 229 | struct go7007_snd *gosnd; |
230 | int ret = 0; | 230 | int ret; |
231 | 231 | ||
232 | if (dev >= SNDRV_CARDS) | 232 | if (dev >= SNDRV_CARDS) |
233 | return -ENODEV; | 233 | return -ENODEV; |
diff --git a/drivers/media/usb/gspca/dtcs033.c b/drivers/media/usb/gspca/dtcs033.c index cdf27cf0112a..7654c8c08eda 100644 --- a/drivers/media/usb/gspca/dtcs033.c +++ b/drivers/media/usb/gspca/dtcs033.c | |||
@@ -76,12 +76,10 @@ static int reg_reqs(struct gspca_dev *gspca_dev, | |||
76 | } else if (preq->bRequestType & USB_DIR_IN) { | 76 | } else if (preq->bRequestType & USB_DIR_IN) { |
77 | 77 | ||
78 | gspca_dbg(gspca_dev, D_STREAM, | 78 | gspca_dbg(gspca_dev, D_STREAM, |
79 | "USB IN (%d) returned[%d] %02X %02X %02X %s\n", | 79 | "USB IN (%d) returned[%d] %3ph %s", |
80 | i, | 80 | i, |
81 | preq->wLength, | 81 | preq->wLength, |
82 | gspca_dev->usb_buf[0], | 82 | gspca_dev->usb_buf, |
83 | gspca_dev->usb_buf[1], | ||
84 | gspca_dev->usb_buf[2], | ||
85 | preq->wLength > 3 ? "...\n" : "\n"); | 83 | preq->wLength > 3 ? "...\n" : "\n"); |
86 | } | 84 | } |
87 | 85 | ||
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 8c2a86d71e8a..82927eb334c4 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c | |||
@@ -648,8 +648,8 @@ static void s2255_fillbuff(struct s2255_vc *vc, | |||
648 | pr_err("s2255: =======no frame\n"); | 648 | pr_err("s2255: =======no frame\n"); |
649 | return; | 649 | return; |
650 | } | 650 | } |
651 | dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", | 651 | dprintk(dev, 2, "s2255fill at : Buffer %p size= %d\n", |
652 | (unsigned long)vbuf, pos); | 652 | vbuf, pos); |
653 | } | 653 | } |
654 | 654 | ||
655 | 655 | ||
@@ -803,10 +803,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
803 | } | 803 | } |
804 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC) | 804 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC) |
805 | f->fmt.pix.width = LINE_SZ_4CIFS_NTSC; | 805 | f->fmt.pix.width = LINE_SZ_4CIFS_NTSC; |
806 | else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC) | ||
807 | f->fmt.pix.width = LINE_SZ_2CIFS_NTSC; | ||
808 | else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC) | ||
809 | f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; | ||
810 | else | 806 | else |
811 | f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; | 807 | f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; |
812 | } else { | 808 | } else { |
@@ -820,10 +816,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
820 | } | 816 | } |
821 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) | 817 | if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) |
822 | f->fmt.pix.width = LINE_SZ_4CIFS_PAL; | 818 | f->fmt.pix.width = LINE_SZ_4CIFS_PAL; |
823 | else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) | ||
824 | f->fmt.pix.width = LINE_SZ_2CIFS_PAL; | ||
825 | else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) | ||
826 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; | ||
827 | else | 819 | else |
828 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; | 820 | f->fmt.pix.width = LINE_SZ_1CIFS_PAL; |
829 | } | 821 | } |
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index f13e4b01b5a5..6d436e9e454f 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c | |||
@@ -179,8 +179,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev, | |||
179 | smsusb_onresponse, | 179 | smsusb_onresponse, |
180 | surb | 180 | surb |
181 | ); | 181 | ); |
182 | surb->urb.transfer_dma = surb->cb->phys; | 182 | surb->urb.transfer_flags |= URB_FREE_BUFFER; |
183 | surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
184 | 183 | ||
185 | return usb_submit_urb(&surb->urb, GFP_ATOMIC); | 184 | return usb_submit_urb(&surb->urb, GFP_ATOMIC); |
186 | } | 185 | } |
@@ -446,6 +445,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) | |||
446 | dev->in_ep, dev->out_ep); | 445 | dev->in_ep, dev->out_ep); |
447 | 446 | ||
448 | params.device = &dev->udev->dev; | 447 | params.device = &dev->udev->dev; |
448 | params.usb_device = dev->udev; | ||
449 | params.buffer_size = dev->buffer_size; | 449 | params.buffer_size = dev->buffer_size; |
450 | params.num_buffers = MAX_BUFFERS; | 450 | params.num_buffers = MAX_BUFFERS; |
451 | params.sendrequest_handler = smsusb_sendrequest; | 451 | params.sendrequest_handler = smsusb_sendrequest; |
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index 4d5f4cc4887e..70939e96b856 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c | |||
@@ -1174,7 +1174,7 @@ static int tm6000_usb_probe(struct usb_interface *interface, | |||
1174 | { | 1174 | { |
1175 | struct usb_device *usbdev; | 1175 | struct usb_device *usbdev; |
1176 | struct tm6000_core *dev; | 1176 | struct tm6000_core *dev; |
1177 | int i, rc = 0; | 1177 | int i, rc; |
1178 | int nr = 0; | 1178 | int nr = 0; |
1179 | char *speed; | 1179 | char *speed; |
1180 | 1180 | ||
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 8314d3fa9241..b2399d4266da 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c | |||
@@ -1346,9 +1346,8 @@ static int __tm6000_open(struct file *file) | |||
1346 | fh->width = dev->width; | 1346 | fh->width = dev->width; |
1347 | fh->height = dev->height; | 1347 | fh->height = dev->height; |
1348 | 1348 | ||
1349 | dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n", | 1349 | dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=%p, dev=%p, dev->vidq=%p\n", |
1350 | (unsigned long)fh, (unsigned long)dev, | 1350 | fh, dev, &dev->vidq); |
1351 | (unsigned long)&dev->vidq); | ||
1352 | dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty queued=%d\n", | 1351 | dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty queued=%d\n", |
1353 | list_empty(&dev->vidq.queued)); | 1352 | list_empty(&dev->vidq.queued)); |
1354 | dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty active=%d\n", | 1353 | dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty active=%d\n", |
diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index 127f8a0c098b..5095c380b2c1 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c | |||
@@ -112,6 +112,8 @@ static int usbtv_probe(struct usb_interface *intf, | |||
112 | return 0; | 112 | return 0; |
113 | 113 | ||
114 | usbtv_audio_fail: | 114 | usbtv_audio_fail: |
115 | /* we must not free at this point */ | ||
116 | usb_get_dev(usbtv->udev); | ||
115 | usbtv_video_free(usbtv); | 117 | usbtv_video_free(usbtv); |
116 | 118 | ||
117 | usbtv_video_fail: | 119 | usbtv_video_fail: |
@@ -145,6 +147,7 @@ static void usbtv_disconnect(struct usb_interface *intf) | |||
145 | static const struct usb_device_id usbtv_id_table[] = { | 147 | static const struct usb_device_id usbtv_id_table[] = { |
146 | { USB_DEVICE(0x1b71, 0x3002) }, | 148 | { USB_DEVICE(0x1b71, 0x3002) }, |
147 | { USB_DEVICE(0x1f71, 0x3301) }, | 149 | { USB_DEVICE(0x1f71, 0x3301) }, |
150 | { USB_DEVICE(0x1f71, 0x3306) }, | ||
148 | {} | 151 | {} |
149 | }; | 152 | }; |
150 | MODULE_DEVICE_TABLE(usb, usbtv_id_table); | 153 | MODULE_DEVICE_TABLE(usb, usbtv_id_table); |
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 20397aba6849..102594ec3e97 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c | |||
@@ -366,10 +366,10 @@ static struct uvc_menu_info exposure_auto_controls[] = { | |||
366 | { 8, "Aperture Priority Mode" }, | 366 | { 8, "Aperture Priority Mode" }, |
367 | }; | 367 | }; |
368 | 368 | ||
369 | static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, | 369 | static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, |
370 | __u8 query, const __u8 *data) | 370 | u8 query, const u8 *data) |
371 | { | 371 | { |
372 | __s8 zoom = (__s8)data[0]; | 372 | s8 zoom = (s8)data[0]; |
373 | 373 | ||
374 | switch (query) { | 374 | switch (query) { |
375 | case UVC_GET_CUR: | 375 | case UVC_GET_CUR: |
@@ -385,17 +385,17 @@ static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, | |||
385 | } | 385 | } |
386 | 386 | ||
387 | static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping, | 387 | static void uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping, |
388 | __s32 value, __u8 *data) | 388 | s32 value, u8 *data) |
389 | { | 389 | { |
390 | data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; | 390 | data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff; |
391 | data[2] = min((int)abs(value), 0xff); | 391 | data[2] = min((int)abs(value), 0xff); |
392 | } | 392 | } |
393 | 393 | ||
394 | static __s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, | 394 | static s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, |
395 | __u8 query, const __u8 *data) | 395 | u8 query, const u8 *data) |
396 | { | 396 | { |
397 | unsigned int first = mapping->offset / 8; | 397 | unsigned int first = mapping->offset / 8; |
398 | __s8 rel = (__s8)data[first]; | 398 | s8 rel = (s8)data[first]; |
399 | 399 | ||
400 | switch (query) { | 400 | switch (query) { |
401 | case UVC_GET_CUR: | 401 | case UVC_GET_CUR: |
@@ -412,7 +412,7 @@ static __s32 uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping, | |||
412 | } | 412 | } |
413 | 413 | ||
414 | static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping, | 414 | static void uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping, |
415 | __s32 value, __u8 *data) | 415 | s32 value, u8 *data) |
416 | { | 416 | { |
417 | unsigned int first = mapping->offset / 8; | 417 | unsigned int first = mapping->offset / 8; |
418 | 418 | ||
@@ -745,17 +745,17 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { | |||
745 | * Utility functions | 745 | * Utility functions |
746 | */ | 746 | */ |
747 | 747 | ||
748 | static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) | 748 | static inline u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) |
749 | { | 749 | { |
750 | return ctrl->uvc_data + id * ctrl->info.size; | 750 | return ctrl->uvc_data + id * ctrl->info.size; |
751 | } | 751 | } |
752 | 752 | ||
753 | static inline int uvc_test_bit(const __u8 *data, int bit) | 753 | static inline int uvc_test_bit(const u8 *data, int bit) |
754 | { | 754 | { |
755 | return (data[bit >> 3] >> (bit & 7)) & 1; | 755 | return (data[bit >> 3] >> (bit & 7)) & 1; |
756 | } | 756 | } |
757 | 757 | ||
758 | static inline void uvc_clear_bit(__u8 *data, int bit) | 758 | static inline void uvc_clear_bit(u8 *data, int bit) |
759 | { | 759 | { |
760 | data[bit >> 3] &= ~(1 << (bit & 7)); | 760 | data[bit >> 3] &= ~(1 << (bit & 7)); |
761 | } | 761 | } |
@@ -765,20 +765,20 @@ static inline void uvc_clear_bit(__u8 *data, int bit) | |||
765 | * a signed 32bit integer. Sign extension will be performed if the mapping | 765 | * a signed 32bit integer. Sign extension will be performed if the mapping |
766 | * references a signed data type. | 766 | * references a signed data type. |
767 | */ | 767 | */ |
768 | static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, | 768 | static s32 uvc_get_le_value(struct uvc_control_mapping *mapping, |
769 | __u8 query, const __u8 *data) | 769 | u8 query, const u8 *data) |
770 | { | 770 | { |
771 | int bits = mapping->size; | 771 | int bits = mapping->size; |
772 | int offset = mapping->offset; | 772 | int offset = mapping->offset; |
773 | __s32 value = 0; | 773 | s32 value = 0; |
774 | __u8 mask; | 774 | u8 mask; |
775 | 775 | ||
776 | data += offset / 8; | 776 | data += offset / 8; |
777 | offset &= 7; | 777 | offset &= 7; |
778 | mask = ((1LL << bits) - 1) << offset; | 778 | mask = ((1LL << bits) - 1) << offset; |
779 | 779 | ||
780 | for (; bits > 0; data++) { | 780 | for (; bits > 0; data++) { |
781 | __u8 byte = *data & mask; | 781 | u8 byte = *data & mask; |
782 | value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); | 782 | value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); |
783 | bits -= 8 - (offset > 0 ? offset : 0); | 783 | bits -= 8 - (offset > 0 ? offset : 0); |
784 | offset -= 8; | 784 | offset -= 8; |
@@ -796,11 +796,11 @@ static __s32 uvc_get_le_value(struct uvc_control_mapping *mapping, | |||
796 | * in the little-endian data stored at 'data' to the value 'value'. | 796 | * in the little-endian data stored at 'data' to the value 'value'. |
797 | */ | 797 | */ |
798 | static void uvc_set_le_value(struct uvc_control_mapping *mapping, | 798 | static void uvc_set_le_value(struct uvc_control_mapping *mapping, |
799 | __s32 value, __u8 *data) | 799 | s32 value, u8 *data) |
800 | { | 800 | { |
801 | int bits = mapping->size; | 801 | int bits = mapping->size; |
802 | int offset = mapping->offset; | 802 | int offset = mapping->offset; |
803 | __u8 mask; | 803 | u8 mask; |
804 | 804 | ||
805 | /* According to the v4l2 spec, writing any value to a button control | 805 | /* According to the v4l2 spec, writing any value to a button control |
806 | * should result in the action belonging to the button control being | 806 | * should result in the action belonging to the button control being |
@@ -826,13 +826,13 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping, | |||
826 | * Terminal and unit management | 826 | * Terminal and unit management |
827 | */ | 827 | */ |
828 | 828 | ||
829 | static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; | 829 | static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING; |
830 | static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; | 830 | static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA; |
831 | static const __u8 uvc_media_transport_input_guid[16] = | 831 | static const u8 uvc_media_transport_input_guid[16] = |
832 | UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; | 832 | UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT; |
833 | 833 | ||
834 | static int uvc_entity_match_guid(const struct uvc_entity *entity, | 834 | static int uvc_entity_match_guid(const struct uvc_entity *entity, |
835 | const __u8 guid[16]) | 835 | const u8 guid[16]) |
836 | { | 836 | { |
837 | switch (UVC_ENTITY_TYPE(entity)) { | 837 | switch (UVC_ENTITY_TYPE(entity)) { |
838 | case UVC_ITT_CAMERA: | 838 | case UVC_ITT_CAMERA: |
@@ -857,7 +857,7 @@ static int uvc_entity_match_guid(const struct uvc_entity *entity, | |||
857 | * UVC Controls | 857 | * UVC Controls |
858 | */ | 858 | */ |
859 | 859 | ||
860 | static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | 860 | static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id, |
861 | struct uvc_control_mapping **mapping, struct uvc_control **control, | 861 | struct uvc_control_mapping **mapping, struct uvc_control **control, |
862 | int next) | 862 | int next) |
863 | { | 863 | { |
@@ -890,7 +890,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
890 | } | 890 | } |
891 | 891 | ||
892 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | 892 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, |
893 | __u32 v4l2_id, struct uvc_control_mapping **mapping) | 893 | u32 v4l2_id, struct uvc_control_mapping **mapping) |
894 | { | 894 | { |
895 | struct uvc_control *ctrl = NULL; | 895 | struct uvc_control *ctrl = NULL; |
896 | struct uvc_entity *entity; | 896 | struct uvc_entity *entity; |
@@ -1019,10 +1019,10 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
1019 | struct uvc_menu_info *menu; | 1019 | struct uvc_menu_info *menu; |
1020 | unsigned int i; | 1020 | unsigned int i; |
1021 | 1021 | ||
1022 | memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); | 1022 | memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); |
1023 | v4l2_ctrl->id = mapping->id; | 1023 | v4l2_ctrl->id = mapping->id; |
1024 | v4l2_ctrl->type = mapping->v4l2_type; | 1024 | v4l2_ctrl->type = mapping->v4l2_type; |
1025 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); | 1025 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof(v4l2_ctrl->name)); |
1026 | v4l2_ctrl->flags = 0; | 1026 | v4l2_ctrl->flags = 0; |
1027 | 1027 | ||
1028 | if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) | 1028 | if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) |
@@ -1182,7 +1182,7 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | |||
1182 | } | 1182 | } |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | 1185 | strlcpy(query_menu->name, menu_info->name, sizeof(query_menu->name)); |
1186 | 1186 | ||
1187 | done: | 1187 | done: |
1188 | mutex_unlock(&chain->ctrl_mutex); | 1188 | mutex_unlock(&chain->ctrl_mutex); |
@@ -1590,6 +1590,36 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1590 | * Dynamic controls | 1590 | * Dynamic controls |
1591 | */ | 1591 | */ |
1592 | 1592 | ||
1593 | /* | ||
1594 | * Retrieve flags for a given control | ||
1595 | */ | ||
1596 | static int uvc_ctrl_get_flags(struct uvc_device *dev, | ||
1597 | const struct uvc_control *ctrl, | ||
1598 | struct uvc_control_info *info) | ||
1599 | { | ||
1600 | u8 *data; | ||
1601 | int ret; | ||
1602 | |||
1603 | data = kmalloc(1, GFP_KERNEL); | ||
1604 | if (data == NULL) | ||
1605 | return -ENOMEM; | ||
1606 | |||
1607 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, | ||
1608 | info->selector, data, 1); | ||
1609 | if (!ret) | ||
1610 | info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX | ||
1611 | | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF | ||
1612 | | (data[0] & UVC_CONTROL_CAP_GET ? | ||
1613 | UVC_CTRL_FLAG_GET_CUR : 0) | ||
1614 | | (data[0] & UVC_CONTROL_CAP_SET ? | ||
1615 | UVC_CTRL_FLAG_SET_CUR : 0) | ||
1616 | | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? | ||
1617 | UVC_CTRL_FLAG_AUTO_UPDATE : 0); | ||
1618 | |||
1619 | kfree(data); | ||
1620 | return ret; | ||
1621 | } | ||
1622 | |||
1593 | static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev, | 1623 | static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev, |
1594 | const struct uvc_control *ctrl, struct uvc_control_info *info) | 1624 | const struct uvc_control *ctrl, struct uvc_control_info *info) |
1595 | { | 1625 | { |
@@ -1659,25 +1689,14 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev, | |||
1659 | 1689 | ||
1660 | info->size = le16_to_cpup((__le16 *)data); | 1690 | info->size = le16_to_cpup((__le16 *)data); |
1661 | 1691 | ||
1662 | /* Query the control information (GET_INFO) */ | 1692 | ret = uvc_ctrl_get_flags(dev, ctrl, info); |
1663 | ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, | ||
1664 | info->selector, data, 1); | ||
1665 | if (ret < 0) { | 1693 | if (ret < 0) { |
1666 | uvc_trace(UVC_TRACE_CONTROL, | 1694 | uvc_trace(UVC_TRACE_CONTROL, |
1667 | "GET_INFO failed on control %pUl/%u (%d).\n", | 1695 | "Failed to get flags for control %pUl/%u (%d).\n", |
1668 | info->entity, info->selector, ret); | 1696 | info->entity, info->selector, ret); |
1669 | goto done; | 1697 | goto done; |
1670 | } | 1698 | } |
1671 | 1699 | ||
1672 | info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX | ||
1673 | | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF | ||
1674 | | (data[0] & UVC_CONTROL_CAP_GET ? | ||
1675 | UVC_CTRL_FLAG_GET_CUR : 0) | ||
1676 | | (data[0] & UVC_CONTROL_CAP_SET ? | ||
1677 | UVC_CTRL_FLAG_SET_CUR : 0) | ||
1678 | | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ? | ||
1679 | UVC_CTRL_FLAG_AUTO_UPDATE : 0); | ||
1680 | |||
1681 | uvc_ctrl_fixup_xu_info(dev, ctrl, info); | 1700 | uvc_ctrl_fixup_xu_info(dev, ctrl, info); |
1682 | 1701 | ||
1683 | uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " | 1702 | uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, " |
@@ -1723,9 +1742,9 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1723 | struct uvc_entity *entity; | 1742 | struct uvc_entity *entity; |
1724 | struct uvc_control *ctrl; | 1743 | struct uvc_control *ctrl; |
1725 | unsigned int i, found = 0; | 1744 | unsigned int i, found = 0; |
1726 | __u32 reqflags; | 1745 | u32 reqflags; |
1727 | __u16 size; | 1746 | u16 size; |
1728 | __u8 *data = NULL; | 1747 | u8 *data = NULL; |
1729 | int ret; | 1748 | int ret; |
1730 | 1749 | ||
1731 | /* Find the extension unit. */ | 1750 | /* Find the extension unit. */ |
@@ -1902,6 +1921,13 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, | |||
1902 | goto done; | 1921 | goto done; |
1903 | } | 1922 | } |
1904 | 1923 | ||
1924 | /* | ||
1925 | * Retrieve control flags from the device. Ignore errors and work with | ||
1926 | * default flag values from the uvc_ctrl array when the device doesn't | ||
1927 | * properly implement GET_INFO on standard controls. | ||
1928 | */ | ||
1929 | uvc_ctrl_get_flags(dev, ctrl, &ctrl->info); | ||
1930 | |||
1905 | ctrl->initialized = 1; | 1931 | ctrl->initialized = 1; |
1906 | 1932 | ||
1907 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " | 1933 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " |
@@ -2150,7 +2176,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) | |||
2150 | list_for_each_entry(entity, &dev->entities, list) { | 2176 | list_for_each_entry(entity, &dev->entities, list) { |
2151 | struct uvc_control *ctrl; | 2177 | struct uvc_control *ctrl; |
2152 | unsigned int bControlSize = 0, ncontrols; | 2178 | unsigned int bControlSize = 0, ncontrols; |
2153 | __u8 *bmControls = NULL; | 2179 | u8 *bmControls = NULL; |
2154 | 2180 | ||
2155 | if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { | 2181 | if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { |
2156 | bmControls = entity->extension.bmControls; | 2182 | bmControls = entity->extension.bmControls; |
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index fd387bf3f02d..2469b49b2b30 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c | |||
@@ -216,7 +216,7 @@ static struct uvc_format_desc uvc_fmts[] = { | |||
216 | */ | 216 | */ |
217 | 217 | ||
218 | struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, | 218 | struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, |
219 | __u8 epaddr) | 219 | u8 epaddr) |
220 | { | 220 | { |
221 | struct usb_host_endpoint *ep; | 221 | struct usb_host_endpoint *ep; |
222 | unsigned int i; | 222 | unsigned int i; |
@@ -230,7 +230,7 @@ struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, | |||
230 | return NULL; | 230 | return NULL; |
231 | } | 231 | } |
232 | 232 | ||
233 | static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16]) | 233 | static struct uvc_format_desc *uvc_format_by_guid(const u8 guid[16]) |
234 | { | 234 | { |
235 | unsigned int len = ARRAY_SIZE(uvc_fmts); | 235 | unsigned int len = ARRAY_SIZE(uvc_fmts); |
236 | unsigned int i; | 236 | unsigned int i; |
@@ -243,9 +243,9 @@ static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16]) | |||
243 | return NULL; | 243 | return NULL; |
244 | } | 244 | } |
245 | 245 | ||
246 | static __u32 uvc_colorspace(const __u8 primaries) | 246 | static u32 uvc_colorspace(const u8 primaries) |
247 | { | 247 | { |
248 | static const __u8 colorprimaries[] = { | 248 | static const u8 colorprimaries[] = { |
249 | 0, | 249 | 0, |
250 | V4L2_COLORSPACE_SRGB, | 250 | V4L2_COLORSPACE_SRGB, |
251 | V4L2_COLORSPACE_470_SYSTEM_M, | 251 | V4L2_COLORSPACE_470_SYSTEM_M, |
@@ -267,14 +267,14 @@ static __u32 uvc_colorspace(const __u8 primaries) | |||
267 | * continued fraction decomposition. Using 8 and 333 for n_terms and threshold | 267 | * continued fraction decomposition. Using 8 and 333 for n_terms and threshold |
268 | * respectively seems to give nice results. | 268 | * respectively seems to give nice results. |
269 | */ | 269 | */ |
270 | void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, | 270 | void uvc_simplify_fraction(u32 *numerator, u32 *denominator, |
271 | unsigned int n_terms, unsigned int threshold) | 271 | unsigned int n_terms, unsigned int threshold) |
272 | { | 272 | { |
273 | uint32_t *an; | 273 | u32 *an; |
274 | uint32_t x, y, r; | 274 | u32 x, y, r; |
275 | unsigned int i, n; | 275 | unsigned int i, n; |
276 | 276 | ||
277 | an = kmalloc(n_terms * sizeof *an, GFP_KERNEL); | 277 | an = kmalloc_array(n_terms, sizeof(*an), GFP_KERNEL); |
278 | if (an == NULL) | 278 | if (an == NULL) |
279 | return; | 279 | return; |
280 | 280 | ||
@@ -318,21 +318,21 @@ void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, | |||
318 | * to compute numerator / denominator * 10000000 using 32 bit fixed point | 318 | * to compute numerator / denominator * 10000000 using 32 bit fixed point |
319 | * arithmetic only. | 319 | * arithmetic only. |
320 | */ | 320 | */ |
321 | uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator) | 321 | u32 uvc_fraction_to_interval(u32 numerator, u32 denominator) |
322 | { | 322 | { |
323 | uint32_t multiplier; | 323 | u32 multiplier; |
324 | 324 | ||
325 | /* Saturate the result if the operation would overflow. */ | 325 | /* Saturate the result if the operation would overflow. */ |
326 | if (denominator == 0 || | 326 | if (denominator == 0 || |
327 | numerator/denominator >= ((uint32_t)-1)/10000000) | 327 | numerator/denominator >= ((u32)-1)/10000000) |
328 | return (uint32_t)-1; | 328 | return (u32)-1; |
329 | 329 | ||
330 | /* Divide both the denominator and the multiplier by two until | 330 | /* Divide both the denominator and the multiplier by two until |
331 | * numerator * multiplier doesn't overflow. If anyone knows a better | 331 | * numerator * multiplier doesn't overflow. If anyone knows a better |
332 | * algorithm please let me know. | 332 | * algorithm please let me know. |
333 | */ | 333 | */ |
334 | multiplier = 10000000; | 334 | multiplier = 10000000; |
335 | while (numerator > ((uint32_t)-1)/multiplier) { | 335 | while (numerator > ((u32)-1)/multiplier) { |
336 | multiplier /= 2; | 336 | multiplier /= 2; |
337 | denominator /= 2; | 337 | denominator /= 2; |
338 | } | 338 | } |
@@ -391,7 +391,7 @@ static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id) | |||
391 | 391 | ||
392 | static int uvc_parse_format(struct uvc_device *dev, | 392 | static int uvc_parse_format(struct uvc_device *dev, |
393 | struct uvc_streaming *streaming, struct uvc_format *format, | 393 | struct uvc_streaming *streaming, struct uvc_format *format, |
394 | __u32 **intervals, unsigned char *buffer, int buflen) | 394 | u32 **intervals, unsigned char *buffer, int buflen) |
395 | { | 395 | { |
396 | struct usb_interface *intf = streaming->intf; | 396 | struct usb_interface *intf = streaming->intf; |
397 | struct usb_host_interface *alts = intf->cur_altsetting; | 397 | struct usb_host_interface *alts = intf->cur_altsetting; |
@@ -401,7 +401,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
401 | unsigned int width_multiplier = 1; | 401 | unsigned int width_multiplier = 1; |
402 | unsigned int interval; | 402 | unsigned int interval; |
403 | unsigned int i, n; | 403 | unsigned int i, n; |
404 | __u8 ftype; | 404 | u8 ftype; |
405 | 405 | ||
406 | format->type = buffer[2]; | 406 | format->type = buffer[2]; |
407 | format->index = buffer[3]; | 407 | format->index = buffer[3]; |
@@ -423,7 +423,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
423 | 423 | ||
424 | if (fmtdesc != NULL) { | 424 | if (fmtdesc != NULL) { |
425 | strlcpy(format->name, fmtdesc->name, | 425 | strlcpy(format->name, fmtdesc->name, |
426 | sizeof format->name); | 426 | sizeof(format->name)); |
427 | format->fcc = fmtdesc->fcc; | 427 | format->fcc = fmtdesc->fcc; |
428 | } else { | 428 | } else { |
429 | uvc_printk(KERN_INFO, "Unknown video format %pUl\n", | 429 | uvc_printk(KERN_INFO, "Unknown video format %pUl\n", |
@@ -466,7 +466,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
466 | return -EINVAL; | 466 | return -EINVAL; |
467 | } | 467 | } |
468 | 468 | ||
469 | strlcpy(format->name, "MJPEG", sizeof format->name); | 469 | strlcpy(format->name, "MJPEG", sizeof(format->name)); |
470 | format->fcc = V4L2_PIX_FMT_MJPEG; | 470 | format->fcc = V4L2_PIX_FMT_MJPEG; |
471 | format->flags = UVC_FMT_FLAG_COMPRESSED; | 471 | format->flags = UVC_FMT_FLAG_COMPRESSED; |
472 | format->bpp = 0; | 472 | format->bpp = 0; |
@@ -484,13 +484,13 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
484 | 484 | ||
485 | switch (buffer[8] & 0x7f) { | 485 | switch (buffer[8] & 0x7f) { |
486 | case 0: | 486 | case 0: |
487 | strlcpy(format->name, "SD-DV", sizeof format->name); | 487 | strlcpy(format->name, "SD-DV", sizeof(format->name)); |
488 | break; | 488 | break; |
489 | case 1: | 489 | case 1: |
490 | strlcpy(format->name, "SDL-DV", sizeof format->name); | 490 | strlcpy(format->name, "SDL-DV", sizeof(format->name)); |
491 | break; | 491 | break; |
492 | case 2: | 492 | case 2: |
493 | strlcpy(format->name, "HD-DV", sizeof format->name); | 493 | strlcpy(format->name, "HD-DV", sizeof(format->name)); |
494 | break; | 494 | break; |
495 | default: | 495 | default: |
496 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " | 496 | uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " |
@@ -501,7 +501,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
501 | } | 501 | } |
502 | 502 | ||
503 | strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", | 503 | strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", |
504 | sizeof format->name); | 504 | sizeof(format->name)); |
505 | 505 | ||
506 | format->fcc = V4L2_PIX_FMT_DV; | 506 | format->fcc = V4L2_PIX_FMT_DV; |
507 | format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; | 507 | format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; |
@@ -510,7 +510,7 @@ static int uvc_parse_format(struct uvc_device *dev, | |||
510 | 510 | ||
511 | /* Create a dummy frame descriptor. */ | 511 | /* Create a dummy frame descriptor. */ |
512 | frame = &format->frame[0]; | 512 | frame = &format->frame[0]; |
513 | memset(&format->frame[0], 0, sizeof format->frame[0]); | 513 | memset(&format->frame[0], 0, sizeof(format->frame[0])); |
514 | frame->bFrameIntervalType = 1; | 514 | frame->bFrameIntervalType = 1; |
515 | frame->dwDefaultFrameInterval = 1; | 515 | frame->dwDefaultFrameInterval = 1; |
516 | frame->dwFrameInterval = *intervals; | 516 | frame->dwFrameInterval = *intervals; |
@@ -658,8 +658,8 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
658 | int _buflen, buflen = alts->extralen; | 658 | int _buflen, buflen = alts->extralen; |
659 | unsigned int nformats = 0, nframes = 0, nintervals = 0; | 659 | unsigned int nformats = 0, nframes = 0, nintervals = 0; |
660 | unsigned int size, i, n, p; | 660 | unsigned int size, i, n, p; |
661 | __u32 *interval; | 661 | u32 *interval; |
662 | __u16 psize; | 662 | u16 psize; |
663 | int ret = -EINVAL; | 663 | int ret = -EINVAL; |
664 | 664 | ||
665 | if (intf->cur_altsetting->desc.bInterfaceSubClass | 665 | if (intf->cur_altsetting->desc.bInterfaceSubClass |
@@ -677,7 +677,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
677 | return -EINVAL; | 677 | return -EINVAL; |
678 | } | 678 | } |
679 | 679 | ||
680 | streaming = kzalloc(sizeof *streaming, GFP_KERNEL); | 680 | streaming = kzalloc(sizeof(*streaming), GFP_KERNEL); |
681 | if (streaming == NULL) { | 681 | if (streaming == NULL) { |
682 | usb_driver_release_interface(&uvc_driver.driver, intf); | 682 | usb_driver_release_interface(&uvc_driver.driver, intf); |
683 | return -EINVAL; | 683 | return -EINVAL; |
@@ -827,8 +827,8 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
827 | goto error; | 827 | goto error; |
828 | } | 828 | } |
829 | 829 | ||
830 | size = nformats * sizeof *format + nframes * sizeof *frame | 830 | size = nformats * sizeof(*format) + nframes * sizeof(*frame) |
831 | + nintervals * sizeof *interval; | 831 | + nintervals * sizeof(*interval); |
832 | format = kzalloc(size, GFP_KERNEL); | 832 | format = kzalloc(size, GFP_KERNEL); |
833 | if (format == NULL) { | 833 | if (format == NULL) { |
834 | ret = -ENOMEM; | 834 | ret = -ENOMEM; |
@@ -836,7 +836,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, | |||
836 | } | 836 | } |
837 | 837 | ||
838 | frame = (struct uvc_frame *)&format[nformats]; | 838 | frame = (struct uvc_frame *)&format[nformats]; |
839 | interval = (__u32 *)&frame[nframes]; | 839 | interval = (u32 *)&frame[nframes]; |
840 | 840 | ||
841 | streaming->format = format; | 841 | streaming->format = format; |
842 | streaming->nformats = nformats; | 842 | streaming->nformats = nformats; |
@@ -930,7 +930,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id, | |||
930 | entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; | 930 | entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; |
931 | 931 | ||
932 | entity->bNrInPins = num_inputs; | 932 | entity->bNrInPins = num_inputs; |
933 | entity->baSourceID = (__u8 *)(&entity->pads[num_pads]); | 933 | entity->baSourceID = (u8 *)(&entity->pads[num_pads]); |
934 | 934 | ||
935 | return entity; | 935 | return entity; |
936 | } | 936 | } |
@@ -995,14 +995,14 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, | |||
995 | unit->extension.bNumControls = buffer[20]; | 995 | unit->extension.bNumControls = buffer[20]; |
996 | memcpy(unit->baSourceID, &buffer[22], p); | 996 | memcpy(unit->baSourceID, &buffer[22], p); |
997 | unit->extension.bControlSize = buffer[22+p]; | 997 | unit->extension.bControlSize = buffer[22+p]; |
998 | unit->extension.bmControls = (__u8 *)unit + sizeof(*unit); | 998 | unit->extension.bmControls = (u8 *)unit + sizeof(*unit); |
999 | unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit) | 999 | unit->extension.bmControlsType = (u8 *)unit + sizeof(*unit) |
1000 | + n; | 1000 | + n; |
1001 | memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); | 1001 | memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); |
1002 | 1002 | ||
1003 | if (buffer[24+p+2*n] != 0) | 1003 | if (buffer[24+p+2*n] != 0) |
1004 | usb_string(udev, buffer[24+p+2*n], unit->name, | 1004 | usb_string(udev, buffer[24+p+2*n], unit->name, |
1005 | sizeof unit->name); | 1005 | sizeof(unit->name)); |
1006 | else | 1006 | else |
1007 | sprintf(unit->name, "Extension %u", buffer[3]); | 1007 | sprintf(unit->name, "Extension %u", buffer[3]); |
1008 | 1008 | ||
@@ -1022,7 +1022,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1022 | struct usb_interface *intf; | 1022 | struct usb_interface *intf; |
1023 | struct usb_host_interface *alts = dev->intf->cur_altsetting; | 1023 | struct usb_host_interface *alts = dev->intf->cur_altsetting; |
1024 | unsigned int i, n, p, len; | 1024 | unsigned int i, n, p, len; |
1025 | __u16 type; | 1025 | u16 type; |
1026 | 1026 | ||
1027 | switch (buffer[2]) { | 1027 | switch (buffer[2]) { |
1028 | case UVC_VC_HEADER: | 1028 | case UVC_VC_HEADER: |
@@ -1101,7 +1101,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1101 | 1101 | ||
1102 | if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { | 1102 | if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { |
1103 | term->camera.bControlSize = n; | 1103 | term->camera.bControlSize = n; |
1104 | term->camera.bmControls = (__u8 *)term + sizeof *term; | 1104 | term->camera.bmControls = (u8 *)term + sizeof(*term); |
1105 | term->camera.wObjectiveFocalLengthMin = | 1105 | term->camera.wObjectiveFocalLengthMin = |
1106 | get_unaligned_le16(&buffer[8]); | 1106 | get_unaligned_le16(&buffer[8]); |
1107 | term->camera.wObjectiveFocalLengthMax = | 1107 | term->camera.wObjectiveFocalLengthMax = |
@@ -1112,17 +1112,17 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1112 | } else if (UVC_ENTITY_TYPE(term) == | 1112 | } else if (UVC_ENTITY_TYPE(term) == |
1113 | UVC_ITT_MEDIA_TRANSPORT_INPUT) { | 1113 | UVC_ITT_MEDIA_TRANSPORT_INPUT) { |
1114 | term->media.bControlSize = n; | 1114 | term->media.bControlSize = n; |
1115 | term->media.bmControls = (__u8 *)term + sizeof *term; | 1115 | term->media.bmControls = (u8 *)term + sizeof(*term); |
1116 | term->media.bTransportModeSize = p; | 1116 | term->media.bTransportModeSize = p; |
1117 | term->media.bmTransportModes = (__u8 *)term | 1117 | term->media.bmTransportModes = (u8 *)term |
1118 | + sizeof *term + n; | 1118 | + sizeof(*term) + n; |
1119 | memcpy(term->media.bmControls, &buffer[9], n); | 1119 | memcpy(term->media.bmControls, &buffer[9], n); |
1120 | memcpy(term->media.bmTransportModes, &buffer[10+n], p); | 1120 | memcpy(term->media.bmTransportModes, &buffer[10+n], p); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if (buffer[7] != 0) | 1123 | if (buffer[7] != 0) |
1124 | usb_string(udev, buffer[7], term->name, | 1124 | usb_string(udev, buffer[7], term->name, |
1125 | sizeof term->name); | 1125 | sizeof(term->name)); |
1126 | else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) | 1126 | else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) |
1127 | sprintf(term->name, "Camera %u", buffer[3]); | 1127 | sprintf(term->name, "Camera %u", buffer[3]); |
1128 | else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) | 1128 | else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) |
@@ -1162,7 +1162,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1162 | 1162 | ||
1163 | if (buffer[8] != 0) | 1163 | if (buffer[8] != 0) |
1164 | usb_string(udev, buffer[8], term->name, | 1164 | usb_string(udev, buffer[8], term->name, |
1165 | sizeof term->name); | 1165 | sizeof(term->name)); |
1166 | else | 1166 | else |
1167 | sprintf(term->name, "Output %u", buffer[3]); | 1167 | sprintf(term->name, "Output %u", buffer[3]); |
1168 | 1168 | ||
@@ -1187,7 +1187,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1187 | 1187 | ||
1188 | if (buffer[5+p] != 0) | 1188 | if (buffer[5+p] != 0) |
1189 | usb_string(udev, buffer[5+p], unit->name, | 1189 | usb_string(udev, buffer[5+p], unit->name, |
1190 | sizeof unit->name); | 1190 | sizeof(unit->name)); |
1191 | else | 1191 | else |
1192 | sprintf(unit->name, "Selector %u", buffer[3]); | 1192 | sprintf(unit->name, "Selector %u", buffer[3]); |
1193 | 1193 | ||
@@ -1213,14 +1213,14 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1213 | unit->processing.wMaxMultiplier = | 1213 | unit->processing.wMaxMultiplier = |
1214 | get_unaligned_le16(&buffer[5]); | 1214 | get_unaligned_le16(&buffer[5]); |
1215 | unit->processing.bControlSize = buffer[7]; | 1215 | unit->processing.bControlSize = buffer[7]; |
1216 | unit->processing.bmControls = (__u8 *)unit + sizeof *unit; | 1216 | unit->processing.bmControls = (u8 *)unit + sizeof(*unit); |
1217 | memcpy(unit->processing.bmControls, &buffer[8], n); | 1217 | memcpy(unit->processing.bmControls, &buffer[8], n); |
1218 | if (dev->uvc_version >= 0x0110) | 1218 | if (dev->uvc_version >= 0x0110) |
1219 | unit->processing.bmVideoStandards = buffer[9+n]; | 1219 | unit->processing.bmVideoStandards = buffer[9+n]; |
1220 | 1220 | ||
1221 | if (buffer[8+n] != 0) | 1221 | if (buffer[8+n] != 0) |
1222 | usb_string(udev, buffer[8+n], unit->name, | 1222 | usb_string(udev, buffer[8+n], unit->name, |
1223 | sizeof unit->name); | 1223 | sizeof(unit->name)); |
1224 | else | 1224 | else |
1225 | sprintf(unit->name, "Processing %u", buffer[3]); | 1225 | sprintf(unit->name, "Processing %u", buffer[3]); |
1226 | 1226 | ||
@@ -1246,12 +1246,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev, | |||
1246 | unit->extension.bNumControls = buffer[20]; | 1246 | unit->extension.bNumControls = buffer[20]; |
1247 | memcpy(unit->baSourceID, &buffer[22], p); | 1247 | memcpy(unit->baSourceID, &buffer[22], p); |
1248 | unit->extension.bControlSize = buffer[22+p]; | 1248 | unit->extension.bControlSize = buffer[22+p]; |
1249 | unit->extension.bmControls = (__u8 *)unit + sizeof *unit; | 1249 | unit->extension.bmControls = (u8 *)unit + sizeof(*unit); |
1250 | memcpy(unit->extension.bmControls, &buffer[23+p], n); | 1250 | memcpy(unit->extension.bmControls, &buffer[23+p], n); |
1251 | 1251 | ||
1252 | if (buffer[23+p+n] != 0) | 1252 | if (buffer[23+p+n] != 0) |
1253 | usb_string(udev, buffer[23+p+n], unit->name, | 1253 | usb_string(udev, buffer[23+p+n], unit->name, |
1254 | sizeof unit->name); | 1254 | sizeof(unit->name)); |
1255 | else | 1255 | else |
1256 | sprintf(unit->name, "Extension %u", buffer[3]); | 1256 | sprintf(unit->name, "Extension %u", buffer[3]); |
1257 | 1257 | ||
@@ -1936,7 +1936,7 @@ int uvc_register_video_device(struct uvc_device *dev, | |||
1936 | break; | 1936 | break; |
1937 | } | 1937 | } |
1938 | 1938 | ||
1939 | strlcpy(vdev->name, dev->name, sizeof vdev->name); | 1939 | strlcpy(vdev->name, dev->name, sizeof(vdev->name)); |
1940 | 1940 | ||
1941 | /* | 1941 | /* |
1942 | * Set the driver data before calling video_register_device, otherwise | 1942 | * Set the driver data before calling video_register_device, otherwise |
@@ -2070,7 +2070,8 @@ static int uvc_probe(struct usb_interface *intf, | |||
2070 | udev->devpath); | 2070 | udev->devpath); |
2071 | 2071 | ||
2072 | /* Allocate memory for the device and initialize it. */ | 2072 | /* Allocate memory for the device and initialize it. */ |
2073 | if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL) | 2073 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
2074 | if (dev == NULL) | ||
2074 | return -ENOMEM; | 2075 | return -ENOMEM; |
2075 | 2076 | ||
2076 | INIT_LIST_HEAD(&dev->entities); | 2077 | INIT_LIST_HEAD(&dev->entities); |
@@ -2089,9 +2090,9 @@ static int uvc_probe(struct usb_interface *intf, | |||
2089 | dev->meta_format = info->meta_format; | 2090 | dev->meta_format = info->meta_format; |
2090 | 2091 | ||
2091 | if (udev->product != NULL) | 2092 | if (udev->product != NULL) |
2092 | strlcpy(dev->name, udev->product, sizeof dev->name); | 2093 | strlcpy(dev->name, udev->product, sizeof(dev->name)); |
2093 | else | 2094 | else |
2094 | snprintf(dev->name, sizeof dev->name, | 2095 | snprintf(dev->name, sizeof(dev->name), |
2095 | "UVC Camera (%04x:%04x)", | 2096 | "UVC Camera (%04x:%04x)", |
2096 | le16_to_cpu(udev->descriptor.idVendor), | 2097 | le16_to_cpu(udev->descriptor.idVendor), |
2097 | le16_to_cpu(udev->descriptor.idProduct)); | 2098 | le16_to_cpu(udev->descriptor.idProduct)); |
diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c index 5059fbf41020..81e6f2187bfb 100644 --- a/drivers/media/usb/uvc/uvc_isight.c +++ b/drivers/media/usb/uvc/uvc_isight.c | |||
@@ -37,16 +37,16 @@ | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, | 39 | static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, |
40 | const __u8 *data, unsigned int len) | 40 | const u8 *data, unsigned int len) |
41 | { | 41 | { |
42 | static const __u8 hdr[] = { | 42 | static const u8 hdr[] = { |
43 | 0x11, 0x22, 0x33, 0x44, | 43 | 0x11, 0x22, 0x33, 0x44, |
44 | 0xde, 0xad, 0xbe, 0xef, | 44 | 0xde, 0xad, 0xbe, 0xef, |
45 | 0xde, 0xad, 0xfa, 0xce | 45 | 0xde, 0xad, 0xfa, 0xce |
46 | }; | 46 | }; |
47 | 47 | ||
48 | unsigned int maxlen, nbytes; | 48 | unsigned int maxlen, nbytes; |
49 | __u8 *mem; | 49 | u8 *mem; |
50 | int is_header = 0; | 50 | int is_header = 0; |
51 | 51 | ||
52 | if (buf == NULL) | 52 | if (buf == NULL) |
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index 1ef20e74b7ac..7b710410584a 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c | |||
@@ -78,7 +78,7 @@ static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, | |||
78 | /* -------------------------------------------------------------------------- | 78 | /* -------------------------------------------------------------------------- |
79 | * Status interrupt endpoint | 79 | * Status interrupt endpoint |
80 | */ | 80 | */ |
81 | static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) | 81 | static void uvc_event_streaming(struct uvc_device *dev, u8 *data, int len) |
82 | { | 82 | { |
83 | if (len < 3) { | 83 | if (len < 3) { |
84 | uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " | 84 | uvc_trace(UVC_TRACE_STATUS, "Invalid streaming status event " |
@@ -99,7 +99,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | static void uvc_event_control(struct uvc_device *dev, __u8 *data, int len) | 102 | static void uvc_event_control(struct uvc_device *dev, u8 *data, int len) |
103 | { | 103 | { |
104 | char *attrs[3] = { "value", "info", "failure" }; | 104 | char *attrs[3] = { "value", "info", "failure" }; |
105 | 105 | ||
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index a13ad4e178be..bd32914259ae 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c | |||
@@ -40,13 +40,13 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, | |||
40 | unsigned int size; | 40 | unsigned int size; |
41 | int ret; | 41 | int ret; |
42 | 42 | ||
43 | map = kzalloc(sizeof *map, GFP_KERNEL); | 43 | map = kzalloc(sizeof(*map), GFP_KERNEL); |
44 | if (map == NULL) | 44 | if (map == NULL) |
45 | return -ENOMEM; | 45 | return -ENOMEM; |
46 | 46 | ||
47 | map->id = xmap->id; | 47 | map->id = xmap->id; |
48 | memcpy(map->name, xmap->name, sizeof map->name); | 48 | memcpy(map->name, xmap->name, sizeof(map->name)); |
49 | memcpy(map->entity, xmap->entity, sizeof map->entity); | 49 | memcpy(map->entity, xmap->entity, sizeof(map->entity)); |
50 | map->selector = xmap->selector; | 50 | map->selector = xmap->selector; |
51 | map->size = xmap->size; | 51 | map->size = xmap->size; |
52 | map->offset = xmap->offset; | 52 | map->offset = xmap->offset; |
@@ -105,12 +105,12 @@ free_map: | |||
105 | * the Video Probe and Commit negotiation, but some hardware don't implement | 105 | * the Video Probe and Commit negotiation, but some hardware don't implement |
106 | * that feature. | 106 | * that feature. |
107 | */ | 107 | */ |
108 | static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) | 108 | static u32 uvc_try_frame_interval(struct uvc_frame *frame, u32 interval) |
109 | { | 109 | { |
110 | unsigned int i; | 110 | unsigned int i; |
111 | 111 | ||
112 | if (frame->bFrameIntervalType) { | 112 | if (frame->bFrameIntervalType) { |
113 | __u32 best = -1, dist; | 113 | u32 best = -1, dist; |
114 | 114 | ||
115 | for (i = 0; i < frame->bFrameIntervalType; ++i) { | 115 | for (i = 0; i < frame->bFrameIntervalType; ++i) { |
116 | dist = interval > frame->dwFrameInterval[i] | 116 | dist = interval > frame->dwFrameInterval[i] |
@@ -125,9 +125,9 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) | |||
125 | 125 | ||
126 | interval = frame->dwFrameInterval[i-1]; | 126 | interval = frame->dwFrameInterval[i-1]; |
127 | } else { | 127 | } else { |
128 | const __u32 min = frame->dwFrameInterval[0]; | 128 | const u32 min = frame->dwFrameInterval[0]; |
129 | const __u32 max = frame->dwFrameInterval[1]; | 129 | const u32 max = frame->dwFrameInterval[1]; |
130 | const __u32 step = frame->dwFrameInterval[2]; | 130 | const u32 step = frame->dwFrameInterval[2]; |
131 | 131 | ||
132 | interval = min + (interval - min + step/2) / step * step; | 132 | interval = min + (interval - min + step/2) / step * step; |
133 | if (interval > max) | 133 | if (interval > max) |
@@ -137,7 +137,7 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval) | |||
137 | return interval; | 137 | return interval; |
138 | } | 138 | } |
139 | 139 | ||
140 | static __u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format, | 140 | static u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format, |
141 | const struct uvc_frame *frame) | 141 | const struct uvc_frame *frame) |
142 | { | 142 | { |
143 | switch (format->fcc) { | 143 | switch (format->fcc) { |
@@ -158,17 +158,17 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
158 | { | 158 | { |
159 | struct uvc_format *format = NULL; | 159 | struct uvc_format *format = NULL; |
160 | struct uvc_frame *frame = NULL; | 160 | struct uvc_frame *frame = NULL; |
161 | __u16 rw, rh; | 161 | u16 rw, rh; |
162 | unsigned int d, maxd; | 162 | unsigned int d, maxd; |
163 | unsigned int i; | 163 | unsigned int i; |
164 | __u32 interval; | 164 | u32 interval; |
165 | int ret = 0; | 165 | int ret = 0; |
166 | __u8 *fcc; | 166 | u8 *fcc; |
167 | 167 | ||
168 | if (fmt->type != stream->type) | 168 | if (fmt->type != stream->type) |
169 | return -EINVAL; | 169 | return -EINVAL; |
170 | 170 | ||
171 | fcc = (__u8 *)&fmt->fmt.pix.pixelformat; | 171 | fcc = (u8 *)&fmt->fmt.pix.pixelformat; |
172 | uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n", | 172 | uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n", |
173 | fmt->fmt.pix.pixelformat, | 173 | fmt->fmt.pix.pixelformat, |
174 | fcc[0], fcc[1], fcc[2], fcc[3], | 174 | fcc[0], fcc[1], fcc[2], fcc[3], |
@@ -197,8 +197,8 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
197 | maxd = (unsigned int)-1; | 197 | maxd = (unsigned int)-1; |
198 | 198 | ||
199 | for (i = 0; i < format->nframes; ++i) { | 199 | for (i = 0; i < format->nframes; ++i) { |
200 | __u16 w = format->frame[i].wWidth; | 200 | u16 w = format->frame[i].wWidth; |
201 | __u16 h = format->frame[i].wHeight; | 201 | u16 h = format->frame[i].wHeight; |
202 | 202 | ||
203 | d = min(w, rw) * min(h, rh); | 203 | d = min(w, rw) * min(h, rh); |
204 | d = w*h + rw*rh - 2*d; | 204 | d = w*h + rw*rh - 2*d; |
@@ -224,7 +224,7 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
224 | (100000000/interval)%10); | 224 | (100000000/interval)%10); |
225 | 225 | ||
226 | /* Set the format index, frame index and frame interval. */ | 226 | /* Set the format index, frame index and frame interval. */ |
227 | memset(probe, 0, sizeof *probe); | 227 | memset(probe, 0, sizeof(*probe)); |
228 | probe->bmHint = 1; /* dwFrameInterval */ | 228 | probe->bmHint = 1; /* dwFrameInterval */ |
229 | probe->bFormatIndex = format->index; | 229 | probe->bFormatIndex = format->index; |
230 | probe->bFrameIndex = frame->bFrameIndex; | 230 | probe->bFrameIndex = frame->bFrameIndex; |
@@ -336,7 +336,7 @@ done: | |||
336 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | 336 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, |
337 | struct v4l2_streamparm *parm) | 337 | struct v4l2_streamparm *parm) |
338 | { | 338 | { |
339 | uint32_t numerator, denominator; | 339 | u32 numerator, denominator; |
340 | 340 | ||
341 | if (parm->type != stream->type) | 341 | if (parm->type != stream->type) |
342 | return -EINVAL; | 342 | return -EINVAL; |
@@ -348,7 +348,7 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
348 | denominator = 10000000; | 348 | denominator = 10000000; |
349 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 349 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
350 | 350 | ||
351 | memset(parm, 0, sizeof *parm); | 351 | memset(parm, 0, sizeof(*parm)); |
352 | parm->type = stream->type; | 352 | parm->type = stream->type; |
353 | 353 | ||
354 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 354 | if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
@@ -373,7 +373,10 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
373 | { | 373 | { |
374 | struct uvc_streaming_control probe; | 374 | struct uvc_streaming_control probe; |
375 | struct v4l2_fract timeperframe; | 375 | struct v4l2_fract timeperframe; |
376 | uint32_t interval; | 376 | struct uvc_format *format; |
377 | struct uvc_frame *frame; | ||
378 | u32 interval, maxd; | ||
379 | unsigned int i; | ||
377 | int ret; | 380 | int ret; |
378 | 381 | ||
379 | if (parm->type != stream->type) | 382 | if (parm->type != stream->type) |
@@ -396,9 +399,33 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
396 | return -EBUSY; | 399 | return -EBUSY; |
397 | } | 400 | } |
398 | 401 | ||
402 | format = stream->cur_format; | ||
403 | frame = stream->cur_frame; | ||
399 | probe = stream->ctrl; | 404 | probe = stream->ctrl; |
400 | probe.dwFrameInterval = | 405 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); |
401 | uvc_try_frame_interval(stream->cur_frame, interval); | 406 | maxd = abs((s32)probe.dwFrameInterval - interval); |
407 | |||
408 | /* Try frames with matching size to find the best frame interval. */ | ||
409 | for (i = 0; i < format->nframes && maxd != 0; i++) { | ||
410 | u32 d, ival; | ||
411 | |||
412 | if (&format->frame[i] == stream->cur_frame) | ||
413 | continue; | ||
414 | |||
415 | if (format->frame[i].wWidth != stream->cur_frame->wWidth || | ||
416 | format->frame[i].wHeight != stream->cur_frame->wHeight) | ||
417 | continue; | ||
418 | |||
419 | ival = uvc_try_frame_interval(&format->frame[i], interval); | ||
420 | d = abs((s32)ival - interval); | ||
421 | if (d >= maxd) | ||
422 | continue; | ||
423 | |||
424 | frame = &format->frame[i]; | ||
425 | probe.bFrameIndex = frame->bFrameIndex; | ||
426 | probe.dwFrameInterval = ival; | ||
427 | maxd = d; | ||
428 | } | ||
402 | 429 | ||
403 | /* Probe the device with the new settings. */ | 430 | /* Probe the device with the new settings. */ |
404 | ret = uvc_probe_video(stream, &probe); | 431 | ret = uvc_probe_video(stream, &probe); |
@@ -408,6 +435,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
408 | } | 435 | } |
409 | 436 | ||
410 | stream->ctrl = probe; | 437 | stream->ctrl = probe; |
438 | stream->cur_frame = frame; | ||
411 | mutex_unlock(&stream->mutex); | 439 | mutex_unlock(&stream->mutex); |
412 | 440 | ||
413 | /* Return the actual frame period. */ | 441 | /* Return the actual frame period. */ |
@@ -498,7 +526,7 @@ static int uvc_v4l2_open(struct file *file) | |||
498 | return ret; | 526 | return ret; |
499 | 527 | ||
500 | /* Create the device handle. */ | 528 | /* Create the device handle. */ |
501 | handle = kzalloc(sizeof *handle, GFP_KERNEL); | 529 | handle = kzalloc(sizeof(*handle), GFP_KERNEL); |
502 | if (handle == NULL) { | 530 | if (handle == NULL) { |
503 | usb_autopm_put_interface(stream->dev->intf); | 531 | usb_autopm_put_interface(stream->dev->intf); |
504 | return -ENOMEM; | 532 | return -ENOMEM; |
@@ -577,7 +605,7 @@ static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, | |||
577 | { | 605 | { |
578 | struct uvc_format *format; | 606 | struct uvc_format *format; |
579 | enum v4l2_buf_type type = fmt->type; | 607 | enum v4l2_buf_type type = fmt->type; |
580 | __u32 index = fmt->index; | 608 | u32 index = fmt->index; |
581 | 609 | ||
582 | if (fmt->type != stream->type || fmt->index >= stream->nformats) | 610 | if (fmt->type != stream->type || fmt->index >= stream->nformats) |
583 | return -EINVAL; | 611 | return -EINVAL; |
@@ -1145,8 +1173,9 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, | |||
1145 | struct uvc_fh *handle = fh; | 1173 | struct uvc_fh *handle = fh; |
1146 | struct uvc_streaming *stream = handle->stream; | 1174 | struct uvc_streaming *stream = handle->stream; |
1147 | struct uvc_format *format = NULL; | 1175 | struct uvc_format *format = NULL; |
1148 | struct uvc_frame *frame; | 1176 | struct uvc_frame *frame = NULL; |
1149 | int i; | 1177 | unsigned int index; |
1178 | unsigned int i; | ||
1150 | 1179 | ||
1151 | /* Look for the given pixel format */ | 1180 | /* Look for the given pixel format */ |
1152 | for (i = 0; i < stream->nformats; i++) { | 1181 | for (i = 0; i < stream->nformats; i++) { |
@@ -1158,10 +1187,20 @@ static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, | |||
1158 | if (format == NULL) | 1187 | if (format == NULL) |
1159 | return -EINVAL; | 1188 | return -EINVAL; |
1160 | 1189 | ||
1161 | if (fsize->index >= format->nframes) | 1190 | /* Skip duplicate frame sizes */ |
1191 | for (i = 0, index = 0; i < format->nframes; i++) { | ||
1192 | if (frame && frame->wWidth == format->frame[i].wWidth && | ||
1193 | frame->wHeight == format->frame[i].wHeight) | ||
1194 | continue; | ||
1195 | frame = &format->frame[i]; | ||
1196 | if (index == fsize->index) | ||
1197 | break; | ||
1198 | index++; | ||
1199 | } | ||
1200 | |||
1201 | if (i == format->nframes) | ||
1162 | return -EINVAL; | 1202 | return -EINVAL; |
1163 | 1203 | ||
1164 | frame = &format->frame[fsize->index]; | ||
1165 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | 1204 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; |
1166 | fsize->discrete.width = frame->wWidth; | 1205 | fsize->discrete.width = frame->wWidth; |
1167 | fsize->discrete.height = frame->wHeight; | 1206 | fsize->discrete.height = frame->wHeight; |
@@ -1175,7 +1214,9 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, | |||
1175 | struct uvc_streaming *stream = handle->stream; | 1214 | struct uvc_streaming *stream = handle->stream; |
1176 | struct uvc_format *format = NULL; | 1215 | struct uvc_format *format = NULL; |
1177 | struct uvc_frame *frame = NULL; | 1216 | struct uvc_frame *frame = NULL; |
1178 | int i; | 1217 | unsigned int nintervals; |
1218 | unsigned int index; | ||
1219 | unsigned int i; | ||
1179 | 1220 | ||
1180 | /* Look for the given pixel format and frame size */ | 1221 | /* Look for the given pixel format and frame size */ |
1181 | for (i = 0; i < stream->nformats; i++) { | 1222 | for (i = 0; i < stream->nformats; i++) { |
@@ -1187,30 +1228,28 @@ static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, | |||
1187 | if (format == NULL) | 1228 | if (format == NULL) |
1188 | return -EINVAL; | 1229 | return -EINVAL; |
1189 | 1230 | ||
1231 | index = fival->index; | ||
1190 | for (i = 0; i < format->nframes; i++) { | 1232 | for (i = 0; i < format->nframes; i++) { |
1191 | if (format->frame[i].wWidth == fival->width && | 1233 | if (format->frame[i].wWidth == fival->width && |
1192 | format->frame[i].wHeight == fival->height) { | 1234 | format->frame[i].wHeight == fival->height) { |
1193 | frame = &format->frame[i]; | 1235 | frame = &format->frame[i]; |
1194 | break; | 1236 | nintervals = frame->bFrameIntervalType ?: 1; |
1237 | if (index < nintervals) | ||
1238 | break; | ||
1239 | index -= nintervals; | ||
1195 | } | 1240 | } |
1196 | } | 1241 | } |
1197 | if (frame == NULL) | 1242 | if (i == format->nframes) |
1198 | return -EINVAL; | 1243 | return -EINVAL; |
1199 | 1244 | ||
1200 | if (frame->bFrameIntervalType) { | 1245 | if (frame->bFrameIntervalType) { |
1201 | if (fival->index >= frame->bFrameIntervalType) | ||
1202 | return -EINVAL; | ||
1203 | |||
1204 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; | 1246 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; |
1205 | fival->discrete.numerator = | 1247 | fival->discrete.numerator = |
1206 | frame->dwFrameInterval[fival->index]; | 1248 | frame->dwFrameInterval[index]; |
1207 | fival->discrete.denominator = 10000000; | 1249 | fival->discrete.denominator = 10000000; |
1208 | uvc_simplify_fraction(&fival->discrete.numerator, | 1250 | uvc_simplify_fraction(&fival->discrete.numerator, |
1209 | &fival->discrete.denominator, 8, 333); | 1251 | &fival->discrete.denominator, 8, 333); |
1210 | } else { | 1252 | } else { |
1211 | if (fival->index) | ||
1212 | return -EINVAL; | ||
1213 | |||
1214 | fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; | 1253 | fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; |
1215 | fival->stepwise.min.numerator = frame->dwFrameInterval[0]; | 1254 | fival->stepwise.min.numerator = frame->dwFrameInterval[0]; |
1216 | fival->stepwise.min.denominator = 10000000; | 1255 | fival->stepwise.min.denominator = 10000000; |
@@ -1261,20 +1300,20 @@ static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio, | |||
1261 | 1300 | ||
1262 | #ifdef CONFIG_COMPAT | 1301 | #ifdef CONFIG_COMPAT |
1263 | struct uvc_xu_control_mapping32 { | 1302 | struct uvc_xu_control_mapping32 { |
1264 | __u32 id; | 1303 | u32 id; |
1265 | __u8 name[32]; | 1304 | u8 name[32]; |
1266 | __u8 entity[16]; | 1305 | u8 entity[16]; |
1267 | __u8 selector; | 1306 | u8 selector; |
1268 | 1307 | ||
1269 | __u8 size; | 1308 | u8 size; |
1270 | __u8 offset; | 1309 | u8 offset; |
1271 | __u32 v4l2_type; | 1310 | u32 v4l2_type; |
1272 | __u32 data_type; | 1311 | u32 data_type; |
1273 | 1312 | ||
1274 | compat_caddr_t menu_info; | 1313 | compat_caddr_t menu_info; |
1275 | __u32 menu_count; | 1314 | u32 menu_count; |
1276 | 1315 | ||
1277 | __u32 reserved[4]; | 1316 | u32 reserved[4]; |
1278 | }; | 1317 | }; |
1279 | 1318 | ||
1280 | static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, | 1319 | static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp, |
@@ -1310,10 +1349,10 @@ static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp, | |||
1310 | } | 1349 | } |
1311 | 1350 | ||
1312 | struct uvc_xu_control_query32 { | 1351 | struct uvc_xu_control_query32 { |
1313 | __u8 unit; | 1352 | u8 unit; |
1314 | __u8 selector; | 1353 | u8 selector; |
1315 | __u8 query; | 1354 | u8 query; |
1316 | __u16 size; | 1355 | u16 size; |
1317 | compat_caddr_t data; | 1356 | compat_caddr_t data; |
1318 | }; | 1357 | }; |
1319 | 1358 | ||
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 5441553f74e1..aa0082fe5833 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c | |||
@@ -30,11 +30,11 @@ | |||
30 | * UVC Controls | 30 | * UVC Controls |
31 | */ | 31 | */ |
32 | 32 | ||
33 | static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 33 | static int __uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, |
34 | __u8 intfnum, __u8 cs, void *data, __u16 size, | 34 | u8 intfnum, u8 cs, void *data, u16 size, |
35 | int timeout) | 35 | int timeout) |
36 | { | 36 | { |
37 | __u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; | 37 | u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; |
38 | unsigned int pipe; | 38 | unsigned int pipe; |
39 | 39 | ||
40 | pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) | 40 | pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0) |
@@ -45,7 +45,7 @@ static int __uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
45 | unit << 8 | intfnum, data, size, timeout); | 45 | unit << 8 | intfnum, data, size, timeout); |
46 | } | 46 | } |
47 | 47 | ||
48 | static const char *uvc_query_name(__u8 query) | 48 | static const char *uvc_query_name(u8 query) |
49 | { | 49 | { |
50 | switch (query) { | 50 | switch (query) { |
51 | case UVC_SET_CUR: | 51 | case UVC_SET_CUR: |
@@ -69,8 +69,8 @@ static const char *uvc_query_name(__u8 query) | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 72 | int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, |
73 | __u8 intfnum, __u8 cs, void *data, __u16 size) | 73 | u8 intfnum, u8 cs, void *data, u16 size) |
74 | { | 74 | { |
75 | int ret; | 75 | int ret; |
76 | 76 | ||
@@ -164,10 +164,10 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, | |||
164 | } | 164 | } |
165 | 165 | ||
166 | static int uvc_get_video_ctrl(struct uvc_streaming *stream, | 166 | static int uvc_get_video_ctrl(struct uvc_streaming *stream, |
167 | struct uvc_streaming_control *ctrl, int probe, __u8 query) | 167 | struct uvc_streaming_control *ctrl, int probe, u8 query) |
168 | { | 168 | { |
169 | __u8 *data; | 169 | u8 *data; |
170 | __u16 size; | 170 | u16 size; |
171 | int ret; | 171 | int ret; |
172 | 172 | ||
173 | size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; | 173 | size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; |
@@ -191,7 +191,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream, | |||
191 | uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " | 191 | uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non " |
192 | "compliance - GET_MIN/MAX(PROBE) incorrectly " | 192 | "compliance - GET_MIN/MAX(PROBE) incorrectly " |
193 | "supported. Enabling workaround.\n"); | 193 | "supported. Enabling workaround.\n"); |
194 | memset(ctrl, 0, sizeof *ctrl); | 194 | memset(ctrl, 0, sizeof(*ctrl)); |
195 | ctrl->wCompQuality = le16_to_cpup((__le16 *)data); | 195 | ctrl->wCompQuality = le16_to_cpup((__le16 *)data); |
196 | ret = 0; | 196 | ret = 0; |
197 | goto out; | 197 | goto out; |
@@ -254,8 +254,8 @@ out: | |||
254 | static int uvc_set_video_ctrl(struct uvc_streaming *stream, | 254 | static int uvc_set_video_ctrl(struct uvc_streaming *stream, |
255 | struct uvc_streaming_control *ctrl, int probe) | 255 | struct uvc_streaming_control *ctrl, int probe) |
256 | { | 256 | { |
257 | __u8 *data; | 257 | u8 *data; |
258 | __u16 size; | 258 | u16 size; |
259 | int ret; | 259 | int ret; |
260 | 260 | ||
261 | size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; | 261 | size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; |
@@ -301,7 +301,7 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
301 | struct uvc_streaming_control *probe) | 301 | struct uvc_streaming_control *probe) |
302 | { | 302 | { |
303 | struct uvc_streaming_control probe_min, probe_max; | 303 | struct uvc_streaming_control probe_min, probe_max; |
304 | __u16 bandwidth; | 304 | u16 bandwidth; |
305 | unsigned int i; | 305 | unsigned int i; |
306 | int ret; | 306 | int ret; |
307 | 307 | ||
@@ -379,7 +379,7 @@ static inline ktime_t uvc_video_get_time(void) | |||
379 | 379 | ||
380 | static void | 380 | static void |
381 | uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, | 381 | uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, |
382 | const __u8 *data, int len) | 382 | const u8 *data, int len) |
383 | { | 383 | { |
384 | struct uvc_clock_sample *sample; | 384 | struct uvc_clock_sample *sample; |
385 | unsigned int header_size; | 385 | unsigned int header_size; |
@@ -705,7 +705,7 @@ done: | |||
705 | */ | 705 | */ |
706 | 706 | ||
707 | static void uvc_video_stats_decode(struct uvc_streaming *stream, | 707 | static void uvc_video_stats_decode(struct uvc_streaming *stream, |
708 | const __u8 *data, int len) | 708 | const u8 *data, int len) |
709 | { | 709 | { |
710 | unsigned int header_size; | 710 | unsigned int header_size; |
711 | bool has_pts = false; | 711 | bool has_pts = false; |
@@ -946,9 +946,9 @@ static void uvc_video_stats_stop(struct uvc_streaming *stream) | |||
946 | * uvc_video_decode_end will never be called with a NULL buffer. | 946 | * uvc_video_decode_end will never be called with a NULL buffer. |
947 | */ | 947 | */ |
948 | static int uvc_video_decode_start(struct uvc_streaming *stream, | 948 | static int uvc_video_decode_start(struct uvc_streaming *stream, |
949 | struct uvc_buffer *buf, const __u8 *data, int len) | 949 | struct uvc_buffer *buf, const u8 *data, int len) |
950 | { | 950 | { |
951 | __u8 fid; | 951 | u8 fid; |
952 | 952 | ||
953 | /* Sanity checks: | 953 | /* Sanity checks: |
954 | * - packet must be at least 2 bytes long | 954 | * - packet must be at least 2 bytes long |
@@ -1009,7 +1009,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
1009 | 1009 | ||
1010 | buf->buf.field = V4L2_FIELD_NONE; | 1010 | buf->buf.field = V4L2_FIELD_NONE; |
1011 | buf->buf.sequence = stream->sequence; | 1011 | buf->buf.sequence = stream->sequence; |
1012 | buf->buf.vb2_buf.timestamp = uvc_video_get_time(); | 1012 | buf->buf.vb2_buf.timestamp = ktime_to_ns(uvc_video_get_time()); |
1013 | 1013 | ||
1014 | /* TODO: Handle PTS and SCR. */ | 1014 | /* TODO: Handle PTS and SCR. */ |
1015 | buf->state = UVC_BUF_STATE_ACTIVE; | 1015 | buf->state = UVC_BUF_STATE_ACTIVE; |
@@ -1043,7 +1043,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | static void uvc_video_decode_data(struct uvc_streaming *stream, | 1045 | static void uvc_video_decode_data(struct uvc_streaming *stream, |
1046 | struct uvc_buffer *buf, const __u8 *data, int len) | 1046 | struct uvc_buffer *buf, const u8 *data, int len) |
1047 | { | 1047 | { |
1048 | unsigned int maxlen, nbytes; | 1048 | unsigned int maxlen, nbytes; |
1049 | void *mem; | 1049 | void *mem; |
@@ -1067,7 +1067,7 @@ static void uvc_video_decode_data(struct uvc_streaming *stream, | |||
1067 | } | 1067 | } |
1068 | 1068 | ||
1069 | static void uvc_video_decode_end(struct uvc_streaming *stream, | 1069 | static void uvc_video_decode_end(struct uvc_streaming *stream, |
1070 | struct uvc_buffer *buf, const __u8 *data, int len) | 1070 | struct uvc_buffer *buf, const u8 *data, int len) |
1071 | { | 1071 | { |
1072 | /* Mark the buffer as done if the EOF marker is set. */ | 1072 | /* Mark the buffer as done if the EOF marker is set. */ |
1073 | if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { | 1073 | if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { |
@@ -1092,7 +1092,7 @@ static void uvc_video_decode_end(struct uvc_streaming *stream, | |||
1092 | * video buffer to the transfer buffer. | 1092 | * video buffer to the transfer buffer. |
1093 | */ | 1093 | */ |
1094 | static int uvc_video_encode_header(struct uvc_streaming *stream, | 1094 | static int uvc_video_encode_header(struct uvc_streaming *stream, |
1095 | struct uvc_buffer *buf, __u8 *data, int len) | 1095 | struct uvc_buffer *buf, u8 *data, int len) |
1096 | { | 1096 | { |
1097 | data[0] = 2; /* Header length */ | 1097 | data[0] = 2; /* Header length */ |
1098 | data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF | 1098 | data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF |
@@ -1101,7 +1101,7 @@ static int uvc_video_encode_header(struct uvc_streaming *stream, | |||
1101 | } | 1101 | } |
1102 | 1102 | ||
1103 | static int uvc_video_encode_data(struct uvc_streaming *stream, | 1103 | static int uvc_video_encode_data(struct uvc_streaming *stream, |
1104 | struct uvc_buffer *buf, __u8 *data, int len) | 1104 | struct uvc_buffer *buf, u8 *data, int len) |
1105 | { | 1105 | { |
1106 | struct uvc_video_queue *queue = &stream->queue; | 1106 | struct uvc_video_queue *queue = &stream->queue; |
1107 | unsigned int nbytes; | 1107 | unsigned int nbytes; |
@@ -1191,7 +1191,8 @@ static void uvc_video_decode_meta(struct uvc_streaming *stream, | |||
1191 | 1191 | ||
1192 | uvc_trace(UVC_TRACE_FRAME, | 1192 | uvc_trace(UVC_TRACE_FRAME, |
1193 | "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n", | 1193 | "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n", |
1194 | __func__, time, meta->sof, meta->length, meta->flags, | 1194 | __func__, ktime_to_ns(time), meta->sof, meta->length, |
1195 | meta->flags, | ||
1195 | has_pts ? *(u32 *)meta->buf : 0, | 1196 | has_pts ? *(u32 *)meta->buf : 0, |
1196 | has_scr ? *(u32 *)scr : 0, | 1197 | has_scr ? *(u32 *)scr : 0, |
1197 | has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0); | 1198 | has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0); |
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index d9e7c70788d0..be5cf179228b 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h | |||
@@ -208,60 +208,60 @@ struct uvc_device; | |||
208 | struct uvc_control_info { | 208 | struct uvc_control_info { |
209 | struct list_head mappings; | 209 | struct list_head mappings; |
210 | 210 | ||
211 | __u8 entity[16]; | 211 | u8 entity[16]; |
212 | __u8 index; /* Bit index in bmControls */ | 212 | u8 index; /* Bit index in bmControls */ |
213 | __u8 selector; | 213 | u8 selector; |
214 | 214 | ||
215 | __u16 size; | 215 | u16 size; |
216 | __u32 flags; | 216 | u32 flags; |
217 | }; | 217 | }; |
218 | 218 | ||
219 | struct uvc_control_mapping { | 219 | struct uvc_control_mapping { |
220 | struct list_head list; | 220 | struct list_head list; |
221 | struct list_head ev_subs; | 221 | struct list_head ev_subs; |
222 | 222 | ||
223 | __u32 id; | 223 | u32 id; |
224 | __u8 name[32]; | 224 | u8 name[32]; |
225 | __u8 entity[16]; | 225 | u8 entity[16]; |
226 | __u8 selector; | 226 | u8 selector; |
227 | 227 | ||
228 | __u8 size; | 228 | u8 size; |
229 | __u8 offset; | 229 | u8 offset; |
230 | enum v4l2_ctrl_type v4l2_type; | 230 | enum v4l2_ctrl_type v4l2_type; |
231 | __u32 data_type; | 231 | u32 data_type; |
232 | 232 | ||
233 | struct uvc_menu_info *menu_info; | 233 | struct uvc_menu_info *menu_info; |
234 | __u32 menu_count; | 234 | u32 menu_count; |
235 | 235 | ||
236 | __u32 master_id; | 236 | u32 master_id; |
237 | __s32 master_manual; | 237 | s32 master_manual; |
238 | __u32 slave_ids[2]; | 238 | u32 slave_ids[2]; |
239 | 239 | ||
240 | __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query, | 240 | s32 (*get)(struct uvc_control_mapping *mapping, u8 query, |
241 | const __u8 *data); | 241 | const u8 *data); |
242 | void (*set) (struct uvc_control_mapping *mapping, __s32 value, | 242 | void (*set)(struct uvc_control_mapping *mapping, s32 value, |
243 | __u8 *data); | 243 | u8 *data); |
244 | }; | 244 | }; |
245 | 245 | ||
246 | struct uvc_control { | 246 | struct uvc_control { |
247 | struct uvc_entity *entity; | 247 | struct uvc_entity *entity; |
248 | struct uvc_control_info info; | 248 | struct uvc_control_info info; |
249 | 249 | ||
250 | __u8 index; /* Used to match the uvc_control entry with a | 250 | u8 index; /* Used to match the uvc_control entry with a |
251 | uvc_control_info. */ | 251 | uvc_control_info. */ |
252 | __u8 dirty:1, | 252 | u8 dirty:1, |
253 | loaded:1, | 253 | loaded:1, |
254 | modified:1, | 254 | modified:1, |
255 | cached:1, | 255 | cached:1, |
256 | initialized:1; | 256 | initialized:1; |
257 | 257 | ||
258 | __u8 *uvc_data; | 258 | u8 *uvc_data; |
259 | }; | 259 | }; |
260 | 260 | ||
261 | struct uvc_format_desc { | 261 | struct uvc_format_desc { |
262 | char *name; | 262 | char *name; |
263 | __u8 guid[16]; | 263 | u8 guid[16]; |
264 | __u32 fcc; | 264 | u32 fcc; |
265 | }; | 265 | }; |
266 | 266 | ||
267 | /* The term 'entity' refers to both UVC units and UVC terminals. | 267 | /* The term 'entity' refers to both UVC units and UVC terminals. |
@@ -287,8 +287,8 @@ struct uvc_entity { | |||
287 | * chain. */ | 287 | * chain. */ |
288 | unsigned int flags; | 288 | unsigned int flags; |
289 | 289 | ||
290 | __u8 id; | 290 | u8 id; |
291 | __u16 type; | 291 | u16 type; |
292 | char name[64]; | 292 | char name[64]; |
293 | 293 | ||
294 | /* Media controller-related fields. */ | 294 | /* Media controller-related fields. */ |
@@ -300,69 +300,69 @@ struct uvc_entity { | |||
300 | 300 | ||
301 | union { | 301 | union { |
302 | struct { | 302 | struct { |
303 | __u16 wObjectiveFocalLengthMin; | 303 | u16 wObjectiveFocalLengthMin; |
304 | __u16 wObjectiveFocalLengthMax; | 304 | u16 wObjectiveFocalLengthMax; |
305 | __u16 wOcularFocalLength; | 305 | u16 wOcularFocalLength; |
306 | __u8 bControlSize; | 306 | u8 bControlSize; |
307 | __u8 *bmControls; | 307 | u8 *bmControls; |
308 | } camera; | 308 | } camera; |
309 | 309 | ||
310 | struct { | 310 | struct { |
311 | __u8 bControlSize; | 311 | u8 bControlSize; |
312 | __u8 *bmControls; | 312 | u8 *bmControls; |
313 | __u8 bTransportModeSize; | 313 | u8 bTransportModeSize; |
314 | __u8 *bmTransportModes; | 314 | u8 *bmTransportModes; |
315 | } media; | 315 | } media; |
316 | 316 | ||
317 | struct { | 317 | struct { |
318 | } output; | 318 | } output; |
319 | 319 | ||
320 | struct { | 320 | struct { |
321 | __u16 wMaxMultiplier; | 321 | u16 wMaxMultiplier; |
322 | __u8 bControlSize; | 322 | u8 bControlSize; |
323 | __u8 *bmControls; | 323 | u8 *bmControls; |
324 | __u8 bmVideoStandards; | 324 | u8 bmVideoStandards; |
325 | } processing; | 325 | } processing; |
326 | 326 | ||
327 | struct { | 327 | struct { |
328 | } selector; | 328 | } selector; |
329 | 329 | ||
330 | struct { | 330 | struct { |
331 | __u8 guidExtensionCode[16]; | 331 | u8 guidExtensionCode[16]; |
332 | __u8 bNumControls; | 332 | u8 bNumControls; |
333 | __u8 bControlSize; | 333 | u8 bControlSize; |
334 | __u8 *bmControls; | 334 | u8 *bmControls; |
335 | __u8 *bmControlsType; | 335 | u8 *bmControlsType; |
336 | } extension; | 336 | } extension; |
337 | }; | 337 | }; |
338 | 338 | ||
339 | __u8 bNrInPins; | 339 | u8 bNrInPins; |
340 | __u8 *baSourceID; | 340 | u8 *baSourceID; |
341 | 341 | ||
342 | unsigned int ncontrols; | 342 | unsigned int ncontrols; |
343 | struct uvc_control *controls; | 343 | struct uvc_control *controls; |
344 | }; | 344 | }; |
345 | 345 | ||
346 | struct uvc_frame { | 346 | struct uvc_frame { |
347 | __u8 bFrameIndex; | 347 | u8 bFrameIndex; |
348 | __u8 bmCapabilities; | 348 | u8 bmCapabilities; |
349 | __u16 wWidth; | 349 | u16 wWidth; |
350 | __u16 wHeight; | 350 | u16 wHeight; |
351 | __u32 dwMinBitRate; | 351 | u32 dwMinBitRate; |
352 | __u32 dwMaxBitRate; | 352 | u32 dwMaxBitRate; |
353 | __u32 dwMaxVideoFrameBufferSize; | 353 | u32 dwMaxVideoFrameBufferSize; |
354 | __u8 bFrameIntervalType; | 354 | u8 bFrameIntervalType; |
355 | __u32 dwDefaultFrameInterval; | 355 | u32 dwDefaultFrameInterval; |
356 | __u32 *dwFrameInterval; | 356 | u32 *dwFrameInterval; |
357 | }; | 357 | }; |
358 | 358 | ||
359 | struct uvc_format { | 359 | struct uvc_format { |
360 | __u8 type; | 360 | u8 type; |
361 | __u8 index; | 361 | u8 index; |
362 | __u8 bpp; | 362 | u8 bpp; |
363 | __u8 colorspace; | 363 | u8 colorspace; |
364 | __u32 fcc; | 364 | u32 fcc; |
365 | __u32 flags; | 365 | u32 flags; |
366 | 366 | ||
367 | char name[32]; | 367 | char name[32]; |
368 | 368 | ||
@@ -371,16 +371,16 @@ struct uvc_format { | |||
371 | }; | 371 | }; |
372 | 372 | ||
373 | struct uvc_streaming_header { | 373 | struct uvc_streaming_header { |
374 | __u8 bNumFormats; | 374 | u8 bNumFormats; |
375 | __u8 bEndpointAddress; | 375 | u8 bEndpointAddress; |
376 | __u8 bTerminalLink; | 376 | u8 bTerminalLink; |
377 | __u8 bControlSize; | 377 | u8 bControlSize; |
378 | __u8 *bmaControls; | 378 | u8 *bmaControls; |
379 | /* The following fields are used by input headers only. */ | 379 | /* The following fields are used by input headers only. */ |
380 | __u8 bmInfo; | 380 | u8 bmInfo; |
381 | __u8 bStillCaptureMethod; | 381 | u8 bStillCaptureMethod; |
382 | __u8 bTriggerSupport; | 382 | u8 bTriggerSupport; |
383 | __u8 bTriggerUsage; | 383 | u8 bTriggerUsage; |
384 | }; | 384 | }; |
385 | 385 | ||
386 | enum uvc_buffer_state { | 386 | enum uvc_buffer_state { |
@@ -490,7 +490,7 @@ struct uvc_streaming { | |||
490 | 490 | ||
491 | struct usb_interface *intf; | 491 | struct usb_interface *intf; |
492 | int intfnum; | 492 | int intfnum; |
493 | __u16 maxpsize; | 493 | u16 maxpsize; |
494 | 494 | ||
495 | struct uvc_streaming_header header; | 495 | struct uvc_streaming_header header; |
496 | enum v4l2_buf_type type; | 496 | enum v4l2_buf_type type; |
@@ -517,16 +517,16 @@ struct uvc_streaming { | |||
517 | struct { | 517 | struct { |
518 | struct video_device vdev; | 518 | struct video_device vdev; |
519 | struct uvc_video_queue queue; | 519 | struct uvc_video_queue queue; |
520 | __u32 format; | 520 | u32 format; |
521 | } meta; | 521 | } meta; |
522 | 522 | ||
523 | /* Context data used by the bulk completion handler. */ | 523 | /* Context data used by the bulk completion handler. */ |
524 | struct { | 524 | struct { |
525 | __u8 header[256]; | 525 | u8 header[256]; |
526 | unsigned int header_size; | 526 | unsigned int header_size; |
527 | int skip_payload; | 527 | int skip_payload; |
528 | __u32 payload_size; | 528 | u32 payload_size; |
529 | __u32 max_payload_size; | 529 | u32 max_payload_size; |
530 | } bulk; | 530 | } bulk; |
531 | 531 | ||
532 | struct urb *urb[UVC_URBS]; | 532 | struct urb *urb[UVC_URBS]; |
@@ -534,8 +534,8 @@ struct uvc_streaming { | |||
534 | dma_addr_t urb_dma[UVC_URBS]; | 534 | dma_addr_t urb_dma[UVC_URBS]; |
535 | unsigned int urb_size; | 535 | unsigned int urb_size; |
536 | 536 | ||
537 | __u32 sequence; | 537 | u32 sequence; |
538 | __u8 last_fid; | 538 | u8 last_fid; |
539 | 539 | ||
540 | /* debugfs */ | 540 | /* debugfs */ |
541 | struct dentry *debugfs_dir; | 541 | struct dentry *debugfs_dir; |
@@ -570,8 +570,8 @@ struct uvc_device { | |||
570 | struct usb_device *udev; | 570 | struct usb_device *udev; |
571 | struct usb_interface *intf; | 571 | struct usb_interface *intf; |
572 | unsigned long warnings; | 572 | unsigned long warnings; |
573 | __u32 quirks; | 573 | u32 quirks; |
574 | __u32 meta_format; | 574 | u32 meta_format; |
575 | int intfnum; | 575 | int intfnum; |
576 | char name[32]; | 576 | char name[32]; |
577 | 577 | ||
@@ -584,8 +584,8 @@ struct uvc_device { | |||
584 | struct media_device mdev; | 584 | struct media_device mdev; |
585 | #endif | 585 | #endif |
586 | struct v4l2_device vdev; | 586 | struct v4l2_device vdev; |
587 | __u16 uvc_version; | 587 | u16 uvc_version; |
588 | __u32 clock_frequency; | 588 | u32 clock_frequency; |
589 | 589 | ||
590 | struct list_head entities; | 590 | struct list_head entities; |
591 | struct list_head chains; | 591 | struct list_head chains; |
@@ -597,7 +597,7 @@ struct uvc_device { | |||
597 | /* Status Interrupt Endpoint */ | 597 | /* Status Interrupt Endpoint */ |
598 | struct usb_host_endpoint *int_ep; | 598 | struct usb_host_endpoint *int_ep; |
599 | struct urb *int_urb; | 599 | struct urb *int_urb; |
600 | __u8 *status; | 600 | u8 *status; |
601 | struct input_dev *input; | 601 | struct input_dev *input; |
602 | char input_phys[64]; | 602 | char input_phys[64]; |
603 | }; | 603 | }; |
@@ -667,40 +667,38 @@ extern unsigned int uvc_hw_timestamps_param; | |||
667 | /* Core driver */ | 667 | /* Core driver */ |
668 | extern struct uvc_driver uvc_driver; | 668 | extern struct uvc_driver uvc_driver; |
669 | 669 | ||
670 | extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); | 670 | struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); |
671 | 671 | ||
672 | /* Video buffers queue management. */ | 672 | /* Video buffers queue management. */ |
673 | extern int uvc_queue_init(struct uvc_video_queue *queue, | 673 | int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, |
674 | enum v4l2_buf_type type, int drop_corrupted); | 674 | int drop_corrupted); |
675 | extern void uvc_queue_release(struct uvc_video_queue *queue); | 675 | void uvc_queue_release(struct uvc_video_queue *queue); |
676 | extern int uvc_request_buffers(struct uvc_video_queue *queue, | 676 | int uvc_request_buffers(struct uvc_video_queue *queue, |
677 | struct v4l2_requestbuffers *rb); | 677 | struct v4l2_requestbuffers *rb); |
678 | extern int uvc_query_buffer(struct uvc_video_queue *queue, | 678 | int uvc_query_buffer(struct uvc_video_queue *queue, |
679 | struct v4l2_buffer *v4l2_buf); | 679 | struct v4l2_buffer *v4l2_buf); |
680 | extern int uvc_create_buffers(struct uvc_video_queue *queue, | 680 | int uvc_create_buffers(struct uvc_video_queue *queue, |
681 | struct v4l2_create_buffers *v4l2_cb); | 681 | struct v4l2_create_buffers *v4l2_cb); |
682 | extern int uvc_queue_buffer(struct uvc_video_queue *queue, | 682 | int uvc_queue_buffer(struct uvc_video_queue *queue, |
683 | struct v4l2_buffer *v4l2_buf); | 683 | struct v4l2_buffer *v4l2_buf); |
684 | extern int uvc_export_buffer(struct uvc_video_queue *queue, | 684 | int uvc_export_buffer(struct uvc_video_queue *queue, |
685 | struct v4l2_exportbuffer *exp); | 685 | struct v4l2_exportbuffer *exp); |
686 | extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, | 686 | int uvc_dequeue_buffer(struct uvc_video_queue *queue, |
687 | struct v4l2_buffer *v4l2_buf, int nonblocking); | 687 | struct v4l2_buffer *v4l2_buf, int nonblocking); |
688 | extern int uvc_queue_streamon(struct uvc_video_queue *queue, | 688 | int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type); |
689 | enum v4l2_buf_type type); | 689 | int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type); |
690 | extern int uvc_queue_streamoff(struct uvc_video_queue *queue, | 690 | void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); |
691 | enum v4l2_buf_type type); | 691 | struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, |
692 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); | 692 | struct uvc_buffer *buf); |
693 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | 693 | int uvc_queue_mmap(struct uvc_video_queue *queue, |
694 | struct uvc_buffer *buf); | 694 | struct vm_area_struct *vma); |
695 | extern int uvc_queue_mmap(struct uvc_video_queue *queue, | 695 | __poll_t uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, |
696 | struct vm_area_struct *vma); | 696 | poll_table *wait); |
697 | extern __poll_t uvc_queue_poll(struct uvc_video_queue *queue, | ||
698 | struct file *file, poll_table *wait); | ||
699 | #ifndef CONFIG_MMU | 697 | #ifndef CONFIG_MMU |
700 | extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | 698 | unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, |
701 | unsigned long pgoff); | 699 | unsigned long pgoff); |
702 | #endif | 700 | #endif |
703 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 701 | int uvc_queue_allocated(struct uvc_video_queue *queue); |
704 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) | 702 | static inline int uvc_queue_streaming(struct uvc_video_queue *queue) |
705 | { | 703 | { |
706 | return vb2_is_streaming(&queue->queue); | 704 | return vb2_is_streaming(&queue->queue); |
@@ -711,18 +709,18 @@ extern const struct v4l2_ioctl_ops uvc_ioctl_ops; | |||
711 | extern const struct v4l2_file_operations uvc_fops; | 709 | extern const struct v4l2_file_operations uvc_fops; |
712 | 710 | ||
713 | /* Media controller */ | 711 | /* Media controller */ |
714 | extern int uvc_mc_register_entities(struct uvc_video_chain *chain); | 712 | int uvc_mc_register_entities(struct uvc_video_chain *chain); |
715 | extern void uvc_mc_cleanup_entity(struct uvc_entity *entity); | 713 | void uvc_mc_cleanup_entity(struct uvc_entity *entity); |
716 | 714 | ||
717 | /* Video */ | 715 | /* Video */ |
718 | extern int uvc_video_init(struct uvc_streaming *stream); | 716 | int uvc_video_init(struct uvc_streaming *stream); |
719 | extern int uvc_video_suspend(struct uvc_streaming *stream); | 717 | int uvc_video_suspend(struct uvc_streaming *stream); |
720 | extern int uvc_video_resume(struct uvc_streaming *stream, int reset); | 718 | int uvc_video_resume(struct uvc_streaming *stream, int reset); |
721 | extern int uvc_video_enable(struct uvc_streaming *stream, int enable); | 719 | int uvc_video_enable(struct uvc_streaming *stream, int enable); |
722 | extern int uvc_probe_video(struct uvc_streaming *stream, | 720 | int uvc_probe_video(struct uvc_streaming *stream, |
723 | struct uvc_streaming_control *probe); | 721 | struct uvc_streaming_control *probe); |
724 | extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | 722 | int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, |
725 | __u8 intfnum, __u8 cs, void *data, __u16 size); | 723 | u8 intfnum, u8 cs, void *data, u16 size); |
726 | void uvc_video_clock_update(struct uvc_streaming *stream, | 724 | void uvc_video_clock_update(struct uvc_streaming *stream, |
727 | struct vb2_v4l2_buffer *vbuf, | 725 | struct vb2_v4l2_buffer *vbuf, |
728 | struct uvc_buffer *buf); | 726 | struct uvc_buffer *buf); |
@@ -737,32 +735,32 @@ int uvc_register_video_device(struct uvc_device *dev, | |||
737 | const struct v4l2_ioctl_ops *ioctl_ops); | 735 | const struct v4l2_ioctl_ops *ioctl_ops); |
738 | 736 | ||
739 | /* Status */ | 737 | /* Status */ |
740 | extern int uvc_status_init(struct uvc_device *dev); | 738 | int uvc_status_init(struct uvc_device *dev); |
741 | extern void uvc_status_cleanup(struct uvc_device *dev); | 739 | void uvc_status_cleanup(struct uvc_device *dev); |
742 | extern int uvc_status_start(struct uvc_device *dev, gfp_t flags); | 740 | int uvc_status_start(struct uvc_device *dev, gfp_t flags); |
743 | extern void uvc_status_stop(struct uvc_device *dev); | 741 | void uvc_status_stop(struct uvc_device *dev); |
744 | 742 | ||
745 | /* Controls */ | 743 | /* Controls */ |
746 | extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops; | 744 | extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops; |
747 | 745 | ||
748 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 746 | int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
749 | struct v4l2_queryctrl *v4l2_ctrl); | 747 | struct v4l2_queryctrl *v4l2_ctrl); |
750 | extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | 748 | int uvc_query_v4l2_menu(struct uvc_video_chain *chain, |
751 | struct v4l2_querymenu *query_menu); | 749 | struct v4l2_querymenu *query_menu); |
752 | 750 | ||
753 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | 751 | int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
754 | const struct uvc_control_mapping *mapping); | 752 | const struct uvc_control_mapping *mapping); |
755 | extern int uvc_ctrl_init_device(struct uvc_device *dev); | 753 | int uvc_ctrl_init_device(struct uvc_device *dev); |
756 | extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); | 754 | void uvc_ctrl_cleanup_device(struct uvc_device *dev); |
757 | extern int uvc_ctrl_restore_values(struct uvc_device *dev); | 755 | int uvc_ctrl_restore_values(struct uvc_device *dev); |
758 | 756 | ||
759 | extern int uvc_ctrl_begin(struct uvc_video_chain *chain); | 757 | int uvc_ctrl_begin(struct uvc_video_chain *chain); |
760 | extern int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, | 758 | int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, |
761 | const struct v4l2_ext_control *xctrls, | 759 | const struct v4l2_ext_control *xctrls, |
762 | unsigned int xctrls_count); | 760 | unsigned int xctrls_count); |
763 | static inline int uvc_ctrl_commit(struct uvc_fh *handle, | 761 | static inline int uvc_ctrl_commit(struct uvc_fh *handle, |
764 | const struct v4l2_ext_control *xctrls, | 762 | const struct v4l2_ext_control *xctrls, |
765 | unsigned int xctrls_count) | 763 | unsigned int xctrls_count) |
766 | { | 764 | { |
767 | return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count); | 765 | return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count); |
768 | } | 766 | } |
@@ -771,25 +769,23 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle) | |||
771 | return __uvc_ctrl_commit(handle, 1, NULL, 0); | 769 | return __uvc_ctrl_commit(handle, 1, NULL, 0); |
772 | } | 770 | } |
773 | 771 | ||
774 | extern int uvc_ctrl_get(struct uvc_video_chain *chain, | 772 | int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); |
775 | struct v4l2_ext_control *xctrl); | 773 | int uvc_ctrl_set(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); |
776 | extern int uvc_ctrl_set(struct uvc_video_chain *chain, | ||
777 | struct v4l2_ext_control *xctrl); | ||
778 | 774 | ||
779 | extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | 775 | int uvc_xu_ctrl_query(struct uvc_video_chain *chain, |
780 | struct uvc_xu_control_query *xqry); | 776 | struct uvc_xu_control_query *xqry); |
781 | 777 | ||
782 | /* Utility functions */ | 778 | /* Utility functions */ |
783 | extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, | 779 | void uvc_simplify_fraction(u32 *numerator, u32 *denominator, |
784 | unsigned int n_terms, unsigned int threshold); | 780 | unsigned int n_terms, unsigned int threshold); |
785 | extern uint32_t uvc_fraction_to_interval(uint32_t numerator, | 781 | u32 uvc_fraction_to_interval(u32 numerator, u32 denominator); |
786 | uint32_t denominator); | 782 | struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts, |
787 | extern struct usb_host_endpoint *uvc_find_endpoint( | 783 | u8 epaddr); |
788 | struct usb_host_interface *alts, __u8 epaddr); | ||
789 | 784 | ||
790 | /* Quirks support */ | 785 | /* Quirks support */ |
791 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, | 786 | void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, |
792 | struct uvc_buffer *buf, struct uvc_buffer *meta_buf); | 787 | struct uvc_buffer *buf, |
788 | struct uvc_buffer *meta_buf); | ||
793 | 789 | ||
794 | /* debugfs and statistics */ | 790 | /* debugfs and statistics */ |
795 | void uvc_debugfs_init(void); | 791 | void uvc_debugfs_init(void); |
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 8b7c19943d46..b8886102c5ed 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c | |||
@@ -517,8 +517,7 @@ static void zr364xx_fillbuff(struct zr364xx_camera *cam, | |||
517 | printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n"); | 517 | printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n"); |
518 | return; | 518 | return; |
519 | } | 519 | } |
520 | DBG("%s: Buffer 0x%08lx size= %d\n", __func__, | 520 | DBG("%s: Buffer %p size= %d\n", __func__, vbuf, pos); |
521 | (unsigned long)vbuf, pos); | ||
522 | /* tell v4l buffer was filled */ | 521 | /* tell v4l buffer was filled */ |
523 | 522 | ||
524 | buf->vb.field_count = cam->frame_count * 2; | 523 | buf->vb.field_count = cam->frame_count * 2; |
@@ -1277,7 +1276,7 @@ static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) | |||
1277 | DBG("%s: cam == NULL\n", __func__); | 1276 | DBG("%s: cam == NULL\n", __func__); |
1278 | return -ENODEV; | 1277 | return -ENODEV; |
1279 | } | 1278 | } |
1280 | DBG("mmap called, vma=0x%08lx\n", (unsigned long)vma); | 1279 | DBG("mmap called, vma=%p\n", vma); |
1281 | 1280 | ||
1282 | ret = videobuf_mmap_mapper(&cam->vb_vidq, vma); | 1281 | ret = videobuf_mmap_mapper(&cam->vb_vidq, vma); |
1283 | 1282 | ||
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 82852f23a3b6..7f858c39753c 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c | |||
@@ -1099,23 +1099,14 @@ static int tuner_s_radio(struct v4l2_subdev *sd) | |||
1099 | */ | 1099 | */ |
1100 | 1100 | ||
1101 | /** | 1101 | /** |
1102 | * tuner_s_power - controls the power state of the tuner | 1102 | * tuner_standby - places the tuner in standby mode |
1103 | * @sd: pointer to struct v4l2_subdev | 1103 | * @sd: pointer to struct v4l2_subdev |
1104 | * @on: a zero value puts the tuner to sleep, non-zero wakes it up | ||
1105 | */ | 1104 | */ |
1106 | static int tuner_s_power(struct v4l2_subdev *sd, int on) | 1105 | static int tuner_standby(struct v4l2_subdev *sd) |
1107 | { | 1106 | { |
1108 | struct tuner *t = to_tuner(sd); | 1107 | struct tuner *t = to_tuner(sd); |
1109 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 1108 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
1110 | 1109 | ||
1111 | if (on) { | ||
1112 | if (t->standby && set_mode(t, t->mode) == 0) { | ||
1113 | dprintk("Waking up tuner\n"); | ||
1114 | set_freq(t, 0); | ||
1115 | } | ||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | dprintk("Putting tuner to sleep\n"); | 1110 | dprintk("Putting tuner to sleep\n"); |
1120 | t->standby = true; | 1111 | t->standby = true; |
1121 | if (analog_ops->standby) | 1112 | if (analog_ops->standby) |
@@ -1328,10 +1319,10 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg) | |||
1328 | 1319 | ||
1329 | static const struct v4l2_subdev_core_ops tuner_core_ops = { | 1320 | static const struct v4l2_subdev_core_ops tuner_core_ops = { |
1330 | .log_status = tuner_log_status, | 1321 | .log_status = tuner_log_status, |
1331 | .s_power = tuner_s_power, | ||
1332 | }; | 1322 | }; |
1333 | 1323 | ||
1334 | static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { | 1324 | static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = { |
1325 | .standby = tuner_standby, | ||
1335 | .s_radio = tuner_s_radio, | 1326 | .s_radio = tuner_s_radio, |
1336 | .g_tuner = tuner_g_tuner, | 1327 | .g_tuner = tuner_g_tuner, |
1337 | .s_tuner = tuner_s_tuner, | 1328 | .s_tuner = tuner_s_tuner, |
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 8650ad92b64d..b518b92d6d96 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c | |||
@@ -357,31 +357,35 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, | |||
357 | } | 357 | } |
358 | EXPORT_SYMBOL_GPL(v4l_bound_align_image); | 358 | EXPORT_SYMBOL_GPL(v4l_bound_align_image); |
359 | 359 | ||
360 | const struct v4l2_frmsize_discrete * | 360 | const void * |
361 | v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes, | 361 | __v4l2_find_nearest_size(const void *array, size_t array_size, |
362 | size_t num_sizes, | 362 | size_t entry_size, size_t width_offset, |
363 | s32 width, s32 height) | 363 | size_t height_offset, s32 width, s32 height) |
364 | { | 364 | { |
365 | int i; | 365 | u32 error, min_error = U32_MAX; |
366 | u32 error, min_error = UINT_MAX; | 366 | const void *best = NULL; |
367 | const struct v4l2_frmsize_discrete *size, *best = NULL; | 367 | unsigned int i; |
368 | 368 | ||
369 | if (!sizes) | 369 | if (!array) |
370 | return NULL; | 370 | return NULL; |
371 | 371 | ||
372 | for (i = 0, size = sizes; i < num_sizes; i++, size++) { | 372 | for (i = 0; i < array_size; i++, array += entry_size) { |
373 | error = abs(size->width - width) + abs(size->height - height); | 373 | const u32 *entry_width = array + width_offset; |
374 | if (error < min_error) { | 374 | const u32 *entry_height = array + height_offset; |
375 | min_error = error; | 375 | |
376 | best = size; | 376 | error = abs(*entry_width - width) + abs(*entry_height - height); |
377 | } | 377 | if (error > min_error) |
378 | continue; | ||
379 | |||
380 | min_error = error; | ||
381 | best = array; | ||
378 | if (!error) | 382 | if (!error) |
379 | break; | 383 | break; |
380 | } | 384 | } |
381 | 385 | ||
382 | return best; | 386 | return best; |
383 | } | 387 | } |
384 | EXPORT_SYMBOL_GPL(v4l2_find_nearest_format); | 388 | EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size); |
385 | 389 | ||
386 | void v4l2_get_timestamp(struct timeval *tv) | 390 | void v4l2_get_timestamp(struct timeval *tv) |
387 | { | 391 | { |
@@ -392,3 +396,51 @@ void v4l2_get_timestamp(struct timeval *tv) | |||
392 | tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC; | 396 | tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC; |
393 | } | 397 | } |
394 | EXPORT_SYMBOL_GPL(v4l2_get_timestamp); | 398 | EXPORT_SYMBOL_GPL(v4l2_get_timestamp); |
399 | |||
400 | int v4l2_g_parm_cap(struct video_device *vdev, | ||
401 | struct v4l2_subdev *sd, struct v4l2_streamparm *a) | ||
402 | { | ||
403 | struct v4l2_subdev_frame_interval ival = { 0 }; | ||
404 | int ret; | ||
405 | |||
406 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
407 | a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
408 | return -EINVAL; | ||
409 | |||
410 | if (vdev->device_caps & V4L2_CAP_READWRITE) | ||
411 | a->parm.capture.readbuffers = 2; | ||
412 | if (v4l2_subdev_has_op(sd, video, g_frame_interval)) | ||
413 | a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
414 | ret = v4l2_subdev_call(sd, video, g_frame_interval, &ival); | ||
415 | if (!ret) | ||
416 | a->parm.capture.timeperframe = ival.interval; | ||
417 | return ret; | ||
418 | } | ||
419 | EXPORT_SYMBOL_GPL(v4l2_g_parm_cap); | ||
420 | |||
421 | int v4l2_s_parm_cap(struct video_device *vdev, | ||
422 | struct v4l2_subdev *sd, struct v4l2_streamparm *a) | ||
423 | { | ||
424 | struct v4l2_subdev_frame_interval ival = { | ||
425 | .interval = a->parm.capture.timeperframe | ||
426 | }; | ||
427 | int ret; | ||
428 | |||
429 | if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
430 | a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
431 | return -EINVAL; | ||
432 | |||
433 | memset(&a->parm, 0, sizeof(a->parm)); | ||
434 | if (vdev->device_caps & V4L2_CAP_READWRITE) | ||
435 | a->parm.capture.readbuffers = 2; | ||
436 | else | ||
437 | a->parm.capture.readbuffers = 0; | ||
438 | |||
439 | if (v4l2_subdev_has_op(sd, video, g_frame_interval)) | ||
440 | a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
441 | ret = v4l2_subdev_call(sd, video, s_frame_interval, &ival); | ||
442 | if (!ret) | ||
443 | a->parm.capture.timeperframe = ival.interval; | ||
444 | return ret; | ||
445 | } | ||
446 | EXPORT_SYMBOL_GPL(v4l2_s_parm_cap); | ||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index ce08b50b8290..d29e45516eb7 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | |||
@@ -480,6 +480,57 @@ const char * const *v4l2_ctrl_get_menu(u32 id) | |||
480 | NULL, | 480 | NULL, |
481 | }; | 481 | }; |
482 | 482 | ||
483 | static const char * const hevc_profile[] = { | ||
484 | "Main", | ||
485 | "Main Still Picture", | ||
486 | "Main 10", | ||
487 | NULL, | ||
488 | }; | ||
489 | static const char * const hevc_level[] = { | ||
490 | "1", | ||
491 | "2", | ||
492 | "2.1", | ||
493 | "3", | ||
494 | "3.1", | ||
495 | "4", | ||
496 | "4.1", | ||
497 | "5", | ||
498 | "5.1", | ||
499 | "5.2", | ||
500 | "6", | ||
501 | "6.1", | ||
502 | "6.2", | ||
503 | NULL, | ||
504 | }; | ||
505 | static const char * const hevc_hierarchial_coding_type[] = { | ||
506 | "B", | ||
507 | "P", | ||
508 | NULL, | ||
509 | }; | ||
510 | static const char * const hevc_refresh_type[] = { | ||
511 | "None", | ||
512 | "CRA", | ||
513 | "IDR", | ||
514 | NULL, | ||
515 | }; | ||
516 | static const char * const hevc_size_of_length_field[] = { | ||
517 | "0", | ||
518 | "1", | ||
519 | "2", | ||
520 | "4", | ||
521 | NULL, | ||
522 | }; | ||
523 | static const char * const hevc_tier[] = { | ||
524 | "Main", | ||
525 | "High", | ||
526 | NULL, | ||
527 | }; | ||
528 | static const char * const hevc_loop_filter_mode[] = { | ||
529 | "Disabled", | ||
530 | "Enabled", | ||
531 | "Disabled at slice boundary", | ||
532 | "NULL", | ||
533 | }; | ||
483 | 534 | ||
484 | switch (id) { | 535 | switch (id) { |
485 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: | 536 | case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: |
@@ -575,6 +626,20 @@ const char * const *v4l2_ctrl_get_menu(u32 id) | |||
575 | return dv_it_content_type; | 626 | return dv_it_content_type; |
576 | case V4L2_CID_DETECT_MD_MODE: | 627 | case V4L2_CID_DETECT_MD_MODE: |
577 | return detect_md_mode; | 628 | return detect_md_mode; |
629 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: | ||
630 | return hevc_profile; | ||
631 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: | ||
632 | return hevc_level; | ||
633 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: | ||
634 | return hevc_hierarchial_coding_type; | ||
635 | case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: | ||
636 | return hevc_refresh_type; | ||
637 | case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: | ||
638 | return hevc_size_of_length_field; | ||
639 | case V4L2_CID_MPEG_VIDEO_HEVC_TIER: | ||
640 | return hevc_tier; | ||
641 | case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: | ||
642 | return hevc_loop_filter_mode; | ||
578 | 643 | ||
579 | default: | 644 | default: |
580 | return NULL; | 645 | return NULL; |
@@ -776,6 +841,53 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
776 | case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; | 841 | case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; |
777 | case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: return "VPX Profile"; | 842 | case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: return "VPX Profile"; |
778 | 843 | ||
844 | /* HEVC controls */ | ||
845 | case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; | ||
846 | case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: return "HEVC P-Frame QP Value"; | ||
847 | case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return "HEVC B-Frame QP Value"; | ||
848 | case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: return "HEVC Minimum QP Value"; | ||
849 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: return "HEVC Maximum QP Value"; | ||
850 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: return "HEVC Profile"; | ||
851 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: return "HEVC Level"; | ||
852 | case V4L2_CID_MPEG_VIDEO_HEVC_TIER: return "HEVC Tier"; | ||
853 | case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: return "HEVC Frame Rate Resolution"; | ||
854 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: return "HEVC Maximum Coding Unit Depth"; | ||
855 | case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC Refresh Type"; | ||
856 | case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC Constant Intra Prediction"; | ||
857 | case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: return "HEVC Lossless Encoding"; | ||
858 | case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: return "HEVC Wavefront"; | ||
859 | case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: return "HEVC Loop Filter"; | ||
860 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: return "HEVC QP Values"; | ||
861 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC Hierarchical Coding Type"; | ||
862 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: return "HEVC Hierarchical Coding Layer"; | ||
863 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: return "HEVC Hierarchical Layer 0 QP"; | ||
864 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: return "HEVC Hierarchical Layer 1 QP"; | ||
865 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: return "HEVC Hierarchical Layer 2 QP"; | ||
866 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: return "HEVC Hierarchical Layer 3 QP"; | ||
867 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: return "HEVC Hierarchical Layer 4 QP"; | ||
868 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: return "HEVC Hierarchical Layer 5 QP"; | ||
869 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: return "HEVC Hierarchical Layer 6 QP"; | ||
870 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: return "HEVC Hierarchical Lay 0 BitRate"; | ||
871 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: return "HEVC Hierarchical Lay 1 BitRate"; | ||
872 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: return "HEVC Hierarchical Lay 2 BitRate"; | ||
873 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: return "HEVC Hierarchical Lay 3 BitRate"; | ||
874 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: return "HEVC Hierarchical Lay 4 BitRate"; | ||
875 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: return "HEVC Hierarchical Lay 5 BitRate"; | ||
876 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: return "HEVC Hierarchical Lay 6 BitRate"; | ||
877 | case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: return "HEVC General PB"; | ||
878 | case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: return "HEVC Temporal ID"; | ||
879 | case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: return "HEVC Strong Intra Smoothing"; | ||
880 | case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: return "HEVC Intra PU Split"; | ||
881 | case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: return "HEVC TMV Prediction"; | ||
882 | case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: return "HEVC Max Num of Candidate MVs"; | ||
883 | case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: return "HEVC ENC Without Startcode"; | ||
884 | case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: return "HEVC Num of I-Frame b/w 2 IDR"; | ||
885 | case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: return "HEVC Loop Filter Beta Offset"; | ||
886 | case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: return "HEVC Loop Filter TC Offset"; | ||
887 | case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field"; | ||
888 | case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame"; | ||
889 | case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR"; | ||
890 | |||
779 | /* CAMERA controls */ | 891 | /* CAMERA controls */ |
780 | /* Keep the order of the 'case's the same as in v4l2-controls.h! */ | 892 | /* Keep the order of the 'case's the same as in v4l2-controls.h! */ |
781 | case V4L2_CID_CAMERA_CLASS: return "Camera Controls"; | 893 | case V4L2_CID_CAMERA_CLASS: return "Camera Controls"; |
@@ -1069,6 +1181,13 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, | |||
1069 | case V4L2_CID_TUNE_DEEMPHASIS: | 1181 | case V4L2_CID_TUNE_DEEMPHASIS: |
1070 | case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: | 1182 | case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: |
1071 | case V4L2_CID_DETECT_MD_MODE: | 1183 | case V4L2_CID_DETECT_MD_MODE: |
1184 | case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: | ||
1185 | case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: | ||
1186 | case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: | ||
1187 | case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: | ||
1188 | case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: | ||
1189 | case V4L2_CID_MPEG_VIDEO_HEVC_TIER: | ||
1190 | case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: | ||
1072 | *type = V4L2_CTRL_TYPE_MENU; | 1191 | *type = V4L2_CTRL_TYPE_MENU; |
1073 | break; | 1192 | break; |
1074 | case V4L2_CID_LINK_FREQ: | 1193 | case V4L2_CID_LINK_FREQ: |
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index e2ee5f00c445..c81faea96fba 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c | |||
@@ -1,21 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
1 | /* | 2 | /* |
2 | * v4l2-dv-timings - dv-timings helper functions | 3 | * v4l2-dv-timings - dv-timings helper functions |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 6 | */ |
20 | 7 | ||
21 | #include <linux/module.h> | 8 | #include <linux/module.h> |
@@ -27,6 +14,7 @@ | |||
27 | #include <linux/v4l2-dv-timings.h> | 14 | #include <linux/v4l2-dv-timings.h> |
28 | #include <media/v4l2-dv-timings.h> | 15 | #include <media/v4l2-dv-timings.h> |
29 | #include <linux/math64.h> | 16 | #include <linux/math64.h> |
17 | #include <linux/hdmi.h> | ||
30 | 18 | ||
31 | MODULE_AUTHOR("Hans Verkuil"); | 19 | MODULE_AUTHOR("Hans Verkuil"); |
32 | MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); | 20 | MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); |
@@ -814,3 +802,143 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait) | |||
814 | return aspect; | 802 | return aspect; |
815 | } | 803 | } |
816 | EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio); | 804 | EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio); |
805 | |||
806 | /** v4l2_hdmi_rx_colorimetry - determine HDMI colorimetry information | ||
807 | * based on various InfoFrames. | ||
808 | * @avi: the AVI InfoFrame | ||
809 | * @hdmi: the HDMI Vendor InfoFrame, may be NULL | ||
810 | * @height: the frame height | ||
811 | * | ||
812 | * Determines the HDMI colorimetry information, i.e. how the HDMI | ||
813 | * pixel color data should be interpreted. | ||
814 | * | ||
815 | * Note that some of the newer features (DCI-P3, HDR) are not yet | ||
816 | * implemented: the hdmi.h header needs to be updated to the HDMI 2.0 | ||
817 | * and CTA-861-G standards. | ||
818 | */ | ||
819 | struct v4l2_hdmi_colorimetry | ||
820 | v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi, | ||
821 | const struct hdmi_vendor_infoframe *hdmi, | ||
822 | unsigned int height) | ||
823 | { | ||
824 | struct v4l2_hdmi_colorimetry c = { | ||
825 | V4L2_COLORSPACE_SRGB, | ||
826 | V4L2_YCBCR_ENC_DEFAULT, | ||
827 | V4L2_QUANTIZATION_FULL_RANGE, | ||
828 | V4L2_XFER_FUNC_SRGB | ||
829 | }; | ||
830 | bool is_ce = avi->video_code || (hdmi && hdmi->vic); | ||
831 | bool is_sdtv = height <= 576; | ||
832 | bool default_is_lim_range_rgb = avi->video_code > 1; | ||
833 | |||
834 | switch (avi->colorspace) { | ||
835 | case HDMI_COLORSPACE_RGB: | ||
836 | /* RGB pixel encoding */ | ||
837 | switch (avi->colorimetry) { | ||
838 | case HDMI_COLORIMETRY_EXTENDED: | ||
839 | switch (avi->extended_colorimetry) { | ||
840 | case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB: | ||
841 | c.colorspace = V4L2_COLORSPACE_ADOBERGB; | ||
842 | c.xfer_func = V4L2_XFER_FUNC_ADOBERGB; | ||
843 | break; | ||
844 | case HDMI_EXTENDED_COLORIMETRY_BT2020: | ||
845 | c.colorspace = V4L2_COLORSPACE_BT2020; | ||
846 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
847 | break; | ||
848 | default: | ||
849 | break; | ||
850 | } | ||
851 | break; | ||
852 | default: | ||
853 | break; | ||
854 | } | ||
855 | switch (avi->quantization_range) { | ||
856 | case HDMI_QUANTIZATION_RANGE_LIMITED: | ||
857 | c.quantization = V4L2_QUANTIZATION_LIM_RANGE; | ||
858 | break; | ||
859 | case HDMI_QUANTIZATION_RANGE_FULL: | ||
860 | break; | ||
861 | default: | ||
862 | if (default_is_lim_range_rgb) | ||
863 | c.quantization = V4L2_QUANTIZATION_LIM_RANGE; | ||
864 | break; | ||
865 | } | ||
866 | break; | ||
867 | |||
868 | default: | ||
869 | /* YCbCr pixel encoding */ | ||
870 | c.quantization = V4L2_QUANTIZATION_LIM_RANGE; | ||
871 | switch (avi->colorimetry) { | ||
872 | case HDMI_COLORIMETRY_NONE: | ||
873 | if (!is_ce) | ||
874 | break; | ||
875 | if (is_sdtv) { | ||
876 | c.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
877 | c.ycbcr_enc = V4L2_YCBCR_ENC_601; | ||
878 | } else { | ||
879 | c.colorspace = V4L2_COLORSPACE_REC709; | ||
880 | c.ycbcr_enc = V4L2_YCBCR_ENC_709; | ||
881 | } | ||
882 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
883 | break; | ||
884 | case HDMI_COLORIMETRY_ITU_601: | ||
885 | c.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
886 | c.ycbcr_enc = V4L2_YCBCR_ENC_601; | ||
887 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
888 | break; | ||
889 | case HDMI_COLORIMETRY_ITU_709: | ||
890 | c.colorspace = V4L2_COLORSPACE_REC709; | ||
891 | c.ycbcr_enc = V4L2_YCBCR_ENC_709; | ||
892 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
893 | break; | ||
894 | case HDMI_COLORIMETRY_EXTENDED: | ||
895 | switch (avi->extended_colorimetry) { | ||
896 | case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601: | ||
897 | c.colorspace = V4L2_COLORSPACE_REC709; | ||
898 | c.ycbcr_enc = V4L2_YCBCR_ENC_XV709; | ||
899 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
900 | break; | ||
901 | case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709: | ||
902 | c.colorspace = V4L2_COLORSPACE_REC709; | ||
903 | c.ycbcr_enc = V4L2_YCBCR_ENC_XV601; | ||
904 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
905 | break; | ||
906 | case HDMI_EXTENDED_COLORIMETRY_S_YCC_601: | ||
907 | c.colorspace = V4L2_COLORSPACE_SRGB; | ||
908 | c.ycbcr_enc = V4L2_YCBCR_ENC_601; | ||
909 | c.xfer_func = V4L2_XFER_FUNC_SRGB; | ||
910 | break; | ||
911 | case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601: | ||
912 | c.colorspace = V4L2_COLORSPACE_ADOBERGB; | ||
913 | c.ycbcr_enc = V4L2_YCBCR_ENC_601; | ||
914 | c.xfer_func = V4L2_XFER_FUNC_ADOBERGB; | ||
915 | break; | ||
916 | case HDMI_EXTENDED_COLORIMETRY_BT2020: | ||
917 | c.colorspace = V4L2_COLORSPACE_BT2020; | ||
918 | c.ycbcr_enc = V4L2_YCBCR_ENC_BT2020; | ||
919 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
920 | break; | ||
921 | case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM: | ||
922 | c.colorspace = V4L2_COLORSPACE_BT2020; | ||
923 | c.ycbcr_enc = V4L2_YCBCR_ENC_BT2020_CONST_LUM; | ||
924 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
925 | break; | ||
926 | default: /* fall back to ITU_709 */ | ||
927 | c.colorspace = V4L2_COLORSPACE_REC709; | ||
928 | c.ycbcr_enc = V4L2_YCBCR_ENC_709; | ||
929 | c.xfer_func = V4L2_XFER_FUNC_709; | ||
930 | break; | ||
931 | } | ||
932 | break; | ||
933 | default: | ||
934 | break; | ||
935 | } | ||
936 | /* | ||
937 | * YCC Quantization Range signaling is more-or-less broken, | ||
938 | * let's just ignore this. | ||
939 | */ | ||
940 | break; | ||
941 | } | ||
942 | return c; | ||
943 | } | ||
944 | EXPORT_SYMBOL_GPL(v4l2_hdmi_rx_colorimetry); | ||
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 260288ca4f55..f48c505550e0 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
@@ -1273,6 +1273,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) | |||
1273 | case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; | 1273 | case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; |
1274 | case V4L2_PIX_FMT_VP8: descr = "VP8"; break; | 1274 | case V4L2_PIX_FMT_VP8: descr = "VP8"; break; |
1275 | case V4L2_PIX_FMT_VP9: descr = "VP9"; break; | 1275 | case V4L2_PIX_FMT_VP9: descr = "VP9"; break; |
1276 | case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ | ||
1276 | case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; | 1277 | case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; |
1277 | case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; | 1278 | case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; |
1278 | case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; | 1279 | case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; |
@@ -2611,7 +2612,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { | |||
2611 | IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE), | 2612 | IOCTL_INFO_FNC(VIDIOC_PREPARE_BUF, v4l_prepare_buf, v4l_print_buffer, INFO_FL_QUEUE), |
2612 | IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)), | 2613 | IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, INFO_FL_CLEAR(v4l2_enum_dv_timings, pad)), |
2613 | IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY), | 2614 | IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, INFO_FL_ALWAYS_COPY), |
2614 | IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)), | 2615 | IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, pad)), |
2615 | IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), | 2616 | IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), |
2616 | IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), | 2617 | IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), |
2617 | IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)), | 2618 | IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)), |
@@ -2832,14 +2833,15 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
2832 | size_t array_size = 0; | 2833 | size_t array_size = 0; |
2833 | void __user *user_ptr = NULL; | 2834 | void __user *user_ptr = NULL; |
2834 | void **kernel_ptr = NULL; | 2835 | void **kernel_ptr = NULL; |
2836 | const size_t ioc_size = _IOC_SIZE(cmd); | ||
2835 | 2837 | ||
2836 | /* Copy arguments into temp kernel buffer */ | 2838 | /* Copy arguments into temp kernel buffer */ |
2837 | if (_IOC_DIR(cmd) != _IOC_NONE) { | 2839 | if (_IOC_DIR(cmd) != _IOC_NONE) { |
2838 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { | 2840 | if (ioc_size <= sizeof(sbuf)) { |
2839 | parg = sbuf; | 2841 | parg = sbuf; |
2840 | } else { | 2842 | } else { |
2841 | /* too big to allocate from stack */ | 2843 | /* too big to allocate from stack */ |
2842 | mbuf = kvmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | 2844 | mbuf = kvmalloc(ioc_size, GFP_KERNEL); |
2843 | if (NULL == mbuf) | 2845 | if (NULL == mbuf) |
2844 | return -ENOMEM; | 2846 | return -ENOMEM; |
2845 | parg = mbuf; | 2847 | parg = mbuf; |
@@ -2847,7 +2849,7 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
2847 | 2849 | ||
2848 | err = -EFAULT; | 2850 | err = -EFAULT; |
2849 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 2851 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
2850 | unsigned int n = _IOC_SIZE(cmd); | 2852 | unsigned int n = ioc_size; |
2851 | 2853 | ||
2852 | /* | 2854 | /* |
2853 | * In some cases, only a few fields are used as input, | 2855 | * In some cases, only a few fields are used as input, |
@@ -2868,11 +2870,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
2868 | goto out; | 2870 | goto out; |
2869 | 2871 | ||
2870 | /* zero out anything we don't copy from userspace */ | 2872 | /* zero out anything we don't copy from userspace */ |
2871 | if (n < _IOC_SIZE(cmd)) | 2873 | if (n < ioc_size) |
2872 | memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); | 2874 | memset((u8 *)parg + n, 0, ioc_size - n); |
2873 | } else { | 2875 | } else { |
2874 | /* read-only ioctl */ | 2876 | /* read-only ioctl */ |
2875 | memset(parg, 0, _IOC_SIZE(cmd)); | 2877 | memset(parg, 0, ioc_size); |
2876 | } | 2878 | } |
2877 | } | 2879 | } |
2878 | 2880 | ||
@@ -2930,7 +2932,7 @@ out_array_args: | |||
2930 | switch (_IOC_DIR(cmd)) { | 2932 | switch (_IOC_DIR(cmd)) { |
2931 | case _IOC_READ: | 2933 | case _IOC_READ: |
2932 | case (_IOC_WRITE | _IOC_READ): | 2934 | case (_IOC_WRITE | _IOC_READ): |
2933 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | 2935 | if (copy_to_user((void __user *)arg, parg, ioc_size)) |
2934 | err = -EFAULT; | 2936 | err = -EFAULT; |
2935 | break; | 2937 | break; |
2936 | } | 2938 | } |
diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index 1d550afeda13..0fc185a2ce90 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c | |||
@@ -1,3 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
2 | |||
1 | /* | 3 | /* |
2 | * Media Controller ancillary functions | 4 | * Media Controller ancillary functions |
3 | * | 5 | * |
@@ -5,16 +7,6 @@ | |||
5 | * Copyright (C) 2016 Shuah Khan <shuahkh@osg.samsung.com> | 7 | * Copyright (C) 2016 Shuah Khan <shuahkh@osg.samsung.com> |
6 | * Copyright (C) 2006-2010 Nokia Corporation | 8 | * Copyright (C) 2006-2010 Nokia Corporation |
7 | * Copyright (c) 2016 Intel Corporation. | 9 | * Copyright (c) 2016 Intel Corporation. |
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | 10 | */ |
19 | 11 | ||
20 | #include <linux/module.h> | 12 | #include <linux/module.h> |
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index c5639817db34..f9eed938d348 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c | |||
@@ -187,27 +187,51 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
187 | 187 | ||
188 | switch (cmd) { | 188 | switch (cmd) { |
189 | case VIDIOC_QUERYCTRL: | 189 | case VIDIOC_QUERYCTRL: |
190 | /* | ||
191 | * TODO: this really should be folded into v4l2_queryctrl (this | ||
192 | * currently returns -EINVAL for NULL control handlers). | ||
193 | * However, v4l2_queryctrl() is still called directly by | ||
194 | * drivers as well and until that has been addressed I believe | ||
195 | * it is safer to do the check here. The same is true for the | ||
196 | * other control ioctls below. | ||
197 | */ | ||
198 | if (!vfh->ctrl_handler) | ||
199 | return -ENOTTY; | ||
190 | return v4l2_queryctrl(vfh->ctrl_handler, arg); | 200 | return v4l2_queryctrl(vfh->ctrl_handler, arg); |
191 | 201 | ||
192 | case VIDIOC_QUERY_EXT_CTRL: | 202 | case VIDIOC_QUERY_EXT_CTRL: |
203 | if (!vfh->ctrl_handler) | ||
204 | return -ENOTTY; | ||
193 | return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg); | 205 | return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg); |
194 | 206 | ||
195 | case VIDIOC_QUERYMENU: | 207 | case VIDIOC_QUERYMENU: |
208 | if (!vfh->ctrl_handler) | ||
209 | return -ENOTTY; | ||
196 | return v4l2_querymenu(vfh->ctrl_handler, arg); | 210 | return v4l2_querymenu(vfh->ctrl_handler, arg); |
197 | 211 | ||
198 | case VIDIOC_G_CTRL: | 212 | case VIDIOC_G_CTRL: |
213 | if (!vfh->ctrl_handler) | ||
214 | return -ENOTTY; | ||
199 | return v4l2_g_ctrl(vfh->ctrl_handler, arg); | 215 | return v4l2_g_ctrl(vfh->ctrl_handler, arg); |
200 | 216 | ||
201 | case VIDIOC_S_CTRL: | 217 | case VIDIOC_S_CTRL: |
218 | if (!vfh->ctrl_handler) | ||
219 | return -ENOTTY; | ||
202 | return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg); | 220 | return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg); |
203 | 221 | ||
204 | case VIDIOC_G_EXT_CTRLS: | 222 | case VIDIOC_G_EXT_CTRLS: |
223 | if (!vfh->ctrl_handler) | ||
224 | return -ENOTTY; | ||
205 | return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg); | 225 | return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg); |
206 | 226 | ||
207 | case VIDIOC_S_EXT_CTRLS: | 227 | case VIDIOC_S_EXT_CTRLS: |
228 | if (!vfh->ctrl_handler) | ||
229 | return -ENOTTY; | ||
208 | return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg); | 230 | return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg); |
209 | 231 | ||
210 | case VIDIOC_TRY_EXT_CTRLS: | 232 | case VIDIOC_TRY_EXT_CTRLS: |
233 | if (!vfh->ctrl_handler) | ||
234 | return -ENOTTY; | ||
211 | return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg); | 235 | return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg); |
212 | 236 | ||
213 | case VIDIOC_DQEVENT: | 237 | case VIDIOC_DQEVENT: |
@@ -239,6 +263,19 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
239 | return -EPERM; | 263 | return -EPERM; |
240 | return v4l2_subdev_call(sd, core, s_register, p); | 264 | return v4l2_subdev_call(sd, core, s_register, p); |
241 | } | 265 | } |
266 | case VIDIOC_DBG_G_CHIP_INFO: | ||
267 | { | ||
268 | struct v4l2_dbg_chip_info *p = arg; | ||
269 | |||
270 | if (p->match.type != V4L2_CHIP_MATCH_SUBDEV || p->match.addr) | ||
271 | return -EINVAL; | ||
272 | if (sd->ops->core && sd->ops->core->s_register) | ||
273 | p->flags |= V4L2_CHIP_FL_WRITABLE; | ||
274 | if (sd->ops->core && sd->ops->core->g_register) | ||
275 | p->flags |= V4L2_CHIP_FL_READABLE; | ||
276 | strlcpy(p->name, sd->name, sizeof(p->name)); | ||
277 | return 0; | ||
278 | } | ||
242 | #endif | 279 | #endif |
243 | 280 | ||
244 | case VIDIOC_LOG_STATUS: { | 281 | case VIDIOC_LOG_STATUS: { |
@@ -260,6 +297,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
260 | if (rval) | 297 | if (rval) |
261 | return rval; | 298 | return rval; |
262 | 299 | ||
300 | memset(format->reserved, 0, sizeof(format->reserved)); | ||
301 | memset(format->format.reserved, 0, sizeof(format->format.reserved)); | ||
263 | return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format); | 302 | return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format); |
264 | } | 303 | } |
265 | 304 | ||
@@ -270,6 +309,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
270 | if (rval) | 309 | if (rval) |
271 | return rval; | 310 | return rval; |
272 | 311 | ||
312 | memset(format->reserved, 0, sizeof(format->reserved)); | ||
313 | memset(format->format.reserved, 0, sizeof(format->format.reserved)); | ||
273 | return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); | 314 | return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); |
274 | } | 315 | } |
275 | 316 | ||
@@ -281,6 +322,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
281 | if (rval) | 322 | if (rval) |
282 | return rval; | 323 | return rval; |
283 | 324 | ||
325 | memset(crop->reserved, 0, sizeof(crop->reserved)); | ||
284 | memset(&sel, 0, sizeof(sel)); | 326 | memset(&sel, 0, sizeof(sel)); |
285 | sel.which = crop->which; | 327 | sel.which = crop->which; |
286 | sel.pad = crop->pad; | 328 | sel.pad = crop->pad; |
@@ -298,6 +340,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
298 | struct v4l2_subdev_crop *crop = arg; | 340 | struct v4l2_subdev_crop *crop = arg; |
299 | struct v4l2_subdev_selection sel; | 341 | struct v4l2_subdev_selection sel; |
300 | 342 | ||
343 | memset(crop->reserved, 0, sizeof(crop->reserved)); | ||
301 | rval = check_crop(sd, crop); | 344 | rval = check_crop(sd, crop); |
302 | if (rval) | 345 | if (rval) |
303 | return rval; | 346 | return rval; |
@@ -326,6 +369,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
326 | if (code->pad >= sd->entity.num_pads) | 369 | if (code->pad >= sd->entity.num_pads) |
327 | return -EINVAL; | 370 | return -EINVAL; |
328 | 371 | ||
372 | memset(code->reserved, 0, sizeof(code->reserved)); | ||
329 | return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad, | 373 | return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad, |
330 | code); | 374 | code); |
331 | } | 375 | } |
@@ -340,6 +384,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
340 | if (fse->pad >= sd->entity.num_pads) | 384 | if (fse->pad >= sd->entity.num_pads) |
341 | return -EINVAL; | 385 | return -EINVAL; |
342 | 386 | ||
387 | memset(fse->reserved, 0, sizeof(fse->reserved)); | ||
343 | return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad, | 388 | return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad, |
344 | fse); | 389 | fse); |
345 | } | 390 | } |
@@ -350,6 +395,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
350 | if (fi->pad >= sd->entity.num_pads) | 395 | if (fi->pad >= sd->entity.num_pads) |
351 | return -EINVAL; | 396 | return -EINVAL; |
352 | 397 | ||
398 | memset(fi->reserved, 0, sizeof(fi->reserved)); | ||
353 | return v4l2_subdev_call(sd, video, g_frame_interval, arg); | 399 | return v4l2_subdev_call(sd, video, g_frame_interval, arg); |
354 | } | 400 | } |
355 | 401 | ||
@@ -359,6 +405,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
359 | if (fi->pad >= sd->entity.num_pads) | 405 | if (fi->pad >= sd->entity.num_pads) |
360 | return -EINVAL; | 406 | return -EINVAL; |
361 | 407 | ||
408 | memset(fi->reserved, 0, sizeof(fi->reserved)); | ||
362 | return v4l2_subdev_call(sd, video, s_frame_interval, arg); | 409 | return v4l2_subdev_call(sd, video, s_frame_interval, arg); |
363 | } | 410 | } |
364 | 411 | ||
@@ -372,6 +419,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
372 | if (fie->pad >= sd->entity.num_pads) | 419 | if (fie->pad >= sd->entity.num_pads) |
373 | return -EINVAL; | 420 | return -EINVAL; |
374 | 421 | ||
422 | memset(fie->reserved, 0, sizeof(fie->reserved)); | ||
375 | return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad, | 423 | return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad, |
376 | fie); | 424 | fie); |
377 | } | 425 | } |
@@ -383,6 +431,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
383 | if (rval) | 431 | if (rval) |
384 | return rval; | 432 | return rval; |
385 | 433 | ||
434 | memset(sel->reserved, 0, sizeof(sel->reserved)); | ||
386 | return v4l2_subdev_call( | 435 | return v4l2_subdev_call( |
387 | sd, pad, get_selection, subdev_fh->pad, sel); | 436 | sd, pad, get_selection, subdev_fh->pad, sel); |
388 | } | 437 | } |
@@ -394,6 +443,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
394 | if (rval) | 443 | if (rval) |
395 | return rval; | 444 | return rval; |
396 | 445 | ||
446 | memset(sel->reserved, 0, sizeof(sel->reserved)); | ||
397 | return v4l2_subdev_call( | 447 | return v4l2_subdev_call( |
398 | sd, pad, set_selection, subdev_fh->pad, sel); | 448 | sd, pad, set_selection, subdev_fh->pad, sel); |
399 | } | 449 | } |
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index f412429cf5ba..add2edb23eac 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c | |||
@@ -244,9 +244,8 @@ static int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, | |||
244 | goto out_free_pages; | 244 | goto out_free_pages; |
245 | } | 245 | } |
246 | 246 | ||
247 | dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n", | 247 | dprintk(1, "vmalloc is at addr %p, size=%d\n", |
248 | (unsigned long)dma->vaddr, | 248 | dma->vaddr, nr_pages << PAGE_SHIFT); |
249 | nr_pages << PAGE_SHIFT); | ||
250 | 249 | ||
251 | memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); | 250 | memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); |
252 | dma->nr_pages = nr_pages; | 251 | dma->nr_pages = nr_pages; |
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index e68e1d343d53..4c495a10025c 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig | |||
@@ -23,12 +23,14 @@ source "drivers/staging/media/atomisp/Kconfig" | |||
23 | 23 | ||
24 | source "drivers/staging/media/bcm2048/Kconfig" | 24 | source "drivers/staging/media/bcm2048/Kconfig" |
25 | 25 | ||
26 | source "drivers/staging/media/cxd2099/Kconfig" | ||
27 | |||
28 | source "drivers/staging/media/davinci_vpfe/Kconfig" | 26 | source "drivers/staging/media/davinci_vpfe/Kconfig" |
29 | 27 | ||
30 | source "drivers/staging/media/imx/Kconfig" | 28 | source "drivers/staging/media/imx/Kconfig" |
31 | 29 | ||
30 | source "drivers/staging/media/imx074/Kconfig" | ||
31 | |||
32 | source "drivers/staging/media/mt9t031/Kconfig" | ||
33 | |||
32 | source "drivers/staging/media/omap4iss/Kconfig" | 34 | source "drivers/staging/media/omap4iss/Kconfig" |
33 | 35 | ||
34 | source "drivers/staging/media/tegra-vde/Kconfig" | 36 | source "drivers/staging/media/tegra-vde/Kconfig" |
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 59a47f69884f..61a5765cb98f 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | obj-$(CONFIG_I2C_BCM2048) += bcm2048/ | 2 | obj-$(CONFIG_I2C_BCM2048) += bcm2048/ |
3 | obj-$(CONFIG_DVB_CXD2099) += cxd2099/ | ||
4 | obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/ | 3 | obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/ |
4 | obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074/ | ||
5 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031/ | ||
5 | obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ | 6 | obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ |
6 | obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ | 7 | obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ |
7 | obj-$(CONFIG_INTEL_ATOMISP) += atomisp/ | 8 | obj-$(CONFIG_INTEL_ATOMISP) += atomisp/ |
diff --git a/drivers/staging/media/atomisp/i2c/Kconfig b/drivers/staging/media/atomisp/i2c/Kconfig index db054d3c7ed6..f7f7177b9b37 100644 --- a/drivers/staging/media/atomisp/i2c/Kconfig +++ b/drivers/staging/media/atomisp/i2c/Kconfig | |||
@@ -28,18 +28,6 @@ config VIDEO_ATOMISP_GC2235 | |||
28 | 28 | ||
29 | It currently only works with the atomisp driver. | 29 | It currently only works with the atomisp driver. |
30 | 30 | ||
31 | config VIDEO_ATOMISP_OV8858 | ||
32 | tristate "Omnivision ov8858 sensor support" | ||
33 | depends on ACPI | ||
34 | depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP | ||
35 | ---help--- | ||
36 | This is a Video4Linux2 sensor-level driver for the Omnivision | ||
37 | ov8858 RAW sensor. | ||
38 | |||
39 | OV8858 is a 8M raw sensor. | ||
40 | |||
41 | It currently only works with the atomisp driver. | ||
42 | |||
43 | config VIDEO_ATOMISP_MSRLIST_HELPER | 31 | config VIDEO_ATOMISP_MSRLIST_HELPER |
44 | tristate "Helper library to load, parse and apply large register lists." | 32 | tristate "Helper library to load, parse and apply large register lists." |
45 | depends on I2C | 33 | depends on I2C |
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index 61b7598469eb..93753cb96180 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c | |||
@@ -1204,57 +1204,6 @@ fail_power_off: | |||
1204 | return ret; | 1204 | return ret; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | static int gc0310_g_parm(struct v4l2_subdev *sd, | ||
1208 | struct v4l2_streamparm *param) | ||
1209 | { | ||
1210 | struct gc0310_device *dev = to_gc0310_sensor(sd); | ||
1211 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1212 | |||
1213 | if (!param) | ||
1214 | return -EINVAL; | ||
1215 | |||
1216 | if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1217 | dev_err(&client->dev, "unsupported buffer type.\n"); | ||
1218 | return -EINVAL; | ||
1219 | } | ||
1220 | |||
1221 | memset(param, 0, sizeof(*param)); | ||
1222 | param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1223 | |||
1224 | if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) { | ||
1225 | param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1226 | param->parm.capture.timeperframe.numerator = 1; | ||
1227 | param->parm.capture.capturemode = dev->run_mode; | ||
1228 | param->parm.capture.timeperframe.denominator = | ||
1229 | gc0310_res[dev->fmt_idx].fps; | ||
1230 | } | ||
1231 | return 0; | ||
1232 | } | ||
1233 | |||
1234 | static int gc0310_s_parm(struct v4l2_subdev *sd, | ||
1235 | struct v4l2_streamparm *param) | ||
1236 | { | ||
1237 | struct gc0310_device *dev = to_gc0310_sensor(sd); | ||
1238 | dev->run_mode = param->parm.capture.capturemode; | ||
1239 | |||
1240 | mutex_lock(&dev->input_lock); | ||
1241 | switch (dev->run_mode) { | ||
1242 | case CI_MODE_VIDEO: | ||
1243 | gc0310_res = gc0310_res_video; | ||
1244 | N_RES = N_RES_VIDEO; | ||
1245 | break; | ||
1246 | case CI_MODE_STILL_CAPTURE: | ||
1247 | gc0310_res = gc0310_res_still; | ||
1248 | N_RES = N_RES_STILL; | ||
1249 | break; | ||
1250 | default: | ||
1251 | gc0310_res = gc0310_res_preview; | ||
1252 | N_RES = N_RES_PREVIEW; | ||
1253 | } | ||
1254 | mutex_unlock(&dev->input_lock); | ||
1255 | return 0; | ||
1256 | } | ||
1257 | |||
1258 | static int gc0310_g_frame_interval(struct v4l2_subdev *sd, | 1207 | static int gc0310_g_frame_interval(struct v4l2_subdev *sd, |
1259 | struct v4l2_subdev_frame_interval *interval) | 1208 | struct v4l2_subdev_frame_interval *interval) |
1260 | { | 1209 | { |
@@ -1313,8 +1262,6 @@ static const struct v4l2_subdev_sensor_ops gc0310_sensor_ops = { | |||
1313 | 1262 | ||
1314 | static const struct v4l2_subdev_video_ops gc0310_video_ops = { | 1263 | static const struct v4l2_subdev_video_ops gc0310_video_ops = { |
1315 | .s_stream = gc0310_s_stream, | 1264 | .s_stream = gc0310_s_stream, |
1316 | .g_parm = gc0310_g_parm, | ||
1317 | .s_parm = gc0310_s_parm, | ||
1318 | .g_frame_interval = gc0310_g_frame_interval, | 1265 | .g_frame_interval = gc0310_g_frame_interval, |
1319 | }; | 1266 | }; |
1320 | 1267 | ||
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index d8de46da64ae..93f9c618f3d8 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | |||
@@ -944,57 +944,6 @@ fail_power_off: | |||
944 | return ret; | 944 | return ret; |
945 | } | 945 | } |
946 | 946 | ||
947 | static int gc2235_g_parm(struct v4l2_subdev *sd, | ||
948 | struct v4l2_streamparm *param) | ||
949 | { | ||
950 | struct gc2235_device *dev = to_gc2235_sensor(sd); | ||
951 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
952 | |||
953 | if (!param) | ||
954 | return -EINVAL; | ||
955 | |||
956 | if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
957 | dev_err(&client->dev, "unsupported buffer type.\n"); | ||
958 | return -EINVAL; | ||
959 | } | ||
960 | |||
961 | memset(param, 0, sizeof(*param)); | ||
962 | param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
963 | |||
964 | if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) { | ||
965 | param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
966 | param->parm.capture.timeperframe.numerator = 1; | ||
967 | param->parm.capture.capturemode = dev->run_mode; | ||
968 | param->parm.capture.timeperframe.denominator = | ||
969 | gc2235_res[dev->fmt_idx].fps; | ||
970 | } | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | static int gc2235_s_parm(struct v4l2_subdev *sd, | ||
975 | struct v4l2_streamparm *param) | ||
976 | { | ||
977 | struct gc2235_device *dev = to_gc2235_sensor(sd); | ||
978 | dev->run_mode = param->parm.capture.capturemode; | ||
979 | |||
980 | mutex_lock(&dev->input_lock); | ||
981 | switch (dev->run_mode) { | ||
982 | case CI_MODE_VIDEO: | ||
983 | gc2235_res = gc2235_res_video; | ||
984 | N_RES = N_RES_VIDEO; | ||
985 | break; | ||
986 | case CI_MODE_STILL_CAPTURE: | ||
987 | gc2235_res = gc2235_res_still; | ||
988 | N_RES = N_RES_STILL; | ||
989 | break; | ||
990 | default: | ||
991 | gc2235_res = gc2235_res_preview; | ||
992 | N_RES = N_RES_PREVIEW; | ||
993 | } | ||
994 | mutex_unlock(&dev->input_lock); | ||
995 | return 0; | ||
996 | } | ||
997 | |||
998 | static int gc2235_g_frame_interval(struct v4l2_subdev *sd, | 947 | static int gc2235_g_frame_interval(struct v4l2_subdev *sd, |
999 | struct v4l2_subdev_frame_interval *interval) | 948 | struct v4l2_subdev_frame_interval *interval) |
1000 | { | 949 | { |
@@ -1052,8 +1001,6 @@ static const struct v4l2_subdev_sensor_ops gc2235_sensor_ops = { | |||
1052 | 1001 | ||
1053 | static const struct v4l2_subdev_video_ops gc2235_video_ops = { | 1002 | static const struct v4l2_subdev_video_ops gc2235_video_ops = { |
1054 | .s_stream = gc2235_s_stream, | 1003 | .s_stream = gc2235_s_stream, |
1055 | .g_parm = gc2235_g_parm, | ||
1056 | .s_parm = gc2235_s_parm, | ||
1057 | .g_frame_interval = gc2235_g_frame_interval, | 1004 | .g_frame_interval = gc2235_g_frame_interval, |
1058 | }; | 1005 | }; |
1059 | 1006 | ||
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index df253a557c76..834fba8c4fa0 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c | |||
@@ -1684,11 +1684,6 @@ static int mt9m114_t_vflip(struct v4l2_subdev *sd, int value) | |||
1684 | 1684 | ||
1685 | return !!err; | 1685 | return !!err; |
1686 | } | 1686 | } |
1687 | static int mt9m114_s_parm(struct v4l2_subdev *sd, | ||
1688 | struct v4l2_streamparm *param) | ||
1689 | { | ||
1690 | return 0; | ||
1691 | } | ||
1692 | 1687 | ||
1693 | static int mt9m114_g_frame_interval(struct v4l2_subdev *sd, | 1688 | static int mt9m114_g_frame_interval(struct v4l2_subdev *sd, |
1694 | struct v4l2_subdev_frame_interval *interval) | 1689 | struct v4l2_subdev_frame_interval *interval) |
@@ -1781,7 +1776,6 @@ static int mt9m114_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) | |||
1781 | } | 1776 | } |
1782 | 1777 | ||
1783 | static const struct v4l2_subdev_video_ops mt9m114_video_ops = { | 1778 | static const struct v4l2_subdev_video_ops mt9m114_video_ops = { |
1784 | .s_parm = mt9m114_s_parm, | ||
1785 | .s_stream = mt9m114_s_stream, | 1779 | .s_stream = mt9m114_s_stream, |
1786 | .g_frame_interval = mt9m114_g_frame_interval, | 1780 | .g_frame_interval = mt9m114_g_frame_interval, |
1787 | }; | 1781 | }; |
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index 84f8d33ce2d1..11412061c40e 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | |||
@@ -1280,60 +1280,6 @@ fail_power_off: | |||
1280 | return ret; | 1280 | return ret; |
1281 | } | 1281 | } |
1282 | 1282 | ||
1283 | static int ov2680_g_parm(struct v4l2_subdev *sd, | ||
1284 | struct v4l2_streamparm *param) | ||
1285 | { | ||
1286 | struct ov2680_device *dev = to_ov2680_sensor(sd); | ||
1287 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1288 | |||
1289 | if (!param) | ||
1290 | return -EINVAL; | ||
1291 | |||
1292 | if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1293 | dev_err(&client->dev, "unsupported buffer type.\n"); | ||
1294 | return -EINVAL; | ||
1295 | } | ||
1296 | |||
1297 | memset(param, 0, sizeof(*param)); | ||
1298 | param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1299 | |||
1300 | if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) { | ||
1301 | param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1302 | param->parm.capture.timeperframe.numerator = 1; | ||
1303 | param->parm.capture.capturemode = dev->run_mode; | ||
1304 | param->parm.capture.timeperframe.denominator = | ||
1305 | ov2680_res[dev->fmt_idx].fps; | ||
1306 | } | ||
1307 | return 0; | ||
1308 | } | ||
1309 | |||
1310 | static int ov2680_s_parm(struct v4l2_subdev *sd, | ||
1311 | struct v4l2_streamparm *param) | ||
1312 | { | ||
1313 | struct ov2680_device *dev = to_ov2680_sensor(sd); | ||
1314 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1315 | dev->run_mode = param->parm.capture.capturemode; | ||
1316 | |||
1317 | v4l2_info(client, "\n%s:run_mode :%x\n", __func__, dev->run_mode); | ||
1318 | |||
1319 | mutex_lock(&dev->input_lock); | ||
1320 | switch (dev->run_mode) { | ||
1321 | case CI_MODE_VIDEO: | ||
1322 | ov2680_res = ov2680_res_video; | ||
1323 | N_RES = N_RES_VIDEO; | ||
1324 | break; | ||
1325 | case CI_MODE_STILL_CAPTURE: | ||
1326 | ov2680_res = ov2680_res_still; | ||
1327 | N_RES = N_RES_STILL; | ||
1328 | break; | ||
1329 | default: | ||
1330 | ov2680_res = ov2680_res_preview; | ||
1331 | N_RES = N_RES_PREVIEW; | ||
1332 | } | ||
1333 | mutex_unlock(&dev->input_lock); | ||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | static int ov2680_g_frame_interval(struct v4l2_subdev *sd, | 1283 | static int ov2680_g_frame_interval(struct v4l2_subdev *sd, |
1338 | struct v4l2_subdev_frame_interval *interval) | 1284 | struct v4l2_subdev_frame_interval *interval) |
1339 | { | 1285 | { |
@@ -1387,8 +1333,6 @@ static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) | |||
1387 | 1333 | ||
1388 | static const struct v4l2_subdev_video_ops ov2680_video_ops = { | 1334 | static const struct v4l2_subdev_video_ops ov2680_video_ops = { |
1389 | .s_stream = ov2680_s_stream, | 1335 | .s_stream = ov2680_s_stream, |
1390 | .g_parm = ov2680_g_parm, | ||
1391 | .s_parm = ov2680_s_parm, | ||
1392 | .g_frame_interval = ov2680_g_frame_interval, | 1336 | .g_frame_interval = ov2680_g_frame_interval, |
1393 | }; | 1337 | }; |
1394 | 1338 | ||
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 2b6ae0faf972..e59358ac89ce 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | |||
@@ -1083,57 +1083,6 @@ fail_power_off: | |||
1083 | return ret; | 1083 | return ret; |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | static int ov2722_g_parm(struct v4l2_subdev *sd, | ||
1087 | struct v4l2_streamparm *param) | ||
1088 | { | ||
1089 | struct ov2722_device *dev = to_ov2722_sensor(sd); | ||
1090 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1091 | |||
1092 | if (!param) | ||
1093 | return -EINVAL; | ||
1094 | |||
1095 | if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1096 | dev_err(&client->dev, "unsupported buffer type.\n"); | ||
1097 | return -EINVAL; | ||
1098 | } | ||
1099 | |||
1100 | memset(param, 0, sizeof(*param)); | ||
1101 | param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1102 | |||
1103 | if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) { | ||
1104 | param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1105 | param->parm.capture.timeperframe.numerator = 1; | ||
1106 | param->parm.capture.capturemode = dev->run_mode; | ||
1107 | param->parm.capture.timeperframe.denominator = | ||
1108 | ov2722_res[dev->fmt_idx].fps; | ||
1109 | } | ||
1110 | return 0; | ||
1111 | } | ||
1112 | |||
1113 | static int ov2722_s_parm(struct v4l2_subdev *sd, | ||
1114 | struct v4l2_streamparm *param) | ||
1115 | { | ||
1116 | struct ov2722_device *dev = to_ov2722_sensor(sd); | ||
1117 | dev->run_mode = param->parm.capture.capturemode; | ||
1118 | |||
1119 | mutex_lock(&dev->input_lock); | ||
1120 | switch (dev->run_mode) { | ||
1121 | case CI_MODE_VIDEO: | ||
1122 | ov2722_res = ov2722_res_video; | ||
1123 | N_RES = N_RES_VIDEO; | ||
1124 | break; | ||
1125 | case CI_MODE_STILL_CAPTURE: | ||
1126 | ov2722_res = ov2722_res_still; | ||
1127 | N_RES = N_RES_STILL; | ||
1128 | break; | ||
1129 | default: | ||
1130 | ov2722_res = ov2722_res_preview; | ||
1131 | N_RES = N_RES_PREVIEW; | ||
1132 | } | ||
1133 | mutex_unlock(&dev->input_lock); | ||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | static int ov2722_g_frame_interval(struct v4l2_subdev *sd, | 1086 | static int ov2722_g_frame_interval(struct v4l2_subdev *sd, |
1138 | struct v4l2_subdev_frame_interval *interval) | 1087 | struct v4l2_subdev_frame_interval *interval) |
1139 | { | 1088 | { |
@@ -1192,8 +1141,6 @@ static const struct v4l2_subdev_sensor_ops ov2722_sensor_ops = { | |||
1192 | 1141 | ||
1193 | static const struct v4l2_subdev_video_ops ov2722_video_ops = { | 1142 | static const struct v4l2_subdev_video_ops ov2722_video_ops = { |
1194 | .s_stream = ov2722_s_stream, | 1143 | .s_stream = ov2722_s_stream, |
1195 | .g_parm = ov2722_g_parm, | ||
1196 | .s_parm = ov2722_s_parm, | ||
1197 | .g_frame_interval = ov2722_g_frame_interval, | 1144 | .g_frame_interval = ov2722_g_frame_interval, |
1198 | }; | 1145 | }; |
1199 | 1146 | ||
diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h index c422d0398fc7..af6b11f6e5e7 100644 --- a/drivers/staging/media/atomisp/i2c/gc0310.h +++ b/drivers/staging/media/atomisp/i2c/gc0310.h | |||
@@ -150,7 +150,6 @@ struct gc0310_device { | |||
150 | struct camera_sensor_platform_data *platform_data; | 150 | struct camera_sensor_platform_data *platform_data; |
151 | int vt_pix_clk_freq_mhz; | 151 | int vt_pix_clk_freq_mhz; |
152 | int fmt_idx; | 152 | int fmt_idx; |
153 | int run_mode; | ||
154 | u8 res; | 153 | u8 res; |
155 | u8 type; | 154 | u8 type; |
156 | }; | 155 | }; |
@@ -400,48 +399,6 @@ struct gc0310_resolution gc0310_res_preview[] = { | |||
400 | }; | 399 | }; |
401 | #define N_RES_PREVIEW (ARRAY_SIZE(gc0310_res_preview)) | 400 | #define N_RES_PREVIEW (ARRAY_SIZE(gc0310_res_preview)) |
402 | 401 | ||
403 | struct gc0310_resolution gc0310_res_still[] = { | ||
404 | { | ||
405 | .desc = "gc0310_VGA_30fps", | ||
406 | .width = 656, // 648, | ||
407 | .height = 496, // 488, | ||
408 | .fps = 30, | ||
409 | //.pix_clk_freq = 73, | ||
410 | .used = 0, | ||
411 | #if 0 | ||
412 | .pixels_per_line = 0x0314, | ||
413 | .lines_per_frame = 0x0213, | ||
414 | #endif | ||
415 | .bin_factor_x = 1, | ||
416 | .bin_factor_y = 1, | ||
417 | .bin_mode = 0, | ||
418 | .skip_frames = 2, | ||
419 | .regs = gc0310_VGA_30fps, | ||
420 | }, | ||
421 | }; | ||
422 | #define N_RES_STILL (ARRAY_SIZE(gc0310_res_still)) | ||
423 | |||
424 | struct gc0310_resolution gc0310_res_video[] = { | ||
425 | { | ||
426 | .desc = "gc0310_VGA_30fps", | ||
427 | .width = 656, // 648, | ||
428 | .height = 496, // 488, | ||
429 | .fps = 30, | ||
430 | //.pix_clk_freq = 73, | ||
431 | .used = 0, | ||
432 | #if 0 | ||
433 | .pixels_per_line = 0x0314, | ||
434 | .lines_per_frame = 0x0213, | ||
435 | #endif | ||
436 | .bin_factor_x = 1, | ||
437 | .bin_factor_y = 1, | ||
438 | .bin_mode = 0, | ||
439 | .skip_frames = 2, | ||
440 | .regs = gc0310_VGA_30fps, | ||
441 | }, | ||
442 | }; | ||
443 | #define N_RES_VIDEO (ARRAY_SIZE(gc0310_res_video)) | ||
444 | |||
445 | static struct gc0310_resolution *gc0310_res = gc0310_res_preview; | 402 | static struct gc0310_resolution *gc0310_res = gc0310_res_preview; |
446 | static unsigned long N_RES = N_RES_PREVIEW; | 403 | static unsigned long N_RES = N_RES_PREVIEW; |
447 | #endif | 404 | #endif |
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h index 3c30a05c3991..0e805bcfa4d8 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.h +++ b/drivers/staging/media/atomisp/i2c/gc2235.h | |||
@@ -156,7 +156,6 @@ struct gc2235_device { | |||
156 | struct camera_sensor_platform_data *platform_data; | 156 | struct camera_sensor_platform_data *platform_data; |
157 | int vt_pix_clk_freq_mhz; | 157 | int vt_pix_clk_freq_mhz; |
158 | int fmt_idx; | 158 | int fmt_idx; |
159 | int run_mode; | ||
160 | u8 res; | 159 | u8 res; |
161 | u8 type; | 160 | u8 type; |
162 | }; | 161 | }; |
@@ -575,6 +574,11 @@ static struct gc2235_resolution gc2235_res_preview[] = { | |||
575 | }; | 574 | }; |
576 | #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview)) | 575 | #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview)) |
577 | 576 | ||
577 | /* | ||
578 | * Disable non-preview configurations until the configuration selection is | ||
579 | * improved. | ||
580 | */ | ||
581 | #if 0 | ||
578 | static struct gc2235_resolution gc2235_res_still[] = { | 582 | static struct gc2235_resolution gc2235_res_still[] = { |
579 | { | 583 | { |
580 | .desc = "gc2235_1600_900_30fps", | 584 | .desc = "gc2235_1600_900_30fps", |
@@ -659,6 +663,7 @@ static struct gc2235_resolution gc2235_res_video[] = { | |||
659 | 663 | ||
660 | }; | 664 | }; |
661 | #define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video)) | 665 | #define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video)) |
666 | #endif | ||
662 | 667 | ||
663 | static struct gc2235_resolution *gc2235_res = gc2235_res_preview; | 668 | static struct gc2235_resolution *gc2235_res = gc2235_res_preview; |
664 | static unsigned long N_RES = N_RES_PREVIEW; | 669 | static unsigned long N_RES = N_RES_PREVIEW; |
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h index 03f75dd80f87..cb38e6e79409 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.h +++ b/drivers/staging/media/atomisp/i2c/ov2680.h | |||
@@ -850,74 +850,6 @@ struct ov2680_format { | |||
850 | }; | 850 | }; |
851 | #define N_RES_PREVIEW (ARRAY_SIZE(ov2680_res_preview)) | 851 | #define N_RES_PREVIEW (ARRAY_SIZE(ov2680_res_preview)) |
852 | 852 | ||
853 | static struct ov2680_resolution ov2680_res_still[] = { | ||
854 | { | ||
855 | .desc = "ov2680_1616x1216_30fps", | ||
856 | .width = 1616, | ||
857 | .height = 1216, | ||
858 | .pix_clk_freq = 66, | ||
859 | .fps = 30, | ||
860 | .used = 0, | ||
861 | .pixels_per_line = 1698,//1704, | ||
862 | .lines_per_frame = 1294, | ||
863 | .bin_factor_x = 0, | ||
864 | .bin_factor_y = 0, | ||
865 | .bin_mode = 0, | ||
866 | .skip_frames = 3, | ||
867 | .regs = ov2680_1616x1216_30fps, | ||
868 | }, | ||
869 | { | ||
870 | .desc = "ov2680_1616x916_30fps", | ||
871 | .width = 1616, | ||
872 | .height = 916, | ||
873 | .fps = 30, | ||
874 | .pix_clk_freq = 66, | ||
875 | .used = 0, | ||
876 | .pixels_per_line = 1698,//1704, | ||
877 | .lines_per_frame = 1294, | ||
878 | .bin_factor_x = 0, | ||
879 | .bin_factor_y = 0, | ||
880 | .bin_mode = 0, | ||
881 | .skip_frames = 3, | ||
882 | .regs = ov2680_1616x916_30fps, | ||
883 | }, | ||
884 | }; | ||
885 | #define N_RES_STILL (ARRAY_SIZE(ov2680_res_still)) | ||
886 | |||
887 | static struct ov2680_resolution ov2680_res_video[] = { | ||
888 | { | ||
889 | .desc = "ov2680_1616x1216_30fps", | ||
890 | .width = 1616, | ||
891 | .height = 1216, | ||
892 | .pix_clk_freq = 66, | ||
893 | .fps = 30, | ||
894 | .used = 0, | ||
895 | .pixels_per_line = 1698,//1704, | ||
896 | .lines_per_frame = 1294, | ||
897 | .bin_factor_x = 0, | ||
898 | .bin_factor_y = 0, | ||
899 | .bin_mode = 0, | ||
900 | .skip_frames = 3, | ||
901 | .regs = ov2680_1616x1216_30fps, | ||
902 | }, | ||
903 | { | ||
904 | .desc = "ov2680_720p_30fps", | ||
905 | .width = 1616, | ||
906 | .height = 916, | ||
907 | .fps = 30, | ||
908 | .pix_clk_freq = 66, | ||
909 | .used = 0, | ||
910 | .pixels_per_line = 1698,//1704, | ||
911 | .lines_per_frame = 1294, | ||
912 | .bin_factor_x = 0, | ||
913 | .bin_factor_y = 0, | ||
914 | .bin_mode = 0, | ||
915 | .skip_frames = 3, | ||
916 | .regs = ov2680_1616x916_30fps, | ||
917 | }, | ||
918 | }; | ||
919 | #define N_RES_VIDEO (ARRAY_SIZE(ov2680_res_video)) | ||
920 | |||
921 | static struct ov2680_resolution *ov2680_res = ov2680_res_preview; | 853 | static struct ov2680_resolution *ov2680_res = ov2680_res_preview; |
922 | static unsigned long N_RES = N_RES_PREVIEW; | 854 | static unsigned long N_RES = N_RES_PREVIEW; |
923 | 855 | ||
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h index d8a973d71699..028b04aaaa8f 100644 --- a/drivers/staging/media/atomisp/i2c/ov2722.h +++ b/drivers/staging/media/atomisp/i2c/ov2722.h | |||
@@ -1148,6 +1148,11 @@ struct ov2722_resolution ov2722_res_preview[] = { | |||
1148 | }; | 1148 | }; |
1149 | #define N_RES_PREVIEW (ARRAY_SIZE(ov2722_res_preview)) | 1149 | #define N_RES_PREVIEW (ARRAY_SIZE(ov2722_res_preview)) |
1150 | 1150 | ||
1151 | /* | ||
1152 | * Disable non-preview configurations until the configuration selection is | ||
1153 | * improved. | ||
1154 | */ | ||
1155 | #if 0 | ||
1151 | struct ov2722_resolution ov2722_res_still[] = { | 1156 | struct ov2722_resolution ov2722_res_still[] = { |
1152 | { | 1157 | { |
1153 | .desc = "ov2722_480P_30fps", | 1158 | .desc = "ov2722_480P_30fps", |
@@ -1250,6 +1255,7 @@ struct ov2722_resolution ov2722_res_video[] = { | |||
1250 | }, | 1255 | }, |
1251 | }; | 1256 | }; |
1252 | #define N_RES_VIDEO (ARRAY_SIZE(ov2722_res_video)) | 1257 | #define N_RES_VIDEO (ARRAY_SIZE(ov2722_res_video)) |
1258 | #endif | ||
1253 | 1259 | ||
1254 | static struct ov2722_resolution *ov2722_res = ov2722_res_preview; | 1260 | static struct ov2722_resolution *ov2722_res = ov2722_res_preview; |
1255 | static unsigned long N_RES = N_RES_PREVIEW; | 1261 | static unsigned long N_RES = N_RES_PREVIEW; |
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c index 40d01bf4bf28..30a735e59e54 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c | |||
@@ -1805,58 +1805,6 @@ fail_power_off: | |||
1805 | return ret; | 1805 | return ret; |
1806 | } | 1806 | } |
1807 | 1807 | ||
1808 | static int ov5693_g_parm(struct v4l2_subdev *sd, | ||
1809 | struct v4l2_streamparm *param) | ||
1810 | { | ||
1811 | struct ov5693_device *dev = to_ov5693_sensor(sd); | ||
1812 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1813 | |||
1814 | if (!param) | ||
1815 | return -EINVAL; | ||
1816 | |||
1817 | if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1818 | dev_err(&client->dev, "unsupported buffer type.\n"); | ||
1819 | return -EINVAL; | ||
1820 | } | ||
1821 | |||
1822 | memset(param, 0, sizeof(*param)); | ||
1823 | param->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1824 | |||
1825 | if (dev->fmt_idx >= 0 && dev->fmt_idx < N_RES) { | ||
1826 | param->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1827 | param->parm.capture.timeperframe.numerator = 1; | ||
1828 | param->parm.capture.capturemode = dev->run_mode; | ||
1829 | param->parm.capture.timeperframe.denominator = | ||
1830 | ov5693_res[dev->fmt_idx].fps; | ||
1831 | } | ||
1832 | return 0; | ||
1833 | } | ||
1834 | |||
1835 | static int ov5693_s_parm(struct v4l2_subdev *sd, | ||
1836 | struct v4l2_streamparm *param) | ||
1837 | { | ||
1838 | struct ov5693_device *dev = to_ov5693_sensor(sd); | ||
1839 | |||
1840 | dev->run_mode = param->parm.capture.capturemode; | ||
1841 | |||
1842 | mutex_lock(&dev->input_lock); | ||
1843 | switch (dev->run_mode) { | ||
1844 | case CI_MODE_VIDEO: | ||
1845 | ov5693_res = ov5693_res_video; | ||
1846 | N_RES = N_RES_VIDEO; | ||
1847 | break; | ||
1848 | case CI_MODE_STILL_CAPTURE: | ||
1849 | ov5693_res = ov5693_res_still; | ||
1850 | N_RES = N_RES_STILL; | ||
1851 | break; | ||
1852 | default: | ||
1853 | ov5693_res = ov5693_res_preview; | ||
1854 | N_RES = N_RES_PREVIEW; | ||
1855 | } | ||
1856 | mutex_unlock(&dev->input_lock); | ||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | static int ov5693_g_frame_interval(struct v4l2_subdev *sd, | 1808 | static int ov5693_g_frame_interval(struct v4l2_subdev *sd, |
1861 | struct v4l2_subdev_frame_interval *interval) | 1809 | struct v4l2_subdev_frame_interval *interval) |
1862 | { | 1810 | { |
@@ -1899,8 +1847,6 @@ static int ov5693_enum_frame_size(struct v4l2_subdev *sd, | |||
1899 | 1847 | ||
1900 | static const struct v4l2_subdev_video_ops ov5693_video_ops = { | 1848 | static const struct v4l2_subdev_video_ops ov5693_video_ops = { |
1901 | .s_stream = ov5693_s_stream, | 1849 | .s_stream = ov5693_s_stream, |
1902 | .g_parm = ov5693_g_parm, | ||
1903 | .s_parm = ov5693_s_parm, | ||
1904 | .g_frame_interval = ov5693_g_frame_interval, | 1850 | .g_frame_interval = ov5693_g_frame_interval, |
1905 | }; | 1851 | }; |
1906 | 1852 | ||
@@ -1947,7 +1893,7 @@ static int ov5693_probe(struct i2c_client *client) | |||
1947 | struct ov5693_device *dev; | 1893 | struct ov5693_device *dev; |
1948 | int i2c; | 1894 | int i2c; |
1949 | int ret = 0; | 1895 | int ret = 0; |
1950 | void *pdata = client->dev.platform_data; | 1896 | void *pdata; |
1951 | unsigned int i; | 1897 | unsigned int i; |
1952 | 1898 | ||
1953 | /* | 1899 | /* |
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h index 68cfcb4a6c3c..6d27dd849a62 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h | |||
@@ -1147,6 +1147,11 @@ struct ov5693_resolution ov5693_res_preview[] = { | |||
1147 | }; | 1147 | }; |
1148 | #define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview)) | 1148 | #define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview)) |
1149 | 1149 | ||
1150 | /* | ||
1151 | * Disable non-preview configurations until the configuration selection is | ||
1152 | * improved. | ||
1153 | */ | ||
1154 | #if 0 | ||
1150 | struct ov5693_resolution ov5693_res_still[] = { | 1155 | struct ov5693_resolution ov5693_res_still[] = { |
1151 | { | 1156 | { |
1152 | .desc = "ov5693_736x496_30fps", | 1157 | .desc = "ov5693_736x496_30fps", |
@@ -1364,6 +1369,7 @@ struct ov5693_resolution ov5693_res_video[] = { | |||
1364 | }, | 1369 | }, |
1365 | }; | 1370 | }; |
1366 | #define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video)) | 1371 | #define N_RES_VIDEO (ARRAY_SIZE(ov5693_res_video)) |
1372 | #endif | ||
1367 | 1373 | ||
1368 | static struct ov5693_resolution *ov5693_res = ov5693_res_preview; | 1374 | static struct ov5693_resolution *ov5693_res = ov5693_res_preview; |
1369 | static unsigned long N_RES = N_RES_PREVIEW; | 1375 | static unsigned long N_RES = N_RES_PREVIEW; |
diff --git a/drivers/staging/media/atomisp/i2c/ov8858.c b/drivers/staging/media/atomisp/i2c/ov8858.c deleted file mode 100644 index 3cf8c710ac65..000000000000 --- a/drivers/staging/media/atomisp/i2c/ov8858.c +++ /dev/null | |||
@@ -1,2169 +0,0 @@ | |||
1 | /* | ||
2 | * Support for OmniVision ov8858 camera sensor. | ||
3 | * | ||
4 | * Copyright (c) 2014 Intel Corporation. All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/delay.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <media/v4l2-device.h> | ||
21 | #include <linux/acpi.h> | ||
22 | #include "../include/linux/atomisp_gmin_platform.h" | ||
23 | #ifdef CONFIG_PLATFORM_BTNS | ||
24 | #include "ov8858_btns.h" | ||
25 | #else | ||
26 | #include "ov8858.h" | ||
27 | #endif | ||
28 | static int ov8858_i2c_read(struct i2c_client *client, u16 len, u16 addr, | ||
29 | u8 *buf) | ||
30 | { | ||
31 | struct i2c_msg msg[2]; | ||
32 | u8 address[2]; | ||
33 | int err; | ||
34 | |||
35 | if (!client->adapter) { | ||
36 | dev_err(&client->dev, "%s error, no adapter\n", __func__); | ||
37 | return -ENODEV; | ||
38 | } | ||
39 | |||
40 | dev_dbg(&client->dev, "%s: len = %d, addr = 0x%04x\n", | ||
41 | __func__, len, addr); | ||
42 | |||
43 | memset(msg, 0, sizeof(msg)); | ||
44 | |||
45 | address[0] = (addr >> 8) & 0xff; | ||
46 | address[1] = addr & 0xff; | ||
47 | |||
48 | msg[0].addr = client->addr; | ||
49 | msg[0].flags = 0; | ||
50 | msg[0].len = I2C_MSG_LENGTH; | ||
51 | msg[0].buf = address; | ||
52 | |||
53 | msg[1].addr = client->addr; | ||
54 | msg[1].len = len; | ||
55 | msg[1].flags = I2C_M_RD; | ||
56 | msg[1].buf = buf; | ||
57 | |||
58 | err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); | ||
59 | if (err != 2) { | ||
60 | if (err >= 0) | ||
61 | err = -EIO; | ||
62 | goto error; | ||
63 | } | ||
64 | |||
65 | return 0; | ||
66 | error: | ||
67 | dev_err(&client->dev, "reading from address 0x%x error %d", addr, err); | ||
68 | return err; | ||
69 | } | ||
70 | |||
71 | static int ov8858_read_reg(struct i2c_client *client, u16 type, u16 reg, | ||
72 | u16 *val) | ||
73 | { | ||
74 | u8 data[OV8858_SHORT_MAX]; | ||
75 | int err; | ||
76 | |||
77 | dev_dbg(&client->dev, "%s: type = %d, reg = 0x%04x\n", | ||
78 | __func__, type, reg); | ||
79 | |||
80 | /* read only 8 and 16 bit values */ | ||
81 | if (type != OV8858_8BIT && type != OV8858_16BIT) { | ||
82 | dev_err(&client->dev, "%s error, invalid data length\n", | ||
83 | __func__); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | memset(data, 0, sizeof(data)); | ||
88 | |||
89 | err = ov8858_i2c_read(client, type, reg, data); | ||
90 | if (err) | ||
91 | goto error; | ||
92 | |||
93 | /* high byte comes first */ | ||
94 | if (type == OV8858_8BIT) | ||
95 | *val = (u8)data[0]; | ||
96 | else | ||
97 | *val = data[0] << 8 | data[1]; | ||
98 | |||
99 | dev_dbg(&client->dev, "%s: val = 0x%04x\n", __func__, *val); | ||
100 | |||
101 | return 0; | ||
102 | |||
103 | error: | ||
104 | dev_err(&client->dev, "read from offset 0x%x error %d", reg, err); | ||
105 | return err; | ||
106 | } | ||
107 | |||
108 | static int ov8858_i2c_write(struct i2c_client *client, u16 len, u8 *data) | ||
109 | { | ||
110 | struct i2c_msg msg; | ||
111 | const int num_msg = 1; | ||
112 | int ret; | ||
113 | |||
114 | msg.addr = client->addr; | ||
115 | msg.flags = 0; | ||
116 | msg.len = len; | ||
117 | msg.buf = data; | ||
118 | |||
119 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
120 | |||
121 | return ret == num_msg ? 0 : -EIO; | ||
122 | } | ||
123 | |||
124 | static int | ||
125 | ov8858_write_reg(struct i2c_client *client, u16 data_length, u16 reg, u16 val) | ||
126 | { | ||
127 | int ret; | ||
128 | unsigned char data[4] = {0}; | ||
129 | u16 *wreg; | ||
130 | const u16 len = data_length + sizeof(u16); /* 16-bit address + data */ | ||
131 | |||
132 | dev_dbg(&client->dev, | ||
133 | "%s: data_length = %d, reg = 0x%04x, val = 0x%04x\n", | ||
134 | __func__, data_length, reg, val); | ||
135 | |||
136 | if (!client->adapter) { | ||
137 | dev_err(&client->dev, "%s error, no adapter\n", __func__); | ||
138 | return -ENODEV; | ||
139 | } | ||
140 | |||
141 | if (data_length != OV8858_8BIT && data_length != OV8858_16BIT) { | ||
142 | dev_err(&client->dev, "%s error, invalid length\n", __func__); | ||
143 | return -EINVAL; | ||
144 | } | ||
145 | |||
146 | /* high byte goes out first */ | ||
147 | wreg = (u16 *)data; | ||
148 | *wreg = cpu_to_be16(reg); | ||
149 | |||
150 | if (data_length == OV8858_8BIT) { | ||
151 | data[2] = (u8)(val); | ||
152 | } else { | ||
153 | /* OV8858_16BIT */ | ||
154 | u16 *wdata = (u16 *)&data[2]; | ||
155 | *wdata = be16_to_cpu(val); | ||
156 | } | ||
157 | |||
158 | ret = ov8858_i2c_write(client, len, data); | ||
159 | if (ret) | ||
160 | dev_err(&client->dev, | ||
161 | "write error: wrote 0x%x to offset 0x%x error %d", | ||
162 | val, reg, ret); | ||
163 | |||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * ov8858_write_reg_array - Initializes a list of registers | ||
169 | * @client: i2c driver client structure | ||
170 | * @reglist: list of registers to be written | ||
171 | * | ||
172 | * This function initializes a list of registers. When consecutive addresses | ||
173 | * are found in a row on the list, this function creates a buffer and sends | ||
174 | * consecutive data in a single i2c_transfer(). | ||
175 | * | ||
176 | * __ov8858_flush_reg_array(), __ov8858_buf_reg_array() and | ||
177 | * __ov8858_write_reg_is_consecutive() are internal functions to | ||
178 | * ov8858_write_reg_array() and should be not used anywhere else. | ||
179 | * | ||
180 | */ | ||
181 | static int __ov8858_flush_reg_array(struct i2c_client *client, | ||
182 | struct ov8858_write_ctrl *ctrl) | ||
183 | { | ||
184 | u16 size; | ||
185 | if (ctrl->index == 0) | ||
186 | return 0; | ||
187 | |||
188 | size = sizeof(u16) + ctrl->index; /* 16-bit address + data */ | ||
189 | ctrl->buffer.addr = cpu_to_be16(ctrl->buffer.addr); | ||
190 | ctrl->index = 0; | ||
191 | |||
192 | return ov8858_i2c_write(client, size, (u8 *)&ctrl->buffer); | ||
193 | } | ||
194 | |||
195 | static int __ov8858_buf_reg_array(struct i2c_client *client, | ||
196 | struct ov8858_write_ctrl *ctrl, | ||
197 | const struct ov8858_reg *next) | ||
198 | { | ||
199 | int size; | ||
200 | u16 *data16; | ||
201 | |||
202 | switch (next->type) { | ||
203 | case OV8858_8BIT: | ||
204 | size = 1; | ||
205 | ctrl->buffer.data[ctrl->index] = (u8)next->val; | ||
206 | break; | ||
207 | case OV8858_16BIT: | ||
208 | size = 2; | ||
209 | data16 = (u16 *)&ctrl->buffer.data[ctrl->index]; | ||
210 | *data16 = cpu_to_be16((u16)next->val); | ||
211 | break; | ||
212 | default: | ||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | /* When first item is added, we need to store its starting address */ | ||
217 | if (ctrl->index == 0) | ||
218 | ctrl->buffer.addr = next->sreg; | ||
219 | |||
220 | ctrl->index += size; | ||
221 | |||
222 | /* | ||
223 | * Buffer cannot guarantee free space for u32? Better flush it to avoid | ||
224 | * possible lack of memory for next item. | ||
225 | */ | ||
226 | if (ctrl->index + sizeof(u16) >= OV8858_MAX_WRITE_BUF_SIZE) | ||
227 | __ov8858_flush_reg_array(client, ctrl); | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | static int | ||
233 | __ov8858_write_reg_is_consecutive(struct i2c_client *client, | ||
234 | struct ov8858_write_ctrl *ctrl, | ||
235 | const struct ov8858_reg *next) | ||
236 | { | ||
237 | if (ctrl->index == 0) | ||
238 | return 1; | ||
239 | |||
240 | return ctrl->buffer.addr + ctrl->index == next->sreg; | ||
241 | } | ||
242 | |||
243 | static int ov8858_write_reg_array(struct i2c_client *client, | ||
244 | const struct ov8858_reg *reglist) | ||
245 | { | ||
246 | const struct ov8858_reg *next = reglist; | ||
247 | struct ov8858_write_ctrl ctrl; | ||
248 | int err; | ||
249 | |||
250 | ctrl.index = 0; | ||
251 | for (; next->type != OV8858_TOK_TERM; next++) { | ||
252 | switch (next->type & OV8858_TOK_MASK) { | ||
253 | case OV8858_TOK_DELAY: | ||
254 | err = __ov8858_flush_reg_array(client, &ctrl); | ||
255 | if (err) | ||
256 | return err; | ||
257 | msleep(next->val); | ||
258 | break; | ||
259 | |||
260 | default: | ||
261 | /* | ||
262 | * If next address is not consecutive, data needs to be | ||
263 | * flushed before proceeding | ||
264 | */ | ||
265 | if (!__ov8858_write_reg_is_consecutive(client, | ||
266 | &ctrl, next)) { | ||
267 | err = __ov8858_flush_reg_array(client, &ctrl); | ||
268 | if (err) | ||
269 | return err; | ||
270 | } | ||
271 | err = __ov8858_buf_reg_array(client, &ctrl, next); | ||
272 | if (err) { | ||
273 | dev_err(&client->dev, "%s: write error\n", | ||
274 | __func__); | ||
275 | return err; | ||
276 | } | ||
277 | break; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | return __ov8858_flush_reg_array(client, &ctrl); | ||
282 | } | ||
283 | |||
284 | static int __ov8858_min_fps_diff(int fps, | ||
285 | const struct ov8858_fps_setting *fps_list) | ||
286 | { | ||
287 | int diff = INT_MAX; | ||
288 | int i; | ||
289 | |||
290 | if (fps == 0) | ||
291 | return 0; | ||
292 | |||
293 | for (i = 0; i < MAX_FPS_OPTIONS_SUPPORTED; i++) { | ||
294 | if (!fps_list[i].fps) | ||
295 | break; | ||
296 | if (abs(fps_list[i].fps - fps) < diff) | ||
297 | diff = abs(fps_list[i].fps - fps); | ||
298 | } | ||
299 | |||
300 | return diff; | ||
301 | } | ||
302 | |||
303 | static int __ov8858_nearest_fps_index(int fps, | ||
304 | const struct ov8858_fps_setting *fps_list) | ||
305 | { | ||
306 | int fps_index = 0; | ||
307 | int i; | ||
308 | |||
309 | for (i = 0; i < MAX_FPS_OPTIONS_SUPPORTED; i++) { | ||
310 | if (!fps_list[i].fps) | ||
311 | break; | ||
312 | if (abs(fps_list[i].fps - fps) | ||
313 | < abs(fps_list[fps_index].fps - fps)) | ||
314 | fps_index = i; | ||
315 | } | ||
316 | return fps_index; | ||
317 | } | ||
318 | |||
319 | static int __ov8858_update_frame_timing(struct v4l2_subdev *sd, | ||
320 | u16 *hts, u16 *vts) | ||
321 | { | ||
322 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
323 | int ret; | ||
324 | |||
325 | |||
326 | dev_dbg(&client->dev, "%s OV8858_TIMING_HTS=0x%04x\n", | ||
327 | __func__, *hts); | ||
328 | |||
329 | /* HTS = pixel_per_line / 2 */ | ||
330 | ret = ov8858_write_reg(client, OV8858_16BIT, | ||
331 | OV8858_TIMING_HTS, *hts >> 1); | ||
332 | if (ret) | ||
333 | return ret; | ||
334 | dev_dbg(&client->dev, "%s OV8858_TIMING_VTS=0x%04x\n", | ||
335 | __func__, *vts); | ||
336 | |||
337 | return ov8858_write_reg(client, OV8858_16BIT, OV8858_TIMING_VTS, *vts); | ||
338 | } | ||
339 | |||
340 | static int __ov8858_set_exposure(struct v4l2_subdev *sd, int exposure, int gain, | ||
341 | int dig_gain, u16 *hts, u16 *vts) | ||
342 | { | ||
343 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
344 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
345 | int exp_val, ret; | ||
346 | dev_dbg(&client->dev, "%s, exposure = %d, gain=%d, dig_gain=%d\n", | ||
347 | __func__, exposure, gain, dig_gain); | ||
348 | |||
349 | if (dev->limit_exposure_flag) { | ||
350 | if (exposure > *vts - OV8858_INTEGRATION_TIME_MARGIN) | ||
351 | exposure = *vts - OV8858_INTEGRATION_TIME_MARGIN; | ||
352 | } else { | ||
353 | if (*vts < exposure + OV8858_INTEGRATION_TIME_MARGIN) | ||
354 | *vts = (u16) exposure + OV8858_INTEGRATION_TIME_MARGIN; | ||
355 | } | ||
356 | |||
357 | ret = __ov8858_update_frame_timing(sd, hts, vts); | ||
358 | if (ret) | ||
359 | return ret; | ||
360 | |||
361 | /* For ov8858, the low 4 bits are fraction bits and must be kept 0 */ | ||
362 | exp_val = exposure << 4; | ||
363 | ret = ov8858_write_reg(client, OV8858_8BIT, | ||
364 | OV8858_LONG_EXPO+2, exp_val & 0xFF); | ||
365 | if (ret) | ||
366 | return ret; | ||
367 | |||
368 | ret = ov8858_write_reg(client, OV8858_8BIT, | ||
369 | OV8858_LONG_EXPO+1, (exp_val >> 8) & 0xFF); | ||
370 | if (ret) | ||
371 | return ret; | ||
372 | |||
373 | ret = ov8858_write_reg(client, OV8858_8BIT, | ||
374 | OV8858_LONG_EXPO, (exp_val >> 16) & 0x0F); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | |||
378 | /* Digital gain : to all MWB channel gains */ | ||
379 | if (dig_gain) { | ||
380 | ret = ov8858_write_reg(client, OV8858_16BIT, | ||
381 | OV8858_MWB_RED_GAIN_H, dig_gain); | ||
382 | if (ret) | ||
383 | return ret; | ||
384 | |||
385 | ret = ov8858_write_reg(client, OV8858_16BIT, | ||
386 | OV8858_MWB_GREEN_GAIN_H, dig_gain); | ||
387 | if (ret) | ||
388 | return ret; | ||
389 | |||
390 | ret = ov8858_write_reg(client, OV8858_16BIT, | ||
391 | OV8858_MWB_BLUE_GAIN_H, dig_gain); | ||
392 | if (ret) | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | ret = ov8858_write_reg(client, OV8858_16BIT, OV8858_LONG_GAIN, | ||
397 | gain & 0x07ff); | ||
398 | if (ret) | ||
399 | return ret; | ||
400 | |||
401 | dev->gain = gain; | ||
402 | dev->exposure = exposure; | ||
403 | dev->digital_gain = dig_gain; | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int ov8858_set_exposure(struct v4l2_subdev *sd, int exposure, int gain, | ||
409 | int dig_gain) | ||
410 | { | ||
411 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
412 | const struct ov8858_resolution *res; | ||
413 | u16 hts, vts; | ||
414 | int ret; | ||
415 | |||
416 | mutex_lock(&dev->input_lock); | ||
417 | |||
418 | /* Validate exposure: cannot exceed 16bit value */ | ||
419 | exposure = clamp_t(int, exposure, 0, OV8858_MAX_EXPOSURE_VALUE); | ||
420 | |||
421 | /* Validate gain: must not exceed maximum 8bit value */ | ||
422 | gain = clamp_t(int, gain, 0, OV8858_MAX_GAIN_VALUE); | ||
423 | |||
424 | /* Validate digital gain: must not exceed 12 bit value*/ | ||
425 | dig_gain = clamp_t(int, dig_gain, 0, OV8858_MWB_GAIN_MAX); | ||
426 | |||
427 | res = &dev->curr_res_table[dev->fmt_idx]; | ||
428 | /* | ||
429 | * Vendor: HTS reg value is half the total pixel line | ||
430 | */ | ||
431 | hts = res->fps_options[dev->fps_index].pixels_per_line; | ||
432 | vts = res->fps_options[dev->fps_index].lines_per_frame; | ||
433 | |||
434 | ret = __ov8858_set_exposure(sd, exposure, gain, dig_gain, &hts, &vts); | ||
435 | |||
436 | mutex_unlock(&dev->input_lock); | ||
437 | |||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | When exposure gain value set to sensor, the sensor changed value. | ||
443 | So we need the function to get real value | ||
444 | */ | ||
445 | static int ov8858_g_update_exposure(struct v4l2_subdev *sd, | ||
446 | struct atomisp_update_exposure *exposure) | ||
447 | { | ||
448 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
449 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
450 | int gain = exposure->gain; | ||
451 | |||
452 | dev_dbg(&client->dev, "%s: gain: %d, digi_gain: %d\n", __func__, | ||
453 | exposure->gain, exposure->digi_gain); | ||
454 | exposure->update_digi_gain = dev->digital_gain; | ||
455 | /* This real gain value fetching function is provided by vendor */ | ||
456 | exposure->update_gain = (((gain & 0x700) >> 8) + 1) * (gain & 0xFF); | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static int ov8858_s_exposure(struct v4l2_subdev *sd, | ||
462 | struct atomisp_exposure *exposure) | ||
463 | { | ||
464 | return ov8858_set_exposure(sd, exposure->integration_time[0], | ||
465 | exposure->gain[0], exposure->gain[1]); | ||
466 | } | ||
467 | |||
468 | static int ov8858_priv_int_data_init(struct v4l2_subdev *sd) | ||
469 | { | ||
470 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
471 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
472 | u32 size = OV8858_OTP_END_ADDR - OV8858_OTP_START_ADDR + 1; | ||
473 | int r; | ||
474 | u16 isp_ctrl2 = 0; | ||
475 | |||
476 | if (!dev->otp_data) { | ||
477 | dev->otp_data = devm_kzalloc(&client->dev, size, GFP_KERNEL); | ||
478 | if (!dev->otp_data) { | ||
479 | r = -ENOMEM; | ||
480 | goto error3; | ||
481 | } | ||
482 | |||
483 | /* Streaming has to be on */ | ||
484 | r = ov8858_write_reg(client, OV8858_8BIT, OV8858_STREAM_MODE, | ||
485 | 0x01); | ||
486 | if (r) | ||
487 | goto error2; | ||
488 | |||
489 | /* Turn off Dead Pixel Correction */ | ||
490 | r = ov8858_read_reg(client, OV8858_8BIT, | ||
491 | OV8858_OTP_ISP_CTRL2, &isp_ctrl2); | ||
492 | if (r) | ||
493 | goto error1; | ||
494 | |||
495 | r = ov8858_write_reg(client, OV8858_8BIT, OV8858_OTP_ISP_CTRL2, | ||
496 | isp_ctrl2 & ~OV8858_OTP_DPC_ENABLE); | ||
497 | if (r) | ||
498 | goto error1; | ||
499 | |||
500 | /* Enable partial OTP read mode */ | ||
501 | r = ov8858_write_reg(client, OV8858_8BIT, OV8858_OTP_MODE_CTRL, | ||
502 | OV8858_OTP_MODE_PROGRAM_DISABLE | | ||
503 | OV8858_OTP_MODE_MANUAL); | ||
504 | if (r) | ||
505 | goto error1; | ||
506 | |||
507 | /* Set address range of OTP memory to read */ | ||
508 | r = ov8858_write_reg(client, OV8858_16BIT, | ||
509 | OV8858_OTP_START_ADDR_REG, | ||
510 | OV8858_OTP_START_ADDR); | ||
511 | if (r) | ||
512 | goto error1; | ||
513 | |||
514 | r = ov8858_write_reg(client, OV8858_16BIT, | ||
515 | OV8858_OTP_END_ADDR_REG, | ||
516 | OV8858_OTP_END_ADDR); | ||
517 | if (r) | ||
518 | goto error1; | ||
519 | |||
520 | /* Load the OTP data into the OTP buffer */ | ||
521 | r = ov8858_write_reg(client, OV8858_8BIT, OV8858_OTP_LOAD_CTRL, | ||
522 | OV8858_OTP_LOAD_ENABLE); | ||
523 | if (r) | ||
524 | goto error1; | ||
525 | |||
526 | /* Wait for the data to load into the buffer */ | ||
527 | usleep_range(5000, 5500); | ||
528 | |||
529 | /* Read the OTP data from the buffer */ | ||
530 | r = ov8858_i2c_read(client, size, OV8858_OTP_START_ADDR, | ||
531 | dev->otp_data); | ||
532 | if (r) | ||
533 | goto error1; | ||
534 | |||
535 | /* Turn on Dead Pixel Correction */ | ||
536 | r = ov8858_write_reg(client, OV8858_8BIT, OV8858_OTP_ISP_CTRL2, | ||
537 | isp_ctrl2 | OV8858_OTP_DPC_ENABLE); | ||
538 | if (r) | ||
539 | goto error1; | ||
540 | |||
541 | /* Stop streaming */ | ||
542 | r = ov8858_write_reg(client, 1, OV8858_STREAM_MODE, 0x00); | ||
543 | if (r) { | ||
544 | dev_err(&client->dev, "%s: cannot turn off streaming\n", | ||
545 | __func__); | ||
546 | goto error1; | ||
547 | } | ||
548 | } | ||
549 | |||
550 | |||
551 | return 0; | ||
552 | |||
553 | error1: | ||
554 | /* Turn on Dead Pixel Correction and set streaming off */ | ||
555 | ov8858_write_reg(client, OV8858_8BIT, OV8858_OTP_ISP_CTRL2, | ||
556 | isp_ctrl2 | OV8858_OTP_DPC_ENABLE); | ||
557 | ov8858_write_reg(client, 1, OV8858_STREAM_MODE, 0x00); | ||
558 | error2: | ||
559 | devm_kfree(&client->dev, dev->otp_data); | ||
560 | dev->otp_data = NULL; | ||
561 | error3: | ||
562 | dev_err(&client->dev, "%s: OTP reading failed\n", __func__); | ||
563 | return r; | ||
564 | } | ||
565 | |||
566 | static int ov8858_g_priv_int_data(struct v4l2_subdev *sd, | ||
567 | struct v4l2_private_int_data *priv) | ||
568 | { | ||
569 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
570 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
571 | u32 size = OV8858_OTP_END_ADDR - OV8858_OTP_START_ADDR + 1; | ||
572 | int r; | ||
573 | |||
574 | mutex_lock(&dev->input_lock); | ||
575 | |||
576 | if (!dev->otp_data) { | ||
577 | dev_err(&client->dev, "%s: otp data is NULL\n", __func__); | ||
578 | mutex_unlock(&dev->input_lock); | ||
579 | return -EFAULT; | ||
580 | } | ||
581 | |||
582 | if (copy_to_user(priv->data, dev->otp_data, | ||
583 | min_t(__u32, priv->size, size))) { | ||
584 | r = -EFAULT; | ||
585 | dev_err(&client->dev, "%s: OTP reading failed\n", __func__); | ||
586 | mutex_unlock(&dev->input_lock); | ||
587 | return r; | ||
588 | } | ||
589 | |||
590 | priv->size = size; | ||
591 | mutex_unlock(&dev->input_lock); | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int __ov8858_init(struct v4l2_subdev *sd) | ||
597 | { | ||
598 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
599 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
600 | int ret; | ||
601 | dev_dbg(&client->dev, "%s\n", __func__); | ||
602 | |||
603 | /* Sets the default FPS */ | ||
604 | dev->fps_index = 0; | ||
605 | |||
606 | /* Set default exposure values (initially start values) */ | ||
607 | dev->exposure = 256; | ||
608 | dev->gain = 16; | ||
609 | dev->digital_gain = 1024; | ||
610 | dev->limit_exposure_flag = false; | ||
611 | |||
612 | dev_dbg(&client->dev, "%s: Writing basic settings to ov8858\n", | ||
613 | __func__); | ||
614 | ret = ov8858_write_reg_array(client, ov8858_BasicSettings); | ||
615 | if (ret) | ||
616 | return ret; | ||
617 | |||
618 | return ov8858_priv_int_data_init(sd); | ||
619 | } | ||
620 | |||
621 | static int ov8858_init(struct v4l2_subdev *sd, u32 val) | ||
622 | { | ||
623 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
624 | int ret; | ||
625 | |||
626 | mutex_lock(&dev->input_lock); | ||
627 | ret = __ov8858_init(sd); | ||
628 | mutex_unlock(&dev->input_lock); | ||
629 | |||
630 | return ret; | ||
631 | } | ||
632 | |||
633 | static void ov8858_uninit(struct v4l2_subdev *sd) | ||
634 | { | ||
635 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
636 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
637 | struct v4l2_ctrl *ctrl; | ||
638 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
639 | |||
640 | dev->exposure = 0; | ||
641 | dev->gain = 0; | ||
642 | dev->digital_gain = 0; | ||
643 | dev->limit_exposure_flag = false; | ||
644 | mutex_unlock(&dev->input_lock); | ||
645 | ctrl = v4l2_ctrl_find(sd->ctrl_handler, | ||
646 | V4L2_CID_EXPOSURE_AUTO_PRIORITY); | ||
647 | if (ctrl) | ||
648 | v4l2_ctrl_s_ctrl(ctrl, V4L2_EXPOSURE_AUTO); | ||
649 | mutex_lock(&dev->input_lock); | ||
650 | } | ||
651 | |||
652 | static int ov8858_g_comp_delay(struct v4l2_subdev *sd, unsigned int *usec) | ||
653 | { | ||
654 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
655 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
656 | int ret = 0, exposure; | ||
657 | u16 vts, data; | ||
658 | |||
659 | if (dev->exposure == 0) { | ||
660 | ret = ov8858_read_reg(client, OV8858_16BIT, | ||
661 | OV8858_LONG_EXPO + 1, &data); | ||
662 | if (ret) | ||
663 | return ret; | ||
664 | exposure = data; | ||
665 | exposure >>= 4; | ||
666 | } else { | ||
667 | exposure = dev->exposure; | ||
668 | } | ||
669 | |||
670 | ret = ov8858_read_reg(client, OV8858_16BIT, OV8858_TIMING_VTS, &vts); | ||
671 | if (ret || vts == 0) | ||
672 | vts = OV8858_DEPTH_VTS_CONST; | ||
673 | |||
674 | *usec = (exposure * 33333 / vts); | ||
675 | if (*usec > OV8858_DEPTH_COMP_CONST) | ||
676 | *usec = *usec - OV8858_DEPTH_COMP_CONST; | ||
677 | else | ||
678 | *usec = OV8858_DEPTH_COMP_CONST; | ||
679 | |||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static long ov8858_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | ||
684 | { | ||
685 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
686 | switch (cmd) { | ||
687 | case ATOMISP_IOC_S_EXPOSURE: | ||
688 | return ov8858_s_exposure(sd, (struct atomisp_exposure *)arg); | ||
689 | case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: | ||
690 | return ov8858_g_priv_int_data(sd, arg); | ||
691 | case ATOMISP_IOC_G_DEPTH_SYNC_COMP: | ||
692 | return ov8858_g_comp_delay(sd, (unsigned int *)arg); | ||
693 | case ATOMISP_IOC_G_UPDATE_EXPOSURE: | ||
694 | return ov8858_g_update_exposure(sd, | ||
695 | (struct atomisp_update_exposure *)arg); | ||
696 | default: | ||
697 | dev_dbg(&client->dev, "Unhandled command 0x%X\n", cmd); | ||
698 | return -EINVAL; | ||
699 | } | ||
700 | } | ||
701 | |||
702 | static int __power_ctrl(struct v4l2_subdev *sd, bool flag) | ||
703 | { | ||
704 | int ret = 0; | ||
705 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
706 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
707 | |||
708 | if (!dev || !dev->platform_data) | ||
709 | return -ENODEV; | ||
710 | |||
711 | if (dev->platform_data->v1p2_ctrl) { | ||
712 | ret = dev->platform_data->v1p2_ctrl(sd, flag); | ||
713 | if (ret) { | ||
714 | dev_err(&client->dev, | ||
715 | "failed to power %s 1.2v power rail\n", | ||
716 | flag ? "up" : "down"); | ||
717 | return ret; | ||
718 | } | ||
719 | } | ||
720 | |||
721 | if (dev->platform_data->v2p8_ctrl) { | ||
722 | ret = dev->platform_data->v2p8_ctrl(sd, flag); | ||
723 | if (ret) { | ||
724 | dev_err(&client->dev, | ||
725 | "failed to power %s 2.8v power rail\n", | ||
726 | flag ? "up" : "down"); | ||
727 | return ret; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | if (dev->platform_data->v1p8_ctrl) { | ||
732 | ret = dev->platform_data->v1p8_ctrl(sd, flag); | ||
733 | if (ret) { | ||
734 | dev_err(&client->dev, | ||
735 | "failed to power %s 1.8v power rail\n", | ||
736 | flag ? "up" : "down"); | ||
737 | if (dev->platform_data->v2p8_ctrl) | ||
738 | dev->platform_data->v2p8_ctrl(sd, 0); | ||
739 | return ret; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | if (flag) | ||
744 | msleep(20); /* Wait for power lines to stabilize */ | ||
745 | return ret; | ||
746 | } | ||
747 | |||
748 | static int __gpio_ctrl(struct v4l2_subdev *sd, bool flag) | ||
749 | { | ||
750 | struct i2c_client *client; | ||
751 | struct ov8858_device *dev; | ||
752 | |||
753 | if (!sd) | ||
754 | return -EINVAL; | ||
755 | |||
756 | client = v4l2_get_subdevdata(sd); | ||
757 | dev = to_ov8858_sensor(sd); | ||
758 | |||
759 | if (!client || !dev || !dev->platform_data) | ||
760 | return -ENODEV; | ||
761 | |||
762 | if (dev->platform_data->gpio0_ctrl) | ||
763 | return dev->platform_data->gpio0_ctrl(sd, flag); | ||
764 | |||
765 | dev_err(&client->dev, "failed to find platform gpio callback\n"); | ||
766 | |||
767 | return -EINVAL; | ||
768 | } | ||
769 | |||
770 | static int power_up(struct v4l2_subdev *sd) | ||
771 | { | ||
772 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
773 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
774 | int ret; | ||
775 | dev_dbg(&client->dev, "%s\n", __func__); | ||
776 | |||
777 | /* Enable power */ | ||
778 | ret = __power_ctrl(sd, 1); | ||
779 | if (ret) { | ||
780 | dev_err(&client->dev, "power rail on failed %d.\n", ret); | ||
781 | goto fail_power; | ||
782 | } | ||
783 | |||
784 | /* Enable clock */ | ||
785 | ret = dev->platform_data->flisclk_ctrl(sd, 1); | ||
786 | if (ret) { | ||
787 | dev_err(&client->dev, "flisclk on failed %d\n", ret); | ||
788 | goto fail_clk; | ||
789 | } | ||
790 | |||
791 | /* Release reset */ | ||
792 | ret = __gpio_ctrl(sd, 1); | ||
793 | if (ret) { | ||
794 | dev_err(&client->dev, "gpio on failed %d\n", ret); | ||
795 | goto fail_gpio; | ||
796 | } | ||
797 | |||
798 | /* Minumum delay is 8192 clock cycles before first i2c transaction, | ||
799 | * which is 1.37 ms at the lowest allowed clock rate 6 MHz */ | ||
800 | usleep_range(2000, 2500); | ||
801 | return 0; | ||
802 | |||
803 | fail_gpio: | ||
804 | dev->platform_data->flisclk_ctrl(sd, 0); | ||
805 | fail_clk: | ||
806 | __power_ctrl(sd, 0); | ||
807 | fail_power: | ||
808 | dev_err(&client->dev, "Sensor power-up failed\n"); | ||
809 | |||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | static int power_down(struct v4l2_subdev *sd) | ||
814 | { | ||
815 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
816 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
817 | int ret; | ||
818 | dev_dbg(&client->dev, "%s\n", __func__); | ||
819 | |||
820 | ret = dev->platform_data->flisclk_ctrl(sd, 0); | ||
821 | if (ret) | ||
822 | dev_err(&client->dev, "flisclk off failed\n"); | ||
823 | |||
824 | ret = __gpio_ctrl(sd, 0); | ||
825 | if (ret) | ||
826 | dev_err(&client->dev, "gpio off failed\n"); | ||
827 | |||
828 | ret = __power_ctrl(sd, 0); | ||
829 | if (ret) | ||
830 | dev_err(&client->dev, "power rail off failed.\n"); | ||
831 | |||
832 | return ret; | ||
833 | } | ||
834 | |||
835 | static int __ov8858_s_power(struct v4l2_subdev *sd, int on) | ||
836 | { | ||
837 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
838 | int ret, r = 0; | ||
839 | |||
840 | if (on == 0) { | ||
841 | ov8858_uninit(sd); | ||
842 | if (dev->vcm_driver && dev->vcm_driver->power_down) | ||
843 | r = dev->vcm_driver->power_down(sd); | ||
844 | ret = power_down(sd); | ||
845 | if (r != 0 && ret == 0) | ||
846 | ret = r; | ||
847 | } else { | ||
848 | ret = power_up(sd); | ||
849 | if (ret) | ||
850 | power_down(sd); | ||
851 | if (dev->vcm_driver && dev->vcm_driver->power_up) { | ||
852 | ret = dev->vcm_driver->power_up(sd); | ||
853 | if (ret) { | ||
854 | power_down(sd); | ||
855 | return ret; | ||
856 | } | ||
857 | } | ||
858 | return __ov8858_init(sd); | ||
859 | } | ||
860 | |||
861 | return ret; | ||
862 | } | ||
863 | |||
864 | static int ov8858_s_power(struct v4l2_subdev *sd, int on) | ||
865 | { | ||
866 | int ret; | ||
867 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
868 | |||
869 | mutex_lock(&dev->input_lock); | ||
870 | ret = __ov8858_s_power(sd, on); | ||
871 | mutex_unlock(&dev->input_lock); | ||
872 | |||
873 | /* | ||
874 | * FIXME: Compatibility with old behaviour: return to preview | ||
875 | * when the device is power cycled. | ||
876 | */ | ||
877 | if (!ret && on) | ||
878 | v4l2_ctrl_s_ctrl(dev->run_mode, ATOMISP_RUN_MODE_PREVIEW); | ||
879 | |||
880 | return ret; | ||
881 | } | ||
882 | |||
883 | /* | ||
884 | * Return value of the specified register, first try getting it from | ||
885 | * the register list and if not found, get from the sensor via i2c. | ||
886 | */ | ||
887 | static int ov8858_get_register(struct v4l2_subdev *sd, int reg, int type, | ||
888 | const struct ov8858_reg *reglist) | ||
889 | { | ||
890 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
891 | const struct ov8858_reg *next; | ||
892 | u16 val; | ||
893 | |||
894 | /* Try if the values are in the register list */ | ||
895 | for (next = reglist; next->type != OV8858_TOK_TERM; next++) { | ||
896 | if (next->sreg == reg) { | ||
897 | if (type == OV8858_8BIT) | ||
898 | return next->val; | ||
899 | |||
900 | if (type == OV8858_16BIT && | ||
901 | next[1].type != OV8858_TOK_TERM) | ||
902 | return next[0].val << 8 | next[1].val; | ||
903 | } | ||
904 | } | ||
905 | |||
906 | /* If not, read from sensor */ | ||
907 | if (ov8858_read_reg(client, type, reg, &val)) { | ||
908 | dev_err(&client->dev, "failed to read register 0x%08x\n", reg); | ||
909 | return -EIO; | ||
910 | } | ||
911 | |||
912 | return val; | ||
913 | } | ||
914 | |||
915 | static inline int ov8858_get_register_16bit(struct v4l2_subdev *sd, int reg, | ||
916 | const struct ov8858_reg *reglist) | ||
917 | { | ||
918 | return ov8858_get_register(sd, reg, OV8858_16BIT, reglist); | ||
919 | } | ||
920 | |||
921 | static inline int ov8858_get_register_8bit(struct v4l2_subdev *sd, int reg, | ||
922 | const struct ov8858_reg *reglist) | ||
923 | { | ||
924 | return ov8858_get_register(sd, reg, OV8858_8BIT, reglist); | ||
925 | } | ||
926 | |||
927 | static int __ov8858_get_pll1_values(struct v4l2_subdev *sd, | ||
928 | int *value, | ||
929 | const struct ov8858_reg *reglist) | ||
930 | { | ||
931 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
932 | unsigned int prediv_idx; | ||
933 | unsigned int multiplier; | ||
934 | unsigned int sys_prediv; | ||
935 | unsigned int prediv_coef[] = {2, 3, 4, 5, 6, 8, 12, 16}; | ||
936 | int ret; | ||
937 | |||
938 | ret = ov8858_get_register_8bit(sd, OV8858_PLL1_PREDIV0, reglist); | ||
939 | if (ret < 0) | ||
940 | return ret; | ||
941 | |||
942 | if (ret & OV8858_PLL1_PREDIV0_MASK) | ||
943 | *value /= 2; | ||
944 | |||
945 | ret = ov8858_get_register_8bit(sd, OV8858_PLL1_PREDIV, reglist); | ||
946 | |||
947 | if (ret < 0) | ||
948 | return ret; | ||
949 | |||
950 | prediv_idx = ret & OV8858_PLL1_PREDIV_MASK; | ||
951 | *value = *value * 2 / prediv_coef[prediv_idx]; | ||
952 | |||
953 | ret = ov8858_get_register_16bit(sd, OV8858_PLL1_MULTIPLIER, reglist); | ||
954 | if (ret < 0) | ||
955 | return ret; | ||
956 | |||
957 | multiplier = ret; | ||
958 | *value *= multiplier & OV8858_PLL1_MULTIPLIER_MASK; | ||
959 | ret = ov8858_get_register_8bit(sd, OV8858_PLL1_SYS_PRE_DIV, reglist); | ||
960 | |||
961 | if (ret < 0) | ||
962 | return ret; | ||
963 | |||
964 | sys_prediv = ret & OV8858_PLL1_SYS_PRE_DIV_MASK; | ||
965 | *value /= (sys_prediv + 3); | ||
966 | ret = ov8858_get_register_8bit(sd, OV8858_PLL1_SYS_DIVIDER, reglist); | ||
967 | |||
968 | if (ret < 0) | ||
969 | return ret; | ||
970 | |||
971 | if (ret & OV8858_PLL1_SYS_DIVIDER_MASK) | ||
972 | *value /= 2; | ||
973 | |||
974 | dev_dbg(&client->dev, "%s: *value: %d\n", __func__, *value); | ||
975 | |||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | static int __ov8858_get_pll2a_values(struct v4l2_subdev *sd, int *value, | ||
980 | const struct ov8858_reg *reglist) | ||
981 | { | ||
982 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
983 | unsigned int prediv_idx; | ||
984 | unsigned int multiplier; | ||
985 | unsigned int prediv_coef[] = {2, 3, 4, 5, 6, 8, 12, 16}; | ||
986 | int ret; | ||
987 | |||
988 | ret = ov8858_get_register_8bit(sd, OV8858_PLL2_PREDIV0, reglist); | ||
989 | if (ret < 0) | ||
990 | return ret; | ||
991 | |||
992 | if (ret & OV8858_PLL2_PREDIV0_MASK) | ||
993 | *value /= 2; | ||
994 | |||
995 | ret = ov8858_get_register_8bit(sd, OV8858_PLL2_PREDIV, reglist); | ||
996 | if (ret < 0) | ||
997 | return ret; | ||
998 | |||
999 | prediv_idx = (ret & OV8858_PLL2_PREDIV_MASK); | ||
1000 | *value = *value * 2 / prediv_coef[prediv_idx]; | ||
1001 | |||
1002 | ret = ov8858_get_register_16bit(sd, OV8858_PLL2_MULTIPLIER, reglist); | ||
1003 | if (ret < 0) | ||
1004 | return ret; | ||
1005 | |||
1006 | multiplier = ret; | ||
1007 | *value *= multiplier & OV8858_PLL2_MULTIPLIER_MASK; | ||
1008 | dev_dbg(&client->dev, "%s: *value: %d\n", __func__, *value); | ||
1009 | |||
1010 | return 0; | ||
1011 | } | ||
1012 | static int __ov8858_get_pll2b_values(struct v4l2_subdev *sd, int *value, | ||
1013 | const struct ov8858_reg *reglist) | ||
1014 | { | ||
1015 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1016 | unsigned int dac_divider; | ||
1017 | int ret; | ||
1018 | |||
1019 | ret = ov8858_get_register_8bit(sd, OV8858_PLL2_DAC_DIVIDER, reglist); | ||
1020 | if (ret < 0) | ||
1021 | return ret; | ||
1022 | |||
1023 | dac_divider = (ret & OV8858_PLL2_DAC_DIVIDER_MASK) + 1; | ||
1024 | *value /= dac_divider; | ||
1025 | |||
1026 | dev_dbg(&client->dev, "%s: *value: %d\n", __func__, *value); | ||
1027 | |||
1028 | return 0; | ||
1029 | } | ||
1030 | static int __ov8858_get_pll2c_values(struct v4l2_subdev *sd, int *value, | ||
1031 | const struct ov8858_reg *reglist) | ||
1032 | { | ||
1033 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1034 | unsigned int sys_pre_div; | ||
1035 | unsigned int sys_divider_idx; | ||
1036 | unsigned int sys_divider_coef[] = {2, 3, 4, 5, 6, 7, 8, 10}; | ||
1037 | int ret; | ||
1038 | |||
1039 | ret = ov8858_get_register_8bit(sd, OV8858_PLL2_SYS_PRE_DIV, reglist); | ||
1040 | if (ret < 0) | ||
1041 | return ret; | ||
1042 | |||
1043 | sys_pre_div = (ret & OV8858_PLL2_SYS_PRE_DIV_MASK) + 1; | ||
1044 | *value /= sys_pre_div; | ||
1045 | |||
1046 | ret = ov8858_get_register_8bit(sd, OV8858_PLL2_SYS_DIVIDER, reglist); | ||
1047 | if (ret < 0) | ||
1048 | return ret; | ||
1049 | |||
1050 | sys_divider_idx = ret & OV8858_PLL2_SYS_DIVIDER_MASK; | ||
1051 | *value *= 2 / sys_divider_coef[sys_divider_idx]; | ||
1052 | |||
1053 | dev_dbg(&client->dev, "%s: *value: %d\n", __func__, *value); | ||
1054 | |||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | static int ov8858_get_intg_factor(struct v4l2_subdev *sd, | ||
1059 | struct camera_mipi_info *info, | ||
1060 | const struct ov8858_reg *reglist) | ||
1061 | { | ||
1062 | const unsigned int ext_clk = 19200000; /* Hz */ | ||
1063 | struct atomisp_sensor_mode_data *m = &info->data; | ||
1064 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1065 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1066 | struct device *d = &client->dev; | ||
1067 | const struct ov8858_resolution *res = | ||
1068 | &dev->curr_res_table[dev->fmt_idx]; | ||
1069 | unsigned int pll_sclksel1; | ||
1070 | unsigned int pll_sclksel2; | ||
1071 | unsigned int sys_pre_div; | ||
1072 | unsigned int sclk_pdiv; | ||
1073 | unsigned int sclk = ext_clk; | ||
1074 | u16 hts; | ||
1075 | int ret; | ||
1076 | |||
1077 | memset(&info->data, 0, sizeof(info->data)); | ||
1078 | |||
1079 | ret = ov8858_get_register_8bit(sd, OV8858_PLL_SCLKSEL1, reglist); | ||
1080 | if (ret < 0) | ||
1081 | return ret; | ||
1082 | |||
1083 | dev_dbg(d, "%s: OV8858_PLL_SCLKSEL1: 0x%02x\n", __func__, ret); | ||
1084 | pll_sclksel1 = ret & OV8858_PLL_SCLKSEL1_MASK; | ||
1085 | |||
1086 | ret = ov8858_get_register_8bit(sd, OV8858_PLL_SCLKSEL2, reglist); | ||
1087 | if (ret < 0) | ||
1088 | return ret; | ||
1089 | |||
1090 | dev_dbg(d, "%s: OV8858_PLL_SCLKSEL2: 0x%02x\n", __func__, ret); | ||
1091 | pll_sclksel2 = ret & OV8858_PLL_SCLKSEL2_MASK; | ||
1092 | |||
1093 | if (pll_sclksel2) { | ||
1094 | ret = __ov8858_get_pll2a_values(sd, &sclk, reglist); | ||
1095 | if (ret < 0) | ||
1096 | return ret; | ||
1097 | ret = __ov8858_get_pll2b_values(sd, &sclk, reglist); | ||
1098 | if (ret < 0) | ||
1099 | return ret; | ||
1100 | } else if (pll_sclksel1) { | ||
1101 | ret = __ov8858_get_pll2a_values(sd, &sclk, reglist); | ||
1102 | if (ret < 0) | ||
1103 | return ret; | ||
1104 | ret = __ov8858_get_pll2c_values(sd, &sclk, reglist); | ||
1105 | if (ret < 0) | ||
1106 | return ret; | ||
1107 | } else { | ||
1108 | ret = __ov8858_get_pll1_values(sd, &sclk, reglist); | ||
1109 | if (ret < 0) | ||
1110 | return ret; | ||
1111 | } | ||
1112 | |||
1113 | ret = ov8858_get_register_8bit(sd, OV8858_SRB_HOST_INPUT_DIS, reglist); | ||
1114 | if (ret < 0) | ||
1115 | return ret; | ||
1116 | |||
1117 | dev_dbg(d, "%s: OV8858_SRB_HOST_INPUT_DIS: 0x%02x\n", __func__, ret); | ||
1118 | |||
1119 | sys_pre_div = ret & OV8858_SYS_PRE_DIV_MASK; | ||
1120 | sys_pre_div >>= OV8858_SYS_PRE_DIV_OFFSET; | ||
1121 | |||
1122 | if (sys_pre_div == 1) | ||
1123 | sclk /= 2; | ||
1124 | else if (sys_pre_div == 2) | ||
1125 | sclk /= 4; | ||
1126 | |||
1127 | sclk_pdiv = ret & OV8858_SCLK_PDIV_MASK; | ||
1128 | sclk_pdiv >>= OV8858_SCLK_PDIV_OFFSET; | ||
1129 | |||
1130 | if (sclk_pdiv > 1) | ||
1131 | sclk /= sclk_pdiv; | ||
1132 | |||
1133 | dev_dbg(d, "%s: sclk: %d\n", __func__, sclk); | ||
1134 | |||
1135 | dev->vt_pix_clk_freq_mhz = sclk; | ||
1136 | m->vt_pix_clk_freq_mhz = sclk; | ||
1137 | |||
1138 | /* HTS and VTS */ | ||
1139 | m->frame_length_lines = | ||
1140 | res->fps_options[dev->fps_index].lines_per_frame; | ||
1141 | m->line_length_pck = res->fps_options[dev->fps_index].pixels_per_line; | ||
1142 | |||
1143 | m->coarse_integration_time_min = 0; | ||
1144 | m->coarse_integration_time_max_margin = OV8858_INTEGRATION_TIME_MARGIN; | ||
1145 | ret = ov8858_read_reg(client, OV8858_16BIT, OV8858_TIMING_HTS, &hts); | ||
1146 | if (ret < 0) | ||
1147 | return ret; | ||
1148 | m->hts = hts; | ||
1149 | dev_dbg(&client->dev, "%s: get HTS %d\n", __func__, hts); | ||
1150 | |||
1151 | /* OV Sensor do not use fine integration time. */ | ||
1152 | m->fine_integration_time_min = 0; | ||
1153 | m->fine_integration_time_max_margin = 0; | ||
1154 | |||
1155 | /* | ||
1156 | * read_mode indicate whether binning is used for calculating | ||
1157 | * the correct exposure value from the user side. So adapt the | ||
1158 | * read mode values accordingly. | ||
1159 | */ | ||
1160 | m->read_mode = res->bin_factor_x ? | ||
1161 | OV8858_READ_MODE_BINNING_ON : OV8858_READ_MODE_BINNING_OFF; | ||
1162 | |||
1163 | ret = ov8858_get_register_8bit(sd, OV8858_H_INC_ODD, res->regs); | ||
1164 | if (ret < 0) | ||
1165 | return ret; | ||
1166 | m->binning_factor_x = (ret + 1) / 2; | ||
1167 | |||
1168 | ret = ov8858_get_register_8bit(sd, OV8858_V_INC_ODD, res->regs); | ||
1169 | if (ret < 0) | ||
1170 | return ret; | ||
1171 | m->binning_factor_y = (ret + 1) / 2; | ||
1172 | |||
1173 | /* Get the cropping and output resolution to ISP for this mode. */ | ||
1174 | ret = ov8858_get_register_16bit(sd, OV8858_HORIZONTAL_START_H, | ||
1175 | res->regs); | ||
1176 | if (ret < 0) | ||
1177 | return ret; | ||
1178 | |||
1179 | m->crop_horizontal_start = ret; | ||
1180 | |||
1181 | ret = ov8858_get_register_16bit(sd, OV8858_VERTICAL_START_H, res->regs); | ||
1182 | if (ret < 0) | ||
1183 | return ret; | ||
1184 | |||
1185 | m->crop_vertical_start = ret; | ||
1186 | |||
1187 | ret = ov8858_get_register_16bit(sd, OV8858_HORIZONTAL_END_H, res->regs); | ||
1188 | if (ret < 0) | ||
1189 | return ret; | ||
1190 | |||
1191 | m->crop_horizontal_end = ret; | ||
1192 | |||
1193 | ret = ov8858_get_register_16bit(sd, OV8858_VERTICAL_END_H, res->regs); | ||
1194 | if (ret < 0) | ||
1195 | return ret; | ||
1196 | |||
1197 | m->crop_vertical_end = ret; | ||
1198 | |||
1199 | ret = ov8858_get_register_16bit(sd, OV8858_HORIZONTAL_OUTPUT_SIZE_H, | ||
1200 | res->regs); | ||
1201 | if (ret < 0) | ||
1202 | return ret; | ||
1203 | |||
1204 | m->output_width = ret; | ||
1205 | |||
1206 | ret = ov8858_get_register_16bit(sd, OV8858_VERTICAL_OUTPUT_SIZE_H, | ||
1207 | res->regs); | ||
1208 | if (ret < 0) | ||
1209 | return ret; | ||
1210 | |||
1211 | m->output_height = ret; | ||
1212 | |||
1213 | return 0; | ||
1214 | } | ||
1215 | |||
1216 | /* | ||
1217 | * distance - calculate the distance | ||
1218 | * @res: resolution | ||
1219 | * @w: width | ||
1220 | * @h: height | ||
1221 | * | ||
1222 | * Get the gap between res_w/res_h and w/h. | ||
1223 | * distance = (res_w/res_h - w/h) / (w/h) * 8192 | ||
1224 | * res->width/height smaller than w/h wouldn't be considered. | ||
1225 | * The gap of ratio larger than 1/8 wouldn't be considered. | ||
1226 | * Returns the value of gap or -1 if fail. | ||
1227 | */ | ||
1228 | #define LARGEST_ALLOWED_RATIO_MISMATCH 1024 | ||
1229 | static int distance(struct ov8858_resolution const *res, const u32 w, | ||
1230 | const u32 h) | ||
1231 | { | ||
1232 | int ratio; | ||
1233 | int distance; | ||
1234 | |||
1235 | if (w == 0 || h == 0 || | ||
1236 | res->width < w || res->height < h) | ||
1237 | return -1; | ||
1238 | |||
1239 | ratio = res->width << 13; | ||
1240 | ratio /= w; | ||
1241 | ratio *= h; | ||
1242 | ratio /= res->height; | ||
1243 | |||
1244 | distance = abs(ratio - 8192); | ||
1245 | |||
1246 | if (distance > LARGEST_ALLOWED_RATIO_MISMATCH) | ||
1247 | return -1; | ||
1248 | return distance; | ||
1249 | } | ||
1250 | |||
1251 | /* | ||
1252 | * Returns the nearest higher resolution index. | ||
1253 | * @w: width | ||
1254 | * @h: height | ||
1255 | * matching is done based on enveloping resolution and | ||
1256 | * aspect ratio. If the aspect ratio cannot be matched | ||
1257 | * to any index, -1 is returned. | ||
1258 | */ | ||
1259 | static int nearest_resolution_index(struct v4l2_subdev *sd, int w, int h) | ||
1260 | { | ||
1261 | int i; | ||
1262 | int idx = -1; | ||
1263 | int dist; | ||
1264 | int fps_diff; | ||
1265 | int min_fps_diff = INT_MAX; | ||
1266 | int min_dist = INT_MAX; | ||
1267 | int min_res_w = INT_MAX; | ||
1268 | const struct ov8858_resolution *tmp_res = NULL; | ||
1269 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1270 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1271 | dev_dbg(&client->dev, "%s: w=%d, h=%d\n", __func__, w, h); | ||
1272 | |||
1273 | for (i = 0; i < dev->entries_curr_table; i++) { | ||
1274 | tmp_res = &dev->curr_res_table[i]; | ||
1275 | dist = distance(tmp_res, w, h); | ||
1276 | dev_dbg(&client->dev, | ||
1277 | "%s[%d]: %dx%d distance=%d\n", tmp_res->desc, | ||
1278 | i, tmp_res->width, tmp_res->height, dist); | ||
1279 | if (dist == -1) | ||
1280 | continue; | ||
1281 | if (dist < min_dist) { | ||
1282 | min_dist = dist; | ||
1283 | min_res_w = tmp_res->width; | ||
1284 | min_fps_diff = __ov8858_min_fps_diff(dev->fps, | ||
1285 | tmp_res->fps_options); | ||
1286 | idx = i; | ||
1287 | } | ||
1288 | if (dist == min_dist) { | ||
1289 | fps_diff = __ov8858_min_fps_diff(dev->fps, | ||
1290 | tmp_res->fps_options); | ||
1291 | if (fps_diff < min_fps_diff) { | ||
1292 | min_fps_diff = fps_diff; | ||
1293 | idx = i; | ||
1294 | } | ||
1295 | if (tmp_res->width < min_res_w) { | ||
1296 | min_res_w = tmp_res->width; | ||
1297 | idx = i; | ||
1298 | } | ||
1299 | } | ||
1300 | } | ||
1301 | |||
1302 | return idx; | ||
1303 | } | ||
1304 | |||
1305 | static int ov8858_set_fmt(struct v4l2_subdev *sd, | ||
1306 | struct v4l2_subdev_pad_config *cfg, | ||
1307 | struct v4l2_subdev_format *format) | ||
1308 | { | ||
1309 | struct v4l2_mbus_framefmt *fmt = &format->format; | ||
1310 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1311 | struct camera_mipi_info *ov8858_info = NULL; | ||
1312 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1313 | const struct ov8858_resolution *res; | ||
1314 | int ret; | ||
1315 | int idx; | ||
1316 | if (format->pad) | ||
1317 | return -EINVAL; | ||
1318 | if (!fmt) | ||
1319 | return -EINVAL; | ||
1320 | |||
1321 | ov8858_info = v4l2_get_subdev_hostdata(sd); | ||
1322 | if (ov8858_info == NULL) | ||
1323 | return -EINVAL; | ||
1324 | |||
1325 | mutex_lock(&dev->input_lock); | ||
1326 | |||
1327 | if ((fmt->width > OV8858_RES_WIDTH_MAX) || | ||
1328 | (fmt->height > OV8858_RES_HEIGHT_MAX)) { | ||
1329 | fmt->width = OV8858_RES_WIDTH_MAX; | ||
1330 | fmt->height = OV8858_RES_HEIGHT_MAX; | ||
1331 | } else { | ||
1332 | idx = nearest_resolution_index(sd, fmt->width, fmt->height); | ||
1333 | |||
1334 | /* | ||
1335 | * nearest_resolution_index() doesn't return smaller | ||
1336 | * resolutions. If it fails, it means the requested resolution | ||
1337 | * is higher than we can support. Fallback to highest possible | ||
1338 | * resolution in this case. | ||
1339 | */ | ||
1340 | if (idx == -1) | ||
1341 | idx = dev->entries_curr_table - 1; | ||
1342 | |||
1343 | fmt->width = dev->curr_res_table[idx].width; | ||
1344 | fmt->height = dev->curr_res_table[idx].height; | ||
1345 | } | ||
1346 | |||
1347 | fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
1348 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
1349 | cfg->try_fmt = *fmt; | ||
1350 | mutex_unlock(&dev->input_lock); | ||
1351 | return 0; | ||
1352 | } | ||
1353 | |||
1354 | dev->fmt_idx = nearest_resolution_index(sd, fmt->width, fmt->height); | ||
1355 | if (dev->fmt_idx == -1) { | ||
1356 | ret = -EINVAL; | ||
1357 | goto out; | ||
1358 | } | ||
1359 | res = &dev->curr_res_table[dev->fmt_idx]; | ||
1360 | dev_dbg(&client->dev, "%s: selected width = %d, height = %d\n", | ||
1361 | __func__, res->width, res->height); | ||
1362 | |||
1363 | /* Adjust the FPS selection based on the resolution selected */ | ||
1364 | dev->fps_index = __ov8858_nearest_fps_index(dev->fps, res->fps_options); | ||
1365 | dev->fps = res->fps_options[dev->fps_index].fps; | ||
1366 | dev->regs = res->fps_options[dev->fps_index].regs; | ||
1367 | if (!dev->regs) | ||
1368 | dev->regs = res->regs; | ||
1369 | |||
1370 | ret = ov8858_write_reg_array(client, dev->regs); | ||
1371 | if (ret) | ||
1372 | goto out; | ||
1373 | |||
1374 | dev->pixels_per_line = res->fps_options[dev->fps_index].pixels_per_line; | ||
1375 | dev->lines_per_frame = res->fps_options[dev->fps_index].lines_per_frame; | ||
1376 | |||
1377 | /* ov8858 only support RGB RAW10 output */ | ||
1378 | ov8858_info->metadata_width = res->width * 10 / 8; | ||
1379 | ov8858_info->metadata_height = 2; | ||
1380 | ov8858_info->metadata_format = ATOMISP_INPUT_FORMAT_EMBEDDED; | ||
1381 | |||
1382 | /* Set the initial exposure */ | ||
1383 | ret = __ov8858_set_exposure(sd, dev->exposure, dev->gain, | ||
1384 | dev->digital_gain, &dev->pixels_per_line, | ||
1385 | &dev->lines_per_frame); | ||
1386 | if (ret) | ||
1387 | goto out; | ||
1388 | |||
1389 | ret = ov8858_get_intg_factor(sd, ov8858_info, dev->regs); | ||
1390 | |||
1391 | out: | ||
1392 | mutex_unlock(&dev->input_lock); | ||
1393 | |||
1394 | return ret; | ||
1395 | } | ||
1396 | |||
1397 | static int ov8858_get_fmt(struct v4l2_subdev *sd, | ||
1398 | struct v4l2_subdev_pad_config *cfg, | ||
1399 | struct v4l2_subdev_format *format) | ||
1400 | { | ||
1401 | struct v4l2_mbus_framefmt *fmt = &format->format; | ||
1402 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1403 | |||
1404 | if (format->pad) | ||
1405 | return -EINVAL; | ||
1406 | if (!fmt) | ||
1407 | return -EINVAL; | ||
1408 | |||
1409 | mutex_lock(&dev->input_lock); | ||
1410 | fmt->width = dev->curr_res_table[dev->fmt_idx].width; | ||
1411 | fmt->height = dev->curr_res_table[dev->fmt_idx].height; | ||
1412 | fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
1413 | mutex_unlock(&dev->input_lock); | ||
1414 | |||
1415 | return 0; | ||
1416 | } | ||
1417 | |||
1418 | static int ov8858_detect(struct i2c_client *client, u16 *id) | ||
1419 | { | ||
1420 | struct i2c_adapter *adapter = client->adapter; | ||
1421 | u16 id_hi = 0; | ||
1422 | u16 id_low = 0; | ||
1423 | int ret; | ||
1424 | |||
1425 | /* i2c check */ | ||
1426 | if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) | ||
1427 | return -ENODEV; | ||
1428 | |||
1429 | dev_dbg(&client->dev, "%s: I2C functionality ok\n", __func__); | ||
1430 | ret = ov8858_read_reg(client, OV8858_8BIT, OV8858_CHIP_ID_HIGH, &id_hi); | ||
1431 | if (ret) | ||
1432 | return ret; | ||
1433 | dev_dbg(&client->dev, "%s: id_high = 0x%04x\n", __func__, id_hi); | ||
1434 | ret = ov8858_read_reg(client, OV8858_8BIT, OV8858_CHIP_ID_LOW, &id_low); | ||
1435 | if (ret) | ||
1436 | return ret; | ||
1437 | dev_dbg(&client->dev, "%s: id_low = 0x%04x\n", __func__, id_low); | ||
1438 | *id = (id_hi << 8) | id_low; | ||
1439 | |||
1440 | dev_dbg(&client->dev, "%s: chip_id = 0x%04x\n", __func__, *id); | ||
1441 | |||
1442 | dev_info(&client->dev, "%s: chip_id = 0x%04x\n", __func__, *id); | ||
1443 | if (*id != OV8858_CHIP_ID) | ||
1444 | return -ENODEV; | ||
1445 | |||
1446 | /* Stream off now. */ | ||
1447 | return ov8858_write_reg(client, OV8858_8BIT, OV8858_STREAM_MODE, 0); | ||
1448 | } | ||
1449 | |||
1450 | static void __ov8858_print_timing(struct v4l2_subdev *sd) | ||
1451 | { | ||
1452 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1453 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1454 | u16 width = dev->curr_res_table[dev->fmt_idx].width; | ||
1455 | u16 height = dev->curr_res_table[dev->fmt_idx].height; | ||
1456 | |||
1457 | dev_dbg(&client->dev, "Dump ov8858 timing in stream on:\n"); | ||
1458 | dev_dbg(&client->dev, "width: %d:\n", width); | ||
1459 | dev_dbg(&client->dev, "height: %d:\n", height); | ||
1460 | dev_dbg(&client->dev, "pixels_per_line: %d:\n", dev->pixels_per_line); | ||
1461 | dev_dbg(&client->dev, "line per frame: %d:\n", dev->lines_per_frame); | ||
1462 | dev_dbg(&client->dev, "pix freq: %d:\n", dev->vt_pix_clk_freq_mhz); | ||
1463 | /* updated formula: pixels_per_line = 2 * HTS */ | ||
1464 | /* updated formula: fps = SCLK / (VTS * HTS) */ | ||
1465 | dev_dbg(&client->dev, "init fps: %d:\n", dev->vt_pix_clk_freq_mhz / | ||
1466 | (dev->pixels_per_line / 2) / dev->lines_per_frame); | ||
1467 | dev_dbg(&client->dev, "HBlank: %d nS:\n", | ||
1468 | 1000 * (dev->pixels_per_line - width) / | ||
1469 | (dev->vt_pix_clk_freq_mhz / 1000000)); | ||
1470 | dev_dbg(&client->dev, "VBlank: %d uS:\n", | ||
1471 | (dev->lines_per_frame - height) * dev->pixels_per_line / | ||
1472 | (dev->vt_pix_clk_freq_mhz / 1000000)); | ||
1473 | } | ||
1474 | |||
1475 | /* | ||
1476 | * ov8858 stream on/off | ||
1477 | */ | ||
1478 | static int ov8858_s_stream(struct v4l2_subdev *sd, int enable) | ||
1479 | { | ||
1480 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1481 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1482 | int ret; | ||
1483 | u16 val; | ||
1484 | dev_dbg(&client->dev, "%s: enable = %d\n", __func__, enable); | ||
1485 | |||
1486 | /* Set orientation */ | ||
1487 | ret = ov8858_read_reg(client, OV8858_8BIT, OV8858_FORMAT2, &val); | ||
1488 | if (ret) | ||
1489 | return ret; | ||
1490 | |||
1491 | ret = ov8858_write_reg(client, OV8858_8BIT, OV8858_FORMAT2, | ||
1492 | dev->hflip ? val | OV8858_FLIP_ENABLE : | ||
1493 | val & ~OV8858_FLIP_ENABLE); | ||
1494 | if (ret) | ||
1495 | return ret; | ||
1496 | |||
1497 | ret = ov8858_read_reg(client, OV8858_8BIT, OV8858_FORMAT1, &val); | ||
1498 | if (ret) | ||
1499 | return ret; | ||
1500 | |||
1501 | ret = ov8858_write_reg(client, OV8858_8BIT, OV8858_FORMAT1, | ||
1502 | dev->vflip ? val | OV8858_FLIP_ENABLE : | ||
1503 | val & ~OV8858_FLIP_ENABLE); | ||
1504 | if (ret) | ||
1505 | return ret; | ||
1506 | |||
1507 | mutex_lock(&dev->input_lock); | ||
1508 | if (enable) { | ||
1509 | __ov8858_print_timing(sd); | ||
1510 | ret = ov8858_write_reg_array(client, ov8858_streaming); | ||
1511 | if (ret != 0) { | ||
1512 | dev_err(&client->dev, "write_reg_array err\n"); | ||
1513 | goto out; | ||
1514 | } | ||
1515 | dev->streaming = 1; | ||
1516 | } else { | ||
1517 | ret = ov8858_write_reg_array(client, ov8858_soft_standby); | ||
1518 | if (ret != 0) { | ||
1519 | dev_err(&client->dev, "write_reg_array err\n"); | ||
1520 | goto out; | ||
1521 | } | ||
1522 | dev->streaming = 0; | ||
1523 | dev->fps_index = 0; | ||
1524 | dev->fps = 0; | ||
1525 | } | ||
1526 | out: | ||
1527 | mutex_unlock(&dev->input_lock); | ||
1528 | return ret; | ||
1529 | } | ||
1530 | |||
1531 | static int __update_ov8858_device_settings(struct ov8858_device *dev, | ||
1532 | u16 sensor_id) | ||
1533 | { | ||
1534 | if (sensor_id == OV8858_CHIP_ID) | ||
1535 | #ifdef CONFIG_PLATFORM_BTNS | ||
1536 | dev->vcm_driver = &ov8858_vcms[OV8858_ID_DEFAULT]; | ||
1537 | #else | ||
1538 | dev->vcm_driver = &ov8858_vcms[OV8858_SUNNY]; | ||
1539 | #endif | ||
1540 | else | ||
1541 | return -ENODEV; | ||
1542 | |||
1543 | if (dev->vcm_driver && dev->vcm_driver->init) | ||
1544 | return dev->vcm_driver->init(&dev->sd); | ||
1545 | |||
1546 | return 0; | ||
1547 | } | ||
1548 | |||
1549 | static int ov8858_s_config(struct v4l2_subdev *sd, | ||
1550 | int irq, void *pdata) | ||
1551 | { | ||
1552 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1553 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1554 | u16 sensor_id; | ||
1555 | int ret; | ||
1556 | |||
1557 | if (pdata == NULL) | ||
1558 | return -ENODEV; | ||
1559 | |||
1560 | dev->platform_data = pdata; | ||
1561 | |||
1562 | mutex_lock(&dev->input_lock); | ||
1563 | |||
1564 | ret = __ov8858_s_power(sd, 1); | ||
1565 | if (ret) { | ||
1566 | dev_err(&client->dev, "power-up error %d!\n", ret); | ||
1567 | mutex_unlock(&dev->input_lock); | ||
1568 | return ret; | ||
1569 | } | ||
1570 | |||
1571 | ret = dev->platform_data->csi_cfg(sd, 1); | ||
1572 | if (ret) | ||
1573 | goto fail_csi_cfg; | ||
1574 | |||
1575 | /* config & detect sensor */ | ||
1576 | ret = ov8858_detect(client, &sensor_id); | ||
1577 | if (ret) { | ||
1578 | dev_err(&client->dev, "detect error %d!\n", ret); | ||
1579 | goto fail_detect; | ||
1580 | } | ||
1581 | |||
1582 | dev->sensor_id = sensor_id; | ||
1583 | |||
1584 | /* power off sensor */ | ||
1585 | ret = __ov8858_s_power(sd, 0); | ||
1586 | if (ret) { | ||
1587 | dev->platform_data->csi_cfg(sd, 0); | ||
1588 | dev_err(&client->dev, "__ov8858_s_power-down error %d!\n", ret); | ||
1589 | goto fail_update; | ||
1590 | } | ||
1591 | |||
1592 | /* Resolution settings depend on sensor type and platform */ | ||
1593 | ret = __update_ov8858_device_settings(dev, dev->sensor_id); | ||
1594 | if (ret) { | ||
1595 | dev->platform_data->csi_cfg(sd, 0); | ||
1596 | dev_err(&client->dev, "__update_ov8858_device_settings error %d!\n", ret); | ||
1597 | goto fail_update; | ||
1598 | } | ||
1599 | |||
1600 | mutex_unlock(&dev->input_lock); | ||
1601 | return ret; | ||
1602 | |||
1603 | fail_detect: | ||
1604 | dev->platform_data->csi_cfg(sd, 0); | ||
1605 | fail_csi_cfg: | ||
1606 | __ov8858_s_power(sd, 0); | ||
1607 | fail_update: | ||
1608 | mutex_unlock(&dev->input_lock); | ||
1609 | dev_err(&client->dev, "sensor power-gating failed\n"); | ||
1610 | return ret; | ||
1611 | } | ||
1612 | |||
1613 | static int | ||
1614 | ov8858_enum_mbus_code(struct v4l2_subdev *sd, | ||
1615 | struct v4l2_subdev_pad_config *cfg, | ||
1616 | struct v4l2_subdev_mbus_code_enum *code) | ||
1617 | { | ||
1618 | if (code->index) | ||
1619 | return -EINVAL; | ||
1620 | code->code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
1621 | |||
1622 | return 0; | ||
1623 | } | ||
1624 | |||
1625 | static int | ||
1626 | ov8858_enum_frame_size(struct v4l2_subdev *sd, | ||
1627 | struct v4l2_subdev_pad_config *cfg, | ||
1628 | struct v4l2_subdev_frame_size_enum *fse) | ||
1629 | { | ||
1630 | int index = fse->index; | ||
1631 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1632 | |||
1633 | mutex_lock(&dev->input_lock); | ||
1634 | if (index >= dev->entries_curr_table) { | ||
1635 | mutex_unlock(&dev->input_lock); | ||
1636 | return -EINVAL; | ||
1637 | } | ||
1638 | |||
1639 | fse->min_width = dev->curr_res_table[index].width; | ||
1640 | fse->min_height = dev->curr_res_table[index].height; | ||
1641 | fse->max_width = dev->curr_res_table[index].width; | ||
1642 | fse->max_height = dev->curr_res_table[index].height; | ||
1643 | mutex_unlock(&dev->input_lock); | ||
1644 | |||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | static int ov8858_s_ctrl(struct v4l2_ctrl *ctrl) | ||
1649 | { | ||
1650 | struct ov8858_device *dev = container_of( | ||
1651 | ctrl->handler, struct ov8858_device, ctrl_handler); | ||
1652 | struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); | ||
1653 | |||
1654 | /* input_lock is taken by the control framework, so it | ||
1655 | * doesn't need to be taken here. | ||
1656 | */ | ||
1657 | |||
1658 | switch (ctrl->id) { | ||
1659 | case V4L2_CID_RUN_MODE: | ||
1660 | switch (ctrl->val) { | ||
1661 | case ATOMISP_RUN_MODE_VIDEO: | ||
1662 | dev->curr_res_table = ov8858_res_video; | ||
1663 | dev->entries_curr_table = ARRAY_SIZE(ov8858_res_video); | ||
1664 | break; | ||
1665 | case ATOMISP_RUN_MODE_STILL_CAPTURE: | ||
1666 | dev->curr_res_table = ov8858_res_still; | ||
1667 | dev->entries_curr_table = ARRAY_SIZE(ov8858_res_still); | ||
1668 | break; | ||
1669 | default: | ||
1670 | dev->curr_res_table = ov8858_res_preview; | ||
1671 | dev->entries_curr_table = | ||
1672 | ARRAY_SIZE(ov8858_res_preview); | ||
1673 | } | ||
1674 | |||
1675 | dev->fmt_idx = 0; | ||
1676 | dev->fps_index = 0; | ||
1677 | |||
1678 | return 0; | ||
1679 | case V4L2_CID_FOCUS_ABSOLUTE: | ||
1680 | if (dev->vcm_driver && dev->vcm_driver->t_focus_abs) | ||
1681 | return dev->vcm_driver->t_focus_abs(&dev->sd, | ||
1682 | ctrl->val); | ||
1683 | return 0; | ||
1684 | case V4L2_CID_EXPOSURE_AUTO_PRIORITY: | ||
1685 | if (ctrl->val == V4L2_EXPOSURE_AUTO) | ||
1686 | dev->limit_exposure_flag = false; | ||
1687 | else if (ctrl->val == V4L2_EXPOSURE_APERTURE_PRIORITY) | ||
1688 | dev->limit_exposure_flag = true; | ||
1689 | return 0; | ||
1690 | case V4L2_CID_HFLIP: | ||
1691 | dev->hflip = ctrl->val; | ||
1692 | return 0; | ||
1693 | case V4L2_CID_VFLIP: | ||
1694 | dev->vflip = ctrl->val; | ||
1695 | return 0; | ||
1696 | default: | ||
1697 | dev_err(&client->dev, "%s: Error: Invalid ctrl: 0x%X\n", | ||
1698 | __func__, ctrl->id); | ||
1699 | return -EINVAL; | ||
1700 | } | ||
1701 | } | ||
1702 | |||
1703 | static int ov8858_g_ctrl(struct v4l2_ctrl *ctrl) | ||
1704 | { | ||
1705 | struct ov8858_device *dev = container_of( | ||
1706 | ctrl->handler, struct ov8858_device, ctrl_handler); | ||
1707 | struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); | ||
1708 | int r_odd, r_even; | ||
1709 | int i = dev->fmt_idx; | ||
1710 | |||
1711 | switch (ctrl->id) { | ||
1712 | case V4L2_CID_FOCUS_STATUS: | ||
1713 | if (dev->vcm_driver && dev->vcm_driver->q_focus_status) | ||
1714 | return dev->vcm_driver->q_focus_status(&dev->sd, | ||
1715 | &(ctrl->val)); | ||
1716 | return 0; | ||
1717 | case V4L2_CID_BIN_FACTOR_HORZ: | ||
1718 | r_odd = ov8858_get_register_8bit(&dev->sd, OV8858_H_INC_ODD, | ||
1719 | dev->curr_res_table[i].regs); | ||
1720 | if (r_odd < 0) | ||
1721 | return r_odd; | ||
1722 | r_even = ov8858_get_register_8bit(&dev->sd, OV8858_H_INC_EVEN, | ||
1723 | dev->curr_res_table[i].regs); | ||
1724 | if (r_even < 0) | ||
1725 | return r_even; | ||
1726 | ctrl->val = fls(r_odd + (r_even)) - 2; | ||
1727 | return 0; | ||
1728 | |||
1729 | case V4L2_CID_BIN_FACTOR_VERT: | ||
1730 | r_odd = ov8858_get_register_8bit(&dev->sd, OV8858_V_INC_ODD, | ||
1731 | dev->curr_res_table[i].regs); | ||
1732 | if (r_odd < 0) | ||
1733 | return r_odd; | ||
1734 | r_even = ov8858_get_register_8bit(&dev->sd, OV8858_V_INC_EVEN, | ||
1735 | dev->curr_res_table[i].regs); | ||
1736 | if (r_even < 0) | ||
1737 | return r_even; | ||
1738 | ctrl->val = fls(r_odd + (r_even)) - 2; | ||
1739 | return 0; | ||
1740 | case V4L2_CID_HFLIP: | ||
1741 | ctrl->val = dev->hflip; | ||
1742 | break; | ||
1743 | case V4L2_CID_VFLIP: | ||
1744 | ctrl->val = dev->vflip; | ||
1745 | break; | ||
1746 | case V4L2_CID_EXPOSURE_ABSOLUTE: | ||
1747 | ctrl->val = dev->exposure; | ||
1748 | break; | ||
1749 | default: | ||
1750 | dev_warn(&client->dev, | ||
1751 | "%s: Error: Invalid ctrl: 0x%X\n", __func__, ctrl->id); | ||
1752 | return -EINVAL; | ||
1753 | } | ||
1754 | |||
1755 | return 0; | ||
1756 | } | ||
1757 | |||
1758 | static int | ||
1759 | ov8858_g_frame_interval(struct v4l2_subdev *sd, | ||
1760 | struct v4l2_subdev_frame_interval *interval) | ||
1761 | { | ||
1762 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1763 | const struct ov8858_resolution *res = | ||
1764 | &dev->curr_res_table[dev->fmt_idx]; | ||
1765 | |||
1766 | mutex_lock(&dev->input_lock); | ||
1767 | interval->interval.denominator = res->fps_options[dev->fps_index].fps; | ||
1768 | interval->interval.numerator = 1; | ||
1769 | mutex_unlock(&dev->input_lock); | ||
1770 | return 0; | ||
1771 | } | ||
1772 | |||
1773 | static int __ov8858_s_frame_interval(struct v4l2_subdev *sd, | ||
1774 | struct v4l2_subdev_frame_interval *interval) | ||
1775 | { | ||
1776 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1777 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1778 | const struct ov8858_resolution *res = | ||
1779 | &dev->curr_res_table[dev->fmt_idx]; | ||
1780 | struct camera_mipi_info *info = NULL; | ||
1781 | unsigned int fps_index; | ||
1782 | int ret = 0; | ||
1783 | int fps; | ||
1784 | |||
1785 | info = v4l2_get_subdev_hostdata(sd); | ||
1786 | if (info == NULL) | ||
1787 | return -EINVAL; | ||
1788 | |||
1789 | if (!interval->interval.numerator) | ||
1790 | interval->interval.numerator = 1; | ||
1791 | |||
1792 | fps = interval->interval.denominator / interval->interval.numerator; | ||
1793 | |||
1794 | /* No need to proceed further if we are not streaming */ | ||
1795 | if (!dev->streaming) { | ||
1796 | /* Save the new FPS and use it while selecting setting */ | ||
1797 | dev->fps = fps; | ||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | /* Ignore if we are already using the required FPS. */ | ||
1802 | if (fps == res->fps_options[dev->fps_index].fps) | ||
1803 | return 0; | ||
1804 | |||
1805 | fps_index = __ov8858_nearest_fps_index(fps, res->fps_options); | ||
1806 | |||
1807 | if (res->fps_options[fps_index].regs && | ||
1808 | res->fps_options[fps_index].regs != dev->regs) { | ||
1809 | dev_err(&client->dev, | ||
1810 | "Sensor is streaming, can't apply new configuration\n"); | ||
1811 | return -EBUSY; | ||
1812 | } | ||
1813 | |||
1814 | dev->fps_index = fps_index; | ||
1815 | dev->fps = res->fps_options[dev->fps_index].fps; | ||
1816 | |||
1817 | /* Update the new frametimings based on FPS */ | ||
1818 | dev->pixels_per_line = | ||
1819 | res->fps_options[dev->fps_index].pixels_per_line; | ||
1820 | dev->lines_per_frame = | ||
1821 | res->fps_options[dev->fps_index].lines_per_frame; | ||
1822 | |||
1823 | /* update frametiming. Conside the curren exposure/gain as well */ | ||
1824 | ret = __ov8858_update_frame_timing(sd, | ||
1825 | &dev->pixels_per_line, &dev->lines_per_frame); | ||
1826 | if (ret) | ||
1827 | return ret; | ||
1828 | |||
1829 | /* Update the new values so that user side knows the current settings */ | ||
1830 | ret = ov8858_get_intg_factor(sd, info, dev->regs); | ||
1831 | if (ret) | ||
1832 | return ret; | ||
1833 | |||
1834 | interval->interval.denominator = res->fps_options[dev->fps_index].fps; | ||
1835 | interval->interval.numerator = 1; | ||
1836 | __ov8858_print_timing(sd); | ||
1837 | |||
1838 | return ret; | ||
1839 | } | ||
1840 | |||
1841 | static int ov8858_s_frame_interval(struct v4l2_subdev *sd, | ||
1842 | struct v4l2_subdev_frame_interval *interval) | ||
1843 | { | ||
1844 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1845 | int ret; | ||
1846 | |||
1847 | mutex_lock(&dev->input_lock); | ||
1848 | ret = __ov8858_s_frame_interval(sd, interval); | ||
1849 | mutex_unlock(&dev->input_lock); | ||
1850 | |||
1851 | return ret; | ||
1852 | } | ||
1853 | |||
1854 | static int ov8858_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) | ||
1855 | { | ||
1856 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1857 | |||
1858 | mutex_lock(&dev->input_lock); | ||
1859 | *frames = dev->curr_res_table[dev->fmt_idx].skip_frames; | ||
1860 | mutex_unlock(&dev->input_lock); | ||
1861 | |||
1862 | return 0; | ||
1863 | } | ||
1864 | |||
1865 | static const struct v4l2_subdev_sensor_ops ov8858_sensor_ops = { | ||
1866 | .g_skip_frames = ov8858_g_skip_frames, | ||
1867 | }; | ||
1868 | |||
1869 | static const struct v4l2_ctrl_ops ctrl_ops = { | ||
1870 | .s_ctrl = ov8858_s_ctrl, | ||
1871 | .g_volatile_ctrl = ov8858_g_ctrl, | ||
1872 | }; | ||
1873 | |||
1874 | static const struct v4l2_subdev_video_ops ov8858_video_ops = { | ||
1875 | .s_stream = ov8858_s_stream, | ||
1876 | .g_frame_interval = ov8858_g_frame_interval, | ||
1877 | .s_frame_interval = ov8858_s_frame_interval, | ||
1878 | }; | ||
1879 | |||
1880 | static const struct v4l2_subdev_core_ops ov8858_core_ops = { | ||
1881 | .s_power = ov8858_s_power, | ||
1882 | .ioctl = ov8858_ioctl, | ||
1883 | .init = ov8858_init, | ||
1884 | }; | ||
1885 | |||
1886 | static const struct v4l2_subdev_pad_ops ov8858_pad_ops = { | ||
1887 | .enum_mbus_code = ov8858_enum_mbus_code, | ||
1888 | .enum_frame_size = ov8858_enum_frame_size, | ||
1889 | .get_fmt = ov8858_get_fmt, | ||
1890 | .set_fmt = ov8858_set_fmt, | ||
1891 | }; | ||
1892 | |||
1893 | static const struct v4l2_subdev_ops ov8858_ops = { | ||
1894 | .core = &ov8858_core_ops, | ||
1895 | .video = &ov8858_video_ops, | ||
1896 | .pad = &ov8858_pad_ops, | ||
1897 | .sensor = &ov8858_sensor_ops, | ||
1898 | }; | ||
1899 | |||
1900 | static const struct media_entity_operations ov_entity_ops = { | ||
1901 | .link_setup = NULL, | ||
1902 | }; | ||
1903 | |||
1904 | static int ov8858_remove(struct i2c_client *client) | ||
1905 | { | ||
1906 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
1907 | struct ov8858_device *dev = to_ov8858_sensor(sd); | ||
1908 | |||
1909 | media_entity_cleanup(&dev->sd.entity); | ||
1910 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | ||
1911 | dev->platform_data->csi_cfg(sd, 0); | ||
1912 | v4l2_device_unregister_subdev(sd); | ||
1913 | kfree(dev); | ||
1914 | |||
1915 | return 0; | ||
1916 | } | ||
1917 | |||
1918 | static const char * const ctrl_run_mode_menu[] = { | ||
1919 | NULL, | ||
1920 | "Video", | ||
1921 | "Still capture", | ||
1922 | "Continuous capture", | ||
1923 | "Preview", | ||
1924 | }; | ||
1925 | |||
1926 | static const struct v4l2_ctrl_config ctrl_run_mode = { | ||
1927 | .ops = &ctrl_ops, | ||
1928 | .id = V4L2_CID_RUN_MODE, | ||
1929 | .name = "run mode", | ||
1930 | .type = V4L2_CTRL_TYPE_MENU, | ||
1931 | .min = 1, | ||
1932 | .def = 4, | ||
1933 | .max = 4, | ||
1934 | .qmenu = ctrl_run_mode_menu, | ||
1935 | }; | ||
1936 | |||
1937 | static const struct v4l2_ctrl_config ctrls[] = { | ||
1938 | { | ||
1939 | .ops = &ctrl_ops, | ||
1940 | .id = V4L2_CID_VFLIP, | ||
1941 | .name = "Vertical flip", | ||
1942 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1943 | .min = false, | ||
1944 | .max = true, | ||
1945 | .step = 1, | ||
1946 | }, { | ||
1947 | .ops = &ctrl_ops, | ||
1948 | .id = V4L2_CID_HFLIP, | ||
1949 | .name = "Horizontal flip", | ||
1950 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1951 | .min = false, | ||
1952 | .max = true, | ||
1953 | .step = 1, | ||
1954 | }, { | ||
1955 | .ops = &ctrl_ops, | ||
1956 | .id = V4L2_CID_EXPOSURE_ABSOLUTE, | ||
1957 | .name = "Absolute exposure", | ||
1958 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1959 | .max = 0xffff, | ||
1960 | .min = 0x0, | ||
1961 | .step = 1, | ||
1962 | .def = 0x00, | ||
1963 | .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE, | ||
1964 | }, { | ||
1965 | .ops = &ctrl_ops, | ||
1966 | .id = V4L2_CID_FOCUS_ABSOLUTE, | ||
1967 | .name = "Focus absolute", | ||
1968 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1969 | .step = 1, | ||
1970 | .max = OV8858_MAX_FOCUS_POS, | ||
1971 | }, { | ||
1972 | /* This one is junk: see the spec for proper use of this CID. */ | ||
1973 | .ops = &ctrl_ops, | ||
1974 | .id = V4L2_CID_FOCUS_STATUS, | ||
1975 | .name = "Focus status", | ||
1976 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1977 | .step = 1, | ||
1978 | .max = 100, | ||
1979 | .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE, | ||
1980 | }, { | ||
1981 | /* This is crap. For compatibility use only. */ | ||
1982 | .ops = &ctrl_ops, | ||
1983 | .id = V4L2_CID_FOCAL_ABSOLUTE, | ||
1984 | .name = "Focal lenght", | ||
1985 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1986 | .min = (OV8858_FOCAL_LENGTH_NUM << 16) | | ||
1987 | OV8858_FOCAL_LENGTH_DEM, | ||
1988 | .max = (OV8858_FOCAL_LENGTH_NUM << 16) | | ||
1989 | OV8858_FOCAL_LENGTH_DEM, | ||
1990 | .step = 1, | ||
1991 | .def = (OV8858_FOCAL_LENGTH_NUM << 16) | | ||
1992 | OV8858_FOCAL_LENGTH_DEM, | ||
1993 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
1994 | }, { | ||
1995 | /* This one is crap, too. For compatibility use only. */ | ||
1996 | .ops = &ctrl_ops, | ||
1997 | .id = V4L2_CID_FNUMBER_ABSOLUTE, | ||
1998 | .name = "F-number", | ||
1999 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
2000 | .min = (OV8858_F_NUMBER_DEFAULT_NUM << 16) | | ||
2001 | OV8858_F_NUMBER_DEM, | ||
2002 | .max = (OV8858_F_NUMBER_DEFAULT_NUM << 16) | | ||
2003 | OV8858_F_NUMBER_DEM, | ||
2004 | .step = 1, | ||
2005 | .def = (OV8858_F_NUMBER_DEFAULT_NUM << 16) | | ||
2006 | OV8858_F_NUMBER_DEM, | ||
2007 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
2008 | }, { | ||
2009 | /* | ||
2010 | * The most utter crap. _Never_ use this, even for | ||
2011 | * compatibility reasons! | ||
2012 | */ | ||
2013 | .ops = &ctrl_ops, | ||
2014 | .id = V4L2_CID_FNUMBER_RANGE, | ||
2015 | .name = "F-number range", | ||
2016 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
2017 | .min = (OV8858_F_NUMBER_DEFAULT_NUM << 24) | | ||
2018 | (OV8858_F_NUMBER_DEM << 16) | | ||
2019 | (OV8858_F_NUMBER_DEFAULT_NUM << 8) | | ||
2020 | OV8858_F_NUMBER_DEM, | ||
2021 | .max = (OV8858_F_NUMBER_DEFAULT_NUM << 24) | | ||
2022 | (OV8858_F_NUMBER_DEM << 16) | | ||
2023 | (OV8858_F_NUMBER_DEFAULT_NUM << 8) | | ||
2024 | OV8858_F_NUMBER_DEM, | ||
2025 | .step = 1, | ||
2026 | .def = (OV8858_F_NUMBER_DEFAULT_NUM << 24) | | ||
2027 | (OV8858_F_NUMBER_DEM << 16) | | ||
2028 | (OV8858_F_NUMBER_DEFAULT_NUM << 8) | | ||
2029 | OV8858_F_NUMBER_DEM, | ||
2030 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
2031 | }, { | ||
2032 | .ops = &ctrl_ops, | ||
2033 | .id = V4L2_CID_BIN_FACTOR_HORZ, | ||
2034 | .name = "Horizontal binning factor", | ||
2035 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
2036 | .max = OV8858_BIN_FACTOR_MAX, | ||
2037 | .step = 1, | ||
2038 | .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE, | ||
2039 | }, { | ||
2040 | .ops = &ctrl_ops, | ||
2041 | .id = V4L2_CID_BIN_FACTOR_VERT, | ||
2042 | .name = "Vertical binning factor", | ||
2043 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
2044 | .max = OV8858_BIN_FACTOR_MAX, | ||
2045 | .step = 1, | ||
2046 | .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE, | ||
2047 | }, { | ||
2048 | .ops = &ctrl_ops, | ||
2049 | .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY, | ||
2050 | .name = "Exposure auto priority", | ||
2051 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
2052 | .min = V4L2_EXPOSURE_AUTO, | ||
2053 | .max = V4L2_EXPOSURE_APERTURE_PRIORITY, | ||
2054 | .step = 1, | ||
2055 | } | ||
2056 | }; | ||
2057 | |||
2058 | static int ov8858_probe(struct i2c_client *client) | ||
2059 | { | ||
2060 | struct ov8858_device *dev; | ||
2061 | unsigned int i; | ||
2062 | int ret = 0; | ||
2063 | struct camera_sensor_platform_data *pdata; | ||
2064 | |||
2065 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
2066 | |||
2067 | /* allocate sensor device & init sub device */ | ||
2068 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
2069 | if (!dev) | ||
2070 | return -ENOMEM; | ||
2071 | |||
2072 | mutex_init(&dev->input_lock); | ||
2073 | |||
2074 | dev->fmt_idx = 0; | ||
2075 | dev->sensor_id = OV_ID_DEFAULT; | ||
2076 | dev->vcm_driver = &ov8858_vcms[OV8858_ID_DEFAULT]; | ||
2077 | |||
2078 | v4l2_i2c_subdev_init(&(dev->sd), client, &ov8858_ops); | ||
2079 | |||
2080 | pdata = gmin_camera_platform_data(&dev->sd, | ||
2081 | ATOMISP_INPUT_FORMAT_RAW_10, | ||
2082 | atomisp_bayer_order_bggr); | ||
2083 | if (!pdata) { | ||
2084 | dev_err(&client->dev, | ||
2085 | "%s: failed to get acpi platform data\n", | ||
2086 | __func__); | ||
2087 | goto out_free; | ||
2088 | } | ||
2089 | ret = ov8858_s_config(&dev->sd, client->irq, pdata); | ||
2090 | if (ret) { | ||
2091 | dev_err(&client->dev, | ||
2092 | "%s: failed to set config\n", __func__); | ||
2093 | goto out_free; | ||
2094 | } | ||
2095 | ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA); | ||
2096 | if (ret) { | ||
2097 | dev_err(&client->dev, | ||
2098 | "%s: failed to register subdev\n", __func__); | ||
2099 | goto out_free; | ||
2100 | } | ||
2101 | |||
2102 | /* | ||
2103 | * sd->name is updated with sensor driver name by the v4l2. | ||
2104 | * change it to sensor name in this case. | ||
2105 | */ | ||
2106 | snprintf(dev->sd.name, sizeof(dev->sd.name), "%s%x %d-%04x", | ||
2107 | OV_SUBDEV_PREFIX, dev->sensor_id, | ||
2108 | i2c_adapter_id(client->adapter), client->addr); | ||
2109 | |||
2110 | dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
2111 | dev->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
2112 | dev->format.code = MEDIA_BUS_FMT_SBGGR10_1X10; | ||
2113 | dev->sd.entity.ops = &ov_entity_ops; | ||
2114 | dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; | ||
2115 | |||
2116 | ret = v4l2_ctrl_handler_init(&dev->ctrl_handler, ARRAY_SIZE(ctrls) + 1); | ||
2117 | if (ret) { | ||
2118 | ov8858_remove(client); | ||
2119 | return ret; | ||
2120 | } | ||
2121 | |||
2122 | dev->run_mode = v4l2_ctrl_new_custom(&dev->ctrl_handler, | ||
2123 | &ctrl_run_mode, NULL); | ||
2124 | |||
2125 | for (i = 0; i < ARRAY_SIZE(ctrls); i++) | ||
2126 | v4l2_ctrl_new_custom(&dev->ctrl_handler, &ctrls[i], NULL); | ||
2127 | |||
2128 | if (dev->ctrl_handler.error) { | ||
2129 | ov8858_remove(client); | ||
2130 | return dev->ctrl_handler.error; | ||
2131 | } | ||
2132 | |||
2133 | /* Use same lock for controls as for everything else. */ | ||
2134 | dev->ctrl_handler.lock = &dev->input_lock; | ||
2135 | dev->sd.ctrl_handler = &dev->ctrl_handler; | ||
2136 | v4l2_ctrl_handler_setup(&dev->ctrl_handler); | ||
2137 | |||
2138 | ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); | ||
2139 | if (ret) { | ||
2140 | ov8858_remove(client); | ||
2141 | return ret; | ||
2142 | } | ||
2143 | |||
2144 | return 0; | ||
2145 | |||
2146 | out_free: | ||
2147 | v4l2_device_unregister_subdev(&dev->sd); | ||
2148 | kfree(dev); | ||
2149 | return ret; | ||
2150 | } | ||
2151 | |||
2152 | static const struct acpi_device_id ov8858_acpi_match[] = { | ||
2153 | {"INT3477"}, | ||
2154 | {}, | ||
2155 | }; | ||
2156 | MODULE_DEVICE_TABLE(acpi, ov8858_acpi_match); | ||
2157 | |||
2158 | static struct i2c_driver ov8858_driver = { | ||
2159 | .driver = { | ||
2160 | .name = "ov8858", | ||
2161 | .acpi_match_table = ov8858_acpi_match, | ||
2162 | }, | ||
2163 | .probe_new = ov8858_probe, | ||
2164 | .remove = ov8858_remove, | ||
2165 | }; | ||
2166 | module_i2c_driver(ov8858_driver); | ||
2167 | |||
2168 | MODULE_DESCRIPTION("A low-level driver for Omnivision OV8858 sensors"); | ||
2169 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/media/atomisp/i2c/ov8858.h b/drivers/staging/media/atomisp/i2c/ov8858.h deleted file mode 100644 index 6c89568bb44e..000000000000 --- a/drivers/staging/media/atomisp/i2c/ov8858.h +++ /dev/null | |||
@@ -1,1474 +0,0 @@ | |||
1 | /* | ||
2 | * Support for the Omnivision OV8858 camera sensor. | ||
3 | * | ||
4 | * Copyright (c) 2014 Intel Corporation. All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef __OV8858_H__ | ||
19 | #define __OV8858_H__ | ||
20 | #include "../include/linux/atomisp_platform.h" | ||
21 | #include <media/v4l2-ctrls.h> | ||
22 | |||
23 | #define I2C_MSG_LENGTH 0x2 | ||
24 | |||
25 | /* | ||
26 | * This should be added into include/linux/videodev2.h | ||
27 | * NOTE: This is most likely not used anywhere. | ||
28 | */ | ||
29 | #define V4L2_IDENT_OV8858 V4L2_IDENT_UNKNOWN | ||
30 | |||
31 | /* | ||
32 | * Indexes for VCM driver lists | ||
33 | */ | ||
34 | #define OV8858_ID_DEFAULT 0 | ||
35 | #define OV8858_SUNNY 1 | ||
36 | |||
37 | #define OV8858_OTP_START_ADDR 0x7010 | ||
38 | #define OV8858_OTP_END_ADDR 0x7186 | ||
39 | |||
40 | /* | ||
41 | * ov8858 System control registers | ||
42 | */ | ||
43 | |||
44 | #define OV8858_OTP_LOAD_CTRL 0x3D81 | ||
45 | #define OV8858_OTP_MODE_CTRL 0x3D84 | ||
46 | #define OV8858_OTP_START_ADDR_REG 0x3D88 | ||
47 | #define OV8858_OTP_END_ADDR_REG 0x3D8A | ||
48 | #define OV8858_OTP_ISP_CTRL2 0x5002 | ||
49 | |||
50 | #define OV8858_OTP_MODE_MANUAL BIT(6) | ||
51 | #define OV8858_OTP_MODE_PROGRAM_DISABLE BIT(7) | ||
52 | #define OV8858_OTP_LOAD_ENABLE BIT(0) | ||
53 | #define OV8858_OTP_DPC_ENABLE BIT(3) | ||
54 | |||
55 | #define OV8858_PLL1_PREDIV0 0x030A | ||
56 | #define OV8858_PLL1_PREDIV 0x0300 | ||
57 | #define OV8858_PLL1_MULTIPLIER 0x0301 | ||
58 | #define OV8858_PLL1_SYS_PRE_DIV 0x0305 | ||
59 | #define OV8858_PLL1_SYS_DIVIDER 0x0306 | ||
60 | |||
61 | #define OV8858_PLL1_PREDIV0_MASK BIT(0) | ||
62 | #define OV8858_PLL1_PREDIV_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
63 | #define OV8858_PLL1_MULTIPLIER_MASK 0x01FF | ||
64 | #define OV8858_PLL1_SYS_PRE_DIV_MASK (BIT(0) | BIT(1)) | ||
65 | #define OV8858_PLL1_SYS_DIVIDER_MASK BIT(0) | ||
66 | |||
67 | #define OV8858_PLL2_PREDIV0 0x0312 | ||
68 | #define OV8858_PLL2_PREDIV 0x030B | ||
69 | #define OV8858_PLL2_MULTIPLIER 0x030C | ||
70 | #define OV8858_PLL2_DAC_DIVIDER 0x0312 | ||
71 | #define OV8858_PLL2_SYS_PRE_DIV 0x030F | ||
72 | #define OV8858_PLL2_SYS_DIVIDER 0x030E | ||
73 | |||
74 | #define OV8858_PLL2_PREDIV0_MASK BIT(4) | ||
75 | #define OV8858_PLL2_PREDIV_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
76 | #define OV8858_PLL2_MULTIPLIER_MASK 0x01FF | ||
77 | #define OV8858_PLL2_DAC_DIVIDER_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) | ||
78 | #define OV8858_PLL2_SYS_PRE_DIV_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) | ||
79 | #define OV8858_PLL2_SYS_DIVIDER_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
80 | |||
81 | #define OV8858_PLL_SCLKSEL1 0x3032 | ||
82 | #define OV8858_PLL_SCLKSEL2 0x3033 | ||
83 | #define OV8858_SRB_HOST_INPUT_DIS 0x3106 | ||
84 | |||
85 | #define OV8858_PLL_SCLKSEL1_MASK BIT(7) | ||
86 | #define OV8858_PLL_SCLKSEL2_MASK BIT(1) | ||
87 | |||
88 | #define OV8858_SYS_PRE_DIV_OFFSET 2 | ||
89 | #define OV8858_SYS_PRE_DIV_MASK (BIT(2) | BIT(3)) | ||
90 | #define OV8858_SCLK_PDIV_OFFSET 4 | ||
91 | #define OV8858_SCLK_PDIV_MASK (BIT(4) | BIT(5) | BIT(6) | BIT(7)) | ||
92 | |||
93 | #define OV8858_TIMING_HTS 0x380C | ||
94 | #define OV8858_TIMING_VTS 0x380E | ||
95 | |||
96 | #define OV8858_HORIZONTAL_START_H 0x3800 | ||
97 | #define OV8858_VERTICAL_START_H 0x3802 | ||
98 | #define OV8858_HORIZONTAL_END_H 0x3804 | ||
99 | #define OV8858_VERTICAL_END_H 0x3806 | ||
100 | #define OV8858_HORIZONTAL_OUTPUT_SIZE_H 0x3808 | ||
101 | #define OV8858_VERTICAL_OUTPUT_SIZE_H 0x380A | ||
102 | |||
103 | #define OV8858_GROUP_ACCESS 0x3208 | ||
104 | #define OV8858_GROUP_ZERO 0x00 | ||
105 | #define OV8858_GROUP_ACCESS_HOLD_START 0x00 | ||
106 | #define OV8858_GROUP_ACCESS_HOLD_END 0x10 | ||
107 | #define OV8858_GROUP_ACCESS_DELAY_LAUNCH 0xA0 | ||
108 | #define OV8858_GROUP_ACCESS_QUICK_LAUNCH 0xE0 | ||
109 | |||
110 | #define OV_SUBDEV_PREFIX "ov" | ||
111 | #define OV_ID_DEFAULT 0x0000 | ||
112 | #define OV8858_CHIP_ID 0x8858 | ||
113 | |||
114 | #define OV8858_LONG_EXPO 0x3500 | ||
115 | #define OV8858_LONG_GAIN 0x3508 | ||
116 | #define OV8858_LONG_DIGI_GAIN 0x350A | ||
117 | #define OV8858_SHORT_GAIN 0x350C | ||
118 | #define OV8858_SHORT_DIGI_GAIN 0x350E | ||
119 | |||
120 | #define OV8858_FORMAT1 0x3820 | ||
121 | #define OV8858_FORMAT2 0x3821 | ||
122 | |||
123 | #define OV8858_FLIP_ENABLE 0x06 | ||
124 | |||
125 | #define OV8858_MWB_RED_GAIN_H 0x5032 | ||
126 | #define OV8858_MWB_GREEN_GAIN_H 0x5034 | ||
127 | #define OV8858_MWB_BLUE_GAIN_H 0x5036 | ||
128 | #define OV8858_MWB_GAIN_MAX 0x0FFF | ||
129 | |||
130 | #define OV8858_CHIP_ID_HIGH 0x300B | ||
131 | #define OV8858_CHIP_ID_LOW 0x300C | ||
132 | #define OV8858_STREAM_MODE 0x0100 | ||
133 | |||
134 | #define OV8858_FOCAL_LENGTH_NUM 294 /* 2.94mm */ | ||
135 | #define OV8858_FOCAL_LENGTH_DEM 100 | ||
136 | #define OV8858_F_NUMBER_DEFAULT_NUM 24 /* 2.4 */ | ||
137 | #define OV8858_F_NUMBER_DEM 10 | ||
138 | |||
139 | #define OV8858_H_INC_ODD 0x3814 | ||
140 | #define OV8858_H_INC_EVEN 0x3815 | ||
141 | #define OV8858_V_INC_ODD 0x382A | ||
142 | #define OV8858_V_INC_EVEN 0x382B | ||
143 | |||
144 | #define OV8858_READ_MODE_BINNING_ON 0x0400 /* ToDo: Check this */ | ||
145 | #define OV8858_READ_MODE_BINNING_OFF 0x00 /* ToDo: Check this */ | ||
146 | #define OV8858_BIN_FACTOR_MAX 2 | ||
147 | #define OV8858_INTEGRATION_TIME_MARGIN 14 | ||
148 | |||
149 | #define OV8858_MAX_VTS_VALUE 0xFFFF | ||
150 | #define OV8858_MAX_EXPOSURE_VALUE \ | ||
151 | (OV8858_MAX_VTS_VALUE - OV8858_INTEGRATION_TIME_MARGIN) | ||
152 | #define OV8858_MAX_GAIN_VALUE 0x07FF | ||
153 | |||
154 | #define OV8858_MAX_FOCUS_POS 1023 | ||
155 | |||
156 | #define OV8858_TEST_PATTERN_REG 0x5E00 | ||
157 | |||
158 | struct ov8858_vcm { | ||
159 | int (*power_up)(struct v4l2_subdev *sd); | ||
160 | int (*power_down)(struct v4l2_subdev *sd); | ||
161 | int (*init)(struct v4l2_subdev *sd); | ||
162 | int (*t_focus_abs)(struct v4l2_subdev *sd, s32 value); | ||
163 | int (*t_focus_rel)(struct v4l2_subdev *sd, s32 value); | ||
164 | int (*q_focus_status)(struct v4l2_subdev *sd, s32 *value); | ||
165 | int (*q_focus_abs)(struct v4l2_subdev *sd, s32 *value); | ||
166 | int (*t_vcm_slew)(struct v4l2_subdev *sd, s32 value); | ||
167 | int (*t_vcm_timing)(struct v4l2_subdev *sd, s32 value); | ||
168 | }; | ||
169 | |||
170 | /* | ||
171 | * Defines for register writes and register array processing | ||
172 | * */ | ||
173 | #define OV8858_BYTE_MAX 32 | ||
174 | #define OV8858_SHORT_MAX 16 | ||
175 | #define OV8858_TOK_MASK 0xFFF0 | ||
176 | |||
177 | #define MAX_FPS_OPTIONS_SUPPORTED 3 | ||
178 | |||
179 | #define OV8858_DEPTH_COMP_CONST 2200 | ||
180 | #define OV8858_DEPTH_VTS_CONST 2573 | ||
181 | |||
182 | enum ov8858_tok_type { | ||
183 | OV8858_8BIT = 0x0001, | ||
184 | OV8858_16BIT = 0x0002, | ||
185 | OV8858_TOK_TERM = 0xF000, /* terminating token for reg list */ | ||
186 | OV8858_TOK_DELAY = 0xFE00 /* delay token for reg list */ | ||
187 | }; | ||
188 | |||
189 | /* | ||
190 | * If register address or register width is not 32 bit width, | ||
191 | * user needs to convert it manually | ||
192 | */ | ||
193 | struct s_register_setting { | ||
194 | u32 reg; | ||
195 | u32 val; | ||
196 | }; | ||
197 | |||
198 | /** | ||
199 | * struct ov8858_reg - MI sensor register format | ||
200 | * @type: type of the register | ||
201 | * @reg: 16-bit offset to register | ||
202 | * @val: 8/16/32-bit register value | ||
203 | * | ||
204 | * Define a structure for sensor register initialization values | ||
205 | */ | ||
206 | struct ov8858_reg { | ||
207 | enum ov8858_tok_type type; | ||
208 | u16 sreg; | ||
209 | u32 val; /* @set value for read/mod/write, @mask */ | ||
210 | }; | ||
211 | |||
212 | struct ov8858_fps_setting { | ||
213 | int fps; | ||
214 | unsigned short pixels_per_line; | ||
215 | unsigned short lines_per_frame; | ||
216 | const struct ov8858_reg *regs; /* regs that the fps setting needs */ | ||
217 | }; | ||
218 | |||
219 | struct ov8858_resolution { | ||
220 | u8 *desc; | ||
221 | const struct ov8858_reg *regs; | ||
222 | int res; | ||
223 | int width; | ||
224 | int height; | ||
225 | bool used; | ||
226 | u8 bin_factor_x; | ||
227 | u8 bin_factor_y; | ||
228 | unsigned short skip_frames; | ||
229 | const struct ov8858_fps_setting fps_options[MAX_FPS_OPTIONS_SUPPORTED]; | ||
230 | }; | ||
231 | |||
232 | /* | ||
233 | * ov8858 device structure | ||
234 | * */ | ||
235 | struct ov8858_device { | ||
236 | struct v4l2_subdev sd; | ||
237 | struct media_pad pad; | ||
238 | struct v4l2_mbus_framefmt format; | ||
239 | |||
240 | struct camera_sensor_platform_data *platform_data; | ||
241 | struct mutex input_lock; /* serialize sensor's ioctl */ | ||
242 | int fmt_idx; | ||
243 | int streaming; | ||
244 | int vt_pix_clk_freq_mhz; | ||
245 | int fps_index; | ||
246 | u16 sensor_id; /* Sensor id from registers */ | ||
247 | u16 i2c_id; /* Sensor id from i2c_device_id */ | ||
248 | int exposure; | ||
249 | int gain; | ||
250 | u16 digital_gain; | ||
251 | u16 pixels_per_line; | ||
252 | u16 lines_per_frame; | ||
253 | u8 fps; | ||
254 | u8 *otp_data; | ||
255 | /* Prevent the framerate from being lowered in low light scenes. */ | ||
256 | int limit_exposure_flag; | ||
257 | bool hflip; | ||
258 | bool vflip; | ||
259 | |||
260 | const struct ov8858_reg *regs; | ||
261 | struct ov8858_vcm *vcm_driver; | ||
262 | const struct ov8858_resolution *curr_res_table; | ||
263 | unsigned long entries_curr_table; | ||
264 | |||
265 | struct v4l2_ctrl_handler ctrl_handler; | ||
266 | struct v4l2_ctrl *run_mode; | ||
267 | }; | ||
268 | |||
269 | #define to_ov8858_sensor(x) container_of(x, struct ov8858_device, sd) | ||
270 | |||
271 | #define OV8858_MAX_WRITE_BUF_SIZE 32 | ||
272 | struct ov8858_write_buffer { | ||
273 | u16 addr; | ||
274 | u8 data[OV8858_MAX_WRITE_BUF_SIZE]; | ||
275 | }; | ||
276 | |||
277 | struct ov8858_write_ctrl { | ||
278 | int index; | ||
279 | struct ov8858_write_buffer buffer; | ||
280 | }; | ||
281 | |||
282 | static const struct ov8858_reg ov8858_soft_standby[] = { | ||
283 | {OV8858_8BIT, 0x0100, 0x00}, | ||
284 | {OV8858_TOK_TERM, 0, 0} | ||
285 | }; | ||
286 | |||
287 | static const struct ov8858_reg ov8858_streaming[] = { | ||
288 | {OV8858_8BIT, 0x0100, 0x01}, | ||
289 | {OV8858_TOK_TERM, 0, 0} | ||
290 | }; | ||
291 | |||
292 | static const struct ov8858_reg ov8858_param_hold[] = { | ||
293 | {OV8858_8BIT, OV8858_GROUP_ACCESS, | ||
294 | OV8858_GROUP_ZERO | OV8858_GROUP_ACCESS_HOLD_START}, | ||
295 | {OV8858_TOK_TERM, 0, 0} | ||
296 | }; | ||
297 | |||
298 | static const struct ov8858_reg ov8858_param_update[] = { | ||
299 | {OV8858_8BIT, OV8858_GROUP_ACCESS, | ||
300 | OV8858_GROUP_ZERO | OV8858_GROUP_ACCESS_HOLD_END}, | ||
301 | {OV8858_8BIT, OV8858_GROUP_ACCESS, | ||
302 | OV8858_GROUP_ZERO | OV8858_GROUP_ACCESS_DELAY_LAUNCH}, | ||
303 | {OV8858_TOK_TERM, 0, 0} | ||
304 | }; | ||
305 | |||
306 | extern int dw9718_vcm_power_up(struct v4l2_subdev *sd); | ||
307 | extern int dw9718_vcm_power_down(struct v4l2_subdev *sd); | ||
308 | extern int dw9718_vcm_init(struct v4l2_subdev *sd); | ||
309 | extern int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value); | ||
310 | extern int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value); | ||
311 | extern int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value); | ||
312 | extern int dw9718_q_focus_abs(struct v4l2_subdev *sd, s32 *value); | ||
313 | extern int dw9718_t_vcm_slew(struct v4l2_subdev *sd, s32 value); | ||
314 | extern int dw9718_t_vcm_timing(struct v4l2_subdev *sd, s32 value); | ||
315 | |||
316 | extern int vcm_power_up(struct v4l2_subdev *sd); | ||
317 | extern int vcm_power_down(struct v4l2_subdev *sd); | ||
318 | |||
319 | static struct ov8858_vcm ov8858_vcms[] = { | ||
320 | [OV8858_SUNNY] = { | ||
321 | .power_up = dw9718_vcm_power_up, | ||
322 | .power_down = dw9718_vcm_power_down, | ||
323 | .init = dw9718_vcm_init, | ||
324 | .t_focus_abs = dw9718_t_focus_abs, | ||
325 | .t_focus_rel = dw9718_t_focus_rel, | ||
326 | .q_focus_status = dw9718_q_focus_status, | ||
327 | .q_focus_abs = dw9718_q_focus_abs, | ||
328 | .t_vcm_slew = dw9718_t_vcm_slew, | ||
329 | .t_vcm_timing = dw9718_t_vcm_timing, | ||
330 | }, | ||
331 | [OV8858_ID_DEFAULT] = { | ||
332 | .power_up = NULL, | ||
333 | .power_down = NULL, | ||
334 | }, | ||
335 | }; | ||
336 | |||
337 | |||
338 | #define OV8858_RES_WIDTH_MAX 3280 | ||
339 | #define OV8858_RES_HEIGHT_MAX 2464 | ||
340 | |||
341 | static struct ov8858_reg ov8858_BasicSettings[] = { | ||
342 | {OV8858_8BIT, 0x0103, 0x01}, /* software_reset */ | ||
343 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
344 | /* PLL settings */ | ||
345 | {OV8858_8BIT, 0x0300, 0x05}, /* pll1_pre_div = /4 */ | ||
346 | {OV8858_8BIT, 0x0302, 0xAF}, /* pll1_multiplier = 175 */ | ||
347 | {OV8858_8BIT, 0x0303, 0x00}, /* pll1_divm = /(1 + 0) */ | ||
348 | {OV8858_8BIT, 0x0304, 0x03}, /* pll1_div_mipi = /8 */ | ||
349 | {OV8858_8BIT, 0x030B, 0x02}, /* pll2_pre_div = /2 */ | ||
350 | {OV8858_8BIT, 0x030D, 0x4E}, /* pll2_r_divp = 78 */ | ||
351 | {OV8858_8BIT, 0x030E, 0x00}, /* pll2_r_divs = /1 */ | ||
352 | {OV8858_8BIT, 0x030F, 0x04}, /* pll2_r_divsp = /(1 + 4) */ | ||
353 | /* pll2_pre_div0 = /1, pll2_r_divdac = /(1 + 1) */ | ||
354 | {OV8858_8BIT, 0x0312, 0x01}, | ||
355 | {OV8858_8BIT, 0x031E, 0x0C}, /* pll1_no_lat = 1, mipi_bitsel_man = 0 */ | ||
356 | |||
357 | /* PAD OEN2, VSYNC out enable=0x80, disable=0x00 */ | ||
358 | {OV8858_8BIT, 0x3002, 0x80}, | ||
359 | /* PAD OUT2, VSYNC pulse direction low-to-high = 1 */ | ||
360 | {OV8858_8BIT, 0x3007, 0x01}, | ||
361 | /* PAD SEL2, VSYNC out value = 0 */ | ||
362 | {OV8858_8BIT, 0x300D, 0x00}, | ||
363 | /* PAD OUT2, VSYNC out select = 0 */ | ||
364 | {OV8858_8BIT, 0x3010, 0x00}, | ||
365 | |||
366 | /* Npump clock div = /2, Ppump clock div = /4 */ | ||
367 | {OV8858_8BIT, 0x3015, 0x01}, | ||
368 | /* | ||
369 | * mipi_lane_mode = 1+3, mipi_lvds_sel = 1 = MIPI enable, | ||
370 | * r_phy_pd_mipi_man = 0, lane_dis_option = 0 | ||
371 | */ | ||
372 | {OV8858_8BIT, 0x3018, 0x72}, | ||
373 | /* Clock switch output = normal, pclk_div = /1 */ | ||
374 | {OV8858_8BIT, 0x3020, 0x93}, | ||
375 | /* | ||
376 | * lvds_mode_o = 0, clock lane disable when pd_mipi = 0, | ||
377 | * pd_mipi enable when rst_sync = 1 | ||
378 | */ | ||
379 | {OV8858_8BIT, 0x3022, 0x01}, | ||
380 | {OV8858_8BIT, 0x3031, 0x0A}, /* mipi_bit_sel = 10 */ | ||
381 | {OV8858_8BIT, 0x3034, 0x00}, /* Unknown */ | ||
382 | /* sclk_div = /1, sclk_pre_div = /1, chip debug = 1 */ | ||
383 | {OV8858_8BIT, 0x3106, 0x01}, | ||
384 | |||
385 | {OV8858_8BIT, 0x3305, 0xF1}, /* Unknown */ | ||
386 | {OV8858_8BIT, 0x3307, 0x04}, /* Unknown */ | ||
387 | {OV8858_8BIT, 0x3308, 0x00}, /* Unknown */ | ||
388 | {OV8858_8BIT, 0x3309, 0x28}, /* Unknown */ | ||
389 | {OV8858_8BIT, 0x330A, 0x00}, /* Unknown */ | ||
390 | {OV8858_8BIT, 0x330B, 0x20}, /* Unknown */ | ||
391 | {OV8858_8BIT, 0x330C, 0x00}, /* Unknown */ | ||
392 | {OV8858_8BIT, 0x330D, 0x00}, /* Unknown */ | ||
393 | {OV8858_8BIT, 0x330E, 0x00}, /* Unknown */ | ||
394 | {OV8858_8BIT, 0x330F, 0x40}, /* Unknown */ | ||
395 | |||
396 | {OV8858_8BIT, 0x3500, 0x00}, /* long exposure = 0x9A20 */ | ||
397 | {OV8858_8BIT, 0x3501, 0x9A}, /* long exposure = 0x9A20 */ | ||
398 | {OV8858_8BIT, 0x3502, 0x20}, /* long exposure = 0x9A20 */ | ||
399 | /* | ||
400 | * Digital fraction gain delay option = Delay 1 frame, | ||
401 | * Gain change delay option = Delay 1 frame, | ||
402 | * Gain delay option = Delay 1 frame, | ||
403 | * Gain manual as sensor gain = Input gain as real gain format, | ||
404 | * Exposure delay option (must be 0 = Delay 1 frame, | ||
405 | * Exposure change delay option (must be 0) = Delay 1 frame | ||
406 | */ | ||
407 | {OV8858_8BIT, 0x3503, 0x00}, | ||
408 | {OV8858_8BIT, 0x3505, 0x80}, /* gain conversation option */ | ||
409 | /* | ||
410 | * [10:7] are integer gain, [6:0] are fraction gain. For example: | ||
411 | * 0x80 is 1x gain, 0x100 is 2x gain, 0x1C0 is 3.5x gain | ||
412 | */ | ||
413 | {OV8858_8BIT, 0x3508, 0x02}, /* long gain = 0x0200 */ | ||
414 | {OV8858_8BIT, 0x3509, 0x00}, /* long gain = 0x0200 */ | ||
415 | {OV8858_8BIT, 0x350C, 0x00}, /* short gain = 0x0080 */ | ||
416 | {OV8858_8BIT, 0x350D, 0x80}, /* short gain = 0x0080 */ | ||
417 | {OV8858_8BIT, 0x3510, 0x00}, /* short exposure = 0x000200 */ | ||
418 | {OV8858_8BIT, 0x3511, 0x02}, /* short exposure = 0x000200 */ | ||
419 | {OV8858_8BIT, 0x3512, 0x00}, /* short exposure = 0x000200 */ | ||
420 | |||
421 | {OV8858_8BIT, 0x3600, 0x00}, /* Unknown */ | ||
422 | {OV8858_8BIT, 0x3601, 0x00}, /* Unknown */ | ||
423 | {OV8858_8BIT, 0x3602, 0x00}, /* Unknown */ | ||
424 | {OV8858_8BIT, 0x3603, 0x00}, /* Unknown */ | ||
425 | {OV8858_8BIT, 0x3604, 0x22}, /* Unknown */ | ||
426 | {OV8858_8BIT, 0x3605, 0x30}, /* Unknown */ | ||
427 | {OV8858_8BIT, 0x3606, 0x00}, /* Unknown */ | ||
428 | {OV8858_8BIT, 0x3607, 0x20}, /* Unknown */ | ||
429 | {OV8858_8BIT, 0x3608, 0x11}, /* Unknown */ | ||
430 | {OV8858_8BIT, 0x3609, 0x28}, /* Unknown */ | ||
431 | {OV8858_8BIT, 0x360A, 0x00}, /* Unknown */ | ||
432 | {OV8858_8BIT, 0x360B, 0x06}, /* Unknown */ | ||
433 | {OV8858_8BIT, 0x360C, 0xDC}, /* Unknown */ | ||
434 | {OV8858_8BIT, 0x360D, 0x40}, /* Unknown */ | ||
435 | {OV8858_8BIT, 0x360E, 0x0C}, /* Unknown */ | ||
436 | {OV8858_8BIT, 0x360F, 0x20}, /* Unknown */ | ||
437 | {OV8858_8BIT, 0x3610, 0x07}, /* Unknown */ | ||
438 | {OV8858_8BIT, 0x3611, 0x20}, /* Unknown */ | ||
439 | {OV8858_8BIT, 0x3612, 0x88}, /* Unknown */ | ||
440 | {OV8858_8BIT, 0x3613, 0x80}, /* Unknown */ | ||
441 | {OV8858_8BIT, 0x3614, 0x58}, /* Unknown */ | ||
442 | {OV8858_8BIT, 0x3615, 0x00}, /* Unknown */ | ||
443 | {OV8858_8BIT, 0x3616, 0x4A}, /* Unknown */ | ||
444 | {OV8858_8BIT, 0x3617, 0x90}, /* Unknown */ | ||
445 | {OV8858_8BIT, 0x3618, 0x56}, /* Unknown */ | ||
446 | {OV8858_8BIT, 0x3619, 0x70}, /* Unknown */ | ||
447 | {OV8858_8BIT, 0x361A, 0x99}, /* Unknown */ | ||
448 | {OV8858_8BIT, 0x361B, 0x00}, /* Unknown */ | ||
449 | {OV8858_8BIT, 0x361C, 0x07}, /* Unknown */ | ||
450 | {OV8858_8BIT, 0x361D, 0x00}, /* Unknown */ | ||
451 | {OV8858_8BIT, 0x361E, 0x00}, /* Unknown */ | ||
452 | {OV8858_8BIT, 0x361F, 0x00}, /* Unknown */ | ||
453 | {OV8858_8BIT, 0x3633, 0x0C}, /* Unknown */ | ||
454 | {OV8858_8BIT, 0x3634, 0x0C}, /* Unknown */ | ||
455 | {OV8858_8BIT, 0x3635, 0x0C}, /* Unknown */ | ||
456 | {OV8858_8BIT, 0x3636, 0x0C}, /* Unknown */ | ||
457 | {OV8858_8BIT, 0x3638, 0xFF}, /* Unknown */ | ||
458 | {OV8858_8BIT, 0x3645, 0x13}, /* Unknown */ | ||
459 | {OV8858_8BIT, 0x3646, 0x83}, /* Unknown */ | ||
460 | {OV8858_8BIT, 0x364A, 0x07}, /* Unknown */ | ||
461 | |||
462 | {OV8858_8BIT, 0x3700, 0x30}, /* Unknown */ | ||
463 | {OV8858_8BIT, 0x3701, 0x18}, /* Unknown */ | ||
464 | {OV8858_8BIT, 0x3702, 0x50}, /* Unknown */ | ||
465 | {OV8858_8BIT, 0x3703, 0x32}, /* Unknown */ | ||
466 | {OV8858_8BIT, 0x3704, 0x28}, /* Unknown */ | ||
467 | {OV8858_8BIT, 0x3705, 0x00}, /* Unknown */ | ||
468 | {OV8858_8BIT, 0x3706, 0x6A}, /* Unknown */ | ||
469 | {OV8858_8BIT, 0x3707, 0x08}, /* Unknown */ | ||
470 | {OV8858_8BIT, 0x3708, 0x48}, /* Unknown */ | ||
471 | {OV8858_8BIT, 0x3709, 0x66}, /* Unknown */ | ||
472 | {OV8858_8BIT, 0x370A, 0x01}, /* Unknown */ | ||
473 | {OV8858_8BIT, 0x370B, 0x6A}, /* Unknown */ | ||
474 | {OV8858_8BIT, 0x370C, 0x07}, /* Unknown */ | ||
475 | {OV8858_8BIT, 0x3712, 0x44}, /* Unknown */ | ||
476 | {OV8858_8BIT, 0x3714, 0x24}, /* Unknown */ | ||
477 | {OV8858_8BIT, 0x3718, 0x14}, /* Unknown */ | ||
478 | {OV8858_8BIT, 0x3719, 0x31}, /* Unknown */ | ||
479 | {OV8858_8BIT, 0x371E, 0x31}, /* Unknown */ | ||
480 | {OV8858_8BIT, 0x371F, 0x7F}, /* Unknown */ | ||
481 | {OV8858_8BIT, 0x3720, 0x0A}, /* Unknown */ | ||
482 | {OV8858_8BIT, 0x3721, 0x0A}, /* Unknown */ | ||
483 | {OV8858_8BIT, 0x3724, 0x0C}, /* Unknown */ | ||
484 | {OV8858_8BIT, 0x3725, 0x02}, /* Unknown */ | ||
485 | {OV8858_8BIT, 0x3726, 0x0C}, /* Unknown */ | ||
486 | {OV8858_8BIT, 0x3728, 0x0A}, /* Unknown */ | ||
487 | {OV8858_8BIT, 0x3729, 0x03}, /* Unknown */ | ||
488 | {OV8858_8BIT, 0x372A, 0x06}, /* Unknown */ | ||
489 | {OV8858_8BIT, 0x372B, 0xA6}, /* Unknown */ | ||
490 | {OV8858_8BIT, 0x372C, 0xA6}, /* Unknown */ | ||
491 | {OV8858_8BIT, 0x372D, 0xA6}, /* Unknown */ | ||
492 | {OV8858_8BIT, 0x372E, 0x0C}, /* Unknown */ | ||
493 | {OV8858_8BIT, 0x372F, 0x20}, /* Unknown */ | ||
494 | {OV8858_8BIT, 0x3730, 0x02}, /* Unknown */ | ||
495 | {OV8858_8BIT, 0x3731, 0x0C}, /* Unknown */ | ||
496 | {OV8858_8BIT, 0x3732, 0x28}, /* Unknown */ | ||
497 | {OV8858_8BIT, 0x3733, 0x10}, /* Unknown */ | ||
498 | {OV8858_8BIT, 0x3734, 0x40}, /* Unknown */ | ||
499 | {OV8858_8BIT, 0x3736, 0x30}, /* Unknown */ | ||
500 | {OV8858_8BIT, 0x373A, 0x0A}, /* Unknown */ | ||
501 | {OV8858_8BIT, 0x373B, 0x0B}, /* Unknown */ | ||
502 | {OV8858_8BIT, 0x373C, 0x14}, /* Unknown */ | ||
503 | {OV8858_8BIT, 0x373E, 0x06}, /* Unknown */ | ||
504 | {OV8858_8BIT, 0x3755, 0x10}, /* Unknown */ | ||
505 | {OV8858_8BIT, 0x3758, 0x00}, /* Unknown */ | ||
506 | {OV8858_8BIT, 0x3759, 0x4C}, /* Unknown */ | ||
507 | {OV8858_8BIT, 0x375A, 0x0C}, /* Unknown */ | ||
508 | {OV8858_8BIT, 0x375B, 0x26}, /* Unknown */ | ||
509 | {OV8858_8BIT, 0x375C, 0x20}, /* Unknown */ | ||
510 | {OV8858_8BIT, 0x375D, 0x04}, /* Unknown */ | ||
511 | {OV8858_8BIT, 0x375E, 0x00}, /* Unknown */ | ||
512 | {OV8858_8BIT, 0x375F, 0x28}, /* Unknown */ | ||
513 | {OV8858_8BIT, 0x3760, 0x00}, /* Unknown */ | ||
514 | {OV8858_8BIT, 0x3761, 0x00}, /* Unknown */ | ||
515 | {OV8858_8BIT, 0x3762, 0x00}, /* Unknown */ | ||
516 | {OV8858_8BIT, 0x3763, 0x00}, /* Unknown */ | ||
517 | {OV8858_8BIT, 0x3766, 0xFF}, /* Unknown */ | ||
518 | {OV8858_8BIT, 0x3768, 0x22}, /* Unknown */ | ||
519 | {OV8858_8BIT, 0x3769, 0x44}, /* Unknown */ | ||
520 | {OV8858_8BIT, 0x376A, 0x44}, /* Unknown */ | ||
521 | {OV8858_8BIT, 0x376B, 0x00}, /* Unknown */ | ||
522 | {OV8858_8BIT, 0x376F, 0x01}, /* Unknown */ | ||
523 | {OV8858_8BIT, 0x3772, 0x46}, /* Unknown */ | ||
524 | {OV8858_8BIT, 0x3773, 0x04}, /* Unknown */ | ||
525 | {OV8858_8BIT, 0x3774, 0x2C}, /* Unknown */ | ||
526 | {OV8858_8BIT, 0x3775, 0x13}, /* Unknown */ | ||
527 | {OV8858_8BIT, 0x3776, 0x08}, /* Unknown */ | ||
528 | {OV8858_8BIT, 0x3777, 0x00}, /* Unknown */ | ||
529 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
530 | {OV8858_8BIT, 0x37A0, 0x88}, /* Unknown */ | ||
531 | {OV8858_8BIT, 0x37A1, 0x7A}, /* Unknown */ | ||
532 | {OV8858_8BIT, 0x37A2, 0x7A}, /* Unknown */ | ||
533 | {OV8858_8BIT, 0x37A3, 0x00}, /* Unknown */ | ||
534 | {OV8858_8BIT, 0x37A4, 0x00}, /* Unknown */ | ||
535 | {OV8858_8BIT, 0x37A5, 0x00}, /* Unknown */ | ||
536 | {OV8858_8BIT, 0x37A6, 0x00}, /* Unknown */ | ||
537 | {OV8858_8BIT, 0x37A7, 0x88}, /* Unknown */ | ||
538 | {OV8858_8BIT, 0x37A8, 0x98}, /* Unknown */ | ||
539 | {OV8858_8BIT, 0x37A9, 0x98}, /* Unknown */ | ||
540 | {OV8858_8BIT, 0x37AA, 0x88}, /* Unknown */ | ||
541 | {OV8858_8BIT, 0x37AB, 0x5C}, /* Unknown */ | ||
542 | {OV8858_8BIT, 0x37AC, 0x5C}, /* Unknown */ | ||
543 | {OV8858_8BIT, 0x37AD, 0x55}, /* Unknown */ | ||
544 | {OV8858_8BIT, 0x37AE, 0x19}, /* Unknown */ | ||
545 | {OV8858_8BIT, 0x37AF, 0x19}, /* Unknown */ | ||
546 | {OV8858_8BIT, 0x37B0, 0x00}, /* Unknown */ | ||
547 | {OV8858_8BIT, 0x37B1, 0x00}, /* Unknown */ | ||
548 | {OV8858_8BIT, 0x37B2, 0x00}, /* Unknown */ | ||
549 | {OV8858_8BIT, 0x37B3, 0x84}, /* Unknown */ | ||
550 | {OV8858_8BIT, 0x37B4, 0x84}, /* Unknown */ | ||
551 | {OV8858_8BIT, 0x37B5, 0x66}, /* Unknown */ | ||
552 | {OV8858_8BIT, 0x37B6, 0x00}, /* Unknown */ | ||
553 | {OV8858_8BIT, 0x37B7, 0x00}, /* Unknown */ | ||
554 | {OV8858_8BIT, 0x37B8, 0x00}, /* Unknown */ | ||
555 | {OV8858_8BIT, 0x37B9, 0xFF}, /* Unknown */ | ||
556 | |||
557 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
558 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low */ | ||
559 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
560 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
561 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
562 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
563 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
564 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
565 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high */ | ||
566 | {OV8858_8BIT, 0x3809, 0xC0}, /* h_output_size low */ | ||
567 | {OV8858_8BIT, 0x380A, 0x09}, /* v_output_size high */ | ||
568 | {OV8858_8BIT, 0x380B, 0x90}, /* v_output_size low */ | ||
569 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
570 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
571 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
572 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
573 | {OV8858_8BIT, 0x3810, 0x00}, /* h_win offset high */ | ||
574 | {OV8858_8BIT, 0x3811, 0x04}, /* h_win offset low */ | ||
575 | {OV8858_8BIT, 0x3812, 0x00}, /* v_win offset high */ | ||
576 | {OV8858_8BIT, 0x3813, 0x02}, /* v_win offset low */ | ||
577 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
578 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
579 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
580 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
581 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
582 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
583 | |||
584 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
585 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
586 | {OV8858_8BIT, 0x3837, 0x18}, /* Unknown */ | ||
587 | {OV8858_8BIT, 0x3841, 0xFF}, /* AUTO_SIZE_CTRL */ | ||
588 | {OV8858_8BIT, 0x3846, 0x48}, /* Unknown */ | ||
589 | |||
590 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
591 | {OV8858_8BIT, 0x3D8C, 0x73}, /* OTP_SETTING_STT_ADDRESS */ | ||
592 | {OV8858_8BIT, 0x3D8D, 0xDE}, /* OTP_SETTING_STT_ADDRESS */ | ||
593 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
594 | {OV8858_8BIT, 0x3F0A, 0x80}, /* PSRAM control register */ | ||
595 | |||
596 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
597 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
598 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
599 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
600 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
601 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
602 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
603 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
604 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
605 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
606 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
607 | {OV8858_8BIT, 0x4022, 0x0B}, /* Anchor left end = 0x0BC3 */ | ||
608 | {OV8858_8BIT, 0x4023, 0xC3}, /* Anchor left end = 0x0BC3 */ | ||
609 | {OV8858_8BIT, 0x4024, 0x0C}, /* Anchor right start = 0x0C36 */ | ||
610 | {OV8858_8BIT, 0x4025, 0x36}, /* Anchor right start = 0x0C36 */ | ||
611 | {OV8858_8BIT, 0x4026, 0x0C}, /* Anchor right end = 0x0C37 */ | ||
612 | {OV8858_8BIT, 0x4027, 0x37}, /* Anchor right end = 0x0C37 */ | ||
613 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
614 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
615 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
616 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
617 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
618 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
619 | {OV8858_8BIT, 0x402E, 0x0C}, /* Bottom black line start = 12 */ | ||
620 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
621 | |||
622 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
623 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
624 | {OV8858_8BIT, 0x4300, 0xFF}, /* clip_max[11:4] = 0xFFF */ | ||
625 | {OV8858_8BIT, 0x4301, 0x00}, /* clip_min[11:4] = 0 */ | ||
626 | {OV8858_8BIT, 0x4302, 0x0F}, /* clip_min/max[3:0] */ | ||
627 | {OV8858_8BIT, 0x4307, 0x01}, /* Unknown */ | ||
628 | {OV8858_8BIT, 0x4316, 0x00}, /* CTRL16 = default */ | ||
629 | {OV8858_8BIT, 0x4503, 0x18}, /* Unknown */ | ||
630 | {OV8858_8BIT, 0x4500, 0x38}, /* Unknown */ | ||
631 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
632 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
633 | /* wkup_dly = Mark1 wakeup delay/2^10 = 0x25 */ | ||
634 | {OV8858_8BIT, 0x4808, 0x25}, | ||
635 | {OV8858_8BIT, 0x4816, 0x52}, /* Embedded data type*/ | ||
636 | {OV8858_8BIT, 0x481F, 0x32}, /* clk_prepare_min = 0x32 */ | ||
637 | {OV8858_8BIT, 0x4825, 0x3A}, /* lpx_p_min = 0x3A */ | ||
638 | {OV8858_8BIT, 0x4826, 0x40}, /* hs_prepare_min = 0x40 */ | ||
639 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
640 | {OV8858_8BIT, 0x4850, 0x10}, /* LANE SEL01 */ | ||
641 | {OV8858_8BIT, 0x4851, 0x32}, /* LANE SEL02 */ | ||
642 | |||
643 | {OV8858_8BIT, 0x4B00, 0x2A}, /* Unknown */ | ||
644 | {OV8858_8BIT, 0x4B0D, 0x00}, /* Unknown */ | ||
645 | {OV8858_8BIT, 0x4D00, 0x04}, /* TPM_CTRL_REG */ | ||
646 | {OV8858_8BIT, 0x4D01, 0x18}, /* TPM_CTRL_REG */ | ||
647 | {OV8858_8BIT, 0x4D02, 0xC3}, /* TPM_CTRL_REG */ | ||
648 | {OV8858_8BIT, 0x4D03, 0xFF}, /* TPM_CTRL_REG */ | ||
649 | {OV8858_8BIT, 0x4D04, 0xFF}, /* TPM_CTRL_REG */ | ||
650 | {OV8858_8BIT, 0x4D05, 0xFF}, /* TPM_CTRL_REG */ | ||
651 | |||
652 | /* | ||
653 | * Lens correction (LENC) function enable = 0 | ||
654 | * Slave sensor AWB Gain function enable = 1 | ||
655 | * Slave sensor AWB Statistics function enable = 1 | ||
656 | * Master sensor AWB Gain function enable = 1 | ||
657 | * Master sensor AWB Statistics function enable = 1 | ||
658 | * Black DPC function enable = 1 | ||
659 | * White DPC function enable =1 | ||
660 | */ | ||
661 | {OV8858_8BIT, 0x5000, 0x7E}, | ||
662 | {OV8858_8BIT, 0x5001, 0x01}, /* BLC function enable = 1 */ | ||
663 | /* | ||
664 | * Horizontal scale function enable = 0 | ||
665 | * WBMATCH bypass mode = Select slave sensor's gain | ||
666 | * WBMATCH function enable = 0 | ||
667 | * Master MWB gain support RGBC = 0 | ||
668 | * OTP_DPC function enable = 1 | ||
669 | * Manual mode of VarioPixel function enable = 0 | ||
670 | * Manual enable of VarioPixel function enable = 0 | ||
671 | * Use VSYNC to latch ISP modules's function enable signals = 0 | ||
672 | */ | ||
673 | {OV8858_8BIT, 0x5002, 0x08}, | ||
674 | /* | ||
675 | * Bypass all ISP modules after BLC module = 0 | ||
676 | * DPC_DBC buffer control enable = 1 | ||
677 | * WBMATCH VSYNC selection = Select master sensor's VSYNC fall | ||
678 | * Select master AWB gain to embed line = AWB gain before manual mode | ||
679 | * Enable BLC's input flip_i signal = 0 | ||
680 | */ | ||
681 | {OV8858_8BIT, 0x5003, 0x20}, | ||
682 | {OV8858_8BIT, 0x5041, 0x1D}, /* ISP CTRL41 - embedded data=on */ | ||
683 | {OV8858_8BIT, 0x5046, 0x12}, /* ISP CTRL46 = default */ | ||
684 | /* | ||
685 | * Tail enable = 1 | ||
686 | * Saturate cross cluster enable = 1 | ||
687 | * Remove cross cluster enable = 1 | ||
688 | * Enable to remove connected defect pixels in same channel = 1 | ||
689 | * Enable to remove connected defect pixels in different channel = 1 | ||
690 | * Smooth enable, use average G for recovery = 1 | ||
691 | * Black/white sensor mode enable = 0 | ||
692 | * Manual mode enable = 0 | ||
693 | */ | ||
694 | {OV8858_8BIT, 0x5780, 0xFC}, | ||
695 | {OV8858_8BIT, 0x5784, 0x0C}, /* DPC CTRL04 */ | ||
696 | {OV8858_8BIT, 0x5787, 0x40}, /* DPC CTRL07 */ | ||
697 | {OV8858_8BIT, 0x5788, 0x08}, /* DPC CTRL08 */ | ||
698 | {OV8858_8BIT, 0x578A, 0x02}, /* DPC CTRL0A */ | ||
699 | {OV8858_8BIT, 0x578B, 0x01}, /* DPC CTRL0B */ | ||
700 | {OV8858_8BIT, 0x578C, 0x01}, /* DPC CTRL0C */ | ||
701 | {OV8858_8BIT, 0x578E, 0x02}, /* DPC CTRL0E */ | ||
702 | {OV8858_8BIT, 0x578F, 0x01}, /* DPC CTRL0F */ | ||
703 | {OV8858_8BIT, 0x5790, 0x01}, /* DPC CTRL10 */ | ||
704 | {OV8858_8BIT, 0x5901, 0x00}, /* VAP CTRL01 = default */ | ||
705 | /* WINC CTRL08 = embedded data in 1st line*/ | ||
706 | {OV8858_8BIT, 0x5A08, 0x00}, | ||
707 | {OV8858_8BIT, 0x5B00, 0x02}, /* OTP CTRL00 */ | ||
708 | {OV8858_8BIT, 0x5B01, 0x10}, /* OTP CTRL01 */ | ||
709 | {OV8858_8BIT, 0x5B02, 0x03}, /* OTP CTRL02 */ | ||
710 | {OV8858_8BIT, 0x5B03, 0xCF}, /* OTP CTRL03 */ | ||
711 | {OV8858_8BIT, 0x5B05, 0x6C}, /* OTP CTRL05 = default */ | ||
712 | {OV8858_8BIT, 0x5E00, 0x00}, /* PRE CTRL00 = default */ | ||
713 | {OV8858_8BIT, 0x5E01, 0x41}, /* PRE_CTRL01 = default */ | ||
714 | |||
715 | {OV8858_TOK_TERM, 0, 0} | ||
716 | }; | ||
717 | |||
718 | /*****************************STILL********************************/ | ||
719 | |||
720 | static const struct ov8858_reg ov8858_8M[] = { | ||
721 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
722 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
723 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
724 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low 12 */ | ||
725 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
726 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
727 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
728 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low 3283 */ | ||
729 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
730 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
731 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high 3280 x 2464 */ | ||
732 | {OV8858_8BIT, 0x3809, 0xD0}, /* h_output_size low */ | ||
733 | {OV8858_8BIT, 0x380A, 0x09}, /* v_output_size high */ | ||
734 | {OV8858_8BIT, 0x380B, 0xa0}, /* v_output_size low */ | ||
735 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
736 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
737 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
738 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
739 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
740 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
741 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
742 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
743 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
744 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
745 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
746 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
747 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
748 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
749 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
750 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
751 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
752 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
753 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
754 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
755 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
756 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
757 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
758 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
759 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
760 | {OV8858_8BIT, 0x4022, 0x0B}, /* Anchor left end = 0x0BC3 */ | ||
761 | {OV8858_8BIT, 0x4023, 0xC3}, /* Anchor left end = 0x0BC3 */ | ||
762 | {OV8858_8BIT, 0x4024, 0x0C}, /* Anchor right start = 0x0C36 */ | ||
763 | {OV8858_8BIT, 0x4025, 0x36}, /* Anchor right start = 0x0C36 */ | ||
764 | {OV8858_8BIT, 0x4026, 0x0C}, /* Anchor right end = 0x0C37 */ | ||
765 | {OV8858_8BIT, 0x4027, 0x37}, /* Anchor right end = 0x0C37 */ | ||
766 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
767 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
768 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
769 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
770 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
771 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
772 | {OV8858_8BIT, 0x402E, 0x0C}, /* Bottom black line start = 12 */ | ||
773 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
774 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
775 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
776 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
777 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
778 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
779 | {OV8858_TOK_TERM, 0, 0} | ||
780 | }; | ||
781 | |||
782 | static const struct ov8858_reg ov8858_3276x1848[] = { | ||
783 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
784 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
785 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
786 | {OV8858_8BIT, 0x3801, 0x10}, /* h_crop_start low 0c->10*/ | ||
787 | {OV8858_8BIT, 0x3802, 0x01}, /* v_crop_start high */ | ||
788 | {OV8858_8BIT, 0x3803, 0x42}, /* v_crop_start low 3e->42*/ | ||
789 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
790 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
791 | {OV8858_8BIT, 0x3806, 0x08}, /* v_crop_end high */ | ||
792 | {OV8858_8BIT, 0x3807, 0x71}, /* v_crop_end low */ | ||
793 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high 3276 x 1848 */ | ||
794 | {OV8858_8BIT, 0x3809, 0xCC}, /* h_output_size low d0->cc*/ | ||
795 | {OV8858_8BIT, 0x380A, 0x07}, /* v_output_size high */ | ||
796 | {OV8858_8BIT, 0x380B, 0x38}, /* v_output_size low 3c->38*/ | ||
797 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
798 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
799 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
800 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
801 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
802 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
803 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
804 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
805 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
806 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
807 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
808 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
809 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
810 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
811 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
812 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
813 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
814 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
815 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
816 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
817 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
818 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
819 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
820 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
821 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
822 | {OV8858_8BIT, 0x4022, 0x0B}, /* Anchor left end = 0x0BC3 */ | ||
823 | {OV8858_8BIT, 0x4023, 0xC3}, /* Anchor left end = 0x0BC3 */ | ||
824 | {OV8858_8BIT, 0x4024, 0x0C}, /* Anchor right start = 0x0C36 */ | ||
825 | {OV8858_8BIT, 0x4025, 0x36}, /* Anchor right start = 0x0C36 */ | ||
826 | {OV8858_8BIT, 0x4026, 0x0C}, /* Anchor right end = 0x0C37 */ | ||
827 | {OV8858_8BIT, 0x4027, 0x37}, /* Anchor right end = 0x0C37 */ | ||
828 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
829 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
830 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
831 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
832 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
833 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
834 | {OV8858_8BIT, 0x402E, 0x0C}, /* Bottom black line start = 12 */ | ||
835 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
836 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
837 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
838 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
839 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
840 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
841 | {OV8858_TOK_TERM, 0, 0} | ||
842 | }; | ||
843 | |||
844 | static const struct ov8858_reg ov8858_6M[] = { | ||
845 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
846 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
847 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
848 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low */ | ||
849 | {OV8858_8BIT, 0x3802, 0x01}, /* v_crop_start high */ | ||
850 | {OV8858_8BIT, 0x3803, 0x3E}, /* v_crop_start low */ | ||
851 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
852 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
853 | {OV8858_8BIT, 0x3806, 0x08}, /* v_crop_end high */ | ||
854 | {OV8858_8BIT, 0x3807, 0x71}, /* v_crop_end low */ | ||
855 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high 3280 x 1852 */ | ||
856 | {OV8858_8BIT, 0x3809, 0xD0}, /* h_output_size low */ | ||
857 | {OV8858_8BIT, 0x380A, 0x07}, /* v_output_size high */ | ||
858 | {OV8858_8BIT, 0x380B, 0x3C}, /* v_output_size low */ | ||
859 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
860 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
861 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
862 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
863 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
864 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
865 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
866 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
867 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
868 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
869 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
870 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
871 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
872 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
873 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
874 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
875 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
876 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
877 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
878 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
879 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
880 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
881 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
882 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
883 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
884 | {OV8858_8BIT, 0x4022, 0x0B}, /* Anchor left end = 0x0BC3 */ | ||
885 | {OV8858_8BIT, 0x4023, 0xC3}, /* Anchor left end = 0x0BC3 */ | ||
886 | {OV8858_8BIT, 0x4024, 0x0C}, /* Anchor right start = 0x0C36 */ | ||
887 | {OV8858_8BIT, 0x4025, 0x36}, /* Anchor right start = 0x0C36 */ | ||
888 | {OV8858_8BIT, 0x4026, 0x0C}, /* Anchor right end = 0x0C37 */ | ||
889 | {OV8858_8BIT, 0x4027, 0x37}, /* Anchor right end = 0x0C37 */ | ||
890 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
891 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
892 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
893 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
894 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
895 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
896 | {OV8858_8BIT, 0x402E, 0x0C}, /* Bottom black line start = 12 */ | ||
897 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
898 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
899 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
900 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
901 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
902 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
903 | {OV8858_TOK_TERM, 0, 0} | ||
904 | }; | ||
905 | |||
906 | static const struct ov8858_reg ov8858_1080P_60[] = { | ||
907 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
908 | {OV8858_8BIT, 0x3778, 0x17}, /* Unknown */ | ||
909 | {OV8858_8BIT, 0x3800, 0x02}, /* h_crop_start high */ | ||
910 | {OV8858_8BIT, 0x3801, 0x26}, /* h_crop_start low */ | ||
911 | {OV8858_8BIT, 0x3802, 0x02}, /* v_crop_start high */ | ||
912 | {OV8858_8BIT, 0x3803, 0x8C}, /* v_crop_start low */ | ||
913 | {OV8858_8BIT, 0x3804, 0x0A}, /* h_crop_end high */ | ||
914 | {OV8858_8BIT, 0x3805, 0x9D}, /* h_crop_end low */ | ||
915 | {OV8858_8BIT, 0x3806, 0x07}, /* v_crop_end high */ | ||
916 | {OV8858_8BIT, 0x3807, 0x0A}, /* v_crop_end low */ | ||
917 | {OV8858_8BIT, 0x3808, 0x07}, /* h_output_size high*/ | ||
918 | {OV8858_8BIT, 0x3809, 0x90}, /* h_output_size low */ | ||
919 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
920 | {OV8858_8BIT, 0x380B, 0x48}, /* v_output_size low */ | ||
921 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
922 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
923 | {OV8858_8BIT, 0x380E, 0x04}, /* vertical timing size high */ | ||
924 | {OV8858_8BIT, 0x380F, 0xEC}, /* vertical timing size low */ | ||
925 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
926 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
927 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
928 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
929 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
930 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
931 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
932 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
933 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
934 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
935 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
936 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
937 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
938 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
939 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
940 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
941 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
942 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
943 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
944 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
945 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
946 | {OV8858_8BIT, 0x4022, 0x07}, /* Anchor left end = 0x072D */ | ||
947 | {OV8858_8BIT, 0x4023, 0x2D}, /* Anchor left end = 0x072D */ | ||
948 | {OV8858_8BIT, 0x4024, 0x07}, /* Anchor right start = 0x079E */ | ||
949 | {OV8858_8BIT, 0x4025, 0x9E}, /* Anchor right start = 0x079E */ | ||
950 | {OV8858_8BIT, 0x4026, 0x07}, /* Anchor right end = 0x079F */ | ||
951 | {OV8858_8BIT, 0x4027, 0x9F}, /* Anchor right end = 0x079F */ | ||
952 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
953 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
954 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
955 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
956 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
957 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
958 | {OV8858_8BIT, 0x402E, 0x0C}, /* Bottom black line start = 12 */ | ||
959 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
960 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
961 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
962 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
963 | {OV8858_8BIT, 0x4601, 0xef}, /* Unknown */ | ||
964 | {OV8858_8BIT, 0x4837, 0x16}, /* pclk_period = 0x16 */ | ||
965 | {OV8858_TOK_TERM, 0, 0} | ||
966 | }; | ||
967 | |||
968 | static const struct ov8858_reg ov8858_1080P_30[] = { | ||
969 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
970 | {OV8858_8BIT, 0x3778, 0x17}, /* Unknown */ | ||
971 | {OV8858_8BIT, 0x3800, 0x02}, /* h_crop_start high */ | ||
972 | {OV8858_8BIT, 0x3801, 0x26}, /* h_crop_start low */ | ||
973 | {OV8858_8BIT, 0x3802, 0x02}, /* v_crop_start high */ | ||
974 | {OV8858_8BIT, 0x3803, 0x8C}, /* v_crop_start low */ | ||
975 | {OV8858_8BIT, 0x3804, 0x0A}, /* h_crop_end high */ | ||
976 | {OV8858_8BIT, 0x3805, 0x9D}, /* h_crop_end low */ | ||
977 | {OV8858_8BIT, 0x3806, 0x07}, /* v_crop_end high */ | ||
978 | {OV8858_8BIT, 0x3807, 0x0A}, /* v_crop_end low */ | ||
979 | {OV8858_8BIT, 0x3808, 0x07}, /* h_output_size high*/ | ||
980 | {OV8858_8BIT, 0x3809, 0x90}, /* h_output_size low */ | ||
981 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
982 | {OV8858_8BIT, 0x380B, 0x48}, /* v_output_size low */ | ||
983 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
984 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
985 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
986 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
987 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
988 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
989 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
990 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
991 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
992 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
993 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
994 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
995 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
996 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
997 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
998 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
999 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
1000 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
1001 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
1002 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
1003 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
1004 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
1005 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
1006 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
1007 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
1008 | {OV8858_8BIT, 0x4022, 0x07}, /* Anchor left end = 0x072D */ | ||
1009 | {OV8858_8BIT, 0x4023, 0x2D}, /* Anchor left end = 0x072D */ | ||
1010 | {OV8858_8BIT, 0x4024, 0x07}, /* Anchor right start = 0x079E */ | ||
1011 | {OV8858_8BIT, 0x4025, 0x9E}, /* Anchor right start = 0x079E */ | ||
1012 | {OV8858_8BIT, 0x4026, 0x07}, /* Anchor right end = 0x079F */ | ||
1013 | {OV8858_8BIT, 0x4027, 0x9F}, /* Anchor right end = 0x079F */ | ||
1014 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
1015 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
1016 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
1017 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
1018 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
1019 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
1020 | {OV8858_8BIT, 0x402E, 0x0C}, /* Bottom black line start = 12 */ | ||
1021 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
1022 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
1023 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
1024 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
1025 | {OV8858_8BIT, 0x4601, 0xef}, /* Unknown */ | ||
1026 | {OV8858_8BIT, 0x4837, 0x16}, /* pclk_period = 0x16 */ | ||
1027 | {OV8858_TOK_TERM, 0, 0} | ||
1028 | }; | ||
1029 | |||
1030 | static const struct ov8858_reg ov8858_1640x1232[] = { | ||
1031 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
1032 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
1033 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
1034 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low 12 */ | ||
1035 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
1036 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
1037 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high 3283 */ | ||
1038 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
1039 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
1040 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
1041 | {OV8858_8BIT, 0x3808, 0x06}, /* h_output_size high 1640 x 1232 */ | ||
1042 | {OV8858_8BIT, 0x3809, 0x68}, /* h_output_size low */ | ||
1043 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
1044 | {OV8858_8BIT, 0x380B, 0xD0}, /* v_output_size low */ | ||
1045 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
1046 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
1047 | {OV8858_8BIT, 0x380E, 0x09}, /* vertical timing size high */ | ||
1048 | {OV8858_8BIT, 0x380F, 0xAA}, /* vertical timing size low */ | ||
1049 | {OV8858_8BIT, 0x3814, 0x03}, /* h_odd_inc */ | ||
1050 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
1051 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
1052 | {OV8858_8BIT, 0x3821, 0x67}, /* format2 */ | ||
1053 | {OV8858_8BIT, 0x382A, 0x03}, /* v_odd_inc */ | ||
1054 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
1055 | {OV8858_8BIT, 0x3830, 0x08}, /* Unknown */ | ||
1056 | {OV8858_8BIT, 0x3836, 0x02}, /* Unknown */ | ||
1057 | {OV8858_8BIT, 0x3D85, 0x16}, /* OTP_REG85 */ | ||
1058 | {OV8858_8BIT, 0x3F08, 0x08}, /* PSRAM control register */ | ||
1059 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
1060 | {OV8858_8BIT, 0x4001, 0x10}, /* BLC CTRL01 */ | ||
1061 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
1062 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
1063 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
1064 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
1065 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
1066 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
1067 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
1068 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
1069 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
1070 | {OV8858_8BIT, 0x4022, 0x04}, /* Anchor left end = 0x04B9 */ | ||
1071 | {OV8858_8BIT, 0x4023, 0xB9}, /* Anchor left end = 0x04B9 */ | ||
1072 | {OV8858_8BIT, 0x4024, 0x05}, /* Anchor right start = 0x052A */ | ||
1073 | {OV8858_8BIT, 0x4025, 0x2A}, /* Anchor right start = 0x052A */ | ||
1074 | {OV8858_8BIT, 0x4026, 0x05}, /* Anchor right end = 0x052B */ | ||
1075 | {OV8858_8BIT, 0x4027, 0x2B}, /* Anchor right end = 0x052B */ | ||
1076 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
1077 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
1078 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
1079 | {OV8858_8BIT, 0x402B, 0x04}, /* Top black line number = 8 */ | ||
1080 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
1081 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
1082 | {OV8858_8BIT, 0x402E, 0x08}, /* Bottom black line start = 8 */ | ||
1083 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
1084 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
1085 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
1086 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
1087 | {OV8858_8BIT, 0x4601, 0xCB}, /* Unknown */ | ||
1088 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
1089 | {OV8858_TOK_TERM, 0, 0} | ||
1090 | }; | ||
1091 | |||
1092 | static const struct ov8858_reg ov8858_1640x1096[] = { | ||
1093 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
1094 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
1095 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
1096 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low 12 */ | ||
1097 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
1098 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
1099 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high 3283 */ | ||
1100 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
1101 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
1102 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
1103 | {OV8858_8BIT, 0x3808, 0x06}, /* h_output_size high 1640 x 1096 */ | ||
1104 | {OV8858_8BIT, 0x3809, 0x68}, /* h_output_size low */ | ||
1105 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
1106 | {OV8858_8BIT, 0x380B, 0x48}, /* v_output_size low */ | ||
1107 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
1108 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
1109 | {OV8858_8BIT, 0x380E, 0x09}, /* vertical timing size high */ | ||
1110 | {OV8858_8BIT, 0x380F, 0xAA}, /* vertical timing size low */ | ||
1111 | {OV8858_8BIT, 0x3814, 0x03}, /* h_odd_inc */ | ||
1112 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
1113 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
1114 | {OV8858_8BIT, 0x3821, 0x67}, /* format2 */ | ||
1115 | {OV8858_8BIT, 0x382A, 0x03}, /* v_odd_inc */ | ||
1116 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
1117 | {OV8858_8BIT, 0x3830, 0x08}, /* Unknown */ | ||
1118 | {OV8858_8BIT, 0x3836, 0x02}, /* Unknown */ | ||
1119 | {OV8858_8BIT, 0x3D85, 0x16}, /* OTP_REG85 */ | ||
1120 | {OV8858_8BIT, 0x3F08, 0x08}, /* PSRAM control register */ | ||
1121 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
1122 | {OV8858_8BIT, 0x4001, 0x10}, /* BLC CTRL01 */ | ||
1123 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
1124 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
1125 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
1126 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
1127 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
1128 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
1129 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
1130 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
1131 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
1132 | {OV8858_8BIT, 0x4022, 0x04}, /* Anchor left end = 0x04B9 */ | ||
1133 | {OV8858_8BIT, 0x4023, 0xB9}, /* Anchor left end = 0x04B9 */ | ||
1134 | {OV8858_8BIT, 0x4024, 0x05}, /* Anchor right start = 0x052A */ | ||
1135 | {OV8858_8BIT, 0x4025, 0x2A}, /* Anchor right start = 0x052A */ | ||
1136 | {OV8858_8BIT, 0x4026, 0x05}, /* Anchor right end = 0x052B */ | ||
1137 | {OV8858_8BIT, 0x4027, 0x2B}, /* Anchor right end = 0x052B */ | ||
1138 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
1139 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
1140 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
1141 | {OV8858_8BIT, 0x402B, 0x04}, /* Top black line number = 8 */ | ||
1142 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
1143 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
1144 | {OV8858_8BIT, 0x402E, 0x08}, /* Bottom black line start = 8 */ | ||
1145 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
1146 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
1147 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
1148 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
1149 | {OV8858_8BIT, 0x4601, 0xCB}, /* Unknown */ | ||
1150 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
1151 | {OV8858_TOK_TERM, 0, 0} | ||
1152 | }; | ||
1153 | |||
1154 | |||
1155 | static const struct ov8858_reg ov8858_1640x926[] = { | ||
1156 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
1157 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
1158 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
1159 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low */ | ||
1160 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
1161 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
1162 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
1163 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
1164 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
1165 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
1166 | {OV8858_8BIT, 0x3808, 0x06}, /* h_output_size high 1640 x 926 */ | ||
1167 | {OV8858_8BIT, 0x3809, 0x68}, /* h_output_size low */ | ||
1168 | {OV8858_8BIT, 0x380A, 0x03}, /* v_output_size high */ | ||
1169 | {OV8858_8BIT, 0x380B, 0x9E}, /* v_output_size low */ | ||
1170 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
1171 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
1172 | {OV8858_8BIT, 0x380E, 0x09}, /* vertical timing size high */ | ||
1173 | {OV8858_8BIT, 0x380F, 0xAA}, /* vertical timing size low */ | ||
1174 | {OV8858_8BIT, 0x3814, 0x03}, /* h_odd_inc */ | ||
1175 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
1176 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
1177 | {OV8858_8BIT, 0x3821, 0x67}, /* format2 */ | ||
1178 | {OV8858_8BIT, 0x382A, 0x03}, /* v_odd_inc */ | ||
1179 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
1180 | {OV8858_8BIT, 0x3830, 0x08}, /* Unknown */ | ||
1181 | {OV8858_8BIT, 0x3836, 0x02}, /* Unknown */ | ||
1182 | {OV8858_8BIT, 0x3D85, 0x16}, /* OTP_REG85 */ | ||
1183 | {OV8858_8BIT, 0x3F08, 0x08}, /* PSRAM control register */ | ||
1184 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
1185 | {OV8858_8BIT, 0x4001, 0x10}, /* BLC CTRL01 */ | ||
1186 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
1187 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
1188 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
1189 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
1190 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
1191 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
1192 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
1193 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
1194 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
1195 | {OV8858_8BIT, 0x4022, 0x04}, /* Anchor left end = 0x04B9 */ | ||
1196 | {OV8858_8BIT, 0x4023, 0xB9}, /* Anchor left end = 0x04B9 */ | ||
1197 | {OV8858_8BIT, 0x4024, 0x05}, /* Anchor right start = 0x052A */ | ||
1198 | {OV8858_8BIT, 0x4025, 0x2A}, /* Anchor right start = 0x052A */ | ||
1199 | {OV8858_8BIT, 0x4026, 0x05}, /* Anchor right end = 0x052B */ | ||
1200 | {OV8858_8BIT, 0x4027, 0x2B}, /* Anchor right end = 0x052B */ | ||
1201 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
1202 | {OV8858_8BIT, 0x4029, 0x02}, /* Top zero line number = 2 */ | ||
1203 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
1204 | {OV8858_8BIT, 0x402B, 0x04}, /* Top black line number = 8 */ | ||
1205 | {OV8858_8BIT, 0x402C, 0x02}, /* Bottom zero start line = 2 */ | ||
1206 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
1207 | {OV8858_8BIT, 0x402E, 0x08}, /* Bottom black line start = 8 */ | ||
1208 | {OV8858_8BIT, 0x402F, 0x02}, /* Bottom black line number = 2 */ | ||
1209 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
1210 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
1211 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
1212 | {OV8858_8BIT, 0x4601, 0xCB}, /* Unknown */ | ||
1213 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
1214 | {OV8858_TOK_TERM, 0, 0} | ||
1215 | }; | ||
1216 | |||
1217 | static struct ov8858_resolution ov8858_res_preview[] = { | ||
1218 | { | ||
1219 | .desc = "ov8858_1640x926_PREVIEW", | ||
1220 | .width = 1640, | ||
1221 | .height = 926, | ||
1222 | .used = 0, | ||
1223 | .regs = ov8858_1640x926, | ||
1224 | .bin_factor_x = 0, | ||
1225 | .bin_factor_y = 0, | ||
1226 | .skip_frames = 0, | ||
1227 | .fps_options = { | ||
1228 | { | ||
1229 | .fps = 30, | ||
1230 | .pixels_per_line = 3880, | ||
1231 | .lines_per_frame = 2573, | ||
1232 | }, | ||
1233 | { | ||
1234 | } | ||
1235 | }, | ||
1236 | }, | ||
1237 | { | ||
1238 | .desc = "ov8858_1640x1232_PREVIEW", | ||
1239 | .width = 1640, | ||
1240 | .height = 1232, | ||
1241 | .used = 0, | ||
1242 | .regs = ov8858_1640x1232, | ||
1243 | .bin_factor_x = 0, | ||
1244 | .bin_factor_y = 0, | ||
1245 | .skip_frames = 0, | ||
1246 | .fps_options = { | ||
1247 | { | ||
1248 | .fps = 30, | ||
1249 | .pixels_per_line = 3880, | ||
1250 | .lines_per_frame = 2573, | ||
1251 | }, | ||
1252 | { | ||
1253 | } | ||
1254 | }, | ||
1255 | }, | ||
1256 | { | ||
1257 | .desc = "ov8858_3276x1848_PREVIEW", | ||
1258 | .width = 3276, | ||
1259 | .height = 1848, | ||
1260 | .used = 0, | ||
1261 | .regs = ov8858_3276x1848, | ||
1262 | .bin_factor_x = 0, | ||
1263 | .bin_factor_y = 0, | ||
1264 | .skip_frames = 0, | ||
1265 | .fps_options = { | ||
1266 | { | ||
1267 | .fps = 30, | ||
1268 | .pixels_per_line = 3880, | ||
1269 | .lines_per_frame = 2573, | ||
1270 | }, | ||
1271 | { | ||
1272 | } | ||
1273 | }, | ||
1274 | }, | ||
1275 | { | ||
1276 | .desc = "ov8858_8M_PREVIEW", | ||
1277 | .width = 3280, | ||
1278 | .height = 2464, | ||
1279 | .used = 0, | ||
1280 | .regs = ov8858_8M, | ||
1281 | .bin_factor_x = 0, | ||
1282 | .bin_factor_y = 0, | ||
1283 | .skip_frames = 0, | ||
1284 | .fps_options = { | ||
1285 | { | ||
1286 | .fps = 30, | ||
1287 | .pixels_per_line = 3880, | ||
1288 | .lines_per_frame = 2573, | ||
1289 | }, | ||
1290 | { | ||
1291 | } | ||
1292 | }, | ||
1293 | }, | ||
1294 | }; | ||
1295 | |||
1296 | static struct ov8858_resolution ov8858_res_still[] = { | ||
1297 | { | ||
1298 | .desc = "ov8858_1640x1232_STILL", | ||
1299 | .width = 1640, | ||
1300 | .height = 1232, | ||
1301 | .used = 0, | ||
1302 | .regs = ov8858_1640x1232, | ||
1303 | .bin_factor_x = 0, | ||
1304 | .bin_factor_y = 0, | ||
1305 | .skip_frames = 0, | ||
1306 | .fps_options = { | ||
1307 | { | ||
1308 | .fps = 30, | ||
1309 | .pixels_per_line = 3880, | ||
1310 | .lines_per_frame = 2573, | ||
1311 | }, | ||
1312 | { | ||
1313 | } | ||
1314 | }, | ||
1315 | }, | ||
1316 | { | ||
1317 | .desc = "ov8858_1640x926_STILL", | ||
1318 | .width = 1640, | ||
1319 | .height = 926, | ||
1320 | .used = 0, | ||
1321 | .regs = ov8858_1640x926, | ||
1322 | .bin_factor_x = 0, | ||
1323 | .bin_factor_y = 0, | ||
1324 | .skip_frames = 1, | ||
1325 | .fps_options = { | ||
1326 | { | ||
1327 | .fps = 30, | ||
1328 | .pixels_per_line = 3880, | ||
1329 | .lines_per_frame = 2573, | ||
1330 | }, | ||
1331 | { | ||
1332 | } | ||
1333 | }, | ||
1334 | }, | ||
1335 | { | ||
1336 | .desc = "ov8858_3276X1848_STILL", | ||
1337 | .width = 3276, | ||
1338 | .height = 1848, | ||
1339 | .used = 0, | ||
1340 | .regs = ov8858_3276x1848, | ||
1341 | .bin_factor_x = 0, | ||
1342 | .bin_factor_y = 0, | ||
1343 | .skip_frames = 1, | ||
1344 | .fps_options = { | ||
1345 | { | ||
1346 | .fps = 30, | ||
1347 | .pixels_per_line = 3880, | ||
1348 | .lines_per_frame = 2573, | ||
1349 | }, | ||
1350 | { | ||
1351 | } | ||
1352 | }, | ||
1353 | }, | ||
1354 | { | ||
1355 | .desc = "ov8858_8M_STILL", | ||
1356 | .width = 3280, | ||
1357 | .height = 2464, | ||
1358 | .used = 0, | ||
1359 | .regs = ov8858_8M, | ||
1360 | .bin_factor_x = 0, | ||
1361 | .bin_factor_y = 0, | ||
1362 | .skip_frames = 1, | ||
1363 | .fps_options = { | ||
1364 | { | ||
1365 | /* Pixel clock: 149.76MHZ */ | ||
1366 | .fps = 10, | ||
1367 | .pixels_per_line = 3880, | ||
1368 | .lines_per_frame = 3859, | ||
1369 | }, | ||
1370 | { | ||
1371 | } | ||
1372 | }, | ||
1373 | }, | ||
1374 | }; | ||
1375 | |||
1376 | static struct ov8858_resolution ov8858_res_video[] = { | ||
1377 | { | ||
1378 | .desc = "ov8858_1640x926_VIDEO", | ||
1379 | .width = 1640, | ||
1380 | .height = 926, | ||
1381 | .used = 0, | ||
1382 | .regs = ov8858_1640x926, | ||
1383 | .bin_factor_x = 0, | ||
1384 | .bin_factor_y = 0, | ||
1385 | .skip_frames = 1, | ||
1386 | .fps_options = { | ||
1387 | { | ||
1388 | .fps = 30, | ||
1389 | .pixels_per_line = 3880, | ||
1390 | .lines_per_frame = 2573, | ||
1391 | }, | ||
1392 | { | ||
1393 | } | ||
1394 | }, | ||
1395 | }, | ||
1396 | { | ||
1397 | .desc = "ov8858_1640x1232_VIDEO", | ||
1398 | .width = 1640, | ||
1399 | .height = 1232, | ||
1400 | .used = 0, | ||
1401 | .regs = ov8858_1640x1232, | ||
1402 | .bin_factor_x = 0, | ||
1403 | .bin_factor_y = 0, | ||
1404 | .skip_frames = 1, | ||
1405 | .fps_options = { | ||
1406 | { | ||
1407 | .fps = 30, | ||
1408 | .pixels_per_line = 3880, | ||
1409 | .lines_per_frame = 2573, | ||
1410 | }, | ||
1411 | { | ||
1412 | } | ||
1413 | }, | ||
1414 | }, | ||
1415 | { | ||
1416 | .desc = "ov8858_1640x1096_VIDEO", | ||
1417 | .width = 1640, | ||
1418 | .height = 1096, | ||
1419 | .used = 0, | ||
1420 | .regs = ov8858_1640x1096, | ||
1421 | .bin_factor_x = 0, | ||
1422 | .bin_factor_y = 0, | ||
1423 | .skip_frames = 1, | ||
1424 | .fps_options = { | ||
1425 | { | ||
1426 | .fps = 30, | ||
1427 | .pixels_per_line = 3880, | ||
1428 | .lines_per_frame = 2573, | ||
1429 | }, | ||
1430 | { | ||
1431 | } | ||
1432 | }, | ||
1433 | }, | ||
1434 | { | ||
1435 | .desc = "ov8858_6M_VIDEO", | ||
1436 | .width = 3280, | ||
1437 | .height = 1852, | ||
1438 | .used = 0, | ||
1439 | .regs = ov8858_6M, | ||
1440 | .bin_factor_x = 0, | ||
1441 | .bin_factor_y = 0, | ||
1442 | .skip_frames = 1, | ||
1443 | .fps_options = { | ||
1444 | { | ||
1445 | .fps = 30, | ||
1446 | .pixels_per_line = 3880, | ||
1447 | .lines_per_frame = 2573, | ||
1448 | }, | ||
1449 | { | ||
1450 | } | ||
1451 | }, | ||
1452 | }, | ||
1453 | { | ||
1454 | .desc = "ov8858_8M_VIDEO", | ||
1455 | .width = 3280, | ||
1456 | .height = 2464, | ||
1457 | .used = 0, | ||
1458 | .regs = ov8858_8M, | ||
1459 | .bin_factor_x = 0, | ||
1460 | .bin_factor_y = 0, | ||
1461 | .skip_frames = 1, | ||
1462 | .fps_options = { | ||
1463 | { | ||
1464 | .fps = 30, | ||
1465 | .pixels_per_line = 3880, | ||
1466 | .lines_per_frame = 2573, | ||
1467 | }, | ||
1468 | { | ||
1469 | } | ||
1470 | }, | ||
1471 | }, | ||
1472 | }; | ||
1473 | |||
1474 | #endif /* __OV8858_H__ */ | ||
diff --git a/drivers/staging/media/atomisp/i2c/ov8858_btns.h b/drivers/staging/media/atomisp/i2c/ov8858_btns.h deleted file mode 100644 index f81851306832..000000000000 --- a/drivers/staging/media/atomisp/i2c/ov8858_btns.h +++ /dev/null | |||
@@ -1,1276 +0,0 @@ | |||
1 | /* | ||
2 | * Support for the Omnivision OV8858 camera sensor. | ||
3 | * | ||
4 | * Copyright (c) 2014 Intel Corporation. All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef __OV8858_H__ | ||
19 | #define __OV8858_H__ | ||
20 | #include "../include/linux/atomisp_platform.h" | ||
21 | #include <media/v4l2-ctrls.h> | ||
22 | |||
23 | #define I2C_MSG_LENGTH 0x2 | ||
24 | |||
25 | /* | ||
26 | * This should be added into include/linux/videodev2.h | ||
27 | * NOTE: This is most likely not used anywhere. | ||
28 | */ | ||
29 | #define V4L2_IDENT_OV8858 V4L2_IDENT_UNKNOWN | ||
30 | |||
31 | /* | ||
32 | * Indexes for VCM driver lists | ||
33 | */ | ||
34 | #define OV8858_ID_DEFAULT 0 | ||
35 | #define OV8858_SUNNY 1 | ||
36 | |||
37 | #define OV8858_OTP_START_ADDR 0x7010 | ||
38 | #define OV8858_OTP_END_ADDR 0x7186 | ||
39 | |||
40 | /* | ||
41 | * ov8858 System control registers | ||
42 | */ | ||
43 | |||
44 | #define OV8858_OTP_LOAD_CTRL 0x3D81 | ||
45 | #define OV8858_OTP_MODE_CTRL 0x3D84 | ||
46 | #define OV8858_OTP_START_ADDR_REG 0x3D88 | ||
47 | #define OV8858_OTP_END_ADDR_REG 0x3D8A | ||
48 | #define OV8858_OTP_ISP_CTRL2 0x5002 | ||
49 | |||
50 | #define OV8858_OTP_MODE_MANUAL BIT(6) | ||
51 | #define OV8858_OTP_MODE_PROGRAM_DISABLE BIT(7) | ||
52 | #define OV8858_OTP_LOAD_ENABLE BIT(0) | ||
53 | #define OV8858_OTP_DPC_ENABLE BIT(3) | ||
54 | |||
55 | #define OV8858_PLL1_PREDIV0 0x030A | ||
56 | #define OV8858_PLL1_PREDIV 0x0300 | ||
57 | #define OV8858_PLL1_MULTIPLIER 0x0301 | ||
58 | #define OV8858_PLL1_SYS_PRE_DIV 0x0305 | ||
59 | #define OV8858_PLL1_SYS_DIVIDER 0x0306 | ||
60 | |||
61 | #define OV8858_PLL1_PREDIV0_MASK BIT(0) | ||
62 | #define OV8858_PLL1_PREDIV_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
63 | #define OV8858_PLL1_MULTIPLIER_MASK 0x01FF | ||
64 | #define OV8858_PLL1_SYS_PRE_DIV_MASK (BIT(0) | BIT(1)) | ||
65 | #define OV8858_PLL1_SYS_DIVIDER_MASK BIT(0) | ||
66 | |||
67 | #define OV8858_PLL2_PREDIV0 0x0312 | ||
68 | #define OV8858_PLL2_PREDIV 0x030B | ||
69 | #define OV8858_PLL2_MULTIPLIER 0x030C | ||
70 | #define OV8858_PLL2_DAC_DIVIDER 0x0312 | ||
71 | #define OV8858_PLL2_SYS_PRE_DIV 0x030F | ||
72 | #define OV8858_PLL2_SYS_DIVIDER 0x030E | ||
73 | |||
74 | #define OV8858_PLL2_PREDIV0_MASK BIT(4) | ||
75 | #define OV8858_PLL2_PREDIV_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
76 | #define OV8858_PLL2_MULTIPLIER_MASK 0x01FF | ||
77 | #define OV8858_PLL2_DAC_DIVIDER_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) | ||
78 | #define OV8858_PLL2_SYS_PRE_DIV_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) | ||
79 | #define OV8858_PLL2_SYS_DIVIDER_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
80 | |||
81 | #define OV8858_PLL_SCLKSEL1 0x3032 | ||
82 | #define OV8858_PLL_SCLKSEL2 0x3033 | ||
83 | #define OV8858_SRB_HOST_INPUT_DIS 0x3106 | ||
84 | |||
85 | #define OV8858_PLL_SCLKSEL1_MASK BIT(7) | ||
86 | #define OV8858_PLL_SCLKSEL2_MASK BIT(1) | ||
87 | |||
88 | #define OV8858_SYS_PRE_DIV_OFFSET 2 | ||
89 | #define OV8858_SYS_PRE_DIV_MASK (BIT(2) | BIT(3)) | ||
90 | #define OV8858_SCLK_PDIV_OFFSET 4 | ||
91 | #define OV8858_SCLK_PDIV_MASK (BIT(4) | BIT(5) | BIT(6) | BIT(7)) | ||
92 | |||
93 | #define OV8858_TIMING_HTS 0x380C | ||
94 | #define OV8858_TIMING_VTS 0x380E | ||
95 | |||
96 | #define OV8858_HORIZONTAL_START_H 0x3800 | ||
97 | #define OV8858_VERTICAL_START_H 0x3802 | ||
98 | #define OV8858_HORIZONTAL_END_H 0x3804 | ||
99 | #define OV8858_VERTICAL_END_H 0x3806 | ||
100 | #define OV8858_HORIZONTAL_OUTPUT_SIZE_H 0x3808 | ||
101 | #define OV8858_VERTICAL_OUTPUT_SIZE_H 0x380A | ||
102 | |||
103 | #define OV8858_GROUP_ACCESS 0x3208 | ||
104 | #define OV8858_GROUP_ZERO 0x00 | ||
105 | #define OV8858_GROUP_ACCESS_HOLD_START 0x00 | ||
106 | #define OV8858_GROUP_ACCESS_HOLD_END 0x10 | ||
107 | #define OV8858_GROUP_ACCESS_DELAY_LAUNCH 0xA0 | ||
108 | #define OV8858_GROUP_ACCESS_QUICK_LAUNCH 0xE0 | ||
109 | |||
110 | #define OV_SUBDEV_PREFIX "ov" | ||
111 | #define OV_ID_DEFAULT 0x0000 | ||
112 | #define OV8858_CHIP_ID 0x8858 | ||
113 | |||
114 | #define OV8858_LONG_EXPO 0x3500 | ||
115 | #define OV8858_LONG_GAIN 0x3508 | ||
116 | #define OV8858_LONG_DIGI_GAIN 0x350A | ||
117 | #define OV8858_SHORT_GAIN 0x350C | ||
118 | #define OV8858_SHORT_DIGI_GAIN 0x350E | ||
119 | |||
120 | #define OV8858_FORMAT1 0x3820 | ||
121 | #define OV8858_FORMAT2 0x3821 | ||
122 | |||
123 | #define OV8858_FLIP_ENABLE 0x06 | ||
124 | |||
125 | #define OV8858_MWB_RED_GAIN_H 0x5032 | ||
126 | #define OV8858_MWB_GREEN_GAIN_H 0x5034 | ||
127 | #define OV8858_MWB_BLUE_GAIN_H 0x5036 | ||
128 | #define OV8858_MWB_GAIN_MAX 0x0FFF | ||
129 | |||
130 | #define OV8858_CHIP_ID_HIGH 0x300B | ||
131 | #define OV8858_CHIP_ID_LOW 0x300C | ||
132 | #define OV8858_STREAM_MODE 0x0100 | ||
133 | |||
134 | #define OV8858_FOCAL_LENGTH_NUM 294 /* 2.94mm */ | ||
135 | #define OV8858_FOCAL_LENGTH_DEM 100 | ||
136 | #define OV8858_F_NUMBER_DEFAULT_NUM 24 /* 2.4 */ | ||
137 | #define OV8858_F_NUMBER_DEM 10 | ||
138 | |||
139 | #define OV8858_H_INC_ODD 0x3814 | ||
140 | #define OV8858_H_INC_EVEN 0x3815 | ||
141 | #define OV8858_V_INC_ODD 0x382A | ||
142 | #define OV8858_V_INC_EVEN 0x382B | ||
143 | |||
144 | #define OV8858_READ_MODE_BINNING_ON 0x0400 /* ToDo: Check this */ | ||
145 | #define OV8858_READ_MODE_BINNING_OFF 0x00 /* ToDo: Check this */ | ||
146 | #define OV8858_BIN_FACTOR_MAX 2 | ||
147 | #define OV8858_INTEGRATION_TIME_MARGIN 14 | ||
148 | |||
149 | #define OV8858_MAX_VTS_VALUE 0xFFFF | ||
150 | #define OV8858_MAX_EXPOSURE_VALUE \ | ||
151 | (OV8858_MAX_VTS_VALUE - OV8858_INTEGRATION_TIME_MARGIN) | ||
152 | #define OV8858_MAX_GAIN_VALUE 0x07FF | ||
153 | |||
154 | #define OV8858_MAX_FOCUS_POS 1023 | ||
155 | |||
156 | #define OV8858_TEST_PATTERN_REG 0x5E00 | ||
157 | |||
158 | struct ov8858_vcm { | ||
159 | int (*power_up)(struct v4l2_subdev *sd); | ||
160 | int (*power_down)(struct v4l2_subdev *sd); | ||
161 | int (*init)(struct v4l2_subdev *sd); | ||
162 | int (*t_focus_abs)(struct v4l2_subdev *sd, s32 value); | ||
163 | int (*t_focus_rel)(struct v4l2_subdev *sd, s32 value); | ||
164 | int (*q_focus_status)(struct v4l2_subdev *sd, s32 *value); | ||
165 | int (*q_focus_abs)(struct v4l2_subdev *sd, s32 *value); | ||
166 | int (*t_vcm_slew)(struct v4l2_subdev *sd, s32 value); | ||
167 | int (*t_vcm_timing)(struct v4l2_subdev *sd, s32 value); | ||
168 | }; | ||
169 | |||
170 | /* | ||
171 | * Defines for register writes and register array processing | ||
172 | * */ | ||
173 | #define OV8858_BYTE_MAX 32 | ||
174 | #define OV8858_SHORT_MAX 16 | ||
175 | #define OV8858_TOK_MASK 0xFFF0 | ||
176 | |||
177 | #define MAX_FPS_OPTIONS_SUPPORTED 3 | ||
178 | |||
179 | #define OV8858_DEPTH_COMP_CONST 2200 | ||
180 | #define OV8858_DEPTH_VTS_CONST 2573 | ||
181 | |||
182 | enum ov8858_tok_type { | ||
183 | OV8858_8BIT = 0x0001, | ||
184 | OV8858_16BIT = 0x0002, | ||
185 | OV8858_TOK_TERM = 0xF000, /* terminating token for reg list */ | ||
186 | OV8858_TOK_DELAY = 0xFE00 /* delay token for reg list */ | ||
187 | }; | ||
188 | |||
189 | /* | ||
190 | * If register address or register width is not 32 bit width, | ||
191 | * user needs to convert it manually | ||
192 | */ | ||
193 | struct s_register_setting { | ||
194 | u32 reg; | ||
195 | u32 val; | ||
196 | }; | ||
197 | |||
198 | /** | ||
199 | * struct ov8858_reg - MI sensor register format | ||
200 | * @type: type of the register | ||
201 | * @reg: 16-bit offset to register | ||
202 | * @val: 8/16/32-bit register value | ||
203 | * | ||
204 | * Define a structure for sensor register initialization values | ||
205 | */ | ||
206 | struct ov8858_reg { | ||
207 | enum ov8858_tok_type type; | ||
208 | u16 sreg; | ||
209 | u32 val; /* @set value for read/mod/write, @mask */ | ||
210 | }; | ||
211 | |||
212 | struct ov8858_fps_setting { | ||
213 | int fps; | ||
214 | unsigned short pixels_per_line; | ||
215 | unsigned short lines_per_frame; | ||
216 | const struct ov8858_reg *regs; /* regs that the fps setting needs */ | ||
217 | }; | ||
218 | |||
219 | struct ov8858_resolution { | ||
220 | u8 *desc; | ||
221 | const struct ov8858_reg *regs; | ||
222 | int res; | ||
223 | int width; | ||
224 | int height; | ||
225 | bool used; | ||
226 | u8 bin_factor_x; | ||
227 | u8 bin_factor_y; | ||
228 | unsigned short skip_frames; | ||
229 | const struct ov8858_fps_setting fps_options[MAX_FPS_OPTIONS_SUPPORTED]; | ||
230 | }; | ||
231 | |||
232 | /* | ||
233 | * ov8858 device structure | ||
234 | * */ | ||
235 | struct ov8858_device { | ||
236 | struct v4l2_subdev sd; | ||
237 | struct media_pad pad; | ||
238 | struct v4l2_mbus_framefmt format; | ||
239 | |||
240 | struct camera_sensor_platform_data *platform_data; | ||
241 | struct mutex input_lock; /* serialize sensor's ioctl */ | ||
242 | int fmt_idx; | ||
243 | int streaming; | ||
244 | int vt_pix_clk_freq_mhz; | ||
245 | int fps_index; | ||
246 | u16 sensor_id; /* Sensor id from registers */ | ||
247 | u16 i2c_id; /* Sensor id from i2c_device_id */ | ||
248 | int exposure; | ||
249 | int gain; | ||
250 | u16 digital_gain; | ||
251 | u16 pixels_per_line; | ||
252 | u16 lines_per_frame; | ||
253 | u8 fps; | ||
254 | u8 *otp_data; | ||
255 | /* Prevent the framerate from being lowered in low light scenes. */ | ||
256 | int limit_exposure_flag; | ||
257 | bool hflip; | ||
258 | bool vflip; | ||
259 | |||
260 | const struct ov8858_reg *regs; | ||
261 | struct ov8858_vcm *vcm_driver; | ||
262 | const struct ov8858_resolution *curr_res_table; | ||
263 | unsigned long entries_curr_table; | ||
264 | |||
265 | struct v4l2_ctrl_handler ctrl_handler; | ||
266 | struct v4l2_ctrl *run_mode; | ||
267 | }; | ||
268 | |||
269 | #define to_ov8858_sensor(x) container_of(x, struct ov8858_device, sd) | ||
270 | |||
271 | #define OV8858_MAX_WRITE_BUF_SIZE 32 | ||
272 | struct ov8858_write_buffer { | ||
273 | u16 addr; | ||
274 | u8 data[OV8858_MAX_WRITE_BUF_SIZE]; | ||
275 | }; | ||
276 | |||
277 | struct ov8858_write_ctrl { | ||
278 | int index; | ||
279 | struct ov8858_write_buffer buffer; | ||
280 | }; | ||
281 | |||
282 | static const struct ov8858_reg ov8858_soft_standby[] = { | ||
283 | {OV8858_8BIT, 0x0100, 0x00}, | ||
284 | {OV8858_TOK_TERM, 0, 0} | ||
285 | }; | ||
286 | |||
287 | static const struct ov8858_reg ov8858_streaming[] = { | ||
288 | {OV8858_8BIT, 0x0100, 0x01}, | ||
289 | {OV8858_TOK_TERM, 0, 0} | ||
290 | }; | ||
291 | |||
292 | static const struct ov8858_reg ov8858_param_hold[] = { | ||
293 | {OV8858_8BIT, OV8858_GROUP_ACCESS, | ||
294 | OV8858_GROUP_ZERO | OV8858_GROUP_ACCESS_HOLD_START}, | ||
295 | {OV8858_TOK_TERM, 0, 0} | ||
296 | }; | ||
297 | |||
298 | static const struct ov8858_reg ov8858_param_update[] = { | ||
299 | {OV8858_8BIT, OV8858_GROUP_ACCESS, | ||
300 | OV8858_GROUP_ZERO | OV8858_GROUP_ACCESS_HOLD_END}, | ||
301 | {OV8858_8BIT, OV8858_GROUP_ACCESS, | ||
302 | OV8858_GROUP_ZERO | OV8858_GROUP_ACCESS_DELAY_LAUNCH}, | ||
303 | {OV8858_TOK_TERM, 0, 0} | ||
304 | }; | ||
305 | |||
306 | extern int dw9718_vcm_power_up(struct v4l2_subdev *sd); | ||
307 | extern int dw9718_vcm_power_down(struct v4l2_subdev *sd); | ||
308 | extern int dw9718_vcm_init(struct v4l2_subdev *sd); | ||
309 | extern int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value); | ||
310 | extern int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value); | ||
311 | extern int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value); | ||
312 | extern int dw9718_q_focus_abs(struct v4l2_subdev *sd, s32 *value); | ||
313 | extern int dw9718_t_vcm_slew(struct v4l2_subdev *sd, s32 value); | ||
314 | extern int dw9718_t_vcm_timing(struct v4l2_subdev *sd, s32 value); | ||
315 | |||
316 | extern int vcm_power_up(struct v4l2_subdev *sd); | ||
317 | extern int vcm_power_down(struct v4l2_subdev *sd); | ||
318 | |||
319 | static struct ov8858_vcm ov8858_vcms[] = { | ||
320 | [OV8858_SUNNY] = { | ||
321 | .power_up = dw9718_vcm_power_up, | ||
322 | .power_down = dw9718_vcm_power_down, | ||
323 | .init = dw9718_vcm_init, | ||
324 | .t_focus_abs = dw9718_t_focus_abs, | ||
325 | .t_focus_rel = dw9718_t_focus_rel, | ||
326 | .q_focus_status = dw9718_q_focus_status, | ||
327 | .q_focus_abs = dw9718_q_focus_abs, | ||
328 | .t_vcm_slew = dw9718_t_vcm_slew, | ||
329 | .t_vcm_timing = dw9718_t_vcm_timing, | ||
330 | }, | ||
331 | [OV8858_ID_DEFAULT] = { | ||
332 | .power_up = NULL, | ||
333 | .power_down = NULL, | ||
334 | }, | ||
335 | }; | ||
336 | |||
337 | |||
338 | #define OV8858_RES_WIDTH_MAX 3280 | ||
339 | #define OV8858_RES_HEIGHT_MAX 2464 | ||
340 | |||
341 | static struct ov8858_reg ov8858_BasicSettings[] = { | ||
342 | {OV8858_8BIT, 0x0103, 0x01}, /* software_reset */ | ||
343 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
344 | /* PLL settings */ | ||
345 | {OV8858_8BIT, 0x0300, 0x05}, /* pll1_pre_div = /4 */ | ||
346 | {OV8858_8BIT, 0x0302, 0xAF}, /* pll1_multiplier = 175 */ | ||
347 | {OV8858_8BIT, 0x0303, 0x00}, /* pll1_divm = /(1 + 0) */ | ||
348 | {OV8858_8BIT, 0x0304, 0x03}, /* pll1_div_mipi = /8 */ | ||
349 | {OV8858_8BIT, 0x030B, 0x02}, /* pll2_pre_div = /2 */ | ||
350 | {OV8858_8BIT, 0x030D, 0x4E}, /* pll2_r_divp = 78 */ | ||
351 | {OV8858_8BIT, 0x030E, 0x00}, /* pll2_r_divs = /1 */ | ||
352 | {OV8858_8BIT, 0x030F, 0x04}, /* pll2_r_divsp = /(1 + 4) */ | ||
353 | /* pll2_pre_div0 = /1, pll2_r_divdac = /(1 + 1) */ | ||
354 | {OV8858_8BIT, 0x0312, 0x01}, | ||
355 | {OV8858_8BIT, 0x031E, 0x0C}, /* pll1_no_lat = 1, mipi_bitsel_man = 0 */ | ||
356 | |||
357 | /* PAD OEN2, VSYNC out enable=0x80, disable=0x00 */ | ||
358 | {OV8858_8BIT, 0x3002, 0x80}, | ||
359 | /* PAD OUT2, VSYNC pulse direction low-to-high = 1 */ | ||
360 | {OV8858_8BIT, 0x3007, 0x01}, | ||
361 | /* PAD SEL2, VSYNC out value = 0 */ | ||
362 | {OV8858_8BIT, 0x300D, 0x00}, | ||
363 | /* PAD OUT2, VSYNC out select = 0 */ | ||
364 | {OV8858_8BIT, 0x3010, 0x00}, | ||
365 | |||
366 | /* Npump clock div = /2, Ppump clock div = /4 */ | ||
367 | {OV8858_8BIT, 0x3015, 0x01}, | ||
368 | /* | ||
369 | * mipi_lane_mode = 1+3, mipi_lvds_sel = 1 = MIPI enable, | ||
370 | * r_phy_pd_mipi_man = 0, lane_dis_option = 0 | ||
371 | */ | ||
372 | {OV8858_8BIT, 0x3018, 0x72}, | ||
373 | /* Clock switch output = normal, pclk_div = /1 */ | ||
374 | {OV8858_8BIT, 0x3020, 0x93}, | ||
375 | /* | ||
376 | * lvds_mode_o = 0, clock lane disable when pd_mipi = 0, | ||
377 | * pd_mipi enable when rst_sync = 1 | ||
378 | */ | ||
379 | {OV8858_8BIT, 0x3022, 0x01}, | ||
380 | {OV8858_8BIT, 0x3031, 0x0A}, /* mipi_bit_sel = 10 */ | ||
381 | {OV8858_8BIT, 0x3034, 0x00}, /* Unknown */ | ||
382 | /* sclk_div = /1, sclk_pre_div = /1, chip debug = 1 */ | ||
383 | {OV8858_8BIT, 0x3106, 0x01}, | ||
384 | |||
385 | {OV8858_8BIT, 0x3305, 0xF1}, /* Unknown */ | ||
386 | {OV8858_8BIT, 0x3307, 0x04}, /* Unknown */ | ||
387 | {OV8858_8BIT, 0x3308, 0x00}, /* Unknown */ | ||
388 | {OV8858_8BIT, 0x3309, 0x28}, /* Unknown */ | ||
389 | {OV8858_8BIT, 0x330A, 0x00}, /* Unknown */ | ||
390 | {OV8858_8BIT, 0x330B, 0x20}, /* Unknown */ | ||
391 | {OV8858_8BIT, 0x330C, 0x00}, /* Unknown */ | ||
392 | {OV8858_8BIT, 0x330D, 0x00}, /* Unknown */ | ||
393 | {OV8858_8BIT, 0x330E, 0x00}, /* Unknown */ | ||
394 | {OV8858_8BIT, 0x330F, 0x40}, /* Unknown */ | ||
395 | |||
396 | {OV8858_8BIT, 0x3500, 0x00}, /* long exposure = 0x9A20 */ | ||
397 | {OV8858_8BIT, 0x3501, 0x9A}, /* long exposure = 0x9A20 */ | ||
398 | {OV8858_8BIT, 0x3502, 0x20}, /* long exposure = 0x9A20 */ | ||
399 | /* | ||
400 | * Digital fraction gain delay option = Delay 1 frame, | ||
401 | * Gain change delay option = Delay 1 frame, | ||
402 | * Gain delay option = Delay 1 frame, | ||
403 | * Gain manual as sensor gain = Input gain as real gain format, | ||
404 | * Exposure delay option (must be 0 = Delay 1 frame, | ||
405 | * Exposure change delay option (must be 0) = Delay 1 frame | ||
406 | */ | ||
407 | {OV8858_8BIT, 0x3503, 0x00}, | ||
408 | {OV8858_8BIT, 0x3505, 0x80}, /* gain conversation option */ | ||
409 | /* | ||
410 | * [10:7] are integer gain, [6:0] are fraction gain. For example: | ||
411 | * 0x80 is 1x gain, 0x100 is 2x gain, 0x1C0 is 3.5x gain | ||
412 | */ | ||
413 | {OV8858_8BIT, 0x3508, 0x02}, /* long gain = 0x0200 */ | ||
414 | {OV8858_8BIT, 0x3509, 0x00}, /* long gain = 0x0200 */ | ||
415 | {OV8858_8BIT, 0x350C, 0x00}, /* short gain = 0x0080 */ | ||
416 | {OV8858_8BIT, 0x350D, 0x80}, /* short gain = 0x0080 */ | ||
417 | {OV8858_8BIT, 0x3510, 0x00}, /* short exposure = 0x000200 */ | ||
418 | {OV8858_8BIT, 0x3511, 0x02}, /* short exposure = 0x000200 */ | ||
419 | {OV8858_8BIT, 0x3512, 0x00}, /* short exposure = 0x000200 */ | ||
420 | |||
421 | {OV8858_8BIT, 0x3600, 0x00}, /* Unknown */ | ||
422 | {OV8858_8BIT, 0x3601, 0x00}, /* Unknown */ | ||
423 | {OV8858_8BIT, 0x3602, 0x00}, /* Unknown */ | ||
424 | {OV8858_8BIT, 0x3603, 0x00}, /* Unknown */ | ||
425 | {OV8858_8BIT, 0x3604, 0x22}, /* Unknown */ | ||
426 | {OV8858_8BIT, 0x3605, 0x30}, /* Unknown */ | ||
427 | {OV8858_8BIT, 0x3606, 0x00}, /* Unknown */ | ||
428 | {OV8858_8BIT, 0x3607, 0x20}, /* Unknown */ | ||
429 | {OV8858_8BIT, 0x3608, 0x11}, /* Unknown */ | ||
430 | {OV8858_8BIT, 0x3609, 0x28}, /* Unknown */ | ||
431 | {OV8858_8BIT, 0x360A, 0x00}, /* Unknown */ | ||
432 | {OV8858_8BIT, 0x360B, 0x06}, /* Unknown */ | ||
433 | {OV8858_8BIT, 0x360C, 0xDC}, /* Unknown */ | ||
434 | {OV8858_8BIT, 0x360D, 0x40}, /* Unknown */ | ||
435 | {OV8858_8BIT, 0x360E, 0x0C}, /* Unknown */ | ||
436 | {OV8858_8BIT, 0x360F, 0x20}, /* Unknown */ | ||
437 | {OV8858_8BIT, 0x3610, 0x07}, /* Unknown */ | ||
438 | {OV8858_8BIT, 0x3611, 0x20}, /* Unknown */ | ||
439 | {OV8858_8BIT, 0x3612, 0x88}, /* Unknown */ | ||
440 | {OV8858_8BIT, 0x3613, 0x80}, /* Unknown */ | ||
441 | {OV8858_8BIT, 0x3614, 0x58}, /* Unknown */ | ||
442 | {OV8858_8BIT, 0x3615, 0x00}, /* Unknown */ | ||
443 | {OV8858_8BIT, 0x3616, 0x4A}, /* Unknown */ | ||
444 | {OV8858_8BIT, 0x3617, 0x90}, /* Unknown */ | ||
445 | {OV8858_8BIT, 0x3618, 0x56}, /* Unknown */ | ||
446 | {OV8858_8BIT, 0x3619, 0x70}, /* Unknown */ | ||
447 | {OV8858_8BIT, 0x361A, 0x99}, /* Unknown */ | ||
448 | {OV8858_8BIT, 0x361B, 0x00}, /* Unknown */ | ||
449 | {OV8858_8BIT, 0x361C, 0x07}, /* Unknown */ | ||
450 | {OV8858_8BIT, 0x361D, 0x00}, /* Unknown */ | ||
451 | {OV8858_8BIT, 0x361E, 0x00}, /* Unknown */ | ||
452 | {OV8858_8BIT, 0x361F, 0x00}, /* Unknown */ | ||
453 | {OV8858_8BIT, 0x3633, 0x0C}, /* Unknown */ | ||
454 | {OV8858_8BIT, 0x3634, 0x0C}, /* Unknown */ | ||
455 | {OV8858_8BIT, 0x3635, 0x0C}, /* Unknown */ | ||
456 | {OV8858_8BIT, 0x3636, 0x0C}, /* Unknown */ | ||
457 | {OV8858_8BIT, 0x3638, 0xFF}, /* Unknown */ | ||
458 | {OV8858_8BIT, 0x3645, 0x13}, /* Unknown */ | ||
459 | {OV8858_8BIT, 0x3646, 0x83}, /* Unknown */ | ||
460 | {OV8858_8BIT, 0x364A, 0x07}, /* Unknown */ | ||
461 | |||
462 | {OV8858_8BIT, 0x3700, 0x30}, /* Unknown */ | ||
463 | {OV8858_8BIT, 0x3701, 0x18}, /* Unknown */ | ||
464 | {OV8858_8BIT, 0x3702, 0x50}, /* Unknown */ | ||
465 | {OV8858_8BIT, 0x3703, 0x32}, /* Unknown */ | ||
466 | {OV8858_8BIT, 0x3704, 0x28}, /* Unknown */ | ||
467 | {OV8858_8BIT, 0x3705, 0x00}, /* Unknown */ | ||
468 | {OV8858_8BIT, 0x3706, 0x6A}, /* Unknown */ | ||
469 | {OV8858_8BIT, 0x3707, 0x08}, /* Unknown */ | ||
470 | {OV8858_8BIT, 0x3708, 0x48}, /* Unknown */ | ||
471 | {OV8858_8BIT, 0x3709, 0x66}, /* Unknown */ | ||
472 | {OV8858_8BIT, 0x370A, 0x01}, /* Unknown */ | ||
473 | {OV8858_8BIT, 0x370B, 0x6A}, /* Unknown */ | ||
474 | {OV8858_8BIT, 0x370C, 0x07}, /* Unknown */ | ||
475 | {OV8858_8BIT, 0x3712, 0x44}, /* Unknown */ | ||
476 | {OV8858_8BIT, 0x3714, 0x24}, /* Unknown */ | ||
477 | {OV8858_8BIT, 0x3718, 0x14}, /* Unknown */ | ||
478 | {OV8858_8BIT, 0x3719, 0x31}, /* Unknown */ | ||
479 | {OV8858_8BIT, 0x371E, 0x31}, /* Unknown */ | ||
480 | {OV8858_8BIT, 0x371F, 0x7F}, /* Unknown */ | ||
481 | {OV8858_8BIT, 0x3720, 0x0A}, /* Unknown */ | ||
482 | {OV8858_8BIT, 0x3721, 0x0A}, /* Unknown */ | ||
483 | {OV8858_8BIT, 0x3724, 0x0C}, /* Unknown */ | ||
484 | {OV8858_8BIT, 0x3725, 0x02}, /* Unknown */ | ||
485 | {OV8858_8BIT, 0x3726, 0x0C}, /* Unknown */ | ||
486 | {OV8858_8BIT, 0x3728, 0x0A}, /* Unknown */ | ||
487 | {OV8858_8BIT, 0x3729, 0x03}, /* Unknown */ | ||
488 | {OV8858_8BIT, 0x372A, 0x06}, /* Unknown */ | ||
489 | {OV8858_8BIT, 0x372B, 0xA6}, /* Unknown */ | ||
490 | {OV8858_8BIT, 0x372C, 0xA6}, /* Unknown */ | ||
491 | {OV8858_8BIT, 0x372D, 0xA6}, /* Unknown */ | ||
492 | {OV8858_8BIT, 0x372E, 0x0C}, /* Unknown */ | ||
493 | {OV8858_8BIT, 0x372F, 0x20}, /* Unknown */ | ||
494 | {OV8858_8BIT, 0x3730, 0x02}, /* Unknown */ | ||
495 | {OV8858_8BIT, 0x3731, 0x0C}, /* Unknown */ | ||
496 | {OV8858_8BIT, 0x3732, 0x28}, /* Unknown */ | ||
497 | {OV8858_8BIT, 0x3733, 0x10}, /* Unknown */ | ||
498 | {OV8858_8BIT, 0x3734, 0x40}, /* Unknown */ | ||
499 | {OV8858_8BIT, 0x3736, 0x30}, /* Unknown */ | ||
500 | {OV8858_8BIT, 0x373A, 0x0A}, /* Unknown */ | ||
501 | {OV8858_8BIT, 0x373B, 0x0B}, /* Unknown */ | ||
502 | {OV8858_8BIT, 0x373C, 0x14}, /* Unknown */ | ||
503 | {OV8858_8BIT, 0x373E, 0x06}, /* Unknown */ | ||
504 | {OV8858_8BIT, 0x3755, 0x10}, /* Unknown */ | ||
505 | {OV8858_8BIT, 0x3758, 0x00}, /* Unknown */ | ||
506 | {OV8858_8BIT, 0x3759, 0x4C}, /* Unknown */ | ||
507 | {OV8858_8BIT, 0x375A, 0x0C}, /* Unknown */ | ||
508 | {OV8858_8BIT, 0x375B, 0x26}, /* Unknown */ | ||
509 | {OV8858_8BIT, 0x375C, 0x20}, /* Unknown */ | ||
510 | {OV8858_8BIT, 0x375D, 0x04}, /* Unknown */ | ||
511 | {OV8858_8BIT, 0x375E, 0x00}, /* Unknown */ | ||
512 | {OV8858_8BIT, 0x375F, 0x28}, /* Unknown */ | ||
513 | {OV8858_8BIT, 0x3760, 0x00}, /* Unknown */ | ||
514 | {OV8858_8BIT, 0x3761, 0x00}, /* Unknown */ | ||
515 | {OV8858_8BIT, 0x3762, 0x00}, /* Unknown */ | ||
516 | {OV8858_8BIT, 0x3763, 0x00}, /* Unknown */ | ||
517 | {OV8858_8BIT, 0x3766, 0xFF}, /* Unknown */ | ||
518 | {OV8858_8BIT, 0x3768, 0x22}, /* Unknown */ | ||
519 | {OV8858_8BIT, 0x3769, 0x44}, /* Unknown */ | ||
520 | {OV8858_8BIT, 0x376A, 0x44}, /* Unknown */ | ||
521 | {OV8858_8BIT, 0x376B, 0x00}, /* Unknown */ | ||
522 | {OV8858_8BIT, 0x376F, 0x01}, /* Unknown */ | ||
523 | {OV8858_8BIT, 0x3772, 0x46}, /* Unknown */ | ||
524 | {OV8858_8BIT, 0x3773, 0x04}, /* Unknown */ | ||
525 | {OV8858_8BIT, 0x3774, 0x2C}, /* Unknown */ | ||
526 | {OV8858_8BIT, 0x3775, 0x13}, /* Unknown */ | ||
527 | {OV8858_8BIT, 0x3776, 0x08}, /* Unknown */ | ||
528 | {OV8858_8BIT, 0x3777, 0x00}, /* Unknown */ | ||
529 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
530 | {OV8858_8BIT, 0x37A0, 0x88}, /* Unknown */ | ||
531 | {OV8858_8BIT, 0x37A1, 0x7A}, /* Unknown */ | ||
532 | {OV8858_8BIT, 0x37A2, 0x7A}, /* Unknown */ | ||
533 | {OV8858_8BIT, 0x37A3, 0x00}, /* Unknown */ | ||
534 | {OV8858_8BIT, 0x37A4, 0x00}, /* Unknown */ | ||
535 | {OV8858_8BIT, 0x37A5, 0x00}, /* Unknown */ | ||
536 | {OV8858_8BIT, 0x37A6, 0x00}, /* Unknown */ | ||
537 | {OV8858_8BIT, 0x37A7, 0x88}, /* Unknown */ | ||
538 | {OV8858_8BIT, 0x37A8, 0x98}, /* Unknown */ | ||
539 | {OV8858_8BIT, 0x37A9, 0x98}, /* Unknown */ | ||
540 | {OV8858_8BIT, 0x37AA, 0x88}, /* Unknown */ | ||
541 | {OV8858_8BIT, 0x37AB, 0x5C}, /* Unknown */ | ||
542 | {OV8858_8BIT, 0x37AC, 0x5C}, /* Unknown */ | ||
543 | {OV8858_8BIT, 0x37AD, 0x55}, /* Unknown */ | ||
544 | {OV8858_8BIT, 0x37AE, 0x19}, /* Unknown */ | ||
545 | {OV8858_8BIT, 0x37AF, 0x19}, /* Unknown */ | ||
546 | {OV8858_8BIT, 0x37B0, 0x00}, /* Unknown */ | ||
547 | {OV8858_8BIT, 0x37B1, 0x00}, /* Unknown */ | ||
548 | {OV8858_8BIT, 0x37B2, 0x00}, /* Unknown */ | ||
549 | {OV8858_8BIT, 0x37B3, 0x84}, /* Unknown */ | ||
550 | {OV8858_8BIT, 0x37B4, 0x84}, /* Unknown */ | ||
551 | {OV8858_8BIT, 0x37B5, 0x66}, /* Unknown */ | ||
552 | {OV8858_8BIT, 0x37B6, 0x00}, /* Unknown */ | ||
553 | {OV8858_8BIT, 0x37B7, 0x00}, /* Unknown */ | ||
554 | {OV8858_8BIT, 0x37B8, 0x00}, /* Unknown */ | ||
555 | {OV8858_8BIT, 0x37B9, 0xFF}, /* Unknown */ | ||
556 | |||
557 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
558 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low */ | ||
559 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
560 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
561 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
562 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
563 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
564 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
565 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high */ | ||
566 | {OV8858_8BIT, 0x3809, 0xC0}, /* h_output_size low */ | ||
567 | {OV8858_8BIT, 0x380A, 0x09}, /* v_output_size high */ | ||
568 | {OV8858_8BIT, 0x380B, 0x90}, /* v_output_size low */ | ||
569 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
570 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
571 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
572 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
573 | {OV8858_8BIT, 0x3810, 0x00}, /* h_win offset high */ | ||
574 | {OV8858_8BIT, 0x3811, 0x04}, /* h_win offset low */ | ||
575 | {OV8858_8BIT, 0x3812, 0x00}, /* v_win offset high */ | ||
576 | {OV8858_8BIT, 0x3813, 0x02}, /* v_win offset low */ | ||
577 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
578 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
579 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
580 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
581 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
582 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
583 | |||
584 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
585 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
586 | {OV8858_8BIT, 0x3837, 0x18}, /* Unknown */ | ||
587 | {OV8858_8BIT, 0x3841, 0xFF}, /* AUTO_SIZE_CTRL */ | ||
588 | {OV8858_8BIT, 0x3846, 0x48}, /* Unknown */ | ||
589 | |||
590 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
591 | {OV8858_8BIT, 0x3D8C, 0x73}, /* OTP_SETTING_STT_ADDRESS */ | ||
592 | {OV8858_8BIT, 0x3D8D, 0xDE}, /* OTP_SETTING_STT_ADDRESS */ | ||
593 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
594 | {OV8858_8BIT, 0x3F0A, 0x80}, /* PSRAM control register */ | ||
595 | |||
596 | {OV8858_8BIT, 0x4000, 0xF1}, /* BLC CTRL00 = default */ | ||
597 | {OV8858_8BIT, 0x4001, 0x00}, /* BLC CTRL01 */ | ||
598 | {OV8858_8BIT, 0x4002, 0x27}, /* BLC offset = 0x27 */ | ||
599 | {OV8858_8BIT, 0x4005, 0x10}, /* BLC target = 0x0010 */ | ||
600 | {OV8858_8BIT, 0x4009, 0x81}, /* BLC CTRL09 */ | ||
601 | {OV8858_8BIT, 0x400B, 0x0C}, /* BLC CTRL0B = default */ | ||
602 | {OV8858_8BIT, 0x400A, 0x01}, | ||
603 | {OV8858_8BIT, 0x4011, 0x20}, /* BLC CTRL11 = 0x20 */ | ||
604 | {OV8858_8BIT, 0x401B, 0x00}, /* Zero line R coeff. = 0x0000 */ | ||
605 | {OV8858_8BIT, 0x401D, 0x00}, /* Zero line T coeff. = 0x0000 */ | ||
606 | {OV8858_8BIT, 0x401F, 0x00}, /* BLC CTRL1F */ | ||
607 | {OV8858_8BIT, 0x4020, 0x00}, /* Anchor left start = 0x0004 */ | ||
608 | {OV8858_8BIT, 0x4021, 0x04}, /* Anchor left start = 0x0004 */ | ||
609 | {OV8858_8BIT, 0x4022, 0x0C}, /* Anchor left end = 0x0C60 */ | ||
610 | {OV8858_8BIT, 0x4023, 0x60}, /* Anchor left end = 0x0C60 */ | ||
611 | {OV8858_8BIT, 0x4024, 0x0F}, /* Anchor right start = 0x0F36 */ | ||
612 | {OV8858_8BIT, 0x4025, 0x36}, /* Anchor right start = 0x0F36 */ | ||
613 | {OV8858_8BIT, 0x4026, 0x0F}, /* Anchor right end = 0x0F37 */ | ||
614 | {OV8858_8BIT, 0x4027, 0x37}, /* Anchor right end = 0x0F37 */ | ||
615 | {OV8858_8BIT, 0x4028, 0x00}, /* Top zero line start = 0 */ | ||
616 | {OV8858_8BIT, 0x4029, 0x04}, /* Top zero line number = 4 */ | ||
617 | {OV8858_8BIT, 0x402A, 0x04}, /* Top black line start = 4 */ | ||
618 | {OV8858_8BIT, 0x402B, 0x08}, /* Top black line number = 8 */ | ||
619 | {OV8858_8BIT, 0x402C, 0x00}, /* Bottom zero start line = 0 */ | ||
620 | {OV8858_8BIT, 0x402D, 0x02}, /* Bottom zero line number = 2 */ | ||
621 | {OV8858_8BIT, 0x402E, 0x04}, /* Bottom black line start = 4 */ | ||
622 | {OV8858_8BIT, 0x402F, 0x08}, /* Bottom black line number = 8 */ | ||
623 | |||
624 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
625 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
626 | {OV8858_8BIT, 0x4300, 0xFF}, /* clip_max[11:4] = 0xFFF */ | ||
627 | {OV8858_8BIT, 0x4301, 0x00}, /* clip_min[11:4] = 0 */ | ||
628 | {OV8858_8BIT, 0x4302, 0x0F}, /* clip_min/max[3:0] */ | ||
629 | {OV8858_8BIT, 0x4307, 0x01}, /* Unknown */ | ||
630 | {OV8858_8BIT, 0x4316, 0x00}, /* CTRL16 = default */ | ||
631 | {OV8858_8BIT, 0x4503, 0x18}, /* Unknown */ | ||
632 | {OV8858_8BIT, 0x4500, 0x38}, /* Unknown */ | ||
633 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
634 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
635 | /* wkup_dly = Mark1 wakeup delay/2^10 = 0x25 */ | ||
636 | {OV8858_8BIT, 0x4808, 0x25}, | ||
637 | {OV8858_8BIT, 0x4816, 0x52}, /* Embedded data type*/ | ||
638 | {OV8858_8BIT, 0x481F, 0x32}, /* clk_prepare_min = 0x32 */ | ||
639 | {OV8858_8BIT, 0x4825, 0x3A}, /* lpx_p_min = 0x3A */ | ||
640 | {OV8858_8BIT, 0x4826, 0x40}, /* hs_prepare_min = 0x40 */ | ||
641 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
642 | {OV8858_8BIT, 0x4850, 0x10}, /* LANE SEL01 */ | ||
643 | {OV8858_8BIT, 0x4851, 0x32}, /* LANE SEL02 */ | ||
644 | |||
645 | {OV8858_8BIT, 0x4B00, 0x2A}, /* Unknown */ | ||
646 | {OV8858_8BIT, 0x4B0D, 0x00}, /* Unknown */ | ||
647 | {OV8858_8BIT, 0x4D00, 0x04}, /* TPM_CTRL_REG */ | ||
648 | {OV8858_8BIT, 0x4D01, 0x18}, /* TPM_CTRL_REG */ | ||
649 | {OV8858_8BIT, 0x4D02, 0xC3}, /* TPM_CTRL_REG */ | ||
650 | {OV8858_8BIT, 0x4D03, 0xFF}, /* TPM_CTRL_REG */ | ||
651 | {OV8858_8BIT, 0x4D04, 0xFF}, /* TPM_CTRL_REG */ | ||
652 | {OV8858_8BIT, 0x4D05, 0xFF}, /* TPM_CTRL_REG */ | ||
653 | |||
654 | /* | ||
655 | * Lens correction (LENC) function enable = 0 | ||
656 | * Slave sensor AWB Gain function enable = 1 | ||
657 | * Slave sensor AWB Statistics function enable = 1 | ||
658 | * Master sensor AWB Gain function enable = 1 | ||
659 | * Master sensor AWB Statistics function enable = 1 | ||
660 | * Black DPC function enable = 1 | ||
661 | * White DPC function enable =1 | ||
662 | */ | ||
663 | {OV8858_8BIT, 0x5000, 0x7E}, | ||
664 | {OV8858_8BIT, 0x5001, 0x01}, /* BLC function enable = 1 */ | ||
665 | /* | ||
666 | * Horizontal scale function enable = 0 | ||
667 | * WBMATCH bypass mode = Select slave sensor's gain | ||
668 | * WBMATCH function enable = 0 | ||
669 | * Master MWB gain support RGBC = 0 | ||
670 | * OTP_DPC function enable = 1 | ||
671 | * Manual mode of VarioPixel function enable = 0 | ||
672 | * Manual enable of VarioPixel function enable = 0 | ||
673 | * Use VSYNC to latch ISP modules's function enable signals = 0 | ||
674 | */ | ||
675 | {OV8858_8BIT, 0x5002, 0x08}, | ||
676 | /* | ||
677 | * Bypass all ISP modules after BLC module = 0 | ||
678 | * DPC_DBC buffer control enable = 1 | ||
679 | * WBMATCH VSYNC selection = Select master sensor's VSYNC fall | ||
680 | * Select master AWB gain to embed line = AWB gain before manual mode | ||
681 | * Enable BLC's input flip_i signal = 0 | ||
682 | */ | ||
683 | {OV8858_8BIT, 0x5003, 0x20}, | ||
684 | {OV8858_8BIT, 0x5041, 0x1D}, /* ISP CTRL41 - embedded data=on */ | ||
685 | {OV8858_8BIT, 0x5046, 0x12}, /* ISP CTRL46 = default */ | ||
686 | /* | ||
687 | * Tail enable = 1 | ||
688 | * Saturate cross cluster enable = 1 | ||
689 | * Remove cross cluster enable = 1 | ||
690 | * Enable to remove connected defect pixels in same channel = 1 | ||
691 | * Enable to remove connected defect pixels in different channel = 1 | ||
692 | * Smooth enable, use average G for recovery = 1 | ||
693 | * Black/white sensor mode enable = 0 | ||
694 | * Manual mode enable = 0 | ||
695 | */ | ||
696 | {OV8858_8BIT, 0x5780, 0xFC}, | ||
697 | {OV8858_8BIT, 0x5784, 0x0C}, /* DPC CTRL04 */ | ||
698 | {OV8858_8BIT, 0x5787, 0x40}, /* DPC CTRL07 */ | ||
699 | {OV8858_8BIT, 0x5788, 0x08}, /* DPC CTRL08 */ | ||
700 | {OV8858_8BIT, 0x578A, 0x02}, /* DPC CTRL0A */ | ||
701 | {OV8858_8BIT, 0x578B, 0x01}, /* DPC CTRL0B */ | ||
702 | {OV8858_8BIT, 0x578C, 0x01}, /* DPC CTRL0C */ | ||
703 | {OV8858_8BIT, 0x578E, 0x02}, /* DPC CTRL0E */ | ||
704 | {OV8858_8BIT, 0x578F, 0x01}, /* DPC CTRL0F */ | ||
705 | {OV8858_8BIT, 0x5790, 0x01}, /* DPC CTRL10 */ | ||
706 | {OV8858_8BIT, 0x5901, 0x00}, /* VAP CTRL01 = default */ | ||
707 | /* WINC CTRL08 = embedded data in 1st line*/ | ||
708 | {OV8858_8BIT, 0x5A08, 0x00}, | ||
709 | {OV8858_8BIT, 0x5B00, 0x02}, /* OTP CTRL00 */ | ||
710 | {OV8858_8BIT, 0x5B01, 0x10}, /* OTP CTRL01 */ | ||
711 | {OV8858_8BIT, 0x5B02, 0x03}, /* OTP CTRL02 */ | ||
712 | {OV8858_8BIT, 0x5B03, 0xCF}, /* OTP CTRL03 */ | ||
713 | {OV8858_8BIT, 0x5B05, 0x6C}, /* OTP CTRL05 = default */ | ||
714 | {OV8858_8BIT, 0x5E00, 0x00}, /* PRE CTRL00 = default */ | ||
715 | {OV8858_8BIT, 0x5E01, 0x41}, /* PRE_CTRL01 = default */ | ||
716 | |||
717 | {OV8858_TOK_TERM, 0, 0} | ||
718 | }; | ||
719 | |||
720 | /*****************************STILL********************************/ | ||
721 | |||
722 | static const struct ov8858_reg ov8858_8M[] = { | ||
723 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
724 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
725 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
726 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low 12 */ | ||
727 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
728 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
729 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
730 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low 3283 */ | ||
731 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
732 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
733 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high 3280 x 2464 */ | ||
734 | {OV8858_8BIT, 0x3809, 0xD0}, /* h_output_size low */ | ||
735 | {OV8858_8BIT, 0x380A, 0x09}, /* v_output_size high */ | ||
736 | {OV8858_8BIT, 0x380B, 0xa0}, /* v_output_size low */ | ||
737 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
738 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
739 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
740 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
741 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
742 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
743 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
744 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
745 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
746 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
747 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
748 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
749 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
750 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
751 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
752 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
753 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
754 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
755 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
756 | {OV8858_TOK_TERM, 0, 0} | ||
757 | }; | ||
758 | |||
759 | static const struct ov8858_reg ov8858_3276x1848[] = { | ||
760 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
761 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
762 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
763 | {OV8858_8BIT, 0x3801, 0x10}, /* h_crop_start low 0c->10*/ | ||
764 | {OV8858_8BIT, 0x3802, 0x01}, /* v_crop_start high */ | ||
765 | {OV8858_8BIT, 0x3803, 0x42}, /* v_crop_start low 3e->42*/ | ||
766 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
767 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
768 | {OV8858_8BIT, 0x3806, 0x08}, /* v_crop_end high */ | ||
769 | {OV8858_8BIT, 0x3807, 0x71}, /* v_crop_end low */ | ||
770 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high 3276 x 1848 */ | ||
771 | {OV8858_8BIT, 0x3809, 0xCC}, /* h_output_size low d0->cc*/ | ||
772 | {OV8858_8BIT, 0x380A, 0x07}, /* v_output_size high */ | ||
773 | {OV8858_8BIT, 0x380B, 0x38}, /* v_output_size low 3c->38*/ | ||
774 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
775 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
776 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
777 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
778 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
779 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
780 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
781 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
782 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
783 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
784 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
785 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
786 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
787 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
788 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
789 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
790 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
791 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
792 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
793 | {OV8858_TOK_TERM, 0, 0} | ||
794 | }; | ||
795 | |||
796 | static const struct ov8858_reg ov8858_6M[] = { | ||
797 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
798 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
799 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
800 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low */ | ||
801 | {OV8858_8BIT, 0x3802, 0x01}, /* v_crop_start high */ | ||
802 | {OV8858_8BIT, 0x3803, 0x3E}, /* v_crop_start low */ | ||
803 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
804 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
805 | {OV8858_8BIT, 0x3806, 0x08}, /* v_crop_end high */ | ||
806 | {OV8858_8BIT, 0x3807, 0x71}, /* v_crop_end low */ | ||
807 | {OV8858_8BIT, 0x3808, 0x0C}, /* h_output_size high 3280 x 1852 */ | ||
808 | {OV8858_8BIT, 0x3809, 0xD0}, /* h_output_size low */ | ||
809 | {OV8858_8BIT, 0x380A, 0x07}, /* v_output_size high */ | ||
810 | {OV8858_8BIT, 0x380B, 0x3C}, /* v_output_size low */ | ||
811 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
812 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
813 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
814 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
815 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
816 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
817 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
818 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
819 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
820 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
821 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
822 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
823 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
824 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
825 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
826 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
827 | {OV8858_8BIT, 0x4600, 0x01}, /* Unknown */ | ||
828 | {OV8858_8BIT, 0x4601, 0x97}, /* Unknown */ | ||
829 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
830 | {OV8858_TOK_TERM, 0, 0} | ||
831 | }; | ||
832 | |||
833 | static const struct ov8858_reg ov8858_1080P_60[] = { | ||
834 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
835 | {OV8858_8BIT, 0x3778, 0x17}, /* Unknown */ | ||
836 | {OV8858_8BIT, 0x3800, 0x02}, /* h_crop_start high */ | ||
837 | {OV8858_8BIT, 0x3801, 0x26}, /* h_crop_start low */ | ||
838 | {OV8858_8BIT, 0x3802, 0x02}, /* v_crop_start high */ | ||
839 | {OV8858_8BIT, 0x3803, 0x8C}, /* v_crop_start low */ | ||
840 | {OV8858_8BIT, 0x3804, 0x0A}, /* h_crop_end high */ | ||
841 | {OV8858_8BIT, 0x3805, 0x9D}, /* h_crop_end low */ | ||
842 | {OV8858_8BIT, 0x3806, 0x07}, /* v_crop_end high */ | ||
843 | {OV8858_8BIT, 0x3807, 0x0A}, /* v_crop_end low */ | ||
844 | {OV8858_8BIT, 0x3808, 0x07}, /* h_output_size high*/ | ||
845 | {OV8858_8BIT, 0x3809, 0x90}, /* h_output_size low */ | ||
846 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
847 | {OV8858_8BIT, 0x380B, 0x48}, /* v_output_size low */ | ||
848 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
849 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
850 | {OV8858_8BIT, 0x380E, 0x04}, /* vertical timing size high */ | ||
851 | {OV8858_8BIT, 0x380F, 0xEC}, /* vertical timing size low */ | ||
852 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
853 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
854 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
855 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
856 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
857 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
858 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
859 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
860 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
861 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
862 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
863 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
864 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
865 | {OV8858_8BIT, 0x4601, 0xef}, /* Unknown */ | ||
866 | {OV8858_8BIT, 0x4837, 0x16}, /* pclk_period = 0x16 */ | ||
867 | {OV8858_TOK_TERM, 0, 0} | ||
868 | }; | ||
869 | |||
870 | static const struct ov8858_reg ov8858_1080P_30[] = { | ||
871 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
872 | {OV8858_8BIT, 0x3778, 0x17}, /* Unknown */ | ||
873 | {OV8858_8BIT, 0x3800, 0x02}, /* h_crop_start high */ | ||
874 | {OV8858_8BIT, 0x3801, 0x26}, /* h_crop_start low */ | ||
875 | {OV8858_8BIT, 0x3802, 0x02}, /* v_crop_start high */ | ||
876 | {OV8858_8BIT, 0x3803, 0x8C}, /* v_crop_start low */ | ||
877 | {OV8858_8BIT, 0x3804, 0x0A}, /* h_crop_end high */ | ||
878 | {OV8858_8BIT, 0x3805, 0x9D}, /* h_crop_end low */ | ||
879 | {OV8858_8BIT, 0x3806, 0x07}, /* v_crop_end high */ | ||
880 | {OV8858_8BIT, 0x3807, 0x0A}, /* v_crop_end low */ | ||
881 | {OV8858_8BIT, 0x3808, 0x07}, /* h_output_size high*/ | ||
882 | {OV8858_8BIT, 0x3809, 0x90}, /* h_output_size low */ | ||
883 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
884 | {OV8858_8BIT, 0x380B, 0x48}, /* v_output_size low */ | ||
885 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
886 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
887 | {OV8858_8BIT, 0x380E, 0x0A}, /* vertical timing size high */ | ||
888 | {OV8858_8BIT, 0x380F, 0x0D}, /* vertical timing size low */ | ||
889 | {OV8858_8BIT, 0x3814, 0x01}, /* h_odd_inc */ | ||
890 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
891 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
892 | {OV8858_8BIT, 0x3821, 0x40}, /* format2 */ | ||
893 | {OV8858_8BIT, 0x382A, 0x01}, /* v_odd_inc */ | ||
894 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
895 | {OV8858_8BIT, 0x3830, 0x06}, /* Unknown */ | ||
896 | {OV8858_8BIT, 0x3836, 0x01}, /* Unknown */ | ||
897 | {OV8858_8BIT, 0x3D85, 0x14}, /* OTP_REG85 */ | ||
898 | {OV8858_8BIT, 0x3F08, 0x10}, /* PSRAM control register */ | ||
899 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
900 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
901 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
902 | {OV8858_8BIT, 0x4601, 0xef}, /* Unknown */ | ||
903 | {OV8858_8BIT, 0x4837, 0x16}, /* pclk_period = 0x16 */ | ||
904 | {OV8858_TOK_TERM, 0, 0} | ||
905 | }; | ||
906 | |||
907 | static const struct ov8858_reg ov8858_1640x1232[] = { | ||
908 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
909 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
910 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
911 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low 12 */ | ||
912 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
913 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
914 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high 3283 */ | ||
915 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
916 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
917 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
918 | {OV8858_8BIT, 0x3808, 0x06}, /* h_output_size high 1640 x 1232 */ | ||
919 | {OV8858_8BIT, 0x3809, 0x68}, /* h_output_size low */ | ||
920 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
921 | {OV8858_8BIT, 0x380B, 0xD0}, /* v_output_size low */ | ||
922 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
923 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
924 | {OV8858_8BIT, 0x380E, 0x09}, /* vertical timing size high */ | ||
925 | {OV8858_8BIT, 0x380F, 0xAA}, /* vertical timing size low */ | ||
926 | {OV8858_8BIT, 0x3814, 0x03}, /* h_odd_inc */ | ||
927 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
928 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
929 | {OV8858_8BIT, 0x3821, 0x67}, /* format2 */ | ||
930 | {OV8858_8BIT, 0x382A, 0x03}, /* v_odd_inc */ | ||
931 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
932 | {OV8858_8BIT, 0x3830, 0x08}, /* Unknown */ | ||
933 | {OV8858_8BIT, 0x3836, 0x02}, /* Unknown */ | ||
934 | {OV8858_8BIT, 0x3D85, 0x16}, /* OTP_REG85 */ | ||
935 | {OV8858_8BIT, 0x3F08, 0x08}, /* PSRAM control register */ | ||
936 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
937 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
938 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
939 | {OV8858_8BIT, 0x4601, 0xCB}, /* Unknown */ | ||
940 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
941 | {OV8858_TOK_TERM, 0, 0} | ||
942 | }; | ||
943 | |||
944 | static const struct ov8858_reg ov8858_1640x1096[] = { | ||
945 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
946 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
947 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
948 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low 12 */ | ||
949 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
950 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
951 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high 3283 */ | ||
952 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
953 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
954 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
955 | {OV8858_8BIT, 0x3808, 0x06}, /* h_output_size high 1640 x 1096 */ | ||
956 | {OV8858_8BIT, 0x3809, 0x68}, /* h_output_size low */ | ||
957 | {OV8858_8BIT, 0x380A, 0x04}, /* v_output_size high */ | ||
958 | {OV8858_8BIT, 0x380B, 0x48}, /* v_output_size low */ | ||
959 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
960 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
961 | {OV8858_8BIT, 0x380E, 0x09}, /* vertical timing size high */ | ||
962 | {OV8858_8BIT, 0x380F, 0xAA}, /* vertical timing size low */ | ||
963 | {OV8858_8BIT, 0x3814, 0x03}, /* h_odd_inc */ | ||
964 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
965 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
966 | {OV8858_8BIT, 0x3821, 0x67}, /* format2 */ | ||
967 | {OV8858_8BIT, 0x382A, 0x03}, /* v_odd_inc */ | ||
968 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
969 | {OV8858_8BIT, 0x3830, 0x08}, /* Unknown */ | ||
970 | {OV8858_8BIT, 0x3836, 0x02}, /* Unknown */ | ||
971 | {OV8858_8BIT, 0x3D85, 0x16}, /* OTP_REG85 */ | ||
972 | {OV8858_8BIT, 0x3F08, 0x08}, /* PSRAM control register */ | ||
973 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
974 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
975 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
976 | {OV8858_8BIT, 0x4601, 0xCB}, /* Unknown */ | ||
977 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
978 | {OV8858_TOK_TERM, 0, 0} | ||
979 | }; | ||
980 | |||
981 | |||
982 | static const struct ov8858_reg ov8858_1640x926[] = { | ||
983 | {OV8858_8BIT, 0x0100, 0x00}, /* software_standby */ | ||
984 | {OV8858_8BIT, 0x3778, 0x16}, /* Unknown */ | ||
985 | {OV8858_8BIT, 0x3800, 0x00}, /* h_crop_start high */ | ||
986 | {OV8858_8BIT, 0x3801, 0x0C}, /* h_crop_start low */ | ||
987 | {OV8858_8BIT, 0x3802, 0x00}, /* v_crop_start high */ | ||
988 | {OV8858_8BIT, 0x3803, 0x0C}, /* v_crop_start low */ | ||
989 | {OV8858_8BIT, 0x3804, 0x0C}, /* h_crop_end high */ | ||
990 | {OV8858_8BIT, 0x3805, 0xD3}, /* h_crop_end low */ | ||
991 | {OV8858_8BIT, 0x3806, 0x09}, /* v_crop_end high */ | ||
992 | {OV8858_8BIT, 0x3807, 0xA3}, /* v_crop_end low */ | ||
993 | {OV8858_8BIT, 0x3808, 0x06}, /* h_output_size high 1640 x 926 */ | ||
994 | {OV8858_8BIT, 0x3809, 0x68}, /* h_output_size low */ | ||
995 | {OV8858_8BIT, 0x380A, 0x03}, /* v_output_size high */ | ||
996 | {OV8858_8BIT, 0x380B, 0x9E}, /* v_output_size low */ | ||
997 | {OV8858_8BIT, 0x380C, 0x07}, /* horizontal timing size high */ | ||
998 | {OV8858_8BIT, 0x380D, 0x94}, /* horizontal timing size low */ | ||
999 | {OV8858_8BIT, 0x380E, 0x09}, /* vertical timing size high */ | ||
1000 | {OV8858_8BIT, 0x380F, 0xAA}, /* vertical timing size low */ | ||
1001 | {OV8858_8BIT, 0x3814, 0x03}, /* h_odd_inc */ | ||
1002 | {OV8858_8BIT, 0x3815, 0x01}, /* h_even_inc */ | ||
1003 | {OV8858_8BIT, 0x3820, 0x00}, /* format1 */ | ||
1004 | {OV8858_8BIT, 0x3821, 0x67}, /* format2 */ | ||
1005 | {OV8858_8BIT, 0x382A, 0x03}, /* v_odd_inc */ | ||
1006 | {OV8858_8BIT, 0x382B, 0x01}, /* v_even_inc */ | ||
1007 | {OV8858_8BIT, 0x3830, 0x08}, /* Unknown */ | ||
1008 | {OV8858_8BIT, 0x3836, 0x02}, /* Unknown */ | ||
1009 | {OV8858_8BIT, 0x3D85, 0x16}, /* OTP_REG85 */ | ||
1010 | {OV8858_8BIT, 0x3F08, 0x08}, /* PSRAM control register */ | ||
1011 | {OV8858_8BIT, 0x4034, 0x3F}, /* Unknown */ | ||
1012 | {OV8858_8BIT, 0x403D, 0x04}, /* BLC CTRL3D */ | ||
1013 | {OV8858_8BIT, 0x4600, 0x00}, /* Unknown */ | ||
1014 | {OV8858_8BIT, 0x4601, 0xCB}, /* Unknown */ | ||
1015 | {OV8858_8BIT, 0x4837, 0x14}, /* pclk_period = 0x14 */ | ||
1016 | {OV8858_TOK_TERM, 0, 0} | ||
1017 | }; | ||
1018 | |||
1019 | static struct ov8858_resolution ov8858_res_preview[] = { | ||
1020 | { | ||
1021 | .desc = "ov8858_1640x926_PREVIEW", | ||
1022 | .width = 1640, | ||
1023 | .height = 926, | ||
1024 | .used = 0, | ||
1025 | .regs = ov8858_1640x926, | ||
1026 | .bin_factor_x = 0, | ||
1027 | .bin_factor_y = 0, | ||
1028 | .skip_frames = 0, | ||
1029 | .fps_options = { | ||
1030 | { | ||
1031 | .fps = 30, | ||
1032 | .pixels_per_line = 3880, | ||
1033 | .lines_per_frame = 2573, | ||
1034 | }, | ||
1035 | { | ||
1036 | } | ||
1037 | }, | ||
1038 | }, | ||
1039 | { | ||
1040 | .desc = "ov8858_1640x1232_PREVIEW", | ||
1041 | .width = 1640, | ||
1042 | .height = 1232, | ||
1043 | .used = 0, | ||
1044 | .regs = ov8858_1640x1232, | ||
1045 | .bin_factor_x = 0, | ||
1046 | .bin_factor_y = 0, | ||
1047 | .skip_frames = 0, | ||
1048 | .fps_options = { | ||
1049 | { | ||
1050 | .fps = 30, | ||
1051 | .pixels_per_line = 3880, | ||
1052 | .lines_per_frame = 2573, | ||
1053 | }, | ||
1054 | { | ||
1055 | } | ||
1056 | }, | ||
1057 | }, | ||
1058 | { | ||
1059 | .desc = "ov8858_1936x1096_PREVIEW", | ||
1060 | .width = 1936, | ||
1061 | .height = 1096, | ||
1062 | .used = 0, | ||
1063 | .regs = ov8858_1080P_30, | ||
1064 | .bin_factor_x = 0, | ||
1065 | .bin_factor_y = 0, | ||
1066 | .skip_frames = 0, | ||
1067 | .fps_options = { | ||
1068 | { | ||
1069 | .fps = 30, | ||
1070 | .pixels_per_line = 3880, | ||
1071 | .lines_per_frame = 2573, | ||
1072 | }, | ||
1073 | { | ||
1074 | } | ||
1075 | }, | ||
1076 | }, | ||
1077 | { | ||
1078 | .desc = "ov8858_3276x1848_PREVIEW", | ||
1079 | .width = 3276, | ||
1080 | .height = 1848, | ||
1081 | .used = 0, | ||
1082 | .regs = ov8858_3276x1848, | ||
1083 | .bin_factor_x = 0, | ||
1084 | .bin_factor_y = 0, | ||
1085 | .skip_frames = 0, | ||
1086 | .fps_options = { | ||
1087 | { | ||
1088 | .fps = 30, | ||
1089 | .pixels_per_line = 3880, | ||
1090 | .lines_per_frame = 2573, | ||
1091 | }, | ||
1092 | { | ||
1093 | } | ||
1094 | }, | ||
1095 | }, | ||
1096 | { | ||
1097 | .desc = "ov8858_8M_PREVIEW", | ||
1098 | .width = 3280, | ||
1099 | .height = 2464, | ||
1100 | .used = 0, | ||
1101 | .regs = ov8858_8M, | ||
1102 | .bin_factor_x = 0, | ||
1103 | .bin_factor_y = 0, | ||
1104 | .skip_frames = 0, | ||
1105 | .fps_options = { | ||
1106 | { | ||
1107 | .fps = 30, | ||
1108 | .pixels_per_line = 3880, | ||
1109 | .lines_per_frame = 2573, | ||
1110 | }, | ||
1111 | { | ||
1112 | } | ||
1113 | }, | ||
1114 | }, | ||
1115 | }; | ||
1116 | |||
1117 | static struct ov8858_resolution ov8858_res_still[] = { | ||
1118 | { | ||
1119 | .desc = "ov8858_1640x1232_STILL", | ||
1120 | .width = 1640, | ||
1121 | .height = 1232, | ||
1122 | .used = 0, | ||
1123 | .regs = ov8858_1640x1232, | ||
1124 | .bin_factor_x = 0, | ||
1125 | .bin_factor_y = 0, | ||
1126 | .skip_frames = 0, | ||
1127 | .fps_options = { | ||
1128 | { | ||
1129 | .fps = 30, | ||
1130 | .pixels_per_line = 3880, | ||
1131 | .lines_per_frame = 2573, | ||
1132 | }, | ||
1133 | { | ||
1134 | } | ||
1135 | }, | ||
1136 | }, | ||
1137 | { | ||
1138 | .desc = "ov8858_1640x926_STILL", | ||
1139 | .width = 1640, | ||
1140 | .height = 926, | ||
1141 | .used = 0, | ||
1142 | .regs = ov8858_1640x926, | ||
1143 | .bin_factor_x = 0, | ||
1144 | .bin_factor_y = 0, | ||
1145 | .skip_frames = 1, | ||
1146 | .fps_options = { | ||
1147 | { | ||
1148 | .fps = 30, | ||
1149 | .pixels_per_line = 3880, | ||
1150 | .lines_per_frame = 2573, | ||
1151 | }, | ||
1152 | { | ||
1153 | } | ||
1154 | }, | ||
1155 | }, | ||
1156 | { | ||
1157 | .desc = "ov8858_3276X1848_STILL", | ||
1158 | .width = 3276, | ||
1159 | .height = 1848, | ||
1160 | .used = 0, | ||
1161 | .regs = ov8858_3276x1848, | ||
1162 | .bin_factor_x = 0, | ||
1163 | .bin_factor_y = 0, | ||
1164 | .skip_frames = 1, | ||
1165 | .fps_options = { | ||
1166 | { | ||
1167 | .fps = 30, | ||
1168 | .pixels_per_line = 3880, | ||
1169 | .lines_per_frame = 2573, | ||
1170 | }, | ||
1171 | { | ||
1172 | } | ||
1173 | }, | ||
1174 | }, | ||
1175 | { | ||
1176 | .desc = "ov8858_8M_STILL", | ||
1177 | .width = 3280, | ||
1178 | .height = 2464, | ||
1179 | .used = 0, | ||
1180 | .regs = ov8858_8M, | ||
1181 | .bin_factor_x = 0, | ||
1182 | .bin_factor_y = 0, | ||
1183 | .skip_frames = 1, | ||
1184 | .fps_options = { | ||
1185 | { | ||
1186 | /* Pixel clock: 149.76MHZ */ | ||
1187 | .fps = 10, | ||
1188 | .pixels_per_line = 3880, | ||
1189 | .lines_per_frame = 3859, | ||
1190 | }, | ||
1191 | { | ||
1192 | } | ||
1193 | }, | ||
1194 | }, | ||
1195 | }; | ||
1196 | |||
1197 | static struct ov8858_resolution ov8858_res_video[] = { | ||
1198 | { | ||
1199 | .desc = "ov8858_1640x926_VIDEO", | ||
1200 | .width = 1640, | ||
1201 | .height = 926, | ||
1202 | .used = 0, | ||
1203 | .regs = ov8858_1640x926, | ||
1204 | .bin_factor_x = 0, | ||
1205 | .bin_factor_y = 0, | ||
1206 | .skip_frames = 1, | ||
1207 | .fps_options = { | ||
1208 | { | ||
1209 | .fps = 30, | ||
1210 | .pixels_per_line = 3880, | ||
1211 | .lines_per_frame = 2573, | ||
1212 | }, | ||
1213 | { | ||
1214 | } | ||
1215 | }, | ||
1216 | }, | ||
1217 | { | ||
1218 | .desc = "ov8858_1640x1232_VIDEO", | ||
1219 | .width = 1640, | ||
1220 | .height = 1232, | ||
1221 | .used = 0, | ||
1222 | .regs = ov8858_1640x1232, | ||
1223 | .bin_factor_x = 0, | ||
1224 | .bin_factor_y = 0, | ||
1225 | .skip_frames = 1, | ||
1226 | .fps_options = { | ||
1227 | { | ||
1228 | .fps = 30, | ||
1229 | .pixels_per_line = 3880, | ||
1230 | .lines_per_frame = 2573, | ||
1231 | }, | ||
1232 | { | ||
1233 | } | ||
1234 | }, | ||
1235 | }, | ||
1236 | { | ||
1237 | .desc = "ov8858_1640x1096_VIDEO", | ||
1238 | .width = 1640, | ||
1239 | .height = 1096, | ||
1240 | .used = 0, | ||
1241 | .regs = ov8858_1640x1096, | ||
1242 | .bin_factor_x = 0, | ||
1243 | .bin_factor_y = 0, | ||
1244 | .skip_frames = 1, | ||
1245 | .fps_options = { | ||
1246 | { | ||
1247 | .fps = 30, | ||
1248 | .pixels_per_line = 3880, | ||
1249 | .lines_per_frame = 2573, | ||
1250 | }, | ||
1251 | { | ||
1252 | } | ||
1253 | }, | ||
1254 | }, | ||
1255 | { | ||
1256 | .desc = "ov8858_1080P_30_VIDEO", | ||
1257 | .width = 1936, | ||
1258 | .height = 1096, | ||
1259 | .used = 0, | ||
1260 | .regs = ov8858_1080P_30, | ||
1261 | .bin_factor_x = 0, | ||
1262 | .bin_factor_y = 0, | ||
1263 | .skip_frames = 1, | ||
1264 | .fps_options = { | ||
1265 | { | ||
1266 | .fps = 30, | ||
1267 | .pixels_per_line = 3880, | ||
1268 | .lines_per_frame = 2573, | ||
1269 | }, | ||
1270 | { | ||
1271 | } | ||
1272 | }, | ||
1273 | }, | ||
1274 | }; | ||
1275 | |||
1276 | #endif /* __OV8858_H__ */ | ||
diff --git a/drivers/staging/media/atomisp/include/linux/vlv2_plat_clock.h b/drivers/staging/media/atomisp/include/linux/vlv2_plat_clock.h deleted file mode 100644 index ed709bdd6498..000000000000 --- a/drivers/staging/media/atomisp/include/linux/vlv2_plat_clock.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * vlv2_plat_clock.h | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corp | ||
5 | * Author: Asutosh Pathak <asutosh.pathak@intel.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 as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef __VLV2_PLAT_CLOCK_H | ||
22 | #define __VLV2_PLAT_CLOCK_H | ||
23 | |||
24 | int vlv2_plat_set_clock_freq(int clock_num, int freq_type); | ||
25 | int vlv2_plat_get_clock_freq(int clock_num); | ||
26 | |||
27 | int vlv2_plat_configure_clock(int clock_num, u32 conf); | ||
28 | int vlv2_plat_get_clock_status(int clock_num); | ||
29 | |||
30 | #endif /* __VLV2_PLAT_CLOCK_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/Makefile b/drivers/staging/media/atomisp/pci/atomisp2/Makefile index ac3805345f20..83f816faba1b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/Makefile +++ b/drivers/staging/media/atomisp/pci/atomisp2/Makefile | |||
@@ -215,7 +215,6 @@ INCLUDES += \ | |||
215 | -I$(atomisp)/css2400/isp/kernels/aa/aa_2/ \ | 215 | -I$(atomisp)/css2400/isp/kernels/aa/aa_2/ \ |
216 | -I$(atomisp)/css2400/isp/kernels/anr/anr_1.0/ \ | 216 | -I$(atomisp)/css2400/isp/kernels/anr/anr_1.0/ \ |
217 | -I$(atomisp)/css2400/isp/kernels/anr/anr_2/ \ | 217 | -I$(atomisp)/css2400/isp/kernels/anr/anr_2/ \ |
218 | -I$(atomisp)/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ \ | ||
219 | -I$(atomisp)/css2400/isp/kernels/bh/bh_2/ \ | 218 | -I$(atomisp)/css2400/isp/kernels/bh/bh_2/ \ |
220 | -I$(atomisp)/css2400/isp/kernels/bnlm/ \ | 219 | -I$(atomisp)/css2400/isp/kernels/bnlm/ \ |
221 | -I$(atomisp)/css2400/isp/kernels/bnr/ \ | 220 | -I$(atomisp)/css2400/isp/kernels/bnr/ \ |
@@ -258,14 +257,10 @@ INCLUDES += \ | |||
258 | -I$(atomisp)/css2400/isp/kernels/io_ls/ \ | 257 | -I$(atomisp)/css2400/isp/kernels/io_ls/ \ |
259 | -I$(atomisp)/css2400/isp/kernels/io_ls/bayer_io_ls/ \ | 258 | -I$(atomisp)/css2400/isp/kernels/io_ls/bayer_io_ls/ \ |
260 | -I$(atomisp)/css2400/isp/kernels/io_ls/common/ \ | 259 | -I$(atomisp)/css2400/isp/kernels/io_ls/common/ \ |
261 | -I$(atomisp)/css2400/isp/kernels/io_ls/plane_io_ls/ \ | ||
262 | -I$(atomisp)/css2400/isp/kernels/io_ls/yuv420_io_ls/ \ | ||
263 | -I$(atomisp)/css2400/isp/kernels/io_ls/yuv444_io_ls/ \ | 260 | -I$(atomisp)/css2400/isp/kernels/io_ls/yuv444_io_ls/ \ |
264 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/ \ | 261 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/ \ |
265 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/bayer_io_ls/ \ | 262 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/bayer_io_ls/ \ |
266 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/common/ \ | 263 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/common/ \ |
267 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ \ | ||
268 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ \ | ||
269 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/yuv444_io_ls/ \ | 264 | -I$(atomisp)/css2400/isp/kernels/ipu2_io_ls/yuv444_io_ls/ \ |
270 | -I$(atomisp)/css2400/isp/kernels/iterator/ \ | 265 | -I$(atomisp)/css2400/isp/kernels/iterator/ \ |
271 | -I$(atomisp)/css2400/isp/kernels/iterator/iterator_1.0/ \ | 266 | -I$(atomisp)/css2400/isp/kernels/iterator/iterator_1.0/ \ |
@@ -289,9 +284,6 @@ INCLUDES += \ | |||
289 | -I$(atomisp)/css2400/isp/kernels/ref/ref_1.0/ \ | 284 | -I$(atomisp)/css2400/isp/kernels/ref/ref_1.0/ \ |
290 | -I$(atomisp)/css2400/isp/kernels/s3a/ \ | 285 | -I$(atomisp)/css2400/isp/kernels/s3a/ \ |
291 | -I$(atomisp)/css2400/isp/kernels/s3a/s3a_1.0/ \ | 286 | -I$(atomisp)/css2400/isp/kernels/s3a/s3a_1.0/ \ |
292 | -I$(atomisp)/css2400/isp/kernels/s3a_stat_ls/ \ | ||
293 | -I$(atomisp)/css2400/isp/kernels/scale/ \ | ||
294 | -I$(atomisp)/css2400/isp/kernels/scale/scale_1.0/ \ | ||
295 | -I$(atomisp)/css2400/isp/kernels/sc/ \ | 287 | -I$(atomisp)/css2400/isp/kernels/sc/ \ |
296 | -I$(atomisp)/css2400/isp/kernels/sc/sc_1.0/ \ | 288 | -I$(atomisp)/css2400/isp/kernels/sc/sc_1.0/ \ |
297 | -I$(atomisp)/css2400/isp/kernels/sdis/ \ | 289 | -I$(atomisp)/css2400/isp/kernels/sdis/ \ |
@@ -315,8 +307,6 @@ INCLUDES += \ | |||
315 | -I$(atomisp)/css2400/isp/kernels/ynr/ \ | 307 | -I$(atomisp)/css2400/isp/kernels/ynr/ \ |
316 | -I$(atomisp)/css2400/isp/kernels/ynr/ynr_1.0/ \ | 308 | -I$(atomisp)/css2400/isp/kernels/ynr/ynr_1.0/ \ |
317 | -I$(atomisp)/css2400/isp/kernels/ynr/ynr_2/ \ | 309 | -I$(atomisp)/css2400/isp/kernels/ynr/ynr_2/ \ |
318 | -I$(atomisp)/css2400/isp/kernels/yuv_ls \ | ||
319 | -I$(atomisp)/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ \ | ||
320 | -I$(atomisp)/css2400/isp/modes/interface/ \ | 310 | -I$(atomisp)/css2400/isp/modes/interface/ \ |
321 | -I$(atomisp)/css2400/runtime/binary/interface/ \ | 311 | -I$(atomisp)/css2400/runtime/binary/interface/ \ |
322 | -I$(atomisp)/css2400/runtime/bufq/interface/ \ | 312 | -I$(atomisp)/css2400/runtime/bufq/interface/ \ |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c index debf0e3853ff..22f2dbcecc15 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c | |||
@@ -1850,7 +1850,7 @@ irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr) | |||
1850 | bool frame_done_found[MAX_STREAM_NUM] = {0}; | 1850 | bool frame_done_found[MAX_STREAM_NUM] = {0}; |
1851 | bool css_pipe_done[MAX_STREAM_NUM] = {0}; | 1851 | bool css_pipe_done[MAX_STREAM_NUM] = {0}; |
1852 | unsigned int i; | 1852 | unsigned int i; |
1853 | struct atomisp_sub_device *asd = &isp->asd[0]; | 1853 | struct atomisp_sub_device *asd; |
1854 | 1854 | ||
1855 | dev_dbg(isp->dev, ">%s\n", __func__); | 1855 | dev_dbg(isp->dev, ">%s\n", __func__); |
1856 | 1856 | ||
@@ -2091,7 +2091,7 @@ int atomisp_set_sensor_runmode(struct atomisp_sub_device *asd, | |||
2091 | struct atomisp_device *isp = asd->isp; | 2091 | struct atomisp_device *isp = asd->isp; |
2092 | struct v4l2_ctrl *c; | 2092 | struct v4l2_ctrl *c; |
2093 | struct v4l2_streamparm p = {0}; | 2093 | struct v4l2_streamparm p = {0}; |
2094 | int ret; | 2094 | int ret = 0; |
2095 | int modes[] = { CI_MODE_NONE, | 2095 | int modes[] = { CI_MODE_NONE, |
2096 | CI_MODE_VIDEO, | 2096 | CI_MODE_VIDEO, |
2097 | CI_MODE_STILL_CAPTURE, | 2097 | CI_MODE_STILL_CAPTURE, |
@@ -2105,13 +2105,8 @@ int atomisp_set_sensor_runmode(struct atomisp_sub_device *asd, | |||
2105 | c = v4l2_ctrl_find(isp->inputs[asd->input_curr].camera->ctrl_handler, | 2105 | c = v4l2_ctrl_find(isp->inputs[asd->input_curr].camera->ctrl_handler, |
2106 | V4L2_CID_RUN_MODE); | 2106 | V4L2_CID_RUN_MODE); |
2107 | 2107 | ||
2108 | if (c) { | 2108 | if (c) |
2109 | ret = v4l2_ctrl_s_ctrl(c, runmode->mode); | 2109 | ret = v4l2_ctrl_s_ctrl(c, runmode->mode); |
2110 | } else { | ||
2111 | p.parm.capture.capturemode = modes[runmode->mode]; | ||
2112 | ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, | ||
2113 | video, s_parm, &p); | ||
2114 | } | ||
2115 | 2110 | ||
2116 | mutex_unlock(asd->ctrl_handler.lock); | 2111 | mutex_unlock(asd->ctrl_handler.lock); |
2117 | return ret; | 2112 | return ret; |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c index b7f9da014641..7621b4537147 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c | |||
@@ -4502,7 +4502,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp, | |||
4502 | { | 4502 | { |
4503 | enum atomisp_input_stream_id stream_id = 0; | 4503 | enum atomisp_input_stream_id stream_id = 0; |
4504 | struct atomisp_css_event current_event; | 4504 | struct atomisp_css_event current_event; |
4505 | struct atomisp_sub_device *asd = &isp->asd[0]; | 4505 | struct atomisp_sub_device *asd; |
4506 | #ifndef ISP2401 | 4506 | #ifndef ISP2401 |
4507 | bool reset_wdt_timer[MAX_STREAM_NUM] = {false}; | 4507 | bool reset_wdt_timer[MAX_STREAM_NUM] = {false}; |
4508 | #endif | 4508 | #endif |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c index 377ec2a9fa6d..c6d96987561d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c | |||
@@ -77,20 +77,6 @@ static int file_input_s_stream(struct v4l2_subdev *sd, int enable) | |||
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | 79 | ||
80 | static int file_input_g_parm(struct v4l2_subdev *sd, | ||
81 | struct v4l2_streamparm *param) | ||
82 | { | ||
83 | /*to fake*/ | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int file_input_s_parm(struct v4l2_subdev *sd, | ||
88 | struct v4l2_streamparm *param) | ||
89 | { | ||
90 | /*to fake*/ | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int file_input_get_fmt(struct v4l2_subdev *sd, | 80 | static int file_input_get_fmt(struct v4l2_subdev *sd, |
95 | struct v4l2_subdev_pad_config *cfg, | 81 | struct v4l2_subdev_pad_config *cfg, |
96 | struct v4l2_subdev_format *format) | 82 | struct v4l2_subdev_format *format) |
@@ -166,8 +152,6 @@ static int file_input_enum_frame_ival(struct v4l2_subdev *sd, | |||
166 | 152 | ||
167 | static const struct v4l2_subdev_video_ops file_input_video_ops = { | 153 | static const struct v4l2_subdev_video_ops file_input_video_ops = { |
168 | .s_stream = file_input_s_stream, | 154 | .s_stream = file_input_s_stream, |
169 | .g_parm = file_input_g_parm, | ||
170 | .s_parm = file_input_s_parm, | ||
171 | }; | 155 | }; |
172 | 156 | ||
173 | static const struct v4l2_subdev_core_ops file_input_core_ops = { | 157 | static const struct v4l2_subdev_core_ops file_input_core_ops = { |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c index 4f9f9dca5e6a..545ef024841d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c | |||
@@ -1279,7 +1279,10 @@ const struct v4l2_file_operations atomisp_fops = { | |||
1279 | .mmap = atomisp_mmap, | 1279 | .mmap = atomisp_mmap, |
1280 | .unlocked_ioctl = video_ioctl2, | 1280 | .unlocked_ioctl = video_ioctl2, |
1281 | #ifdef CONFIG_COMPAT | 1281 | #ifdef CONFIG_COMPAT |
1282 | /* | ||
1283 | * There are problems with this code. Disable this for now. | ||
1282 | .compat_ioctl32 = atomisp_compat_ioctl32, | 1284 | .compat_ioctl32 = atomisp_compat_ioctl32, |
1285 | */ | ||
1283 | #endif | 1286 | #endif |
1284 | .poll = atomisp_poll, | 1287 | .poll = atomisp_poll, |
1285 | }; | 1288 | }; |
@@ -1291,7 +1294,10 @@ const struct v4l2_file_operations atomisp_file_fops = { | |||
1291 | .mmap = atomisp_file_mmap, | 1294 | .mmap = atomisp_file_mmap, |
1292 | .unlocked_ioctl = video_ioctl2, | 1295 | .unlocked_ioctl = video_ioctl2, |
1293 | #ifdef CONFIG_COMPAT | 1296 | #ifdef CONFIG_COMPAT |
1297 | /* | ||
1298 | * There are problems with this code. Disable this for now. | ||
1294 | .compat_ioctl32 = atomisp_compat_ioctl32, | 1299 | .compat_ioctl32 = atomisp_compat_ioctl32, |
1300 | */ | ||
1295 | #endif | 1301 | #endif |
1296 | .poll = atomisp_poll, | 1302 | .poll = atomisp_poll, |
1297 | }; | 1303 | }; |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c index f3e18d627b0a..b78276ac22da 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c | |||
@@ -819,12 +819,6 @@ static int __atomisp_update_run_mode(struct atomisp_sub_device *asd) | |||
819 | struct atomisp_device *isp = asd->isp; | 819 | struct atomisp_device *isp = asd->isp; |
820 | struct v4l2_ctrl *ctrl = asd->run_mode; | 820 | struct v4l2_ctrl *ctrl = asd->run_mode; |
821 | struct v4l2_ctrl *c; | 821 | struct v4l2_ctrl *c; |
822 | struct v4l2_streamparm p = {0}; | ||
823 | int modes[] = { CI_MODE_NONE, | ||
824 | CI_MODE_VIDEO, | ||
825 | CI_MODE_STILL_CAPTURE, | ||
826 | CI_MODE_CONTINUOUS, | ||
827 | CI_MODE_PREVIEW }; | ||
828 | s32 mode; | 822 | s32 mode; |
829 | 823 | ||
830 | if (ctrl->val != ATOMISP_RUN_MODE_VIDEO && | 824 | if (ctrl->val != ATOMISP_RUN_MODE_VIDEO && |
@@ -840,11 +834,7 @@ static int __atomisp_update_run_mode(struct atomisp_sub_device *asd) | |||
840 | if (c) | 834 | if (c) |
841 | return v4l2_ctrl_s_ctrl(c, mode); | 835 | return v4l2_ctrl_s_ctrl(c, mode); |
842 | 836 | ||
843 | /* Fall back to obsolete s_parm */ | 837 | return 0; |
844 | p.parm.capture.capturemode = modes[mode]; | ||
845 | |||
846 | return v4l2_subdev_call( | ||
847 | isp->inputs[asd->input_curr].camera, video, s_parm, &p); | ||
848 | } | 838 | } |
849 | 839 | ||
850 | int atomisp_update_run_mode(struct atomisp_sub_device *asd) | 840 | int atomisp_update_run_mode(struct atomisp_sub_device *asd) |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c index b71cc7bcdbab..adc900272f6f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c | |||
@@ -27,18 +27,6 @@ static int tpg_s_stream(struct v4l2_subdev *sd, int enable) | |||
27 | return 0; | 27 | return 0; |
28 | } | 28 | } |
29 | 29 | ||
30 | static int tpg_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param) | ||
31 | { | ||
32 | /*to fake*/ | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static int tpg_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param) | ||
37 | { | ||
38 | /*to fake*/ | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static int tpg_get_fmt(struct v4l2_subdev *sd, | 30 | static int tpg_get_fmt(struct v4l2_subdev *sd, |
43 | struct v4l2_subdev_pad_config *cfg, | 31 | struct v4l2_subdev_pad_config *cfg, |
44 | struct v4l2_subdev_format *format) | 32 | struct v4l2_subdev_format *format) |
@@ -101,8 +89,6 @@ static int tpg_enum_frame_ival(struct v4l2_subdev *sd, | |||
101 | 89 | ||
102 | static const struct v4l2_subdev_video_ops tpg_video_ops = { | 90 | static const struct v4l2_subdev_video_ops tpg_video_ops = { |
103 | .s_stream = tpg_s_stream, | 91 | .s_stream = tpg_s_stream, |
104 | .g_parm = tpg_g_parm, | ||
105 | .s_parm = tpg_s_parm, | ||
106 | }; | 92 | }; |
107 | 93 | ||
108 | static const struct v4l2_subdev_core_ops tpg_core_ops = { | 94 | static const struct v4l2_subdev_core_ops tpg_core_ops = { |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c index 548e00e7d67b..ba20344ec560 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c | |||
@@ -1137,7 +1137,6 @@ static int init_atomisp_wdts(struct atomisp_device *isp) | |||
1137 | 1137 | ||
1138 | for (i = 0; i < isp->num_of_streams; i++) { | 1138 | for (i = 0; i < isp->num_of_streams; i++) { |
1139 | struct atomisp_sub_device *asd = &isp->asd[i]; | 1139 | struct atomisp_sub_device *asd = &isp->asd[i]; |
1140 | asd = &isp->asd[i]; | ||
1141 | #ifndef ISP2401 | 1140 | #ifndef ISP2401 |
1142 | timer_setup(&asd->wdt, atomisp_wdt, 0); | 1141 | timer_setup(&asd->wdt, atomisp_wdt, 0); |
1143 | #else | 1142 | #else |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/gp_regs_defs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/gp_regs_defs.h deleted file mode 100644 index 34e734f6648e..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/gp_regs_defs.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _gp_regs_defs_h | ||
16 | #define _gp_regs_defs_h | ||
17 | |||
18 | #define _HRT_GP_REGS_IS_FWD_REG_IDX 0 | ||
19 | |||
20 | #define _HRT_GP_REGS_REG_ALIGN 4 | ||
21 | |||
22 | #endif /* _gp_regs_defs_h */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/sp_hrt.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/sp_hrt.h deleted file mode 100644 index 7ee4deba519a..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/sp_hrt.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _sp_hrt_h_ | ||
17 | #define _sp_hrt_h_ | ||
18 | |||
19 | #define hrt_sp_dmem(cell) HRT_PROC_TYPE_PROP(cell, _dmem) | ||
20 | |||
21 | #define hrt_sp_dmem_master_port_address(cell) hrt_mem_master_port_address(cell, hrt_sp_dmem(cell)) | ||
22 | |||
23 | #endif /* _sp_hrt_h_ */ | ||
24 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/gp_regs_defs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/gp_regs_defs.h deleted file mode 100644 index 34e734f6648e..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/gp_regs_defs.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _gp_regs_defs_h | ||
16 | #define _gp_regs_defs_h | ||
17 | |||
18 | #define _HRT_GP_REGS_IS_FWD_REG_IDX 0 | ||
19 | |||
20 | #define _HRT_GP_REGS_REG_ALIGN 4 | ||
21 | |||
22 | #endif /* _gp_regs_defs_h */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/sp_hrt.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/sp_hrt.h deleted file mode 100644 index 7ee4deba519a..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/sp_hrt.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _sp_hrt_h_ | ||
17 | #define _sp_hrt_h_ | ||
18 | |||
19 | #define hrt_sp_dmem(cell) HRT_PROC_TYPE_PROP(cell, _dmem) | ||
20 | |||
21 | #define hrt_sp_dmem_master_port_address(cell) hrt_mem_master_port_address(cell, hrt_sp_dmem(cell)) | ||
22 | |||
23 | #endif /* _sp_hrt_h_ */ | ||
24 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/gp_regs_defs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/gp_regs_defs.h deleted file mode 100644 index 34e734f6648e..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/gp_regs_defs.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _gp_regs_defs_h | ||
16 | #define _gp_regs_defs_h | ||
17 | |||
18 | #define _HRT_GP_REGS_IS_FWD_REG_IDX 0 | ||
19 | |||
20 | #define _HRT_GP_REGS_REG_ALIGN 4 | ||
21 | |||
22 | #endif /* _gp_regs_defs_h */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/sp_hrt.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/sp_hrt.h deleted file mode 100644 index 7ee4deba519a..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/sp_hrt.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _sp_hrt_h_ | ||
17 | #define _sp_hrt_h_ | ||
18 | |||
19 | #define hrt_sp_dmem(cell) HRT_PROC_TYPE_PROP(cell, _dmem) | ||
20 | |||
21 | #define hrt_sp_dmem_master_port_address(cell) hrt_mem_master_port_address(cell, hrt_sp_dmem(cell)) | ||
22 | |||
23 | #endif /* _sp_hrt_h_ */ | ||
24 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_api_version.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_api_version.h deleted file mode 100644 index efcd6e1679e8..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_api_version.h +++ /dev/null | |||
@@ -1,673 +0,0 @@ | |||
1 | /* | ||
2 | #ifndef ISP2401 | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | #else | ||
16 | Support for Intel Camera Imaging ISP subsystem. | ||
17 | Copyright (c) 2010 - 2015, Intel Corporation. | ||
18 | #endif | ||
19 | |||
20 | #ifdef ISP2401 | ||
21 | This program is free software; you can redistribute it and/or modify it | ||
22 | under the terms and conditions of the GNU General Public License, | ||
23 | version 2, as published by the Free Software Foundation. | ||
24 | |||
25 | This program is distributed in the hope it will be useful, but WITHOUT | ||
26 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
27 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
28 | more details. | ||
29 | */ | ||
30 | #endif | ||
31 | #ifndef __CSS_API_VERSION_H | ||
32 | #define __CSS_API_VERSION_H | ||
33 | |||
34 | /* @file | ||
35 | * CSS API version file. This file contains the version number of the CSS-API. | ||
36 | * | ||
37 | * This file is generated from a set of input files describing the CSS-API | ||
38 | * changes. Don't edit this file directly. | ||
39 | */ | ||
40 | |||
41 | |||
42 | /** | ||
43 | |||
44 | The version string has four dot-separated numbers, read left to right: | ||
45 | The first two are the API version, and should not be changed. | ||
46 | The third number is incremented by a CSS firmware developer when the | ||
47 | API change is not backwards compatible. | ||
48 | The fourth number is incremented by the a CSS firmware developer for | ||
49 | every API change. | ||
50 | It should be zeroed when the third number changes. | ||
51 | |||
52 | */ | ||
53 | |||
54 | #ifndef ISP2401 | ||
55 | #define CSS_API_VERSION_STRING "2.1.15.3" | ||
56 | #else | ||
57 | #define CSS_API_VERSION_STRING "2.1.20.9" | ||
58 | #endif | ||
59 | |||
60 | /* | ||
61 | Change log | ||
62 | |||
63 | v2.0.1.0, initial version: | ||
64 | - added API versioning | ||
65 | |||
66 | v2.0.1.1, activate CSS-API versioning: | ||
67 | - added description of major and minor version numbers | ||
68 | |||
69 | v2.0.1.2, modified struct ia_css_frame_info: | ||
70 | - added new member ia_css_crop_info | ||
71 | |||
72 | v2.0.1.3, added IA_CSS_ERR_NOT_SUPPORTED | ||
73 | |||
74 | v2.1.0.0 | ||
75 | - moved version number to 2.1.0.0 | ||
76 | - created new files for refactoring the code | ||
77 | |||
78 | v2.1.1.0, modified struct ia_css_pipe_config and struct ia_css_pipe_info and struct ia_css_pipe: | ||
79 | - use array to handle multiple output ports | ||
80 | |||
81 | v2.1.1.1 | ||
82 | - added api to lock/unlock of RAW Buffers to Support HALv3 Feature | ||
83 | |||
84 | v2.1.1.2, modified struct ia_css_stream_config: | ||
85 | - to support multiple isys streams in one virtual channel, keep the old one for backward compatibility | ||
86 | |||
87 | v2.1.2.0, modify ia_css_stream_config: | ||
88 | - add isys_config and input_config to support multiple isys stream within one virtual channel | ||
89 | |||
90 | v2.1.2.1, add IA_CSS_STREAM_FORMAT_NUM | ||
91 | - add IA_CSS_STREAM_FORMAT_NUM definition to reflect the number of ia_css_stream_format enums | ||
92 | |||
93 | v2.1.2.2, modified enum ia_css_stream_format | ||
94 | - Add 16bit YUV formats to ia_css_stream_format enum: | ||
95 | - IA_CSS_STREAM_FORMAT_YUV420_16 (directly after IA_CSS_STREAM_FORMAT_YUV420_10) | ||
96 | - IA_CSS_STREAM_FORMAT_YUV422_16 (directly after IA_CSS_STREAM_FORMAT_YUV422_10) | ||
97 | |||
98 | v2.1.2.3 | ||
99 | - added api to enable/disable digital zoom for capture pipe. | ||
100 | |||
101 | v2.1.2.4, change CSS API to generate the shading table which should be directly sent to ISP: | ||
102 | - keep the old CSS API (which uses the conversion of the shading table in CSS) for backward compatibility | ||
103 | |||
104 | v2.1.2.5 | ||
105 | - Added SP frame time measurement (in ticks) and result is sent on a new member | ||
106 | - in ia_css_buffer.h. | ||
107 | |||
108 | v2.1.2.6, add function ia_css_check_firmware_version() | ||
109 | - the function ia_css_check_firmware_version() returns true when the firmware version matches and returns false otherwise. | ||
110 | |||
111 | v2.1.2.7 | ||
112 | - rename dynamic_data_index to dynamic_queue_id in struct ia_css_frame. | ||
113 | - update IA_CSS_PIPE_MODE_NUM | ||
114 | |||
115 | v2.1.2.8 | ||
116 | - added flag for video full range | ||
117 | |||
118 | v2.1.2.9 | ||
119 | - add public parameters for xnr3 kernel | ||
120 | |||
121 | v2.1.2.10 | ||
122 | - add new interface to enable output mirroring | ||
123 | |||
124 | v2.1.2.11, MIPI buffers optimization | ||
125 | - modified struct ia_css_mipi_buffer_config, added number of MIPI buffers needed for the stream | ||
126 | - backwards compatible, need another patch to remove legacy function and code | ||
127 | |||
128 | v2.1.2.12 | ||
129 | - create consolidated firmware package for 2400, 2401, csi2p, bxtpoc | ||
130 | |||
131 | v2.1.3.0 | ||
132 | - rename ia_css_output_config.enable_mirror | ||
133 | - add new interface to enable vertical output flipping | ||
134 | |||
135 | v2.1.3.1 | ||
136 | - deprecated ia_css_rx_get_irq_info and ia_css_rx_clear_irq_info because both are hardcoded to work on CSI port 1. | ||
137 | - added new functions ia_css_rx_port_get_irq_info and ia_css_rx_port_clear_irq_info, both have a port ID as extra argument. | ||
138 | |||
139 | v2.1.3.2 | ||
140 | - reverted v2.1.3.0 change | ||
141 | |||
142 | v2.1.3.3 | ||
143 | - Added isys event queue. | ||
144 | - Renamed ia_css_dequeue_event to ia_css_dequeue_psys_event | ||
145 | - Made ia_css_dequeue_event deprecated | ||
146 | |||
147 | v2.1.3.4 | ||
148 | - added new interface to support ACC extension QoS feature. | ||
149 | - added IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE. | ||
150 | |||
151 | v2.1.3.5 | ||
152 | - added tiled frame format IA_CSS_FRAME_FORMAT_NV12_TILEY | ||
153 | |||
154 | v2.1.3.6 | ||
155 | - added functions ia_css_host_data_allocate and ia_css_host_data_free | ||
156 | |||
157 | v2.1.4.0, default pipe config change | ||
158 | - disable enable_dz param by default | ||
159 | |||
160 | v2.1.5.0 | ||
161 | - removed mix_range field from yuvp1_y_ee_nr_frng_public_config | ||
162 | |||
163 | v2.1.5.1, exposure IDs per stream | ||
164 | - added MIN/MAX exposure ID macros | ||
165 | - made exposure ID sequence per-stream instead of global (across all streams) | ||
166 | |||
167 | #ifdef ISP2401 | ||
168 | v2.1.5.1, Add parameters to mmgr routines via a macro. | ||
169 | - Replaced mmgr funtions with macros to add caller func name + line #. | ||
170 | - This is done to help debug memory access issues, allocation issues, etc. | ||
171 | |||
172 | #endif | ||
173 | v2.1.6.0, Interface for vertical output flip | ||
174 | - add new interface to enable vertical output flipping | ||
175 | - rename ia_css_output_config.enable_mirror | ||
176 | |||
177 | #ifndef ISP2401 | ||
178 | v2.1.6.1, Effective res on pipe | ||
179 | #else | ||
180 | v2.1.6.2 (2 changes parallel), Effective res on pipe | ||
181 | #endif | ||
182 | - Added input_effective_res to struct ia_css_pipe_config in ia_css_pipe_public.h. | ||
183 | |||
184 | #ifndef ISP2401 | ||
185 | v2.1.6.2, CSS-API version file generated from individual changes | ||
186 | #else | ||
187 | v2.1.6.3 (2 changes parallel), CSS-API version file generated from individual changes | ||
188 | #endif | ||
189 | - Avoid merge-conflicts by generating version file from individual CSS-API changes. | ||
190 | - Parallel CSS-API changes can map to the same version number after this change. | ||
191 | - Version numbers for a change could increase due to parallel changes being merged. | ||
192 | - The version number would not decrease for a change. | ||
193 | |||
194 | #ifndef ISP2401 | ||
195 | v2.1.6.5 (2 changes parallel), Add SP FW error event | ||
196 | #else | ||
197 | v2.1.6.6 (4 changes parallel), Add SP FW error event | ||
198 | #endif | ||
199 | - Added FW error event. This gets raised when the SP FW runs into an | ||
200 | - error situation from which it cannot recover. | ||
201 | |||
202 | #ifndef ISP2401 | ||
203 | v2.1.6.5 (2 changes parallel), expose bnr FF enable bits in bnr public API | ||
204 | #else | ||
205 | v2.1.6.6 (4 changes parallel), expose bnr FF enable bits in bnr public API | ||
206 | #endif | ||
207 | - Added ff enable bits to bnr_public_config_dn_detect_ctrl_config_t struct | ||
208 | |||
209 | #ifndef ISP2401 | ||
210 | v2.1.6.5 (2 changes parallel), ISP configuration per pipe | ||
211 | #else | ||
212 | v2.1.6.6 (4 changes parallel), ISP configuration per pipe | ||
213 | #endif | ||
214 | - Added ISP configuration per pipe support: p_isp_config field in | ||
215 | - struct ia_css_pipe_config and ia_css_pipe_set_isp_config_on_pipe | ||
216 | - and ia_css_pipe_set_isp_config functions | ||
217 | |||
218 | #ifndef ISP2401 | ||
219 | v2.1.7.0, removed css_version.h | ||
220 | #else | ||
221 | v2.1.7.0 (2 changes parallel), removed css_version.h | ||
222 | #endif | ||
223 | - Removed css_version.h that was used for versioning in manual (non-CI) releases. | ||
224 | |||
225 | #ifndef ISP2401 | ||
226 | v2.1.7.1, Add helpers (get and set) for ISP cfg per pipe | ||
227 | #else | ||
228 | v2.1.7.2 (2 changes parallel), Add helpers (get and set) for ISP cfg per pipe | ||
229 | #endif | ||
230 | - Add helpers (get and set) for ISP configuration per pipe | ||
231 | |||
232 | #ifndef ISP2401 | ||
233 | v2.1.7.2, Add feature to lock all RAW buffers | ||
234 | #else | ||
235 | v2.1.7.3 (2 changes parallel), Add feature to lock all RAW buffers | ||
236 | #endif | ||
237 | - This API change adds a boolean flag (lock_all) in the stream_config struct. | ||
238 | - If this flag is set to true, then all frames will be locked if locking is | ||
239 | - enabled. By default this flag is set to false. | ||
240 | - When this flag is false, then only buffers that are sent to the preview pipe | ||
241 | - will be locked. If continuous viewfinder is disabled, the flag should be set | ||
242 | - to true. | ||
243 | |||
244 | #ifndef ISP2401 | ||
245 | v2.1.8.0 (2 changes parallel), Various changes to support ACC configuration per pipe | ||
246 | #else | ||
247 | v2.1.8.0 (4 changes parallel), Various changes to support ACC configuration per pipe | ||
248 | #endif | ||
249 | - Add ia_css_pipe_get_isp_config() | ||
250 | - Remove ia_css_pipe_set_isp_config_on_pipe (duplicated | ||
251 | - by ia_css_pipe_set_isp_config) | ||
252 | - Add isp configuration as parameter for | ||
253 | - ia_css_pipe_set_isp_config | ||
254 | - Remove ia_css_pipe_isp_config_set() | ||
255 | - Remove ia_css_pipe_isp_config_get() | ||
256 | |||
257 | #ifndef ISP2401 | ||
258 | v2.1.8.2 (2 changes parallel), Added member num_invalid_frames to ia_css_pipe_info structure. | ||
259 | #else | ||
260 | v2.1.8.3 (4 changes parallel), Added member num_invalid_frames to ia_css_pipe_info structure. | ||
261 | #endif | ||
262 | - Added member num_invalid_frames to ia_css_pipe_info structure. | ||
263 | - This helps the driver make sure that the first valid output | ||
264 | - frame goes into the first user-supplied output buffer. | ||
265 | |||
266 | #ifndef ISP2401 | ||
267 | v2.1.8.4 (2 changes parallel), ISYS EOF timestamp for output buffers | ||
268 | #else | ||
269 | v2.1.8.5 (4 changes parallel), ISYS EOF timestamp for output buffers | ||
270 | #endif | ||
271 | - driver gets EOF timer to every out frame . ia_css_buffer modified to accomodate same. | ||
272 | |||
273 | #ifndef ISP2401 | ||
274 | v2.1.8.4 (4 changes parallel), display_config | ||
275 | #else | ||
276 | v2.1.8.5 (6 changes parallel), display_config | ||
277 | #endif | ||
278 | - Added formats- and output config parameters for configuration of the (optional) display output. | ||
279 | |||
280 | #ifndef ISP2401 | ||
281 | v2.1.8.4 (2 changes parallel), Adding zoom region parameters to CSS API | ||
282 | #else | ||
283 | v2.1.8.5 (4 changes parallel), Adding zoom region parameters to CSS API | ||
284 | #endif | ||
285 | - Adding ia_css_point and ia_css_region structures to css-api. | ||
286 | - Adding zoom_region(type ia_css_region) parameter to ia_css_dz_config structure. | ||
287 | - By using this user can do the zoom based on zoom region and | ||
288 | - the center of the zoom region is not restricted at the center of the input frame. | ||
289 | |||
290 | #ifndef ISP2401 | ||
291 | v2.1.8.6 (1 changes parallel), Add new ia_css_fw_warning type | ||
292 | #else | ||
293 | v2.1.8.7 (3 changes parallel), Add new ia_css_fw_warning type | ||
294 | #endif | ||
295 | - Add IA_CSS_FW_WARNING_TAG_EXP_ID_FAILED enum to ia_css_fw_warning type | ||
296 | - Extend sp_warning() with exp_id parameter | ||
297 | |||
298 | #ifndef ISP2401 | ||
299 | v2.1.8.6 (1 changes parallel), Add includes in GC, GC2 kernel interface files | ||
300 | #else | ||
301 | v2.1.8.7 (3 changes parallel), Add includes in GC, GC2 kernel interface files | ||
302 | #endif | ||
303 | - add ia_css_ctc_types.h includes in ia_css_gc_types.h and ia_css_gc2_types.h. Needed to get ia_css_vamem_type. | ||
304 | |||
305 | #ifndef ISP2401 | ||
306 | v2.1.9.0 (1 changes parallel), Introduce sp assert event. | ||
307 | #else | ||
308 | v2.1.9.0 (3 changes parallel), Introduce sp assert event. | ||
309 | #endif | ||
310 | - Add IA_CSS_EVENT_TYPE_FW_ASSERT. The FW sends the event in case an assert goes off. | ||
311 | |||
312 | #ifndef ISP2401 | ||
313 | v2.1.9.1 (1 changes parallel), Exclude driver part from ia_css_buffer.h as it is also used by SP | ||
314 | #else | ||
315 | v2.1.9.2 (3 changes parallel), Exclude driver part from ia_css_buffer.h as it is also used by SP | ||
316 | #endif | ||
317 | - Excluded driver part of the interface from SP/ISP code | ||
318 | - Driver I/F is not affected | ||
319 | |||
320 | #ifndef ISP2401 | ||
321 | v2.1.9.2, added IA_CSS_EVENT_TYPE_TIMER | ||
322 | #else | ||
323 | v2.1.9.3 (2 changes parallel), added IA_CSS_EVENT_TYPE_TIMER | ||
324 | #endif | ||
325 | - Added a new event called IA_CSS_EVENT_TYPE_TIMER | ||
326 | |||
327 | #ifndef ISP2401 | ||
328 | v2.1.10.0 (4 changes parallel), Add a flag "enable_dpc" to "struct ia_css_pipe_config" | ||
329 | #else | ||
330 | v2.1.10.0 (6 changes parallel), Add a flag "enable_dpc" to "struct ia_css_pipe_config" | ||
331 | #endif | ||
332 | - Add a flag "enable_dpc" to "struct ia_css_pipe_config" | ||
333 | |||
334 | #ifndef ISP2401 | ||
335 | v2.1.10.6 (6 changes parallel), change the pipe version type from integer to enum | ||
336 | #else | ||
337 | v2.1.10.8 (9 changes parallel), change the pipe version type from integer to enum | ||
338 | #endif | ||
339 | - add new enum to enumerate ISP pipe version | ||
340 | - change the pipe version type in pipe_config from integer to enum | ||
341 | |||
342 | #ifndef ISP2401 | ||
343 | v2.1.13.0 (8 changes parallel), Stop Support for Skycam B0 | ||
344 | #else | ||
345 | v2.1.14.0 (12 changes parallel), Stop Support for Skycam B0 | ||
346 | #endif | ||
347 | - Remove a few pre-processor defines for Skycam B0/C0 as support | ||
348 | |||
349 | #ifndef ISP2401 | ||
350 | v2.1.14.0 (24 changes parallel), change the pipe version type from integer to enum | ||
351 | #else | ||
352 | v2.1.15.0 (28 changes parallel), change the pipe version type from integer to enum | ||
353 | #endif | ||
354 | - remove the temporary workaround for backward compatability | ||
355 | |||
356 | #ifndef ISP2401 | ||
357 | v2.1.14.0 (13 changes parallel), expose_gamma_enable_option | ||
358 | #else | ||
359 | v2.1.15.0 (17 changes parallel), expose_gamma_enable_option | ||
360 | #endif | ||
361 | - added enable param to gamma_corr_public_config | ||
362 | - added documentation to rgbpp_public.h | ||
363 | |||
364 | #ifndef ISP2401 | ||
365 | v2.1.14.0 (12 changes parallel), Remove deprecated FW_ERROR event. | ||
366 | #else | ||
367 | v2.1.15.0 (16 changes parallel), Remove deprecated FW_ERROR event. | ||
368 | #endif | ||
369 | - Remove code for deprecated FW_ERROR event. | ||
370 | |||
371 | #ifndef ISP2401 | ||
372 | v2.1.14.3 (5 changes parallel), fix IEFD's puclic API types | ||
373 | #else | ||
374 | v2.1.15.5 (8 changes parallel), fix IEFD's puclic API types | ||
375 | #endif | ||
376 | - fix IEFD public API members types: rad_cu6_x1,rad_cu_unsharp_x1 & unsharp_amount | ||
377 | |||
378 | #ifndef ISP2401 | ||
379 | v2.1.14.3 (5 changes parallel), Add IA_CSS_FW_WARNING_FRAME_PARAM_MISMATCH | ||
380 | #else | ||
381 | v2.1.15.5 (8 changes parallel), Add IA_CSS_FW_WARNING_FRAME_PARAM_MISMATCH | ||
382 | #endif | ||
383 | - Add IA_CSS_FW_WARNING_FRAME_PARAM_MISMATCH enum to ia_css_fw_warning type | ||
384 | |||
385 | #ifndef ISP2401 | ||
386 | v2.1.14.4 (5 changes parallel), new API getter functions for gdc in buffer information | ||
387 | #else | ||
388 | v2.1.15.8 (11 changes parallel), add_flag_to_disable_continous_viewfinder | ||
389 | - add a new flag in stream_config to disable continuous viewfinder | ||
390 | - in ZSL use case. | ||
391 | |||
392 | v2.1.16.0 (8 changes parallel), revert ia_css_skc_dvs_statistics field size change | ||
393 | - Reverted field size change, change was not ready for driver yet. | ||
394 | |||
395 | v2.1.17.0 (7 changes parallel), change CSS API to fix the shading correction off-center issue | ||
396 | - update the ia_css_shading_info structure in ia_css_types.h | ||
397 | |||
398 | v2.1.17.0 (32 changes parallel), add_flag_to_disable_continous_viewfinder_part2 | ||
399 | - remove the old interfaces | ||
400 | |||
401 | v2.1.17.4 (8 changes parallel), Added public interface for setting the scaler LUT. | ||
402 | - Added the public struct to output system and modified the global config struct. | ||
403 | |||
404 | v2.1.17.5 (7 changes parallel), Add parameters for new TNR3 component | ||
405 | - Add new parameters for new TNR3 component | ||
406 | |||
407 | v2.1.17.6 (9 changes parallel), Update skycam DPC_MAX_NUMBER_OF_DP | ||
408 | - Automated tooling requires an API change request | ||
409 | - This change changes the implementation of #define DPC_MAX_NUMBER_OF_DP | ||
410 | - it now returns a different number | ||
411 | |||
412 | v2.1.17.6 (8 changes parallel), Return an error when both DPC and BDS are enabled in a pipe config | ||
413 | - Return an error when both DPC and BDS are enabled in a pipe config | ||
414 | |||
415 | v2.1.17.6 (9 changes parallel), new API getter functions for gdc in buffer information | ||
416 | #endif | ||
417 | - ia_css_pipe_get_dvs_filter() added | ||
418 | - ia_css_pipe_get_gdc_in_buffer_info() added | ||
419 | |||
420 | #ifndef ISP2401 | ||
421 | v2.1.14.5 (8 changes parallel), Update CNR2 ineffective values | ||
422 | #else | ||
423 | v2.1.17.7 (12 changes parallel), Update CNR2 ineffective values | ||
424 | #endif | ||
425 | - Fixed Incorrect ineffective values listed in ia_css_cnr_config | ||
426 | - Correct Ineffective value is 8191 | ||
427 | |||
428 | #ifndef ISP2401 | ||
429 | v2.1.14.5 (8 changes parallel), af_roi_api | ||
430 | #else | ||
431 | v2.1.17.7 (12 changes parallel), af_roi_api | ||
432 | #endif | ||
433 | - added a new function to set AF ROI ia_css_set_af_roi | ||
434 | - added a new struct ia_css_s3a_roi_offset | ||
435 | |||
436 | #ifndef ISP2401 | ||
437 | v2.1.14.5 (8 changes parallel), remove x_y_end_from_ae_and_awb | ||
438 | #else | ||
439 | v2.1.17.7 (12 changes parallel), Enlarge AF AWB_FR stats buffers | ||
440 | - Enlarge AF and AWB_FR stats buffers to support max grid width per stripe as oppose to per frame | ||
441 | |||
442 | v2.1.17.7 (12 changes parallel), remove x_y_end_from_ae_and_awb | ||
443 | #endif | ||
444 | - added a flag to prepare removal of x_end and y_end from ae grid public config | ||
445 | - added a flag to prepare removal of x_end and y_end from awb grid public config | ||
446 | |||
447 | #ifndef ISP2401 | ||
448 | v2.1.14.5 (4 changes parallel), Added public interface for setting the scaler LUT. | ||
449 | - Added the public struct to output system and modified the global config struct. | ||
450 | #else | ||
451 | v2.1.17.8 (5 changes parallel) | ||
452 | - added input_yuv , input_raw to ia_css_binary_info.enable | ||
453 | - struct, these attributes were always there but not saved | ||
454 | - in the binary_info struct | ||
455 | #endif | ||
456 | |||
457 | #ifndef ISP2401 | ||
458 | v2.1.14.6 (8 changes parallel), add_flag_to_disable_continous_viewfinder | ||
459 | - add a new flag in stream_config to disable continuous viewfinder | ||
460 | - in ZSL use case. | ||
461 | #else | ||
462 | v2.1.17.9 (6 changes parallel), cleanup_awb_ae_rgb_integration_flags | ||
463 | - this change only cleans up an approved api CR see wikis below | ||
464 | #endif | ||
465 | |||
466 | #ifndef ISP2401 | ||
467 | v2.1.14.6 (8 changes parallel), Enlarge AF AWB_FR stats buffers | ||
468 | - Enlarge AF and AWB_FR stats buffers to support max grid width per stripe as oppose to per frame | ||
469 | #else | ||
470 | v2.1.17.10 (6 changes parallel), output_system_input_resolution | ||
471 | - adedd gdc_output_system_in_resolution to pipe config struct | ||
472 | #endif | ||
473 | |||
474 | #ifndef ISP2401 | ||
475 | v2.1.14.8 (6 changes parallel), pipe config option for vf output bci mode downscaling | ||
476 | #else | ||
477 | v2.1.17.10 (5 changes parallel), Per pipe DPC configuration is added to ia_css_isp_parameters | ||
478 | - Per pipe DPC configuration is added to ia_css_isp_parameters | ||
479 | |||
480 | v2.1.17.10 (10 changes parallel), pipe config option for vf output bci mode downscaling | ||
481 | #endif | ||
482 | - vf downscaling using yuv_scale binary. | ||
483 | |||
484 | #ifndef ISP2401 | ||
485 | v2.1.14.10 (7 changes parallel), Add scale mode GDC V2 LUT to CSS API | ||
486 | #else | ||
487 | v2.1.17.12 (11 changes parallel), Add scale mode GDC V2 LUT to CSS API | ||
488 | #endif | ||
489 | - Allow client to set global LUT for gdc v2 (First step in this change. See wiki page for more details) | ||
490 | |||
491 | #ifndef ISP2401 | ||
492 | v2.1.14.10 (8 changes parallel), Include added to type-support.h. | ||
493 | #else | ||
494 | v2.1.17.12 (12 changes parallel), Include added to type-support.h. | ||
495 | #endif | ||
496 | - Include of hive/cell_support.h was added to type-support.h, in order to | ||
497 | - have access to define HAVE_STDINT. | ||
498 | |||
499 | #ifndef ISP2401 | ||
500 | v2.1.14.11 (7 changes parallel), Pipe configuration to enable BLI mode downscaling for | ||
501 | #else | ||
502 | v2.1.17.13 (11 changes parallel), Pipe configuration to enable BLI mode downscaling for | ||
503 | #endif | ||
504 | - BLI mode downscaling for capture post-processing | ||
505 | |||
506 | #ifndef ISP2401 | ||
507 | v2.1.14.14 (9 changes parallel), Fix copyright headers (no functional change) | ||
508 | #else | ||
509 | v2.1.17.15 (8 changes parallel), Add copyright headers to css files | ||
510 | - Add copyright headers to css API files | ||
511 | |||
512 | v2.1.17.15 (8 changes parallel), add copyright header to include files | ||
513 | - add copyright header to include files | ||
514 | |||
515 | v2.1.17.15 (8 changes parallel), add copyright header to isp files | ||
516 | - add copyright header to isp files | ||
517 | |||
518 | v2.1.17.15 (8 changes parallel), add copyright header to refactored code | ||
519 | - add copyright header to refactored code | ||
520 | - (base, camera, runtime directories) | ||
521 | |||
522 | v2.1.17.16 (13 changes parallel), Fix copyright headers (no functional change) | ||
523 | #endif | ||
524 | - No functional change; only fixes copyright headers | ||
525 | |||
526 | #ifndef ISP2401 | ||
527 | v2.1.14.14 (6 changes parallel), Remove continuous mode special case handling in ia_css_pipe_set_isp_config | ||
528 | #else | ||
529 | v2.1.17.16 (10 changes parallel), Remove continuous mode special case handling in ia_css_pipe_set_isp_config | ||
530 | #endif | ||
531 | - For continuous mode isp_config was being send to all pipes, | ||
532 | - even though API ia_css_pipe_set_isp_config is for single pipe | ||
533 | - Removed incorrect case | ||
534 | |||
535 | #ifndef ISP2401 | ||
536 | v2.1.14.14 (6 changes parallel), DVS statistics grid produced by accelerator | ||
537 | #else | ||
538 | v2.1.17.16 (5 changes parallel), Added documentation to formats_config header file | ||
539 | - Added description of ranges for full-range flag | ||
540 | |||
541 | v2.1.17.16 (10 changes parallel), DVS statistics grid produced by accelerator | ||
542 | #endif | ||
543 | - Add DVS statistics produced by accelerator grid to pipe info | ||
544 | - Add ia_css_pipe_has_dvs_stats function | ||
545 | |||
546 | #ifndef ISP2401 | ||
547 | v2.1.14.15 (7 changes parallel), cont_remove_x_y_end_from_ae_and_awb | ||
548 | #else | ||
549 | v2.1.17.17 (5 changes parallel), Provide the CSS interface to select the luma only binaries | ||
550 | - Add a flag "enable_luma_only" to "struct ia_css_pipe_config" | ||
551 | |||
552 | v2.1.17.17 (11 changes parallel), cont_remove_x_y_end_from_ae_and_awb | ||
553 | #endif | ||
554 | - this patch doesn't introduce any new api change, it only fixes a recent | ||
555 | - api merged change (#31938) , in order to have success CI i had to upload an api change request | ||
556 | |||
557 | #ifndef ISP2401 | ||
558 | v2.1.14.17 (6 changes parallel), Add XNR3 blending strength to kernel interface | ||
559 | - Added a blending strength field to the XNR3 kernel interface to add | ||
560 | - support for blending. | ||
561 | #else | ||
562 | v2.1.17.17 (10 changes parallel), GAC state dump for debug | ||
563 | - added ia_css_dump_gac_state function | ||
564 | |||
565 | v2.1.17.18 (23 changes parallel), output_format_nv12_16 | ||
566 | - added new output fromat nv12_16 | ||
567 | #endif | ||
568 | |||
569 | #ifndef ISP2401 | ||
570 | v2.1.14.18 (22 changes parallel), eliminate two_pixels_per_clock field | ||
571 | #else | ||
572 | v2.1.17.18 (4 changes parallel), Remove author details from SKC src code | ||
573 | - remove author details from skc src code | ||
574 | |||
575 | v2.1.17.19 (26 changes parallel), eliminate two_pixels_per_clock field | ||
576 | #endif | ||
577 | - remove obsolete field two_pixels_per_clock | ||
578 | |||
579 | #ifndef ISP2401 | ||
580 | v2.1.14.19 (3 changes parallel), Fix copyright headers (no functional change) | ||
581 | #else | ||
582 | v2.1.17.20 (7 changes parallel), Fix copyright headers (no functional change) | ||
583 | #endif | ||
584 | - No functional change; only fixes copyright headers | ||
585 | |||
586 | #ifndef ISP2401 | ||
587 | v2.1.14.21 (3 changes parallel), ia_css_skc_dvs_statistics field size change | ||
588 | - ia_css_skc_dvs_statistics field size change | ||
589 | #else | ||
590 | v2.1.17.20 (11 changes parallel), Add XNR3 blending strength to kernel interface | ||
591 | - Added a blending strength field to the XNR3 kernel interface to add | ||
592 | - support for blending. | ||
593 | #endif | ||
594 | |||
595 | #ifndef ISP2401 | ||
596 | v2.1.15.0 (3 changes parallel), revert ia_css_skc_dvs_statistics field size change | ||
597 | - Reverted field size change, change was not ready for driver yet. | ||
598 | #else | ||
599 | v2.1.17.21 (24 changes parallel), Add N_CSS_PRBS_IDS and N_CSS_TPG_IDS | ||
600 | - Add N_CSS_PRBS_IDS to reflect the number of ia_css_prbs_id enum | ||
601 | - Add N_CSS_TPG_IDS to reflect the number of ia_css_tpg_id enum | ||
602 | #endif | ||
603 | |||
604 | #ifndef ISP2401 | ||
605 | v2.1.15.2 (3 changes parallel), Return an error when both DPC and BDS are enabled in a pipe config | ||
606 | - Return an error when both DPC and BDS are enabled in a pipe config | ||
607 | #else | ||
608 | v2.1.17.23 (8 changes parallel), ia_css_skc_dvs_statistics field size change | ||
609 | - ia_css_skc_dvs_statistics field size change | ||
610 | #endif | ||
611 | |||
612 | #ifndef ISP2401 | ||
613 | v2.1.15.3 (2 changes parallel), Update skycam DPC_MAX_NUMBER_OF_DP | ||
614 | - Automated tooling requires an API change request | ||
615 | - This change changes the implementation of #define DPC_MAX_NUMBER_OF_DP | ||
616 | - it now returns a different number | ||
617 | #else | ||
618 | v2.1.19.0 (6 changes parallel) | ||
619 | - Added code to calculate input_res using the Windows specification of binning | ||
620 | #endif | ||
621 | |||
622 | #ifndef ISP2401 | ||
623 | v2.1.15.3 (18 changes parallel), output_format_nv12_16 | ||
624 | - added new output fromat nv12_16 | ||
625 | #else | ||
626 | v2.1.20.0 (7 changes parallel), Add interface to select TNR enabled binaries | ||
627 | - Add a bool "enable_tnr" to "struct ia_css_pipe_config" | ||
628 | |||
629 | v2.1.20.0 (6 changes parallel), OSYS & GDC Debug dump function addition | ||
630 | - add GDC state dump function | ||
631 | - add OSYS state dump function | ||
632 | |||
633 | v2.1.20.4 (7 changes parallel), Add ref_buf_select parameter for TNR3 to kernel interface | ||
634 | - Added a ref_buf_select parameter to the TNR3 kernel interface to add | ||
635 | - support for multiple reference buffers. | ||
636 | |||
637 | v2.1.20.4 (6 changes parallel), DVS MAX grid dimensions to cover maximal resolution | ||
638 | - rename DVS_TABLE_HEIGHT/WIDTH to MAX_DVS_COORDS_TABLE_HEIGHT/WIDTH | ||
639 | - modify value of the above macros to cover max resolution | ||
640 | |||
641 | v2.1.20.5 (54 changes parallel), add input feeder calculations getter | ||
642 | - add input_feeder_config public struct | ||
643 | - add get_input_feeder_config getter | ||
644 | |||
645 | v2.1.20.5 (4 changes parallel), Enable runtime updating mapped args for QoS extension pipe | ||
646 | - added ia_css_pipe_update_qos_ext_mapped_arg() | ||
647 | |||
648 | v2.1.20.7 (77 changes parallel), Add parameters to CPU routines via a macro. | ||
649 | - Replaced CPU memory allocation functions with macros to add caller func name + line number. | ||
650 | - This is done to help debug memory access issues, allocation issues, etc. | ||
651 | - Changed API: only ia_css_env.h | ||
652 | |||
653 | v2.1.20.7 (2 changes parallel), Frame format override | ||
654 | - Added a function call to the pipe interface for overriding | ||
655 | - the frame format as set in the pipe. | ||
656 | - This is an optional interface that can be used under | ||
657 | - some strict conditions. | ||
658 | |||
659 | v2.1.20.7 (2 changes parallel), Output_system_in_res Information | ||
660 | - Output_system_in_res_info field added to pipe_info struct | ||
661 | |||
662 | v2.1.20.8, Temprarily disable memory debug features for SVOS. | ||
663 | - Temporary commented out the additions to allow SKC testing till root cause found | ||
664 | - Changed files ia_css_env.h and sh_css.c. | ||
665 | |||
666 | v2.1.20.9, Enable ISP 2.7 naming | ||
667 | - Add IA_CSS_PIPE_VERSION_2_7 to enum ia_css_pipe_version | ||
668 | - Add #define SH_CSS_ISP_PIPE_VERSION_2_7 4 | ||
669 | #endif | ||
670 | |||
671 | */ | ||
672 | |||
673 | #endif /*__CSS_API_VERSION_H*/ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hive_isp_css_ddr_hrt_modified.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hive_isp_css_ddr_hrt_modified.h deleted file mode 100644 index 39785aa21459..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hive_isp_css_ddr_hrt_modified.h +++ /dev/null | |||
@@ -1,148 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2010-2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _hive_isp_css_ddr_hrt_modified_h_ | ||
16 | #define _hive_isp_css_ddr_hrt_modified_h_ | ||
17 | |||
18 | #include <hmm_64/hmm.h> | ||
19 | |||
20 | /* This function reads an image from DDR and stores it in the img_buf array | ||
21 | that has been allocated by the caller. | ||
22 | The specifics of how the pixels are stored into DDR by the DMA are taken | ||
23 | into account (bits padded to a width of 256, depending on the number of | ||
24 | elements per ddr word). | ||
25 | The DMA specific parameters give to this function (elems_per_xword and sign_extend) | ||
26 | should correspond to those given to the DMA engine. | ||
27 | The address is a virtual address which will be translated to a physical address before | ||
28 | data is loaded from or stored to that address. | ||
29 | |||
30 | The return value is 0 in case of success and 1 in case of failure. | ||
31 | */ | ||
32 | unsigned int | ||
33 | hrt_isp_css_read_image_from_ddr( | ||
34 | unsigned short *img_buf, | ||
35 | unsigned int width, | ||
36 | unsigned int height, | ||
37 | unsigned int elems_per_xword, | ||
38 | unsigned int sign_extend, | ||
39 | hmm_ptr virt_addr); | ||
40 | |||
41 | /* This function writes an image to DDR, keeping the same aspects into account as the read_image function | ||
42 | above. */ | ||
43 | unsigned int | ||
44 | hrt_isp_css_write_image_to_ddr( | ||
45 | const unsigned short *img_buf, | ||
46 | unsigned int width, | ||
47 | unsigned int height, | ||
48 | unsigned int elems_per_xword, | ||
49 | unsigned int sign_extend, | ||
50 | hmm_ptr virt_addr); | ||
51 | |||
52 | /* return the size in bytes of an image (frame or plane). */ | ||
53 | unsigned int | ||
54 | hrt_isp_css_sizeof_image_in_ddr( | ||
55 | unsigned int width, | ||
56 | unsigned int height, | ||
57 | unsigned int bits_per_element); | ||
58 | |||
59 | unsigned int | ||
60 | hrt_isp_css_stride_of_image_in_ddr( | ||
61 | unsigned int width, | ||
62 | unsigned int bits_per_element); | ||
63 | |||
64 | hmm_ptr | ||
65 | hrt_isp_css_alloc_image_in_ddr( | ||
66 | unsigned int width, | ||
67 | unsigned int height, | ||
68 | unsigned int elems_per_xword); | ||
69 | |||
70 | hmm_ptr | ||
71 | hrt_isp_css_calloc_image_in_ddr( | ||
72 | unsigned int width, | ||
73 | unsigned int height, | ||
74 | unsigned int elems_per_xword); | ||
75 | |||
76 | #ifndef HIVE_ISP_NO_GDC | ||
77 | #include "gdc_v2_defs.h" | ||
78 | |||
79 | hmm_ptr | ||
80 | hrt_isp_css_alloc_gdc_lut_in_ddr(void); | ||
81 | |||
82 | void | ||
83 | hrt_isp_css_write_gdc_lut_to_ddr( | ||
84 | short values[4][HRT_GDC_N], | ||
85 | hmm_ptr virt_addr); | ||
86 | #endif | ||
87 | |||
88 | #ifdef _HIVE_ISP_CSS_FPGA_SYSTEM | ||
89 | hmm_ptr | ||
90 | hrt_isp_css_alloc_image_for_display( | ||
91 | unsigned int width, | ||
92 | unsigned int height, | ||
93 | unsigned int elems_per_xword); | ||
94 | |||
95 | hmm_ptr | ||
96 | hrt_isp_css_calloc_image_for_display( | ||
97 | unsigned int width, | ||
98 | unsigned int height, | ||
99 | unsigned int elems_per_xword); | ||
100 | #endif | ||
101 | |||
102 | /* New set of functions, these do not require the elems_per_xword, but use bits_per_element instead, | ||
103 | this way the user does not need to know about the width of a DDR word. */ | ||
104 | unsigned int | ||
105 | hrt_isp_css_read_unsigned( | ||
106 | unsigned short *target, | ||
107 | unsigned int width, | ||
108 | unsigned int height, | ||
109 | unsigned int source_bits_per_element, | ||
110 | hmm_ptr source); | ||
111 | |||
112 | unsigned int | ||
113 | hrt_isp_css_read_signed( | ||
114 | short *target, | ||
115 | unsigned int width, | ||
116 | unsigned int height, | ||
117 | unsigned int source_bits_per_element, | ||
118 | hmm_ptr source); | ||
119 | |||
120 | unsigned int | ||
121 | hrt_isp_css_write_unsigned( | ||
122 | const unsigned short *source, | ||
123 | unsigned int width, | ||
124 | unsigned int height, | ||
125 | unsigned int target_bits_per_element, | ||
126 | hmm_ptr target); | ||
127 | |||
128 | unsigned int | ||
129 | hrt_isp_css_write_signed( | ||
130 | const short *source, | ||
131 | unsigned int width, | ||
132 | unsigned int height, | ||
133 | unsigned int target_bits_per_element, | ||
134 | hmm_ptr target); | ||
135 | |||
136 | hmm_ptr | ||
137 | hrt_isp_css_alloc( | ||
138 | unsigned int width, | ||
139 | unsigned int height, | ||
140 | unsigned int bits_per_element); | ||
141 | |||
142 | hmm_ptr | ||
143 | hrt_isp_css_calloc( | ||
144 | unsigned int width, | ||
145 | unsigned int height, | ||
146 | unsigned int bits_per_element); | ||
147 | |||
148 | #endif /* _hive_isp_css_ddr_hrt_modified_h_ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hive_isp_css_hrt_modified.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hive_isp_css_hrt_modified.h deleted file mode 100644 index 342553d10e08..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hive_isp_css_hrt_modified.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2010-2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _hive_isp_css_hrt_h | ||
16 | #define _hive_isp_css_hrt_h | ||
17 | |||
18 | #include "system_types.h" | ||
19 | |||
20 | #include "hive_isp_css_host_ids_hrt.h" | ||
21 | #include "hive_isp_css_defs.h" | ||
22 | |||
23 | #ifdef HRT_ISP_CSS_CUSTOM_HOST | ||
24 | #ifndef HRT_USE_VIR_ADDRS | ||
25 | #define HRT_USE_VIR_ADDRS | ||
26 | #endif | ||
27 | /*#include "hive_isp_css_custom_host_hrt.h"*/ | ||
28 | #endif | ||
29 | |||
30 | #include <gpio_block.h> | ||
31 | #include <gp_regs.h> | ||
32 | #include <gp_timer_hrt.h> | ||
33 | #include <css_receiver_2400_hrt.h> | ||
34 | // #include <isp2400_mamoiada_params.h> | ||
35 | // #include <isp2400_support.h> | ||
36 | /* insert idle signal clearing and setting around hrt_main */ | ||
37 | #if !defined(HRT_HW) || defined(HRT_ISP_CSS_INSERT_IDLE_SIGNAL) | ||
38 | #define hrt_main _hrt_isp_css_main | ||
39 | #endif | ||
40 | #ifdef _HIVE_ISP_CSS_SPECMAN_SYSTEM | ||
41 | #include "hive_isp_css_2400_specman_system.h" | ||
42 | #else | ||
43 | #if defined(IS_ISP_2400_MAMOIADA_SYSTEM) | ||
44 | #include "hive_isp_css_2400_system.h" | ||
45 | #elif defined(IS_ISP_2401_MAMOIADA_SYSTEM) | ||
46 | #include "hive_isp_css_2401_system.h" | ||
47 | #else | ||
48 | #error "hive_isp_css_hrt_modified.h: SYSTEM must be one of {2400_MAMOIADA_SYSTEM, 2401_MAMOIADA_SYSTEM}" | ||
49 | #endif | ||
50 | #endif | ||
51 | #include <sp_hrt.h> | ||
52 | #include <input_system_hrt.h> | ||
53 | #include <input_selector_hrt.h> | ||
54 | #include <sig_monitor_hrt.h> | ||
55 | |||
56 | #include "hive_isp_css_sdram_wakeup_hrt.h" | ||
57 | #include "hive_isp_css_idle_signal_hrt.h" | ||
58 | #include "hive_isp_css_sp_hrt.h" | ||
59 | #include "hive_isp_css_isp_hrt.h" | ||
60 | #include "hive_isp_css_streaming_to_mipi_hrt.h" | ||
61 | #include "hive_isp_css_testbench_hrt.h" | ||
62 | #include "hive_isp_css_streaming_monitors_hrt.h" | ||
63 | #include "hive_isp_css_gp_regs_hrt.h" | ||
64 | #if defined(IS_ISP_2400_MAMOIADA_SYSTEM) | ||
65 | #include "hive_isp_css_irq_hrt.h" | ||
66 | #elif defined(IS_ISP_2401_MAMOIADA_SYSTEM) | ||
67 | #include "hive_isp_css_2401_irq_hrt.h" | ||
68 | #else | ||
69 | #error "hive_isp_css_hrt_modified.h: SYSTEM must be one of {2400_MAMOIADA_SYSTEM, 2401_MAMOIADA_SYSTEM}" | ||
70 | #endif | ||
71 | |||
72 | #include "hive_isp_css_stream_switch_hrt.h" | ||
73 | |||
74 | #include "hive_isp_css_ddr_hrt_modified.h" | ||
75 | #include "hive_isp_css_dma_set_hrt.h" | ||
76 | |||
77 | #define HIVE_ISP_CSS_NO_STREAM_SWITCH 1 | ||
78 | |||
79 | #endif /* _hive_isp_css_hrt_h */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/input_formatter_global.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/input_formatter_global.h index 5654d911db65..7558f4964313 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/input_formatter_global.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/input_formatter_global.h | |||
@@ -107,22 +107,6 @@ struct input_formatter_cfg_s { | |||
107 | uint32_t block_no_reqs; | 107 | uint32_t block_no_reqs; |
108 | }; | 108 | }; |
109 | 109 | ||
110 | #define DEFAULT_IF_CONFIG \ | ||
111 | { \ | ||
112 | 0, /* start_line */\ | ||
113 | 0, /* start_column */\ | ||
114 | 0, /* left_padding */\ | ||
115 | 0, /* cropped_height */\ | ||
116 | 0, /* cropped_width */\ | ||
117 | 0, /* deinterleaving */\ | ||
118 | 0, /*.buf_vecs */\ | ||
119 | 0, /* buf_start_index */\ | ||
120 | 0, /* buf_increment */\ | ||
121 | 0, /* buf_eol_offset */\ | ||
122 | false, /* is_yuv420_format */\ | ||
123 | false /* block_no_reqs */\ | ||
124 | } | ||
125 | |||
126 | extern const hrt_address HIVE_IF_SRST_ADDRESS[N_INPUT_FORMATTER_ID]; | 110 | extern const hrt_address HIVE_IF_SRST_ADDRESS[N_INPUT_FORMATTER_ID]; |
127 | extern const hrt_data HIVE_IF_SRST_MASK[N_INPUT_FORMATTER_ID]; | 111 | extern const hrt_data HIVE_IF_SRST_MASK[N_INPUT_FORMATTER_ID]; |
128 | extern const uint8_t HIVE_IF_SWITCH_CODE[N_INPUT_FORMATTER_ID]; | 112 | extern const uint8_t HIVE_IF_SWITCH_CODE[N_INPUT_FORMATTER_ID]; |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/resource_global.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/resource_global.h deleted file mode 100644 index 01c915c033a9..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/resource_global.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __RESOURCE_GLOBAL_H_INCLUDED__ | ||
16 | #define __RESOURCE_GLOBAL_H_INCLUDED__ | ||
17 | |||
18 | #define IS_RESOURCE_VERSION_1 | ||
19 | |||
20 | typedef enum { | ||
21 | DMA_CHANNEL_RESOURCE_TYPE, | ||
22 | IRQ_CHANNEL_RESOURCE_TYPE, | ||
23 | MEM_SECTION_RESOURCE_TYPE, | ||
24 | N_RESOURCE_TYPE | ||
25 | } resource_type_ID_t; | ||
26 | |||
27 | typedef enum { | ||
28 | PERMANENT_RESOURCE_RESERVATION, | ||
29 | PERSISTENT_RESOURCE_RESERVATION, | ||
30 | DEDICTATED_RESOURCE_RESERVATION, | ||
31 | SHARED_RESOURCE_RESERVATION, | ||
32 | N_RESOURCE_RESERVATION | ||
33 | } resource_reservation_t; | ||
34 | |||
35 | #endif /* __RESOURCE_GLOBAL_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/xmem_global.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/xmem_global.h deleted file mode 100644 index 1d3a43abe55d..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/xmem_global.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XMEM_GLOBAL_H_INCLUDED__ | ||
16 | #define __XMEM_GLOBAL_H_INCLUDED__ | ||
17 | |||
18 | #include "isp.h" | ||
19 | |||
20 | #endif /* __XMEM_GLOBAL_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h deleted file mode 100644 index 6928965cf513..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __BAMEM_H_INCLUDED__ | ||
16 | #define __BAMEM_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is included on every cell {SP,ISP,host} and on every system | ||
20 | * that uses the BAMEM device. It defines the API to DLI bridge | ||
21 | * | ||
22 | * System and cell specific interfaces and inline code are included | ||
23 | * conditionally through Makefile path settings. | ||
24 | * | ||
25 | * - . system and cell agnostic interfaces, constants and identifiers | ||
26 | * - public: system agnostic, cell specific interfaces | ||
27 | * - private: system dependent, cell specific interfaces & inline implementations | ||
28 | * - global: system specific constants and identifiers | ||
29 | * - local: system and cell specific constants and identifiers | ||
30 | */ | ||
31 | |||
32 | |||
33 | #include "system_local.h" | ||
34 | #include "bamem_local.h" | ||
35 | |||
36 | #ifndef __INLINE_BAMEM__ | ||
37 | #define STORAGE_CLASS_BAMEM_H extern | ||
38 | #define STORAGE_CLASS_BAMEM_C | ||
39 | #include "bamem_public.h" | ||
40 | #else /* __INLINE_BAMEM__ */ | ||
41 | #define STORAGE_CLASS_BAMEM_H static inline | ||
42 | #define STORAGE_CLASS_BAMEM_C static inline | ||
43 | #include "bamem_private.h" | ||
44 | #endif /* __INLINE_BAMEM__ */ | ||
45 | |||
46 | #endif /* __BAMEM_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bbb_config.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bbb_config.h deleted file mode 100644 index 18bc5ef3d0bf..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bbb_config.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __BBB_CONFIG_H_INCLUDED__ | ||
16 | #define __BBB_CONFIG_H_INCLUDED__ | ||
17 | /* This header contains BBB defines common to ISP and host */ | ||
18 | |||
19 | #define BFA_MAX_KWAY (49) | ||
20 | #define BFA_RW_LUT_SIZE (7) | ||
21 | |||
22 | #define SAD3x3_IN_SHIFT (2) /* input right shift value for SAD3x3 */ | ||
23 | #define SAD3x3_OUT_SHIFT (2) /* output right shift value for SAD3x3 */ | ||
24 | |||
25 | /* XCU and BMA related defines shared between host and ISP | ||
26 | * also need to be moved here */ | ||
27 | #endif /* __BBB_CONFIG_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/cpu_mem_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/cpu_mem_support.h deleted file mode 100644 index 6d014fafb713..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/cpu_mem_support.h +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __CPU_MEM_SUPPORT_H_INCLUDED__ | ||
16 | #define __CPU_MEM_SUPPORT_H_INCLUDED__ | ||
17 | |||
18 | #if defined (__KERNEL__) | ||
19 | #include <linux/string.h> /* memset */ | ||
20 | #else | ||
21 | #include <string.h> /* memset */ | ||
22 | #endif | ||
23 | |||
24 | #include "sh_css_internal.h" /* sh_css_malloc and sh_css_free */ | ||
25 | |||
26 | static inline void* | ||
27 | ia_css_cpu_mem_alloc(unsigned int size) | ||
28 | { | ||
29 | return sh_css_malloc(size); | ||
30 | } | ||
31 | |||
32 | static inline void* | ||
33 | ia_css_cpu_mem_copy(void* dst, const void* src, unsigned int size) | ||
34 | { | ||
35 | if(!src || !dst) | ||
36 | return NULL; | ||
37 | |||
38 | return memcpy(dst, src, size); | ||
39 | } | ||
40 | |||
41 | static inline void* | ||
42 | ia_css_cpu_mem_set_zero(void* dst, unsigned int size) | ||
43 | { | ||
44 | if(!dst) | ||
45 | return NULL; | ||
46 | |||
47 | return memset(dst, 0, size); | ||
48 | } | ||
49 | |||
50 | static inline void | ||
51 | ia_css_cpu_mem_free(void* ptr) | ||
52 | { | ||
53 | if(!ptr) | ||
54 | return; | ||
55 | |||
56 | sh_css_free(ptr); | ||
57 | } | ||
58 | |||
59 | #endif /* __CPU_MEM_SUPPORT_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2400_config.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2400_config.h deleted file mode 100644 index ab3391716c82..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2400_config.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP2400_CONFIG_H_INCLUDED__ | ||
16 | #define __ISP2400_CONFIG_H_INCLUDED__ | ||
17 | |||
18 | #define NUM_BITS 14 | ||
19 | #define NUM_SLICE_ELEMS 4 | ||
20 | #define ROUNDMODE ROUND_NEAREST_EVEN | ||
21 | #define MAX_SHIFT_1W (NUM_BITS-1) /* Max number of bits a 1w input can be shifted */ | ||
22 | #define MAX_SHIFT_2W (2*NUM_BITS-1) /* Max number of bits a 2w input can be shifted */ | ||
23 | |||
24 | #endif /* __ISP2400_CONFIG_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2500_config.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2500_config.h deleted file mode 100644 index 4fae856f5a23..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2500_config.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP2500_CONFIG_H_INCLUDED__ | ||
16 | #define __ISP2500_CONFIG_H_INCLUDED__ | ||
17 | |||
18 | #define NUM_BITS 12 | ||
19 | #define NUM_SLICE_ELEMS 4 | ||
20 | #define ROUNDMODE ROUND_NEAREST_EVEN | ||
21 | #define MAX_SHIFT_1W (NUM_BITS-1) /* Max number of bits a 1w input can be shifted */ | ||
22 | #define MAX_SHIFT_2W (2*NUM_BITS-1) /* Max number of bits a 2w input can be shifted */ | ||
23 | |||
24 | |||
25 | #define HAS_div_unit | ||
26 | |||
27 | #define HAS_vec_sub | ||
28 | |||
29 | #endif /* __ISP2500_CONFIG_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2600_config.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2600_config.h deleted file mode 100644 index 6086be8cb0d3..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2600_config.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP2600_CONFIG_H_INCLUDED__ | ||
16 | #define __ISP2600_CONFIG_H_INCLUDED__ | ||
17 | |||
18 | |||
19 | #define NUM_BITS 16 | ||
20 | |||
21 | |||
22 | #define NUM_SLICE_ELEMS 8 | ||
23 | #define ROUNDMODE ROUND_NEAREST_EVEN | ||
24 | #define MAX_SHIFT_1W (NUM_BITS-1) /* Max number of bits a 1w input can be shifted */ | ||
25 | #define MAX_SHIFT_2W (2*NUM_BITS-1) /* Max number of bits a 2w input can be shifted */ | ||
26 | #define ISP_NWAY 32 /* Number of elements in a vector in ISP 2600 */ | ||
27 | |||
28 | #define HAS_div_unit | ||
29 | #define HAS_1w_sqrt_u_unit | ||
30 | #define HAS_2w_sqrt_u_unit | ||
31 | |||
32 | #define HAS_vec_sub | ||
33 | |||
34 | #endif /* __ISP2600_CONFIG_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2601_config.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2601_config.h deleted file mode 100644 index beceefa24ca0..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp2601_config.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __ISP2601_CONFIG_H_INCLUDED__ | ||
17 | #define __ISP2601_CONFIG_H_INCLUDED__ | ||
18 | |||
19 | #define NUM_BITS 16 | ||
20 | #define ISP_VEC_ELEMBITS NUM_BITS | ||
21 | #define ISP_NWAY 32 | ||
22 | #define NUM_SLICE_ELEMS 4 | ||
23 | #define ROUNDMODE ROUND_NEAREST_EVEN | ||
24 | #define MAX_SHIFT_1W (NUM_BITS-1) /* Max number of bits a 1w input can be shifted */ | ||
25 | #define MAX_SHIFT_2W (2*NUM_BITS-1) /* Max number of bits a 2w input can be shifted */ | ||
26 | |||
27 | #define HAS_div_unit | ||
28 | #define HAS_bfa_unit | ||
29 | #define HAS_1w_sqrt_u_unit | ||
30 | #define HAS_2w_sqrt_u_unit | ||
31 | |||
32 | #define HAS_vec_sub | ||
33 | |||
34 | /* Bit widths and element widths defined in HW implementation of BFA */ | ||
35 | #define BFA_THRESHOLD_BIT_CNT (8) | ||
36 | #define BFA_THRESHOLD_MASK ((1<<BFA_THRESHOLD_BIT_CNT)-1) | ||
37 | #define BFA_SW_BIT_CNT (7) | ||
38 | #define BFA_SW_MASK ((1<<BFA_SW_BIT_CNT)-1) | ||
39 | |||
40 | #define BFA_RW_BIT_CNT (7) | ||
41 | #define BFA_RW_MASK ((1<<BFA_RW_BIT_CNT)-1) | ||
42 | #define BFA_RW_SLOPE_BIT_POS (8) | ||
43 | #define BFA_RW_SLOPE_BIT_SHIFT (5) | ||
44 | |||
45 | #define BFA_RW_IDX_BIT_CNT (3) | ||
46 | #define BFA_RW_FRAC_BIT_CNT (5) | ||
47 | #define BFA_RW_LUT0_FRAC_START_BIT (0) | ||
48 | #define BFA_RW_LUT0_FRAC_END_BIT (BFA_RW_LUT0_FRAC_START_BIT+BFA_RW_FRAC_BIT_CNT-1) /* 4 */ | ||
49 | #define BFA_RW_LUT1_FRAC_START_BIT (2) | ||
50 | #define BFA_RW_LUT1_FRAC_END_BIT (BFA_RW_LUT1_FRAC_START_BIT+BFA_RW_FRAC_BIT_CNT-1) /* 6 */ | ||
51 | /* LUT IDX end bit computation, start+idx_bit_cnt-2, one -1 comes as we count | ||
52 | * bits from 0, another -1 comes as we use 2 lut table, so idx_bit_cnt is one | ||
53 | * bit more */ | ||
54 | #define BFA_RW_LUT0_IDX_START_BIT (BFA_RW_LUT0_FRAC_END_BIT+1) /* 5 */ | ||
55 | #define BFA_RW_LUT0_IDX_END_BIT (BFA_RW_LUT0_IDX_START_BIT+BFA_RW_IDX_BIT_CNT-2) /* 6 */ | ||
56 | #define BFA_RW_LUT1_IDX_START_BIT (BFA_RW_LUT1_FRAC_END_BIT + 1) /* 7 */ | ||
57 | #define BFA_RW_LUT1_IDX_END_BIT (BFA_RW_LUT1_IDX_START_BIT+BFA_RW_IDX_BIT_CNT-2) /* 8 */ | ||
58 | #define BFA_RW_LUT_THRESHOLD (1<<(BFA_RW_LUT1_IDX_END_BIT-1)) /* 0x80 : next bit after lut1 end is set */ | ||
59 | #define BFA_RW_LUT1_IDX_OFFSET ((1<<(BFA_RW_IDX_BIT_CNT-1))-1) /* 3 */ | ||
60 | |||
61 | #define BFA_CP_MASK (0xFFFFFF80) | ||
62 | #define BFA_SUBABS_SHIFT (6) | ||
63 | #define BFA_SUBABS_BIT_CNT (8) | ||
64 | #define BFA_SUBABS_MAX ((1<<BFA_SUBABS_BIT_CNT)-1) | ||
65 | #define BFA_SUBABSSAT_BIT_CNT (9) | ||
66 | #define BFA_SUBABSSAT_MAX ((1<<BFA_SUBABSSAT_BIT_CNT)-1) | ||
67 | #define BFA_WEIGHT_SHIFT (6) | ||
68 | |||
69 | #endif /* __ISP2601_CONFIG_H_INCLUDED__ */ | ||
70 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_config.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_config.h deleted file mode 100644 index 80506f2419a8..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_config.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP_CONFIG_H_INCLUDED__ | ||
16 | #define __ISP_CONFIG_H_INCLUDED__ | ||
17 | |||
18 | #if defined(ISP2400) || defined(ISP2401) | ||
19 | #include "isp2400_config.h" | ||
20 | #else | ||
21 | #error "Please define a core {ISP2400, ISP2401}" | ||
22 | #endif | ||
23 | |||
24 | #endif /* __ISP_CONFIG_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h deleted file mode 100644 index 0d978e5911c0..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h +++ /dev/null | |||
@@ -1,844 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP_OP1W_H_INCLUDED__ | ||
16 | #define __ISP_OP1W_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is part of the Multi-precision vector operations exstension package. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Single-precision vector operations | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * Prerequisites: | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #ifdef INLINE_ISP_OP1W | ||
32 | #define STORAGE_CLASS_ISP_OP1W_FUNC_H static inline | ||
33 | #define STORAGE_CLASS_ISP_OP1W_DATA_H static inline_DATA | ||
34 | #else /* INLINE_ISP_OP1W */ | ||
35 | #define STORAGE_CLASS_ISP_OP1W_FUNC_H extern | ||
36 | #define STORAGE_CLASS_ISP_OP1W_DATA_H extern_DATA | ||
37 | #endif /* INLINE_ISP_OP1W */ | ||
38 | |||
39 | /* | ||
40 | * Single-precision data type specification | ||
41 | */ | ||
42 | |||
43 | #include "isp_op1w_types.h" | ||
44 | #include "isp_op2w_types.h" // for doubling operations. | ||
45 | |||
46 | /* | ||
47 | * Single-precision prototype specification | ||
48 | */ | ||
49 | |||
50 | /* Arithmetic */ | ||
51 | |||
52 | /* @brief bitwise AND | ||
53 | * | ||
54 | * @param[in] _a first argument | ||
55 | * @param[in] _b second argument | ||
56 | * | ||
57 | * @return bitwise and of both input arguments | ||
58 | * | ||
59 | * This function will calculate the bitwise and. | ||
60 | * result = _a & _b | ||
61 | */ | ||
62 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_and( | ||
63 | const tvector1w _a, | ||
64 | const tvector1w _b); | ||
65 | |||
66 | /* @brief bitwise OR | ||
67 | * | ||
68 | * @param[in] _a first argument | ||
69 | * @param[in] _b second argument | ||
70 | * | ||
71 | * @return bitwise or of both input arguments | ||
72 | * | ||
73 | * This function will calculate the bitwise or. | ||
74 | * result = _a | _b | ||
75 | */ | ||
76 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_or( | ||
77 | const tvector1w _a, | ||
78 | const tvector1w _b); | ||
79 | |||
80 | /* @brief bitwise XOR | ||
81 | * | ||
82 | * @param[in] _a first argument | ||
83 | * @param[in] _b second argument | ||
84 | * | ||
85 | * @return bitwise xor of both input arguments | ||
86 | * | ||
87 | * This function will calculate the bitwise xor. | ||
88 | * result = _a ^ _b | ||
89 | */ | ||
90 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_xor( | ||
91 | const tvector1w _a, | ||
92 | const tvector1w _b); | ||
93 | |||
94 | /* @brief bitwise inverse | ||
95 | * | ||
96 | * @param[in] _a first argument | ||
97 | * | ||
98 | * @return bitwise inverse of both input arguments | ||
99 | * | ||
100 | * This function will calculate the bitwise inverse. | ||
101 | * result = ~_a | ||
102 | */ | ||
103 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_inv( | ||
104 | const tvector1w _a); | ||
105 | |||
106 | /* Additive */ | ||
107 | |||
108 | /* @brief addition | ||
109 | * | ||
110 | * @param[in] _a first argument | ||
111 | * @param[in] _b second argument | ||
112 | * | ||
113 | * @return sum of both input arguments | ||
114 | * | ||
115 | * This function will calculate the sum of the input arguments. | ||
116 | * in case of overflow it will wrap around. | ||
117 | * result = _a + _b | ||
118 | */ | ||
119 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_add( | ||
120 | const tvector1w _a, | ||
121 | const tvector1w _b); | ||
122 | |||
123 | /* @brief subtraction | ||
124 | * | ||
125 | * @param[in] _a first argument | ||
126 | * @param[in] _b second argument | ||
127 | * | ||
128 | * @return _b subtracted from _a. | ||
129 | * | ||
130 | * This function will subtract _b from _a. | ||
131 | * in case of overflow it will wrap around. | ||
132 | * result = _a - _b | ||
133 | */ | ||
134 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_sub( | ||
135 | const tvector1w _a, | ||
136 | const tvector1w _b); | ||
137 | |||
138 | /* @brief saturated addition | ||
139 | * | ||
140 | * @param[in] _a first argument | ||
141 | * @param[in] _b second argument | ||
142 | * | ||
143 | * @return saturated sum of both input arguments | ||
144 | * | ||
145 | * This function will calculate the sum of the input arguments. | ||
146 | * in case of overflow it will saturate. | ||
147 | * result = CLIP(_a + _b, MIN_RANGE, MAX_RANGE); | ||
148 | */ | ||
149 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_addsat( | ||
150 | const tvector1w _a, | ||
151 | const tvector1w _b); | ||
152 | |||
153 | /* @brief saturated subtraction | ||
154 | * | ||
155 | * @param[in] _a first argument | ||
156 | * @param[in] _b second argument | ||
157 | * | ||
158 | * @return saturated subtraction of both input arguments | ||
159 | * | ||
160 | * This function will subtract _b from _a. | ||
161 | * in case of overflow it will saturate. | ||
162 | * result = CLIP(_a - _b, MIN_RANGE, MAX_RANGE); | ||
163 | */ | ||
164 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subsat( | ||
165 | const tvector1w _a, | ||
166 | const tvector1w _b); | ||
167 | |||
168 | #ifdef ISP2401 | ||
169 | /* @brief Unsigned saturated subtraction | ||
170 | * | ||
171 | * @param[in] _a first argument | ||
172 | * @param[in] _b second argument | ||
173 | * | ||
174 | * @return saturated subtraction of both input arguments | ||
175 | * | ||
176 | * This function will subtract _b from _a. | ||
177 | * in case of overflow it will saturate. | ||
178 | * result = CLIP(_a - _b, 0, MAX_RANGE); | ||
179 | */ | ||
180 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w_unsigned OP_1w_subsat_u( | ||
181 | const tvector1w_unsigned _a, | ||
182 | const tvector1w_unsigned _b); | ||
183 | |||
184 | #endif | ||
185 | /* @brief subtraction with shift right and rounding | ||
186 | * | ||
187 | * @param[in] _a first argument | ||
188 | * @param[in] _b second argument | ||
189 | * | ||
190 | * @return (a - b) >> 1 | ||
191 | * | ||
192 | * This function subtracts _b from _a and right shifts | ||
193 | * the result by 1 bit with rounding. | ||
194 | * No overflow can occur. | ||
195 | * result = (_a - _b) >> 1 | ||
196 | * | ||
197 | * Note: This function will be deprecated due to | ||
198 | * the naming confusion and it will be replaced | ||
199 | * by "OP_1w_subhalfrnd". | ||
200 | */ | ||
201 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subasr1( | ||
202 | const tvector1w _a, | ||
203 | const tvector1w _b); | ||
204 | |||
205 | /* @brief Subtraction with shift right and rounding | ||
206 | * | ||
207 | * @param[in] _a first operand | ||
208 | * @param[in] _b second operand | ||
209 | * | ||
210 | * @return (_a - _b) >> 1 | ||
211 | * | ||
212 | * This function subtracts _b from _a and right shifts | ||
213 | * the result by 1 bit with rounding. | ||
214 | * No overflow can occur. | ||
215 | */ | ||
216 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subhalfrnd( | ||
217 | const tvector1w _a, | ||
218 | const tvector1w _b); | ||
219 | |||
220 | /* @brief Subtraction with shift right and no rounding | ||
221 | * | ||
222 | * @param[in] _a first operand | ||
223 | * @param[in] _b second operand | ||
224 | * | ||
225 | * @return (_a - _b) >> 1 | ||
226 | * | ||
227 | * This function subtracts _b from _a and right shifts | ||
228 | * the result by 1 bit without rounding (i.e. truncation). | ||
229 | * No overflow can occur. | ||
230 | */ | ||
231 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subhalf( | ||
232 | const tvector1w _a, | ||
233 | const tvector1w _b); | ||
234 | |||
235 | |||
236 | /* @brief saturated absolute value | ||
237 | * | ||
238 | * @param[in] _a input | ||
239 | * | ||
240 | * @return saturated absolute value of the input | ||
241 | * | ||
242 | * This function will calculate the saturated absolute value of the input. | ||
243 | * in case of overflow it will saturate. | ||
244 | * if (_a > 0) return _a;<br> | ||
245 | * else return CLIP(-_a, MIN_RANGE, MAX_RANGE);<br> | ||
246 | */ | ||
247 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_abs( | ||
248 | const tvector1w _a); | ||
249 | |||
250 | /* @brief saturated absolute difference | ||
251 | * | ||
252 | * @param[in] _a first argument | ||
253 | * @param[in] _b second argument | ||
254 | * | ||
255 | * @return sat(abs(a-b)); | ||
256 | * | ||
257 | * This function will calculate the saturated absolute value | ||
258 | * of the saturated difference of both inputs. | ||
259 | * result = sat(abs(sat(_a - _b))); | ||
260 | */ | ||
261 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_subabssat( | ||
262 | const tvector1w _a, | ||
263 | const tvector1w _b); | ||
264 | |||
265 | /* Multiplicative */ | ||
266 | |||
267 | /* @brief doubling multiply | ||
268 | * | ||
269 | * @param[in] _a first argument | ||
270 | * @param[in] _b second argument | ||
271 | * | ||
272 | * @return product of _a and _b | ||
273 | * | ||
274 | * This function will calculate the product | ||
275 | * of the input arguments and returns a double | ||
276 | * precision result. | ||
277 | * No overflow can occur. | ||
278 | * result = _a * _b; | ||
279 | */ | ||
280 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector2w OP_1w_muld( | ||
281 | const tvector1w _a, | ||
282 | const tvector1w _b); | ||
283 | |||
284 | /* @brief integer multiply | ||
285 | * | ||
286 | * @param[in] _a first argument | ||
287 | * @param[in] _b second argument | ||
288 | * | ||
289 | * @return product of _a and _b | ||
290 | * | ||
291 | * This function will calculate the product | ||
292 | * of the input arguments and returns the LSB | ||
293 | * aligned single precision result. | ||
294 | * In case of overflow it will wrap around. | ||
295 | * result = _a * _b; | ||
296 | */ | ||
297 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_mul( | ||
298 | const tvector1w _a, | ||
299 | const tvector1w _b); | ||
300 | |||
301 | /* @brief fractional saturating multiply | ||
302 | * | ||
303 | * @param[in] _a first argument | ||
304 | * @param[in] _b second argument | ||
305 | * | ||
306 | * @return saturated product of _a and _b | ||
307 | * | ||
308 | * This function will calculate the fixed point | ||
309 | * product of the input arguments | ||
310 | * and returns a single precision result. | ||
311 | * In case of overflow it will saturate. | ||
312 | * FP_UNITY * FP_UNITY => FP_UNITY. | ||
313 | * result = CLIP(_a * _b >> (NUM_BITS-1), MIN_RANGE, MAX_RANGE); | ||
314 | */ | ||
315 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_qmul( | ||
316 | const tvector1w _a, | ||
317 | const tvector1w _b); | ||
318 | |||
319 | /* @brief fractional saturating multiply with rounding | ||
320 | * | ||
321 | * @param[in] _a first argument | ||
322 | * @param[in] _b second argument | ||
323 | * | ||
324 | * @return product of _a and _b | ||
325 | * | ||
326 | * This function will calculate the fixed point | ||
327 | * product of the input arguments | ||
328 | * and returns a single precision result. | ||
329 | * FP_UNITY * FP_UNITY => FP_UNITY. | ||
330 | * Depending on the rounding mode of the core | ||
331 | * it will round to nearest or to nearest even. | ||
332 | * result = CLIP(_a * _b >> (NUM_BITS-1), MIN_RANGE, MAX_RANGE); | ||
333 | */ | ||
334 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_qrmul( | ||
335 | const tvector1w _a, | ||
336 | const tvector1w _b); | ||
337 | |||
338 | /* Comparative */ | ||
339 | |||
340 | /* @brief equal | ||
341 | * | ||
342 | * @param[in] _a first argument | ||
343 | * @param[in] _b second argument | ||
344 | * | ||
345 | * @return _a == _b | ||
346 | * | ||
347 | * This function will return true if both inputs | ||
348 | * are equal, and false if not equal. | ||
349 | */ | ||
350 | STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_eq( | ||
351 | const tvector1w _a, | ||
352 | const tvector1w _b); | ||
353 | |||
354 | /* @brief not equal | ||
355 | * | ||
356 | * @param[in] _a first argument | ||
357 | * @param[in] _b second argument | ||
358 | * | ||
359 | * @return _a != _b | ||
360 | * | ||
361 | * This function will return false if both inputs | ||
362 | * are equal, and true if not equal. | ||
363 | */ | ||
364 | STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_ne( | ||
365 | const tvector1w _a, | ||
366 | const tvector1w _b); | ||
367 | |||
368 | /* @brief less or equal | ||
369 | * | ||
370 | * @param[in] _a first argument | ||
371 | * @param[in] _b second argument | ||
372 | * | ||
373 | * @return _a <= _b | ||
374 | * | ||
375 | * This function will return true if _a is smaller | ||
376 | * or equal than _b. | ||
377 | */ | ||
378 | STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_le( | ||
379 | const tvector1w _a, | ||
380 | const tvector1w _b); | ||
381 | |||
382 | /* @brief less then | ||
383 | * | ||
384 | * @param[in] _a first argument | ||
385 | * @param[in] _b second argument | ||
386 | * | ||
387 | * @return _a < _b | ||
388 | * | ||
389 | * This function will return true if _a is smaller | ||
390 | * than _b. | ||
391 | */ | ||
392 | STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_lt( | ||
393 | const tvector1w _a, | ||
394 | const tvector1w _b); | ||
395 | |||
396 | /* @brief greater or equal | ||
397 | * | ||
398 | * @param[in] _a first argument | ||
399 | * @param[in] _b second argument | ||
400 | * | ||
401 | * @return _a >= _b | ||
402 | * | ||
403 | * This function will return true if _a is greater | ||
404 | * or equal than _b. | ||
405 | */ | ||
406 | STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_ge( | ||
407 | const tvector1w _a, | ||
408 | const tvector1w _b); | ||
409 | |||
410 | /* @brief greater than | ||
411 | * | ||
412 | * @param[in] _a first argument | ||
413 | * @param[in] _b second argument | ||
414 | * | ||
415 | * @return _a > _b | ||
416 | * | ||
417 | * This function will return true if _a is greater | ||
418 | * than _b. | ||
419 | */ | ||
420 | STORAGE_CLASS_ISP_OP1W_FUNC_H tflags OP_1w_gt( | ||
421 | const tvector1w _a, | ||
422 | const tvector1w _b); | ||
423 | |||
424 | /* Shift */ | ||
425 | |||
426 | /* @brief aritmetic shift right | ||
427 | * | ||
428 | * @param[in] _a input | ||
429 | * @param[in] _b shift amount | ||
430 | * | ||
431 | * @return _a >> _b | ||
432 | * | ||
433 | * This function will shift _a with _b bits to the right, | ||
434 | * preserving the sign bit. | ||
435 | * It asserts 0 <= _b <= MAX_SHIFT_1W. | ||
436 | * | ||
437 | * The operation count for this function assumes that | ||
438 | * the shift amount is a cloned scalar input. | ||
439 | */ | ||
440 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_asr( | ||
441 | const tvector1w _a, | ||
442 | const tvector1w _b); | ||
443 | |||
444 | /* @brief aritmetic shift right with rounding | ||
445 | * | ||
446 | * @param[in] _a input | ||
447 | * @param[in] _b shift amount | ||
448 | * | ||
449 | * @return _a >> _b | ||
450 | * | ||
451 | * If _b < NUM_BITS, this function will shift _a with _b bits to the right, | ||
452 | * preserving the sign bit, and depending on the rounding mode of the core | ||
453 | * it will round to nearest or to nearest even. | ||
454 | * If _b >= NUM_BITS, this function will return 0. | ||
455 | * It asserts 0 <= _b <= MAX_SHIFT_1W. | ||
456 | * The operation count for this function assumes that | ||
457 | * the shift amount is a cloned scalar input. | ||
458 | */ | ||
459 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_asrrnd( | ||
460 | const tvector1w _a, | ||
461 | const tvector1w _b); | ||
462 | |||
463 | /* @brief saturating arithmetic shift left | ||
464 | * | ||
465 | * @param[in] _a input | ||
466 | * @param[in] _b shift amount | ||
467 | * | ||
468 | * @return _a << _b | ||
469 | * | ||
470 | * If _b < MAX_BITDEPTH, this function will shift _a with _b bits to the left, | ||
471 | * saturating at MIN_RANGE/MAX_RANGE in case of overflow. | ||
472 | * If _b >= MAX_BITDEPTH, this function will return MIN_RANGE if _a < 0, | ||
473 | * MAX_RANGE if _a > 0, 0 if _a == 0. | ||
474 | * (with MAX_BITDEPTH=64) | ||
475 | * It asserts 0 <= _b <= MAX_SHIFT_1W. | ||
476 | * The operation count for this function assumes that | ||
477 | * the shift amount is a cloned scalar input. | ||
478 | */ | ||
479 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_asl( | ||
480 | const tvector1w _a, | ||
481 | const tvector1w _b); | ||
482 | |||
483 | /* @brief saturating aritmetic shift left | ||
484 | * | ||
485 | * @param[in] _a input | ||
486 | * @param[in] _b shift amount | ||
487 | * | ||
488 | * @return _a << _b | ||
489 | * | ||
490 | * This function is identical to OP_1w_asl( ) | ||
491 | */ | ||
492 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_aslsat( | ||
493 | const tvector1w _a, | ||
494 | const tvector1w _b); | ||
495 | |||
496 | /* @brief logical shift left | ||
497 | * | ||
498 | * @param[in] _a input | ||
499 | * @param[in] _b shift amount | ||
500 | * | ||
501 | * @return _a << _b | ||
502 | * | ||
503 | * This function will shift _a with _b bits to the left. | ||
504 | * It will insert zeroes on the right. | ||
505 | * It asserts 0 <= _b <= MAX_SHIFT_1W. | ||
506 | * The operation count for this function assumes that | ||
507 | * the shift amount is a cloned scalar input. | ||
508 | */ | ||
509 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_lsl( | ||
510 | const tvector1w _a, | ||
511 | const tvector1w _b); | ||
512 | |||
513 | /* @brief logical shift right | ||
514 | * | ||
515 | * @param[in] _a input | ||
516 | * @param[in] _b shift amount | ||
517 | * | ||
518 | * @return _a >> _b | ||
519 | * | ||
520 | * This function will shift _a with _b bits to the right. | ||
521 | * It will insert zeroes on the left. | ||
522 | * It asserts 0 <= _b <= MAX_SHIFT_1W. | ||
523 | * The operation count for this function assumes that | ||
524 | * the shift amount is a cloned scalar input. | ||
525 | */ | ||
526 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_lsr( | ||
527 | const tvector1w _a, | ||
528 | const tvector1w _b); | ||
529 | |||
530 | #ifdef ISP2401 | ||
531 | /* @brief bidirectional saturating arithmetic shift | ||
532 | * | ||
533 | * @param[in] _a input | ||
534 | * @param[in] _b shift amount | ||
535 | * | ||
536 | * @return _a << |_b| if _b is positive | ||
537 | * _a >> |_b| if _b is negative | ||
538 | * | ||
539 | * If _b > 0, this function will shift _a with _b bits to the left, | ||
540 | * saturating at MIN_RANGE/MAX_RANGE in case of overflow. | ||
541 | * if _b < 0, this function will shift _a with _b bits to the right. | ||
542 | * It asserts -MAX_SHIFT_1W <= _b <= MAX_SHIFT_1W. | ||
543 | * If _b = 0, it returns _a. | ||
544 | */ | ||
545 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_ashift_sat( | ||
546 | const tvector1w _a, | ||
547 | const tvector1w _b); | ||
548 | |||
549 | /* @brief bidirectional non-saturating arithmetic shift | ||
550 | * | ||
551 | * @param[in] _a input | ||
552 | * @param[in] _b shift amount | ||
553 | * | ||
554 | * @return _a << |_b| if _b is positive | ||
555 | * _a >> |_b| if _b is negative | ||
556 | * | ||
557 | * If _b > 0, this function will shift _a with _b bits to the left, | ||
558 | * no saturation is performed in case of overflow. | ||
559 | * if _b < 0, this function will shift _a with _b bits to the right. | ||
560 | * It asserts -MAX_SHIFT_1W <= _b <= MAX_SHIFT_1W. | ||
561 | * If _b = 0, it returns _a. | ||
562 | */ | ||
563 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_ashift( | ||
564 | const tvector1w _a, | ||
565 | const tvector1w _b); | ||
566 | |||
567 | |||
568 | /* @brief bidirectional logical shift | ||
569 | * | ||
570 | * @param[in] _a input | ||
571 | * @param[in] _b shift amount | ||
572 | * | ||
573 | * @return _a << |_b| if _b is positive | ||
574 | * _a >> |_b| if _b is negative | ||
575 | * | ||
576 | * This function will shift _a with _b bits to the left if _b is positive. | ||
577 | * This function will shift _a with _b bits to the right if _b is negative. | ||
578 | * It asserts -MAX_SHIFT_1W <= _b <= MAX_SHIFT_1W. | ||
579 | * It inserts zeros on the left or right depending on the shift direction: | ||
580 | * right or left. | ||
581 | * The operation count for this function assumes that | ||
582 | * the shift amount is a cloned scalar input. | ||
583 | */ | ||
584 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_lshift( | ||
585 | const tvector1w _a, | ||
586 | const tvector1w _b); | ||
587 | |||
588 | #endif | ||
589 | /* Cast */ | ||
590 | |||
591 | /* @brief Cast from int to 1w | ||
592 | * | ||
593 | * @param[in] _a input | ||
594 | * | ||
595 | * @return _a | ||
596 | * | ||
597 | * This function casts the input from integer type to | ||
598 | * single precision. It asserts there is no overflow. | ||
599 | * | ||
600 | */ | ||
601 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_int_cast_to_1w( | ||
602 | const int _a); | ||
603 | |||
604 | /* @brief Cast from 1w to int | ||
605 | * | ||
606 | * @param[in] _a input | ||
607 | * | ||
608 | * @return _a | ||
609 | * | ||
610 | * This function casts the input from single precision type to | ||
611 | * integer, preserving value and sign. | ||
612 | * | ||
613 | */ | ||
614 | STORAGE_CLASS_ISP_OP1W_FUNC_H int OP_1w_cast_to_int( | ||
615 | const tvector1w _a); | ||
616 | |||
617 | /* @brief Cast from 1w to 2w | ||
618 | * | ||
619 | * @param[in] _a input | ||
620 | * | ||
621 | * @return _a | ||
622 | * | ||
623 | * This function casts the input from single precision type to | ||
624 | * double precision, preserving value and sign. | ||
625 | * | ||
626 | */ | ||
627 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector2w OP_1w_cast_to_2w( | ||
628 | const tvector1w _a); | ||
629 | |||
630 | /* @brief Cast from 2w to 1w | ||
631 | * | ||
632 | * @param[in] _a input | ||
633 | * | ||
634 | * @return _a | ||
635 | * | ||
636 | * This function casts the input from double precision type to | ||
637 | * single precision. In case of overflow it will wrap around. | ||
638 | * | ||
639 | */ | ||
640 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_2w_cast_to_1w( | ||
641 | const tvector2w _a); | ||
642 | |||
643 | |||
644 | /* @brief Cast from 2w to 1w with saturation | ||
645 | * | ||
646 | * @param[in] _a input | ||
647 | * | ||
648 | * @return _a | ||
649 | * | ||
650 | * This function casts the input from double precision type to | ||
651 | * single precision after saturating it to the range of single | ||
652 | * precision. | ||
653 | * | ||
654 | */ | ||
655 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_2w_sat_cast_to_1w( | ||
656 | const tvector2w _a); | ||
657 | |||
658 | /* clipping */ | ||
659 | |||
660 | /* @brief Clip asymmetrical | ||
661 | * | ||
662 | * @param[in] _a first argument | ||
663 | * @param[in] _b second argument | ||
664 | * | ||
665 | * @return _a clipped between ~_b and b | ||
666 | * | ||
667 | * This function will clip the first argument between | ||
668 | * (-_b - 1) and _b. | ||
669 | * It asserts _b >= 0. | ||
670 | * | ||
671 | */ | ||
672 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_clip_asym( | ||
673 | const tvector1w _a, | ||
674 | const tvector1w _b); | ||
675 | |||
676 | /* @brief Clip zero | ||
677 | * | ||
678 | * @param[in] _a first argument | ||
679 | * @param[in] _b second argument | ||
680 | * | ||
681 | * @return _a clipped beteween 0 and _b | ||
682 | * | ||
683 | * This function will clip the first argument between | ||
684 | * zero and _b. | ||
685 | * It asserts _b >= 0. | ||
686 | * | ||
687 | */ | ||
688 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_clipz( | ||
689 | const tvector1w _a, | ||
690 | const tvector1w _b); | ||
691 | |||
692 | /* division */ | ||
693 | |||
694 | /* @brief Truncated division | ||
695 | * | ||
696 | * @param[in] _a first argument | ||
697 | * @param[in] _b second argument | ||
698 | * | ||
699 | * @return trunc( _a / _b ) | ||
700 | * | ||
701 | * This function will divide the first argument by | ||
702 | * the second argument, with rounding toward 0. | ||
703 | * If _b == 0 and _a < 0, the function will return MIN_RANGE. | ||
704 | * If _b == 0 and _a == 0, the function will return 0. | ||
705 | * If _b == 0 and _a > 0, the function will return MAX_RANGE. | ||
706 | */ | ||
707 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_div( | ||
708 | const tvector1w _a, | ||
709 | const tvector1w _b); | ||
710 | |||
711 | /* @brief Fractional saturating divide | ||
712 | * | ||
713 | * @param[in] _a first argument | ||
714 | * @param[in] _b second argument | ||
715 | * | ||
716 | * @return _a / _b | ||
717 | * | ||
718 | * This function will perform fixed point division of | ||
719 | * the first argument by the second argument, with rounding toward 0. | ||
720 | * In case of overflow it will saturate. | ||
721 | * If _b == 0 and _a < 0, the function will return MIN_RANGE. | ||
722 | * If _b == 0 and _a == 0, the function will return 0. | ||
723 | * If _b == 0 and _a > 0, the function will return MAX_RANGE. | ||
724 | */ | ||
725 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_qdiv( | ||
726 | const tvector1w _a, | ||
727 | const tvector1w _b); | ||
728 | |||
729 | /* @brief Modulo | ||
730 | * | ||
731 | * @param[in] _a first argument | ||
732 | * @param[in] _b second argument | ||
733 | * | ||
734 | * @return _a % _b | ||
735 | * | ||
736 | * This function will return the remainder r = _a - _b * trunc( _a / _b ), | ||
737 | * Note that the sign of the remainder is always equal to the sign of _a. | ||
738 | * If _b == 0 the function will return _a. | ||
739 | */ | ||
740 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_mod( | ||
741 | const tvector1w _a, | ||
742 | const tvector1w _b); | ||
743 | |||
744 | /* @brief Unsigned integer Square root | ||
745 | * | ||
746 | * @param[in] _a input | ||
747 | * | ||
748 | * @return Integer square root of _a | ||
749 | * | ||
750 | * This function will calculate the Integer square root of _a | ||
751 | */ | ||
752 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w_unsigned OP_1w_sqrt_u( | ||
753 | const tvector1w_unsigned _a); | ||
754 | |||
755 | /* Miscellaneous */ | ||
756 | |||
757 | /* @brief Multiplexer | ||
758 | * | ||
759 | * @param[in] _a first argument | ||
760 | * @param[in] _b second argument | ||
761 | * @param[in] _c condition | ||
762 | * | ||
763 | * @return _c ? _a : _b | ||
764 | * | ||
765 | * This function will return _a if the condition _c | ||
766 | * is true and _b otherwise. | ||
767 | */ | ||
768 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_mux( | ||
769 | const tvector1w _a, | ||
770 | const tvector1w _b, | ||
771 | const tflags _c); | ||
772 | |||
773 | /* @brief Average without rounding | ||
774 | * | ||
775 | * @param[in] _a first operand | ||
776 | * @param[in] _b second operand | ||
777 | * | ||
778 | * @return (_a + _b) >> 1 | ||
779 | * | ||
780 | * This function will add _a and _b, and right shift | ||
781 | * the result by one without rounding. No overflow | ||
782 | * will occur because addition is performed in the | ||
783 | * proper precision. | ||
784 | */ | ||
785 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_avg( | ||
786 | const tvector1w _a, | ||
787 | const tvector1w _b); | ||
788 | |||
789 | /* @brief Average with rounding | ||
790 | * | ||
791 | * @param[in] _a first argument | ||
792 | * @param[in] _b second argument | ||
793 | * | ||
794 | * @return (_a + _b) >> 1 | ||
795 | * | ||
796 | * This function will add _a and _b at full precision, | ||
797 | * and right shift with rounding the result with 1 bit. | ||
798 | * Depending on the rounding mode of the core | ||
799 | * it will round to nearest or to nearest even. | ||
800 | */ | ||
801 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_avgrnd( | ||
802 | const tvector1w _a, | ||
803 | const tvector1w _b); | ||
804 | |||
805 | /* @brief Minimum | ||
806 | * | ||
807 | * @param[in] _a first argument | ||
808 | * @param[in] _b second argument | ||
809 | * | ||
810 | * @return (_a < _b) ? _a : _b; | ||
811 | * | ||
812 | * This function will return the smallest of both | ||
813 | * input arguments. | ||
814 | */ | ||
815 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_min( | ||
816 | const tvector1w _a, | ||
817 | const tvector1w _b); | ||
818 | |||
819 | /* @brief Maximum | ||
820 | * | ||
821 | * @param[in] _a first argument | ||
822 | * @param[in] _b second argument | ||
823 | * | ||
824 | * @return (_a > _b) ? _a : _b; | ||
825 | * | ||
826 | * This function will return the largest of both | ||
827 | * input arguments. | ||
828 | */ | ||
829 | STORAGE_CLASS_ISP_OP1W_FUNC_H tvector1w OP_1w_max( | ||
830 | const tvector1w _a, | ||
831 | const tvector1w _b); | ||
832 | |||
833 | #ifndef INLINE_ISP_OP1W | ||
834 | #define STORAGE_CLASS_ISP_OP1W_FUNC_C | ||
835 | #define STORAGE_CLASS_ISP_OP1W_DATA_C const | ||
836 | #else /* INLINE_ISP_OP1W */ | ||
837 | #define STORAGE_CLASS_ISP_OP1W_FUNC_C STORAGE_CLASS_ISP_OP1W_FUNC_H | ||
838 | #define STORAGE_CLASS_ISP_OP1W_DATA_C STORAGE_CLASS_ISP_OP1W_DATA_H | ||
839 | #include "isp_op1w.c" | ||
840 | #define ISP_OP1W_INLINED | ||
841 | #endif /* INLINE_ISP_OP1W */ | ||
842 | |||
843 | #endif /* __ISP_OP1W_H_INCLUDED__ */ | ||
844 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w_types.h deleted file mode 100644 index c81e587509a1..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w_types.h +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP_OP1W_TYPES_H_INCLUDED__ | ||
16 | #define __ISP_OP1W_TYPES_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is part of the Multi-precision vector operations exstension package. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Single-precision vector operations | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * Prerequisites: | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #include "mpmath.h" | ||
32 | |||
33 | /* | ||
34 | * Single-precision data type specification | ||
35 | */ | ||
36 | |||
37 | |||
38 | typedef mpsdata_t tvector1w; | ||
39 | typedef mpsdata_t tscalar1w; | ||
40 | typedef spsdata_t tflags; | ||
41 | typedef mpudata_t tvector1w_unsigned; | ||
42 | typedef mpsdata_t tscalar1w_weight; | ||
43 | typedef mpsdata_t tvector1w_signed_positive; | ||
44 | typedef mpsdata_t tvector1w_weight; | ||
45 | #ifdef ISP2401 | ||
46 | typedef bool tscalar_bool; | ||
47 | #endif | ||
48 | |||
49 | typedef struct { | ||
50 | tvector1w d; | ||
51 | tflags f; | ||
52 | } tvector1w_tflags1w; | ||
53 | |||
54 | #endif /* __ISP_OP1W_TYPES_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h deleted file mode 100644 index 7575d260b837..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h +++ /dev/null | |||
@@ -1,674 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP_OP2W_H_INCLUDED__ | ||
16 | #define __ISP_OP2W_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is part of the Multi-precision vector operations exstension package. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Double-precision vector operations | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * Prerequisites: | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #ifdef INLINE_ISP_OP2W | ||
32 | #define STORAGE_CLASS_ISP_OP2W_FUNC_H static inline | ||
33 | #define STORAGE_CLASS_ISP_OP2W_DATA_H static inline_DATA | ||
34 | #else /* INLINE_ISP_OP2W */ | ||
35 | #define STORAGE_CLASS_ISP_OP2W_FUNC_H extern | ||
36 | #define STORAGE_CLASS_ISP_OP2W_DATA_H extern_DATA | ||
37 | #endif /* INLINE_ISP_OP2W */ | ||
38 | |||
39 | /* | ||
40 | * Double-precision data type specification | ||
41 | */ | ||
42 | |||
43 | #include "isp_op2w_types.h" | ||
44 | |||
45 | /* | ||
46 | * Double-precision prototype specification | ||
47 | */ | ||
48 | |||
49 | /* Arithmetic */ | ||
50 | |||
51 | /* @brief bitwise AND | ||
52 | * | ||
53 | * @param[in] _a first argument | ||
54 | * @param[in] _b second argument | ||
55 | * | ||
56 | * @return bitwise and of both input arguments | ||
57 | * | ||
58 | * This function will calculate the bitwise and. | ||
59 | * result = _a & _b | ||
60 | */ | ||
61 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_and( | ||
62 | const tvector2w _a, | ||
63 | const tvector2w _b); | ||
64 | |||
65 | /* @brief bitwise OR | ||
66 | * | ||
67 | * @param[in] _a first argument | ||
68 | * @param[in] _b second argument | ||
69 | * | ||
70 | * @return bitwise or of both input arguments | ||
71 | * | ||
72 | * This function will calculate the bitwise or. | ||
73 | * result = _a | _b | ||
74 | */ | ||
75 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_or( | ||
76 | const tvector2w _a, | ||
77 | const tvector2w _b); | ||
78 | |||
79 | /* @brief bitwise XOR | ||
80 | * | ||
81 | * @param[in] _a first argument | ||
82 | * @param[in] _b second argument | ||
83 | * | ||
84 | * @return bitwise xor of both input arguments | ||
85 | * | ||
86 | * This function will calculate the bitwise xor. | ||
87 | * result = _a ^ _b | ||
88 | */ | ||
89 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_xor( | ||
90 | const tvector2w _a, | ||
91 | const tvector2w _b); | ||
92 | |||
93 | /* @brief bitwise inverse | ||
94 | * | ||
95 | * @param[in] _a first argument | ||
96 | * | ||
97 | * @return bitwise inverse of both input arguments | ||
98 | * | ||
99 | * This function will calculate the bitwise inverse. | ||
100 | * result = ~_a | ||
101 | */ | ||
102 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_inv( | ||
103 | const tvector2w _a); | ||
104 | |||
105 | /* Additive */ | ||
106 | |||
107 | /* @brief addition | ||
108 | * | ||
109 | * @param[in] _a first argument | ||
110 | * @param[in] _b second argument | ||
111 | * | ||
112 | * @return sum of both input arguments | ||
113 | * | ||
114 | * This function will calculate the sum of the input arguments. | ||
115 | * in case of overflow it will wrap around. | ||
116 | * result = _a + _b | ||
117 | */ | ||
118 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_add( | ||
119 | const tvector2w _a, | ||
120 | const tvector2w _b); | ||
121 | |||
122 | /* @brief subtraction | ||
123 | * | ||
124 | * @param[in] _a first argument | ||
125 | * @param[in] _b second argument | ||
126 | * | ||
127 | * @return _b subtracted from _a. | ||
128 | * | ||
129 | * This function will subtract _b from _a. | ||
130 | * in case of overflow it will wrap around. | ||
131 | * result = _a - _b | ||
132 | */ | ||
133 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_sub( | ||
134 | const tvector2w _a, | ||
135 | const tvector2w _b); | ||
136 | |||
137 | /* @brief saturated addition | ||
138 | * | ||
139 | * @param[in] _a first argument | ||
140 | * @param[in] _b second argument | ||
141 | * | ||
142 | * @return saturated sum of both input arguments | ||
143 | * | ||
144 | * This function will calculate the sum of the input arguments. | ||
145 | * in case of overflow it will saturate | ||
146 | * result = CLIP(_a + _b, MIN_RANGE, MAX_RANGE); | ||
147 | */ | ||
148 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_addsat( | ||
149 | const tvector2w _a, | ||
150 | const tvector2w _b); | ||
151 | |||
152 | /* @brief saturated subtraction | ||
153 | * | ||
154 | * @param[in] _a first argument | ||
155 | * @param[in] _b second argument | ||
156 | * | ||
157 | * @return saturated subtraction of both input arguments | ||
158 | * | ||
159 | * This function will subtract _b from _a. | ||
160 | * in case of overflow it will saturate | ||
161 | * result = CLIP(_a - _b, MIN_RANGE, MAX_RANGE); | ||
162 | */ | ||
163 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_subsat( | ||
164 | const tvector2w _a, | ||
165 | const tvector2w _b); | ||
166 | |||
167 | /* @brief subtraction with shift right and rounding | ||
168 | * | ||
169 | * @param[in] _a first argument | ||
170 | * @param[in] _b second argument | ||
171 | * | ||
172 | * @return (a - b) >> 1 | ||
173 | * | ||
174 | * This function subtracts _b from _a and right shifts | ||
175 | * the result by 1 bit with rounding. | ||
176 | * No overflow can occur. | ||
177 | * result = (_a - _b) >> 1 | ||
178 | * | ||
179 | * Note: This function will be deprecated due to | ||
180 | * the naming confusion and it will be replaced | ||
181 | * by "OP_2w_subhalfrnd". | ||
182 | */ | ||
183 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_subasr1( | ||
184 | const tvector2w _a, | ||
185 | const tvector2w _b); | ||
186 | |||
187 | /* @brief Subtraction with shift right and rounding | ||
188 | * | ||
189 | * @param[in] _a first operand | ||
190 | * @param[in] _b second operand | ||
191 | * | ||
192 | * @return (_a - _b) >> 1 | ||
193 | * | ||
194 | * This function subtracts _b from _a and right shifts | ||
195 | * the result by 1 bit with rounding. | ||
196 | * No overflow can occur. | ||
197 | */ | ||
198 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_subhalfrnd( | ||
199 | const tvector2w _a, | ||
200 | const tvector2w _b); | ||
201 | |||
202 | /* @brief Subtraction with shift right and no rounding | ||
203 | * | ||
204 | * @param[in] _a first operand | ||
205 | * @param[in] _b second operand | ||
206 | * | ||
207 | * @return (_a - _b) >> 1 | ||
208 | * | ||
209 | * This function subtracts _b from _a and right shifts | ||
210 | * the result by 1 bit without rounding (i.e. truncation). | ||
211 | * No overflow can occur. | ||
212 | */ | ||
213 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_subhalf( | ||
214 | const tvector2w _a, | ||
215 | const tvector2w _b); | ||
216 | |||
217 | /* @brief saturated absolute value | ||
218 | * | ||
219 | * @param[in] _a input | ||
220 | * | ||
221 | * @return saturated absolute value of the input | ||
222 | * | ||
223 | * This function will calculate the saturated absolute value of the input. | ||
224 | * In case of overflow it will saturate. | ||
225 | * if (_a > 0) return _a;<br> | ||
226 | * else return CLIP(-_a, MIN_RANGE, MAX_RANGE);<br> | ||
227 | */ | ||
228 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_abs( | ||
229 | const tvector2w _a); | ||
230 | |||
231 | /* @brief saturated absolute difference | ||
232 | * | ||
233 | * @param[in] _a first argument | ||
234 | * @param[in] _b second argument | ||
235 | * | ||
236 | * @return sat(abs(sat(a-b))); | ||
237 | * | ||
238 | * This function will calculate the saturated absolute value | ||
239 | * of the saturated difference of both inputs. | ||
240 | * result = sat(abs(sat(_a - _b))); | ||
241 | */ | ||
242 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_subabssat( | ||
243 | const tvector2w _a, | ||
244 | const tvector2w _b); | ||
245 | |||
246 | /* Multiplicative */ | ||
247 | |||
248 | /* @brief integer multiply | ||
249 | * | ||
250 | * @param[in] _a first argument | ||
251 | * @param[in] _b second argument | ||
252 | * | ||
253 | * @return product of _a and _b | ||
254 | * | ||
255 | * This function will calculate the product | ||
256 | * of the input arguments and returns the LSB | ||
257 | * aligned double precision result. | ||
258 | * In case of overflow it will wrap around. | ||
259 | * result = _a * _b; | ||
260 | */ | ||
261 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_mul( | ||
262 | const tvector2w _a, | ||
263 | const tvector2w _b); | ||
264 | |||
265 | /* @brief fractional saturating multiply | ||
266 | * | ||
267 | * @param[in] _a first argument | ||
268 | * @param[in] _b second argument | ||
269 | * | ||
270 | * @return saturated product of _a and _b | ||
271 | * | ||
272 | * This function will calculate the fixed point | ||
273 | * product of the input arguments | ||
274 | * and returns a double precision result. | ||
275 | * In case of overflow it will saturate. | ||
276 | * result =((_a * _b) << 1) >> (2*NUM_BITS); | ||
277 | */ | ||
278 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_qmul( | ||
279 | const tvector2w _a, | ||
280 | const tvector2w _b); | ||
281 | |||
282 | /* @brief fractional saturating multiply with rounding | ||
283 | * | ||
284 | * @param[in] _a first argument | ||
285 | * @param[in] _b second argument | ||
286 | * | ||
287 | * @return product of _a and _b | ||
288 | * | ||
289 | * This function will calculate the fixed point | ||
290 | * product of the input arguments | ||
291 | * and returns a double precision result. | ||
292 | * Depending on the rounding mode of the core | ||
293 | * it will round to nearest or to nearest even. | ||
294 | * In case of overflow it will saturate. | ||
295 | * result = ((_a * _b) << 1) >> (2*NUM_BITS); | ||
296 | */ | ||
297 | |||
298 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_qrmul( | ||
299 | const tvector2w _a, | ||
300 | const tvector2w _b); | ||
301 | |||
302 | /* Comparative */ | ||
303 | |||
304 | /* @brief equal | ||
305 | * | ||
306 | * @param[in] _a first argument | ||
307 | * @param[in] _b second argument | ||
308 | * | ||
309 | * @return _a == _b | ||
310 | * | ||
311 | * This function will return true if both inputs | ||
312 | * are equal, and false if not equal. | ||
313 | */ | ||
314 | STORAGE_CLASS_ISP_OP2W_FUNC_H tflags OP_2w_eq( | ||
315 | const tvector2w _a, | ||
316 | const tvector2w _b); | ||
317 | |||
318 | /* @brief not equal | ||
319 | * | ||
320 | * @param[in] _a first argument | ||
321 | * @param[in] _b second argument | ||
322 | * | ||
323 | * @return _a != _b | ||
324 | * | ||
325 | * This function will return false if both inputs | ||
326 | * are equal, and true if not equal. | ||
327 | */ | ||
328 | STORAGE_CLASS_ISP_OP2W_FUNC_H tflags OP_2w_ne( | ||
329 | const tvector2w _a, | ||
330 | const tvector2w _b); | ||
331 | |||
332 | /* @brief less or equal | ||
333 | * | ||
334 | * @param[in] _a first argument | ||
335 | * @param[in] _b second argument | ||
336 | * | ||
337 | * @return _a <= _b | ||
338 | * | ||
339 | * This function will return true if _a is smaller | ||
340 | * or equal than _b. | ||
341 | */ | ||
342 | STORAGE_CLASS_ISP_OP2W_FUNC_H tflags OP_2w_le( | ||
343 | const tvector2w _a, | ||
344 | const tvector2w _b); | ||
345 | |||
346 | /* @brief less then | ||
347 | * | ||
348 | * @param[in] _a first argument | ||
349 | * @param[in] _b second argument | ||
350 | * | ||
351 | * @return _a < _b | ||
352 | * | ||
353 | * This function will return true if _a is smaller | ||
354 | * than _b. | ||
355 | */ | ||
356 | STORAGE_CLASS_ISP_OP2W_FUNC_H tflags OP_2w_lt( | ||
357 | const tvector2w _a, | ||
358 | const tvector2w _b); | ||
359 | |||
360 | /* @brief greater or equal | ||
361 | * | ||
362 | * @param[in] _a first argument | ||
363 | * @param[in] _b second argument | ||
364 | * | ||
365 | * @return _a >= _b | ||
366 | * | ||
367 | * This function will return true if _a is greater | ||
368 | * or equal than _b. | ||
369 | */ | ||
370 | STORAGE_CLASS_ISP_OP2W_FUNC_H tflags OP_2w_ge( | ||
371 | const tvector2w _a, | ||
372 | const tvector2w _b); | ||
373 | |||
374 | /* @brief greater than | ||
375 | * | ||
376 | * @param[in] _a first argument | ||
377 | * @param[in] _b second argument | ||
378 | * | ||
379 | * @return _a > _b | ||
380 | * | ||
381 | * This function will return true if _a is greater | ||
382 | * than _b. | ||
383 | */ | ||
384 | STORAGE_CLASS_ISP_OP2W_FUNC_H tflags OP_2w_gt( | ||
385 | const tvector2w _a, | ||
386 | const tvector2w _b); | ||
387 | |||
388 | /* Shift */ | ||
389 | |||
390 | /* @brief aritmetic shift right | ||
391 | * | ||
392 | * @param[in] _a input | ||
393 | * @param[in] _b shift amount | ||
394 | * | ||
395 | * @return _a >> _b | ||
396 | * | ||
397 | * This function will shift _a with _b bits to the right, | ||
398 | * preserving the sign bit. | ||
399 | * It asserts 0 <= _b <= MAX_SHIFT_2W. | ||
400 | * The operation count for this function assumes that | ||
401 | * the shift amount is a cloned scalar input. | ||
402 | */ | ||
403 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_asr( | ||
404 | const tvector2w _a, | ||
405 | const tvector2w _b); | ||
406 | |||
407 | /* @brief aritmetic shift right with rounding | ||
408 | * | ||
409 | * @param[in] _a input | ||
410 | * @param[in] _b shift amount | ||
411 | * | ||
412 | * @return _a >> _b | ||
413 | * | ||
414 | * If _b < 2*NUM_BITS, this function will shift _a with _b bits to the right, | ||
415 | * preserving the sign bit, and depending on the rounding mode of the core | ||
416 | * it will round to nearest or to nearest even. | ||
417 | * If _b >= 2*NUM_BITS, this function will return 0. | ||
418 | * It asserts 0 <= _b <= MAX_SHIFT_2W. | ||
419 | * The operation count for this function assumes that | ||
420 | * the shift amount is a cloned scalar input. | ||
421 | */ | ||
422 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_asrrnd( | ||
423 | const tvector2w _a, | ||
424 | const tvector2w _b); | ||
425 | |||
426 | /* @brief saturating aritmetic shift left | ||
427 | * | ||
428 | * @param[in] _a input | ||
429 | * @param[in] _b shift amount | ||
430 | * | ||
431 | * @return _a << _b | ||
432 | * | ||
433 | * If _b < MAX_BITDEPTH, this function will shift _a with _b bits to the left, | ||
434 | * saturating at MIN_RANGE/MAX_RANGE in case of overflow. | ||
435 | * If _b >= MAX_BITDEPTH, this function will return MIN_RANGE if _a < 0, | ||
436 | * MAX_RANGE if _a > 0, 0 if _a == 0. | ||
437 | * (with MAX_BITDEPTH=64) | ||
438 | * It asserts 0 <= _b <= MAX_SHIFT_2W. | ||
439 | * The operation count for this function assumes that | ||
440 | * the shift amount is a cloned scalar input. | ||
441 | */ | ||
442 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_asl( | ||
443 | const tvector2w _a, | ||
444 | const tvector2w _b); | ||
445 | |||
446 | /* @brief saturating aritmetic shift left | ||
447 | * | ||
448 | * @param[in] _a input | ||
449 | * @param[in] _b shift amount | ||
450 | * | ||
451 | * @return _a << _b | ||
452 | * | ||
453 | * This function is identical to OP_2w_asl( ) | ||
454 | */ | ||
455 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_aslsat( | ||
456 | const tvector2w _a, | ||
457 | const tvector2w _b); | ||
458 | |||
459 | /* @brief logical shift left | ||
460 | * | ||
461 | * @param[in] _a input | ||
462 | * @param[in] _b shift amount | ||
463 | * | ||
464 | * @return _a << _b | ||
465 | * | ||
466 | * This function will shift _a with _b bits to the left. | ||
467 | * It will insert zeroes on the right. | ||
468 | * It asserts 0 <= _b <= MAX_SHIFT_2W. | ||
469 | * The operation count for this function assumes that | ||
470 | * the shift amount is a cloned scalar input. | ||
471 | */ | ||
472 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_lsl( | ||
473 | const tvector2w _a, | ||
474 | const tvector2w _b); | ||
475 | |||
476 | /* @brief logical shift right | ||
477 | * | ||
478 | * @param[in] _a input | ||
479 | * @param[in] _b shift amount | ||
480 | * | ||
481 | * @return _a >> _b | ||
482 | * | ||
483 | * This function will shift _a with _b bits to the right. | ||
484 | * It will insert zeroes on the left. | ||
485 | * It asserts 0 <= _b <= MAX_SHIFT_2W. | ||
486 | * The operation count for this function assumes that | ||
487 | * the shift amount is a cloned scalar input. | ||
488 | */ | ||
489 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_lsr( | ||
490 | const tvector2w _a, | ||
491 | const tvector2w _b); | ||
492 | |||
493 | /* clipping */ | ||
494 | |||
495 | /* @brief Clip asymmetrical | ||
496 | * | ||
497 | * @param[in] _a first argument | ||
498 | * @param[in] _b second argument | ||
499 | * | ||
500 | * @return _a clipped between ~_b and b | ||
501 | * | ||
502 | * This function will clip the first argument between | ||
503 | * (-_b - 1) and _b. | ||
504 | * It asserts _b >= 0. | ||
505 | */ | ||
506 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_clip_asym( | ||
507 | const tvector2w _a, | ||
508 | const tvector2w _b); | ||
509 | |||
510 | /* @brief Clip zero | ||
511 | * | ||
512 | * @param[in] _a first argument | ||
513 | * @param[in] _b second argument | ||
514 | * | ||
515 | * @return _a clipped beteween 0 and _b | ||
516 | * | ||
517 | * This function will clip the first argument between | ||
518 | * zero and _b. | ||
519 | * It asserts _b >= 0. | ||
520 | */ | ||
521 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_clipz( | ||
522 | const tvector2w _a, | ||
523 | const tvector2w _b); | ||
524 | |||
525 | /* division */ | ||
526 | |||
527 | /* @brief Truncated division | ||
528 | * | ||
529 | * @param[in] _a first argument | ||
530 | * @param[in] _b second argument | ||
531 | * | ||
532 | * @return trunc( _a / _b ) | ||
533 | * | ||
534 | * This function will divide the first argument by | ||
535 | * the second argument, with rounding toward 0. | ||
536 | * If _b == 0 and _a < 0, the function will return MIN_RANGE. | ||
537 | * If _b == 0 and _a == 0, the function will return 0. | ||
538 | * If _b == 0 and _a > 0, the function will return MAX_RANGE. | ||
539 | */ | ||
540 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_div( | ||
541 | const tvector2w _a, | ||
542 | const tvector2w _b); | ||
543 | |||
544 | /* @brief Saturating truncated division | ||
545 | * | ||
546 | * @param[in] _a first argument | ||
547 | * @param[in] _b second argument | ||
548 | * | ||
549 | * @return CLIP( trunc( _a / _b ), MIN_RANGE1w, MAX_RANGE1w ) | ||
550 | * | ||
551 | * This function will divide the first argument by | ||
552 | * the second argument, with rounding toward 0, and | ||
553 | * saturate the result to the range of single precision. | ||
554 | * If _b == 0 and _a < 0, the function will return MIN_RANGE. | ||
555 | * If _b == 0 and _a == 0, the function will return 0. | ||
556 | * If _b == 0 and _a > 0, the function will return MAX_RANGE. | ||
557 | */ | ||
558 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector1w OP_2w_divh( | ||
559 | const tvector2w _a, | ||
560 | const tvector1w _b); | ||
561 | |||
562 | /* @brief Modulo | ||
563 | * | ||
564 | * @param[in] _a first argument | ||
565 | * @param[in] _b second argument | ||
566 | * | ||
567 | * @return n/a | ||
568 | * | ||
569 | * This function has not yet been implemented. | ||
570 | */ | ||
571 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_mod( | ||
572 | const tvector2w _a, | ||
573 | const tvector2w _b); | ||
574 | |||
575 | /* @brief Unsigned Integer Square root | ||
576 | * | ||
577 | * @param[in] _a input | ||
578 | * | ||
579 | * @return square root of _a | ||
580 | * | ||
581 | * This function will calculate the unsigned integer square root of _a | ||
582 | */ | ||
583 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector1w_unsigned OP_2w_sqrt_u( | ||
584 | const tvector2w_unsigned _a); | ||
585 | |||
586 | /* Miscellaneous */ | ||
587 | |||
588 | /* @brief Multiplexer | ||
589 | * | ||
590 | * @param[in] _a first argument | ||
591 | * @param[in] _b second argument | ||
592 | * @param[in] _c condition | ||
593 | * | ||
594 | * @return _c ? _a : _b | ||
595 | * | ||
596 | * This function will return _a if the condition _c | ||
597 | * is true and _b otherwise. | ||
598 | */ | ||
599 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_mux( | ||
600 | const tvector2w _a, | ||
601 | const tvector2w _b, | ||
602 | const tflags _c); | ||
603 | |||
604 | /* @brief Average without rounding | ||
605 | * | ||
606 | * @param[in] _a first operand | ||
607 | * @param[in] _b second operand | ||
608 | * | ||
609 | * @return (_a + _b) >> 1 | ||
610 | * | ||
611 | * This function will add _a and _b, and right shift | ||
612 | * the result by one without rounding. No overflow | ||
613 | * will occur because addition is performed in the | ||
614 | * proper precision. | ||
615 | */ | ||
616 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_avg( | ||
617 | const tvector2w _a, | ||
618 | const tvector2w _b); | ||
619 | |||
620 | /* @brief Average with rounding | ||
621 | * | ||
622 | * @param[in] _a first argument | ||
623 | * @param[in] _b second argument | ||
624 | * | ||
625 | * @return (_a + _b) >> 1 | ||
626 | * | ||
627 | * This function will add _a and _b at full precision, | ||
628 | * and right shift with rounding the result with 1 bit. | ||
629 | * Depending on the rounding mode of the core | ||
630 | * it will round to nearest or to nearest even. | ||
631 | */ | ||
632 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_avgrnd( | ||
633 | const tvector2w _a, | ||
634 | const tvector2w _b); | ||
635 | |||
636 | /* @brief Minimum | ||
637 | * | ||
638 | * @param[in] _a first argument | ||
639 | * @param[in] _b second argument | ||
640 | * | ||
641 | * @return (_a < _b) ? _a : _b; | ||
642 | * | ||
643 | * This function will return the smallest of both | ||
644 | * input arguments. | ||
645 | */ | ||
646 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_min( | ||
647 | const tvector2w _a, | ||
648 | const tvector2w _b); | ||
649 | |||
650 | /* @brief Maximum | ||
651 | * | ||
652 | * @param[in] _a first argument | ||
653 | * @param[in] _b second argument | ||
654 | * | ||
655 | * @return (_a > _b) ? _a : _b; | ||
656 | * | ||
657 | * This function will return the largest of both | ||
658 | * input arguments. | ||
659 | */ | ||
660 | STORAGE_CLASS_ISP_OP2W_FUNC_H tvector2w OP_2w_max( | ||
661 | const tvector2w _a, | ||
662 | const tvector2w _b); | ||
663 | |||
664 | #ifndef INLINE_ISP_OP2W | ||
665 | #define STORAGE_CLASS_ISP_OP2W_FUNC_C | ||
666 | #define STORAGE_CLASS_ISP_OP2W_DATA_C const | ||
667 | #else /* INLINE_ISP_OP2W */ | ||
668 | #define STORAGE_CLASS_ISP_OP2W_FUNC_C STORAGE_CLASS_ISP_OP2W_FUNC_H | ||
669 | #define STORAGE_CLASS_ISP_OP2W_DATA_C STORAGE_CLASS_ISP_OP2W_DATA_H | ||
670 | #include "isp_op2w.c" | ||
671 | #define ISP_OP2W_INLINED | ||
672 | #endif /* INLINE_ISP_OP2W */ | ||
673 | |||
674 | #endif /* __ISP_OP2W_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w_types.h deleted file mode 100644 index 7e86083a8a33..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w_types.h +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP_OP2W_TYPES_H_INCLUDED__ | ||
16 | #define __ISP_OP2W_TYPES_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is part of the Multi-precision vector operations exstension package. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * Double-precision vector operations | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * Prerequisites: | ||
28 | * | ||
29 | */ | ||
30 | #include "mpmath.h" | ||
31 | #include "isp_op1w_types.h" | ||
32 | |||
33 | /* | ||
34 | * Single-precision data type specification | ||
35 | */ | ||
36 | |||
37 | |||
38 | typedef mpsdata_t tvector2w; | ||
39 | typedef mpsdata_t tscalar2w; | ||
40 | typedef mpsdata_t tvector2w_signed_positive; | ||
41 | typedef mpudata_t tvector2w_unsigned; | ||
42 | |||
43 | |||
44 | typedef struct { | ||
45 | tvector2w d; | ||
46 | tflags f; | ||
47 | } tvector2w_tflags; | ||
48 | |||
49 | #endif /* __ISP_OP2W_TYPES_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op_count.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op_count.h deleted file mode 100644 index 8e7b48d026b0..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op_count.h +++ /dev/null | |||
@@ -1,226 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ISP_OP_COUNT_H_INCLUDED__ | ||
16 | #define __ISP_OP_COUNT_H_INCLUDED__ | ||
17 | |||
18 | #include <stdio.h> | ||
19 | |||
20 | typedef struct { | ||
21 | long long bbb_cnt; /* number of bbb */ | ||
22 | int bbb_op; /* operations per bbb */ | ||
23 | long long total_cnt; /* bbb_cnt * bbb_op */ | ||
24 | } bbb_stat_t; | ||
25 | |||
26 | typedef enum { | ||
27 | bbb_func_OP_1w_and, | ||
28 | bbb_func_OP_1w_or, | ||
29 | bbb_func_OP_1w_xor, | ||
30 | bbb_func_OP_1w_inv, | ||
31 | bbb_func_OP_1w_add, | ||
32 | bbb_func_OP_1w_sub, | ||
33 | bbb_func_OP_1w_addsat, | ||
34 | bbb_func_OP_1w_subsat, | ||
35 | bbb_func_OP_1w_subasr1, | ||
36 | bbb_func_OP_1w_subhalf, | ||
37 | bbb_func_OP_1w_subhalfrnd, | ||
38 | bbb_func_OP_1w_abs, | ||
39 | bbb_func_OP_1w_subabssat, | ||
40 | #ifdef ISP2401 | ||
41 | bbb_func_OP_1w_subsat_u, | ||
42 | #endif | ||
43 | bbb_func_OP_1w_muld, | ||
44 | bbb_func_OP_1w_mul, | ||
45 | bbb_func_OP_1w_qmul, | ||
46 | bbb_func_OP_1w_qrmul, | ||
47 | bbb_func_OP_1w_eq, | ||
48 | bbb_func_OP_1w_ne, | ||
49 | bbb_func_OP_1w_le, | ||
50 | bbb_func_OP_1w_lt, | ||
51 | bbb_func_OP_1w_ge, | ||
52 | bbb_func_OP_1w_gt, | ||
53 | bbb_func_OP_1w_asr, | ||
54 | bbb_func_OP_1w_asrrnd, | ||
55 | bbb_func_OP_1w_asl, | ||
56 | bbb_func_OP_1w_aslsat, | ||
57 | bbb_func_OP_1w_lsl, | ||
58 | bbb_func_OP_1w_lsr, | ||
59 | #ifdef ISP2401 | ||
60 | bbb_func_OP_1w_ashift, | ||
61 | bbb_func_OP_1w_lshift, | ||
62 | #endif | ||
63 | bbb_func_OP_int_cast_to_1w , | ||
64 | bbb_func_OP_1w_cast_to_int , | ||
65 | bbb_func_OP_1w_cast_to_2w , | ||
66 | bbb_func_OP_2w_cast_to_1w , | ||
67 | bbb_func_OP_2w_sat_cast_to_1w , | ||
68 | bbb_func_OP_1w_clip_asym, | ||
69 | bbb_func_OP_1w_clipz, | ||
70 | bbb_func_OP_1w_div, | ||
71 | bbb_func_OP_1w_qdiv, | ||
72 | bbb_func_OP_1w_mod, | ||
73 | bbb_func_OP_1w_sqrt_u, | ||
74 | bbb_func_OP_1w_mux, | ||
75 | bbb_func_OP_1w_avg, | ||
76 | bbb_func_OP_1w_avgrnd, | ||
77 | bbb_func_OP_1w_min, | ||
78 | bbb_func_OP_1w_max, | ||
79 | bbb_func_OP_2w_and, | ||
80 | bbb_func_OP_2w_or, | ||
81 | bbb_func_OP_2w_xor, | ||
82 | bbb_func_OP_2w_inv, | ||
83 | bbb_func_OP_2w_add, | ||
84 | bbb_func_OP_2w_sub, | ||
85 | bbb_func_OP_2w_addsat, | ||
86 | bbb_func_OP_2w_subsat, | ||
87 | bbb_func_OP_2w_subasr1, | ||
88 | bbb_func_OP_2w_subhalf, | ||
89 | bbb_func_OP_2w_subhalfrnd, | ||
90 | bbb_func_OP_2w_abs, | ||
91 | bbb_func_OP_2w_subabssat, | ||
92 | bbb_func_OP_2w_mul, | ||
93 | bbb_func_OP_2w_qmul, | ||
94 | bbb_func_OP_2w_qrmul, | ||
95 | bbb_func_OP_2w_eq, | ||
96 | bbb_func_OP_2w_ne, | ||
97 | bbb_func_OP_2w_le, | ||
98 | bbb_func_OP_2w_lt, | ||
99 | bbb_func_OP_2w_ge, | ||
100 | bbb_func_OP_2w_gt, | ||
101 | bbb_func_OP_2w_asr, | ||
102 | bbb_func_OP_2w_asrrnd, | ||
103 | bbb_func_OP_2w_asl, | ||
104 | bbb_func_OP_2w_aslsat, | ||
105 | bbb_func_OP_2w_lsl, | ||
106 | bbb_func_OP_2w_lsr, | ||
107 | bbb_func_OP_2w_clip_asym, | ||
108 | bbb_func_OP_2w_clipz, | ||
109 | bbb_func_OP_2w_div, | ||
110 | bbb_func_OP_2w_divh, | ||
111 | bbb_func_OP_2w_mod, | ||
112 | bbb_func_OP_2w_sqrt_u, | ||
113 | bbb_func_OP_2w_mux, | ||
114 | bbb_func_OP_2w_avg, | ||
115 | bbb_func_OP_2w_avgrnd, | ||
116 | bbb_func_OP_2w_min, | ||
117 | bbb_func_OP_2w_max, | ||
118 | bbb_func_OP_1w_mul_realigning, | ||
119 | #ifdef ISP2401 | ||
120 | bbb_func_OP_1w_imax32, | ||
121 | bbb_func_OP_1w_imaxidx32, | ||
122 | bbb_func_OP_1w_cond_add, | ||
123 | #endif | ||
124 | |||
125 | bbb_func_num_functions | ||
126 | } bbb_functions_t; | ||
127 | |||
128 | typedef enum { | ||
129 | core_func_OP_and, | ||
130 | core_func_OP_or, | ||
131 | core_func_OP_xor, | ||
132 | core_func_OP_inv, | ||
133 | core_func_OP_add, | ||
134 | core_func_OP_sub, | ||
135 | core_func_OP_addsat, | ||
136 | core_func_OP_subsat, | ||
137 | core_func_OP_subasr1, | ||
138 | core_func_OP_abs, | ||
139 | core_func_OP_subabssat, | ||
140 | #ifdef ISP2401 | ||
141 | core_func_OP_subsat_u, | ||
142 | #endif | ||
143 | core_func_OP_muld, | ||
144 | core_func_OP_mul, | ||
145 | core_func_OP_qrmul, | ||
146 | core_func_OP_eq, | ||
147 | core_func_OP_ne, | ||
148 | core_func_OP_le, | ||
149 | core_func_OP_lt, | ||
150 | core_func_OP_ge, | ||
151 | core_func_OP_gt, | ||
152 | core_func_OP_asr, | ||
153 | core_func_OP_asl, | ||
154 | core_func_OP_asrrnd, | ||
155 | core_func_OP_lsl, | ||
156 | core_func_OP_lslsat, | ||
157 | core_func_OP_lsr, | ||
158 | core_func_OP_lsrrnd, | ||
159 | core_func_OP_clip_asym, | ||
160 | core_func_OP_clipz, | ||
161 | core_func_OP_div, | ||
162 | core_func_OP_mod, | ||
163 | core_func_OP_sqrt, | ||
164 | core_func_OP_mux, | ||
165 | core_func_OP_avgrnd, | ||
166 | core_func_OP_min, | ||
167 | core_func_OP_max, | ||
168 | |||
169 | core_func_num_functions | ||
170 | |||
171 | } core_functions_t; | ||
172 | |||
173 | /* inc_bbb_count() can be used for building blocks that are implemented with one operation | ||
174 | inc_bbb_count_ext() will be used in case the operation count is not known or greater than one. | ||
175 | |||
176 | For some operations there is a difference in operation count for the cloned version and the | ||
177 | not cloned version. this difference is not vissible on the reference code side. | ||
178 | We could add a min and max operation count for those operations, and keep track of those counts | ||
179 | separately. That way in the report the impact can be seen. */ | ||
180 | |||
181 | #ifdef DISABLE_OPCNT | ||
182 | #define inc_bbb_count(func) | ||
183 | #define inc_bbb_count_ext(func, cnt) | ||
184 | #define enable_bbb_count() | ||
185 | #define disable_bbb_count() | ||
186 | #else | ||
187 | #define inc_bbb_count(func) _inc_bbb_count(func) | ||
188 | #define inc_bbb_count_ext(func, cnt) _inc_bbb_count_ext(func, cnt) | ||
189 | #define enable_bbb_count() _enable_bbb_count() | ||
190 | #define disable_bbb_count() _disable_bbb_count() | ||
191 | #endif | ||
192 | |||
193 | void | ||
194 | inc_core_count_n( | ||
195 | core_functions_t func, | ||
196 | unsigned n); | ||
197 | |||
198 | void | ||
199 | _enable_bbb_count(void); | ||
200 | |||
201 | void | ||
202 | _disable_bbb_count(void); | ||
203 | |||
204 | void | ||
205 | _inc_bbb_count( | ||
206 | bbb_functions_t func); | ||
207 | |||
208 | void | ||
209 | _inc_bbb_count_ext( | ||
210 | bbb_functions_t func, | ||
211 | int op_count); | ||
212 | |||
213 | void | ||
214 | bbb_func_reset_count(void); | ||
215 | |||
216 | void | ||
217 | bbb_func_print_totals( | ||
218 | FILE * fp, | ||
219 | unsigned non_zero_only); | ||
220 | |||
221 | void | ||
222 | core_func_print_totals( | ||
223 | FILE* fp, | ||
224 | unsigned non_zero_only); | ||
225 | |||
226 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/osys_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/osys_public.h deleted file mode 100644 index 8695e3c01fa6..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/osys_public.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __OSYS_PUBLIC_H_INCLUDED__ | ||
16 | #define __OSYS_PUBLIC_H_INCLUDED__ | ||
17 | |||
18 | #include "system_types.h" | ||
19 | |||
20 | #endif /* __OSYS_PUBLIC_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/pipeline_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/pipeline_public.h deleted file mode 100644 index 32cea582b4c4..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/pipeline_public.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PIPELINE_PUBLIC_H_INCLUDED__ | ||
16 | #define __PIPELINE_PUBLIC_H_INCLUDED__ | ||
17 | |||
18 | #endif /* __PIPELINE_PUBLIC_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h deleted file mode 100644 index c1638c06407d..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h +++ /dev/null | |||
@@ -1,1221 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _REF_VECTOR_FUNC_H_INCLUDED_ | ||
16 | #define _REF_VECTOR_FUNC_H_INCLUDED_ | ||
17 | |||
18 | |||
19 | #ifdef INLINE_VECTOR_FUNC | ||
20 | #define STORAGE_CLASS_REF_VECTOR_FUNC_H static inline | ||
21 | #define STORAGE_CLASS_REF_VECTOR_DATA_H static inline_DATA | ||
22 | #else /* INLINE_VECTOR_FUNC */ | ||
23 | #define STORAGE_CLASS_REF_VECTOR_FUNC_H extern | ||
24 | #define STORAGE_CLASS_REF_VECTOR_DATA_H extern_DATA | ||
25 | #endif /* INLINE_VECTOR_FUNC */ | ||
26 | |||
27 | |||
28 | #include "ref_vector_func_types.h" | ||
29 | |||
30 | /* @brief Doubling multiply accumulate with saturation | ||
31 | * | ||
32 | * @param[in] acc accumulator | ||
33 | * @param[in] a multiply input | ||
34 | * @param[in] b multiply input | ||
35 | * | ||
36 | * @return acc + (a*b) | ||
37 | * | ||
38 | * This function will do a doubling multiply ont | ||
39 | * inputs a and b, and will add the result to acc. | ||
40 | * in case of an overflow of acc, it will saturate. | ||
41 | */ | ||
42 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector2w OP_1w_maccd_sat( | ||
43 | tvector2w acc, | ||
44 | tvector1w a, | ||
45 | tvector1w b ); | ||
46 | |||
47 | /* @brief Doubling multiply accumulate | ||
48 | * | ||
49 | * @param[in] acc accumulator | ||
50 | * @param[in] a multiply input | ||
51 | * @param[in] b multiply input | ||
52 | * | ||
53 | * @return acc + (a*b) | ||
54 | * | ||
55 | * This function will do a doubling multiply ont | ||
56 | * inputs a and b, and will add the result to acc. | ||
57 | * in case of overflow it will not saturate but wrap around. | ||
58 | */ | ||
59 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector2w OP_1w_maccd( | ||
60 | tvector2w acc, | ||
61 | tvector1w a, | ||
62 | tvector1w b ); | ||
63 | |||
64 | /* @brief Re-aligning multiply | ||
65 | * | ||
66 | * @param[in] a multiply input | ||
67 | * @param[in] b multiply input | ||
68 | * @param[in] shift shift amount | ||
69 | * | ||
70 | * @return (a*b)>>shift | ||
71 | * | ||
72 | * This function will multiply a with b, followed by a right | ||
73 | * shift with rounding. the result is saturated and casted | ||
74 | * to single precision. | ||
75 | */ | ||
76 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_mul_realigning( | ||
77 | tvector1w a, | ||
78 | tvector1w b, | ||
79 | tscalar1w shift ); | ||
80 | |||
81 | /* @brief Leading bit index | ||
82 | * | ||
83 | * @param[in] a input | ||
84 | * | ||
85 | * @return index of the leading bit of each element | ||
86 | * | ||
87 | * This function finds the index of leading one (set) bit of the | ||
88 | * input. The index starts with 0 for the LSB and can go upto | ||
89 | * ISP_VEC_ELEMBITS-1 for the MSB. For an input equal to zero, | ||
90 | * the returned index is -1. | ||
91 | */ | ||
92 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_lod( | ||
93 | tvector1w a); | ||
94 | |||
95 | /* @brief Config Unit Input Processing | ||
96 | * | ||
97 | * @param[in] a input | ||
98 | * @param[in] input_scale input scaling factor | ||
99 | * @param[in] input_offset input offset factor | ||
100 | * | ||
101 | * @return scaled & offset added input clamped to MAXVALUE | ||
102 | * | ||
103 | * As part of input processing for piecewise linear estimation config unit, | ||
104 | * this function will perform scaling followed by adding offset and | ||
105 | * then clamping to the MAX InputValue | ||
106 | * It asserts -MAX_SHIFT_1W <= input_scale <= MAX_SHIFT_1W, and | ||
107 | * -MAX_SHIFT_1W <= input_offset <= MAX_SHIFT_1W | ||
108 | */ | ||
109 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_input_scaling_offset_clamping( | ||
110 | tvector1w a, | ||
111 | tscalar1w_5bit_signed input_scale, | ||
112 | tscalar1w_5bit_signed input_offset); | ||
113 | |||
114 | /* @brief Config Unit Output Processing | ||
115 | * | ||
116 | * @param[in] a output | ||
117 | * @param[in] output_scale output scaling factor | ||
118 | * | ||
119 | * @return scaled & clamped output value | ||
120 | * | ||
121 | * As part of output processing for piecewise linear estimation config unit, | ||
122 | * This function will perform scaling and then clamping to output | ||
123 | * MAX value. | ||
124 | * It asserts -MAX_SHIFT_1W <= output_scale <= MAX_SHIFT_1W | ||
125 | */ | ||
126 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_output_scaling_clamping( | ||
127 | tvector1w a, | ||
128 | tscalar1w_5bit_signed output_scale); | ||
129 | |||
130 | /* @brief Config Unit Piecewiselinear estimation | ||
131 | * | ||
132 | * @param[in] a input | ||
133 | * @param[in] config_points config parameter structure | ||
134 | * | ||
135 | * @return piecewise linear estimated output | ||
136 | * | ||
137 | * Given a set of N points {(x1,y1),()x2,y2), ....,(xn,yn)}, to find | ||
138 | * the functional value at an arbitrary point around the input set, | ||
139 | * this function will perform input processing followed by piecewise | ||
140 | * linear estimation and then output processing to yield the final value. | ||
141 | */ | ||
142 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_piecewise_estimation( | ||
143 | tvector1w a, | ||
144 | ref_config_points config_points); | ||
145 | |||
146 | /* @brief Fast Config Unit | ||
147 | * | ||
148 | * @param[in] x input | ||
149 | * @param[in] init_vectors LUT data structure | ||
150 | * | ||
151 | * @return piecewise linear estimated output | ||
152 | * This block gets an input x and a set of input configuration points stored in a look-up | ||
153 | * table of 32 elements. First, the x input is clipped to be within the range [x1, xn+1]. | ||
154 | * Then, it computes the interval in which the input lies. Finally, the output is computed | ||
155 | * by performing linear interpolation based on the interval properties (i.e. x_prev, slope, | ||
156 | * and offset). This block assumes that the points are equally spaced and that the interval | ||
157 | * size is a power of 2. | ||
158 | **/ | ||
159 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_XCU( | ||
160 | tvector1w x, | ||
161 | xcu_ref_init_vectors init_vectors); | ||
162 | |||
163 | |||
164 | /* @brief LXCU | ||
165 | * | ||
166 | * @param[in] x input | ||
167 | * @param[in] init_vectors LUT data structure | ||
168 | * | ||
169 | * @return logarithmic piecewise linear estimated output. | ||
170 | * This block gets an input x and a set of input configuration points stored in a look-up | ||
171 | * table of 32 elements. It computes the interval in which the input lies. | ||
172 | * Then output is computed by performing linear interpolation based on the interval | ||
173 | * properties (i.e. x_prev, slope, * and offset). | ||
174 | * This BBB assumes spacing x-coordinates of "init vectors" increase exponentially as | ||
175 | * shown below. | ||
176 | * interval size : 2^0 2^1 2^2 2^3 | ||
177 | * x-coordinates: x0<--->x1<---->x2<---->x3<----> | ||
178 | **/ | ||
179 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_LXCU( | ||
180 | tvector1w x, | ||
181 | xcu_ref_init_vectors init_vectors); | ||
182 | |||
183 | /* @brief Coring | ||
184 | * | ||
185 | * @param[in] coring_vec Amount of coring based on brightness level | ||
186 | * @param[in] filt_input Vector of input pixels on which Coring is applied | ||
187 | * @param[in] m_CnrCoring0 Coring Level0 | ||
188 | * | ||
189 | * @return vector of filtered pixels after coring is applied | ||
190 | * | ||
191 | * This function will perform adaptive coring based on brightness level to | ||
192 | * remove noise | ||
193 | */ | ||
194 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w coring( | ||
195 | tvector1w coring_vec, | ||
196 | tvector1w filt_input, | ||
197 | tscalar1w m_CnrCoring0 ); | ||
198 | |||
199 | /* @brief Normalised FIR with coefficients [3,4,1] | ||
200 | * | ||
201 | * @param[in] m 1x3 matrix with pixels | ||
202 | * | ||
203 | * @return filtered output | ||
204 | * | ||
205 | * This function will calculate the | ||
206 | * Normalised FIR with coefficients [3,4,1], | ||
207 | *-5dB at Fs/2, -90 degree phase shift (quarter pixel) | ||
208 | */ | ||
209 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_5dB_m90_nrm ( | ||
210 | const s_1w_1x3_matrix m); | ||
211 | |||
212 | /* @brief Normalised FIR with coefficients [1,4,3] | ||
213 | * | ||
214 | * @param[in] m 1x3 matrix with pixels | ||
215 | * | ||
216 | * @return filtered output | ||
217 | * | ||
218 | * This function will calculate the | ||
219 | * Normalised FIR with coefficients [1,4,3], | ||
220 | *-5dB at Fs/2, +90 degree phase shift (quarter pixel) | ||
221 | */ | ||
222 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_5dB_p90_nrm ( | ||
223 | const s_1w_1x3_matrix m); | ||
224 | |||
225 | /* @brief Normalised FIR with coefficients [1,2,1] | ||
226 | * | ||
227 | * @param[in] m 1x3 matrix with pixels | ||
228 | * | ||
229 | * @return filtered output | ||
230 | * | ||
231 | * This function will calculate the | ||
232 | * Normalised FIR with coefficients [1,2,1], -6dB at Fs/2 | ||
233 | */ | ||
234 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_6dB_nrm ( | ||
235 | const s_1w_1x3_matrix m); | ||
236 | |||
237 | /* @brief Normalised FIR with coefficients [13,16,3] | ||
238 | * | ||
239 | * @param[in] m 1x3 matrix with pixels | ||
240 | * | ||
241 | * @return filtered output | ||
242 | * | ||
243 | * This function will calculate the | ||
244 | * Normalised FIR with coefficients [13,16,3], | ||
245 | */ | ||
246 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_6dB_nrm_ph0 ( | ||
247 | const s_1w_1x3_matrix m); | ||
248 | |||
249 | /* @brief Normalised FIR with coefficients [9,16,7] | ||
250 | * | ||
251 | * @param[in] m 1x3 matrix with pixels | ||
252 | * | ||
253 | * @return filtered output | ||
254 | * | ||
255 | * This function will calculate the | ||
256 | * Normalised FIR with coefficients [9,16,7], | ||
257 | */ | ||
258 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_6dB_nrm_ph1 ( | ||
259 | const s_1w_1x3_matrix m); | ||
260 | |||
261 | /* @brief Normalised FIR with coefficients [5,16,11] | ||
262 | * | ||
263 | * @param[in] m 1x3 matrix with pixels | ||
264 | * | ||
265 | * @return filtered output | ||
266 | * | ||
267 | * This function will calculate the | ||
268 | * Normalised FIR with coefficients [5,16,11], | ||
269 | */ | ||
270 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_6dB_nrm_ph2 ( | ||
271 | const s_1w_1x3_matrix m); | ||
272 | |||
273 | /* @brief Normalised FIR with coefficients [1,16,15] | ||
274 | * | ||
275 | * @param[in] m 1x3 matrix with pixels | ||
276 | * | ||
277 | * @return filtered output | ||
278 | * | ||
279 | * This function will calculate the | ||
280 | * Normalised FIR with coefficients [1,16,15], | ||
281 | */ | ||
282 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_6dB_nrm_ph3 ( | ||
283 | const s_1w_1x3_matrix m); | ||
284 | |||
285 | /* @brief Normalised FIR with programable phase shift | ||
286 | * | ||
287 | * @param[in] m 1x3 matrix with pixels | ||
288 | * @param[in] coeff phase shift | ||
289 | * | ||
290 | * @return filtered output | ||
291 | * | ||
292 | * This function will calculate the | ||
293 | * Normalised FIR with coefficients [8-coeff,16,8+coeff], | ||
294 | */ | ||
295 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_6dB_nrm_calc_coeff ( | ||
296 | const s_1w_1x3_matrix m, tscalar1w_3bit coeff); | ||
297 | |||
298 | /* @brief 3 tap FIR with coefficients [1,1,1] | ||
299 | * | ||
300 | * @param[in] m 1x3 matrix with pixels | ||
301 | * | ||
302 | * @return filtered output | ||
303 | * | ||
304 | * This function will calculate the | ||
305 | * FIR with coefficients [1,1,1], -9dB at Fs/2 normalized with factor 1/2 | ||
306 | */ | ||
307 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x3m_9dB_nrm ( | ||
308 | const s_1w_1x3_matrix m); | ||
309 | |||
310 | #ifdef ISP2401 | ||
311 | /* @brief symmetric 3 tap FIR acts as LPF or BSF | ||
312 | * | ||
313 | * @param[in] m 1x3 matrix with pixels | ||
314 | * @param[in] k filter coefficient shift | ||
315 | * @param[in] bsf_flag 1 for BSF and 0 for LPF | ||
316 | * | ||
317 | * @return filtered output | ||
318 | * | ||
319 | * This function performs variable coefficient symmetric 3 tap filter which can | ||
320 | * be either used as Low Pass Filter or Band Stop Filter. | ||
321 | * Symmetric 3tap tap filter with DC gain 1 has filter coefficients [a, 1-2a, a] | ||
322 | * For LPF 'a' can be approximated as (1 - 2^(-k))/4, k = 0, 1, 2, ... | ||
323 | * and filter output can be approximated as: | ||
324 | * out_LPF = ((v00 + v02) - ((v00 + v02) >> k) + (2 * (v01 + (v01 >> k)))) >> 2 | ||
325 | * For BSF 'a' can be approximated as (1 + 2^(-k))/4, k = 0, 1, 2, ... | ||
326 | * and filter output can be approximated as: | ||
327 | * out_BSF = ((v00 + v02) + ((v00 + v02) >> k) + (2 * (v01 - (v01 >> k)))) >> 2 | ||
328 | * For a given filter coefficient shift 'k' and bsf_flag this function | ||
329 | * behaves either as LPF or BSF. | ||
330 | * All computation is done using 1w arithmetic and implementation does not use | ||
331 | * any multiplication. | ||
332 | */ | ||
333 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
334 | sym_fir1x3m_lpf_bsf(s_1w_1x3_matrix m, | ||
335 | tscalar1w k, | ||
336 | tscalar_bool bsf_flag); | ||
337 | #endif | ||
338 | |||
339 | /* @brief Normalised 2D FIR with coefficients [1;2;1] * [1,2,1] | ||
340 | * | ||
341 | * @param[in] m 3x3 matrix with pixels | ||
342 | * | ||
343 | * @return filtered output | ||
344 | * | ||
345 | * This function will calculate the | ||
346 | * Normalised FIR with coefficients [1;2;1] * [1,2,1] | ||
347 | * Unity gain filter through repeated scaling and rounding | ||
348 | * - 6 rotate operations per output | ||
349 | * - 8 vector operations per output | ||
350 | * _______ | ||
351 | * 14 total operations | ||
352 | */ | ||
353 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir3x3m_6dB_nrm ( | ||
354 | const s_1w_3x3_matrix m); | ||
355 | |||
356 | /* @brief Normalised 2D FIR with coefficients [1;1;1] * [1,1,1] | ||
357 | * | ||
358 | * @param[in] m 3x3 matrix with pixels | ||
359 | * | ||
360 | * @return filtered output | ||
361 | * | ||
362 | * This function will calculate the | ||
363 | * Normalised FIR with coefficients [1;1;1] * [1,1,1] | ||
364 | * | ||
365 | * (near) Unity gain filter through repeated scaling and rounding | ||
366 | * - 6 rotate operations per output | ||
367 | * - 8 vector operations per output | ||
368 | * _______ | ||
369 | * 14 operations | ||
370 | */ | ||
371 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir3x3m_9dB_nrm ( | ||
372 | const s_1w_3x3_matrix m); | ||
373 | |||
374 | /* @brief Normalised dual output 2D FIR with coefficients [1;2;1] * [1,2,1] | ||
375 | * | ||
376 | * @param[in] m 4x3 matrix with pixels | ||
377 | * | ||
378 | * @return two filtered outputs (2x1 matrix) | ||
379 | * | ||
380 | * This function will calculate the | ||
381 | * Normalised FIR with coefficients [1;2;1] * [1,2,1] | ||
382 | * and produce two outputs (vertical) | ||
383 | * Unity gain filter through repeated scaling and rounding | ||
384 | * compute two outputs per call to re-use common intermediates | ||
385 | * - 4 rotate operations per output | ||
386 | * - 6 vector operations per output (alternative possible, but in this | ||
387 | * form it's not obvious to re-use variables) | ||
388 | * _______ | ||
389 | * 10 total operations | ||
390 | */ | ||
391 | STORAGE_CLASS_REF_VECTOR_FUNC_H s_1w_2x1_matrix fir3x3m_6dB_out2x1_nrm ( | ||
392 | const s_1w_4x3_matrix m); | ||
393 | |||
394 | /* @brief Normalised dual output 2D FIR with coefficients [1;1;1] * [1,1,1] | ||
395 | * | ||
396 | * @param[in] m 4x3 matrix with pixels | ||
397 | * | ||
398 | * @return two filtered outputs (2x1 matrix) | ||
399 | * | ||
400 | * This function will calculate the | ||
401 | * Normalised FIR with coefficients [1;1;1] * [1,1,1] | ||
402 | * and produce two outputs (vertical) | ||
403 | * (near) Unity gain filter through repeated scaling and rounding | ||
404 | * compute two outputs per call to re-use common intermediates | ||
405 | * - 4 rotate operations per output | ||
406 | * - 7 vector operations per output (alternative possible, but in this | ||
407 | * form it's not obvious to re-use variables) | ||
408 | * _______ | ||
409 | * 11 total operations | ||
410 | */ | ||
411 | STORAGE_CLASS_REF_VECTOR_FUNC_H s_1w_2x1_matrix fir3x3m_9dB_out2x1_nrm ( | ||
412 | const s_1w_4x3_matrix m); | ||
413 | |||
414 | /* @brief Normalised 2D FIR 5x5 | ||
415 | * | ||
416 | * @param[in] m 5x5 matrix with pixels | ||
417 | * | ||
418 | * @return filtered output | ||
419 | * | ||
420 | * This function will calculate the | ||
421 | * Normalised FIR with coefficients [1;1;1] * [1;2;1] * [1,2,1] * [1,1,1] | ||
422 | * and produce a filtered output | ||
423 | * (near) Unity gain filter through repeated scaling and rounding | ||
424 | * - 20 rotate operations per output | ||
425 | * - 28 vector operations per output | ||
426 | * _______ | ||
427 | * 48 total operations | ||
428 | */ | ||
429 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir5x5m_15dB_nrm ( | ||
430 | const s_1w_5x5_matrix m); | ||
431 | |||
432 | /* @brief Normalised FIR 1x5 | ||
433 | * | ||
434 | * @param[in] m 1x5 matrix with pixels | ||
435 | * | ||
436 | * @return filtered output | ||
437 | * | ||
438 | * This function will calculate the | ||
439 | * Normalised FIR with coefficients [1,2,1] * [1,1,1] = [1,4,6,4,1] | ||
440 | * and produce a filtered output | ||
441 | * (near) Unity gain filter through repeated scaling and rounding | ||
442 | * - 4 rotate operations per output | ||
443 | * - 5 vector operations per output | ||
444 | * _______ | ||
445 | * 9 total operations | ||
446 | */ | ||
447 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x5m_12dB_nrm ( | ||
448 | const s_1w_1x5_matrix m); | ||
449 | |||
450 | /* @brief Normalised 2D FIR 5x5 | ||
451 | * | ||
452 | * @param[in] m 5x5 matrix with pixels | ||
453 | * | ||
454 | * @return filtered output | ||
455 | * | ||
456 | * This function will calculate the | ||
457 | * Normalised FIR with coefficients [1;2;1] * [1;2;1] * [1,2,1] * [1,2,1] | ||
458 | * and produce a filtered output | ||
459 | * (near) Unity gain filter through repeated scaling and rounding | ||
460 | * - 20 rotate operations per output | ||
461 | * - 30 vector operations per output | ||
462 | * _______ | ||
463 | * 50 total operations | ||
464 | */ | ||
465 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir5x5m_12dB_nrm ( | ||
466 | const s_1w_5x5_matrix m); | ||
467 | |||
468 | /* @brief Approximate averaging FIR 1x5 | ||
469 | * | ||
470 | * @param[in] m 1x5 matrix with pixels | ||
471 | * | ||
472 | * @return filtered output | ||
473 | * | ||
474 | * This function will produce filtered output by | ||
475 | * applying the filter coefficients (1/8) * [1,1,1,1,1] | ||
476 | * _______ | ||
477 | * 5 vector operations | ||
478 | */ | ||
479 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x5m_box ( | ||
480 | s_1w_1x5_matrix m); | ||
481 | |||
482 | /* @brief Approximate averaging FIR 1x9 | ||
483 | * | ||
484 | * @param[in] m 1x9 matrix with pixels | ||
485 | * | ||
486 | * @return filtered output | ||
487 | * | ||
488 | * This function will produce filtered output by | ||
489 | * applying the filter coefficients (1/16) * [1,1,1,1,1,1,1,1,1] | ||
490 | * _______ | ||
491 | * 9 vector operations | ||
492 | */ | ||
493 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x9m_box ( | ||
494 | s_1w_1x9_matrix m); | ||
495 | |||
496 | /* @brief Approximate averaging FIR 1x11 | ||
497 | * | ||
498 | * @param[in] m 1x11 matrix with pixels | ||
499 | * | ||
500 | * @return filtered output | ||
501 | * | ||
502 | * This function will produce filtered output by | ||
503 | * applying the filter coefficients (1/16) * [1,1,1,1,1,1,1,1,1,1,1] | ||
504 | * _______ | ||
505 | * 12 vector operations | ||
506 | */ | ||
507 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w fir1x11m_box ( | ||
508 | s_1w_1x11_matrix m); | ||
509 | |||
510 | /* @brief Symmetric 7 tap filter with normalization | ||
511 | * | ||
512 | * @param[in] in 1x7 matrix with pixels | ||
513 | * @param[in] coeff 1x4 matrix with coefficients | ||
514 | * @param[in] out_shift output pixel shift value for normalization | ||
515 | * | ||
516 | * @return symmetric 7 tap filter output | ||
517 | * | ||
518 | * This function performs symmetric 7 tap filter over input pixels. | ||
519 | * Filter sum is normalized by shifting out_shift bits. | ||
520 | * Filter sum: p0*c3 + p1*c2 + p2*c1 + p3*c0 + p4*c1 + p5*c2 + p6*c3 | ||
521 | * is implemented as: (p0 + p6)*c3 + (p1 + p5)*c2 + (p2 + p4)*c1 + p3*c0 to | ||
522 | * reduce multiplication. | ||
523 | * Input pixels should to be scaled, otherwise overflow is possible during | ||
524 | * addition | ||
525 | */ | ||
526 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
527 | fir1x7m_sym_nrm(s_1w_1x7_matrix in, | ||
528 | s_1w_1x4_matrix coeff, | ||
529 | tvector1w out_shift); | ||
530 | |||
531 | /* @brief Symmetric 7 tap filter with normalization at input side | ||
532 | * | ||
533 | * @param[in] in 1x7 matrix with pixels | ||
534 | * @param[in] coeff 1x4 matrix with coefficients | ||
535 | * | ||
536 | * @return symmetric 7 tap filter output | ||
537 | * | ||
538 | * This function performs symmetric 7 tap filter over input pixels. | ||
539 | * Filter sum: p0*c3 + p1*c2 + p2*c1 + p3*c0 + p4*c1 + p5*c2 + p6*c3 | ||
540 | * = (p0 + p6)*c3 + (p1 + p5)*c2 + (p2 + p4)*c1 + p3*c0 | ||
541 | * Input pixels and coefficients are in Qn format, where n = | ||
542 | * ISP_VEC_ELEMBITS - 1 (ie Q15 for Broxton) | ||
543 | * To avoid double precision arithmetic input pixel sum and final sum is | ||
544 | * implemented using avgrnd and coefficient multiplication using qrmul. | ||
545 | * Final result is in Qm format where m = ISP_VEC_ELEMBITS - 2 (ie Q14 for | ||
546 | * Broxton) | ||
547 | */ | ||
548 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
549 | fir1x7m_sym_innrm_approx(s_1w_1x7_matrix in, | ||
550 | s_1w_1x4_matrix coeff); | ||
551 | |||
552 | /* @brief Symmetric 7 tap filter with normalization at output side | ||
553 | * | ||
554 | * @param[in] in 1x7 matrix with pixels | ||
555 | * @param[in] coeff 1x4 matrix with coefficients | ||
556 | * | ||
557 | * @return symmetric 7 tap filter output | ||
558 | * | ||
559 | * This function performs symmetric 7 tap filter over input pixels. | ||
560 | * Filter sum: p0*c3 + p1*c2 + p2*c1 + p3*c0 + p4*c1 + p5*c2 + p6*c3 | ||
561 | * = (p0 + p6)*c3 + (p1 + p5)*c2 + (p2 + p4)*c1 + p3*c0 | ||
562 | * Input pixels are in Qn and coefficients are in Qm format, where n = | ||
563 | * ISP_VEC_ELEMBITS - 2 and m = ISP_VEC_ELEMBITS - 1 (ie Q14 and Q15 | ||
564 | * respectively for Broxton) | ||
565 | * To avoid double precision arithmetic input pixel sum and final sum is | ||
566 | * implemented using addsat and coefficient multiplication using qrmul. | ||
567 | * Final sum is left shifted by 2 and saturated to produce result is Qm format | ||
568 | * (ie Q15 for Broxton) | ||
569 | */ | ||
570 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
571 | fir1x7m_sym_outnrm_approx(s_1w_1x7_matrix in, | ||
572 | s_1w_1x4_matrix coeff); | ||
573 | |||
574 | /* @brief 4 tap filter with normalization | ||
575 | * | ||
576 | * @param[in] in 1x4 matrix with pixels | ||
577 | * @param[in] coeff 1x4 matrix with coefficients | ||
578 | * @param[in] out_shift output pixel shift value for normalization | ||
579 | * | ||
580 | * @return 4 tap filter output | ||
581 | * | ||
582 | * This function performs 4 tap filter over input pixels. | ||
583 | * Filter sum is normalized by shifting out_shift bits. | ||
584 | * Filter sum: p0*c0 + p1*c1 + p2*c2 + p3*c3 | ||
585 | */ | ||
586 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
587 | fir1x4m_nrm(s_1w_1x4_matrix in, | ||
588 | s_1w_1x4_matrix coeff, | ||
589 | tvector1w out_shift); | ||
590 | |||
591 | /* @brief 4 tap filter with normalization for half pixel interpolation | ||
592 | * | ||
593 | * @param[in] in 1x4 matrix with pixels | ||
594 | * | ||
595 | * @return 4 tap filter output with filter tap [-1 9 9 -1]/16 | ||
596 | * | ||
597 | * This function performs 4 tap filter over input pixels. | ||
598 | * Filter sum: -p0 + 9*p1 + 9*p2 - p3 | ||
599 | * This filter implementation is completely free from multiplication and double | ||
600 | * precision arithmetic. | ||
601 | * Typical usage of this filter is to half pixel interpolation of Bezier | ||
602 | * surface | ||
603 | * */ | ||
604 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
605 | fir1x4m_bicubic_bezier_half(s_1w_1x4_matrix in); | ||
606 | |||
607 | /* @brief 4 tap filter with normalization for quarter pixel interpolation | ||
608 | * | ||
609 | * @param[in] in 1x4 matrix with pixels | ||
610 | * @param[in] coeff 1x4 matrix with coefficients | ||
611 | * | ||
612 | * @return 4 tap filter output | ||
613 | * | ||
614 | * This function performs 4 tap filter over input pixels. | ||
615 | * Filter sum: p0*c0 + p1*c1 + p2*c2 + p3*c3 | ||
616 | * To avoid double precision arithmetic we implemented multiplication using | ||
617 | * qrmul and addition using avgrnd. Coefficients( c0 to c3) formats are assumed | ||
618 | * to be: Qm, Qn, Qo, Qm, where m = n + 2 and o = n + 1. | ||
619 | * Typical usage of this filter is to quarter pixel interpolation of Bezier | ||
620 | * surface with filter coefficients:[-9 111 29 -3]/128. For which coefficient | ||
621 | * values should be: [-9216/2^17 28416/2^15 1484/2^16 -3072/2^17] for | ||
622 | * ISP_VEC_ELEMBITS = 16. | ||
623 | */ | ||
624 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
625 | fir1x4m_bicubic_bezier_quarter(s_1w_1x4_matrix in, | ||
626 | s_1w_1x4_matrix coeff); | ||
627 | |||
628 | |||
629 | /* @brief Symmetric 3 tap filter with normalization | ||
630 | * | ||
631 | * @param[in] in 1x3 matrix with pixels | ||
632 | * @param[in] coeff 1x2 matrix with coefficients | ||
633 | * @param[in] out_shift output pixel shift value for normalization | ||
634 | * | ||
635 | * @return symmetric 3 tap filter output | ||
636 | * | ||
637 | * This function performs symmetric 3 tap filter input pixels. | ||
638 | * Filter sum is normalized by shifting out_shift bits. | ||
639 | * Filter sum: p0*c1 + p1*c0 + p2*c1 | ||
640 | * is implemented as: (p0 + p2)*c1 + p1*c0 to reduce multiplication. | ||
641 | * Input pixels should to be scaled, otherwise overflow is possible during | ||
642 | * addition | ||
643 | */ | ||
644 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
645 | fir1x3m_sym_nrm(s_1w_1x3_matrix in, | ||
646 | s_1w_1x2_matrix coeff, | ||
647 | tvector1w out_shift); | ||
648 | |||
649 | /* @brief Symmetric 3 tap filter with normalization | ||
650 | * | ||
651 | * @param[in] in 1x3 matrix with pixels | ||
652 | * @param[in] coeff 1x2 matrix with coefficients | ||
653 | * | ||
654 | * @return symmetric 3 tap filter output | ||
655 | * | ||
656 | * This function performs symmetric 3 tap filter over input pixels. | ||
657 | * Filter sum: p0*c1 + p1*c0 + p2*c1 = (p0 + p2)*c1 + p1*c0 | ||
658 | * Input pixels are in Qn and coefficient c0 is in Qm and c1 is in Qn format, | ||
659 | * where n = ISP_VEC_ELEMBITS - 1 and m = ISP_VEC_ELEMBITS - 2 ( ie Q15 and Q14 | ||
660 | * respectively for Broxton) | ||
661 | * To avoid double precision arithmetic input pixel sum is implemented using | ||
662 | * avgrnd, coefficient multiplication using qrmul and final sum using addsat | ||
663 | * Final sum is Qm format (ie Q14 for Broxton) | ||
664 | */ | ||
665 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
666 | fir1x3m_sym_nrm_approx(s_1w_1x3_matrix in, | ||
667 | s_1w_1x2_matrix coeff); | ||
668 | |||
669 | /* @brief Mean of 1x3 matrix | ||
670 | * | ||
671 | * @param[in] m 1x3 matrix with pixels | ||
672 | * | ||
673 | * @return mean of 1x3 matrix | ||
674 | * | ||
675 | * This function calculates the mean of 1x3 pixels, | ||
676 | * with a factor of 4/3. | ||
677 | */ | ||
678 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean1x3m( | ||
679 | s_1w_1x3_matrix m); | ||
680 | |||
681 | /* @brief Mean of 3x3 matrix | ||
682 | * | ||
683 | * @param[in] m 3x3 matrix with pixels | ||
684 | * | ||
685 | * @return mean of 3x3 matrix | ||
686 | * | ||
687 | * This function calculates the mean of 3x3 pixels, | ||
688 | * with a factor of 16/9. | ||
689 | */ | ||
690 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean3x3m( | ||
691 | s_1w_3x3_matrix m); | ||
692 | |||
693 | /* @brief Mean of 1x4 matrix | ||
694 | * | ||
695 | * @param[in] m 1x4 matrix with pixels | ||
696 | * | ||
697 | * @return mean of 1x4 matrix | ||
698 | * | ||
699 | * This function calculates the mean of 1x4 pixels | ||
700 | */ | ||
701 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean1x4m( | ||
702 | s_1w_1x4_matrix m); | ||
703 | |||
704 | /* @brief Mean of 4x4 matrix | ||
705 | * | ||
706 | * @param[in] m 4x4 matrix with pixels | ||
707 | * | ||
708 | * @return mean of 4x4 matrix | ||
709 | * | ||
710 | * This function calculates the mean of 4x4 matrix with pixels | ||
711 | */ | ||
712 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean4x4m( | ||
713 | s_1w_4x4_matrix m); | ||
714 | |||
715 | /* @brief Mean of 2x3 matrix | ||
716 | * | ||
717 | * @param[in] m 2x3 matrix with pixels | ||
718 | * | ||
719 | * @return mean of 2x3 matrix | ||
720 | * | ||
721 | * This function calculates the mean of 2x3 matrix with pixels | ||
722 | * with a factor of 8/6. | ||
723 | */ | ||
724 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean2x3m( | ||
725 | s_1w_2x3_matrix m); | ||
726 | |||
727 | /* @brief Mean of 1x5 matrix | ||
728 | * | ||
729 | * @param[in] m 1x5 matrix with pixels | ||
730 | * | ||
731 | * @return mean of 1x5 matrix | ||
732 | * | ||
733 | * This function calculates the mean of 1x5 matrix with pixels | ||
734 | * with a factor of 8/5. | ||
735 | */ | ||
736 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean1x5m(s_1w_1x5_matrix m); | ||
737 | |||
738 | /* @brief Mean of 1x6 matrix | ||
739 | * | ||
740 | * @param[in] m 1x6 matrix with pixels | ||
741 | * | ||
742 | * @return mean of 1x6 matrix | ||
743 | * | ||
744 | * This function calculates the mean of 1x6 matrix with pixels | ||
745 | * with a factor of 8/6. | ||
746 | */ | ||
747 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean1x6m( | ||
748 | s_1w_1x6_matrix m); | ||
749 | |||
750 | /* @brief Mean of 5x5 matrix | ||
751 | * | ||
752 | * @param[in] m 5x5 matrix with pixels | ||
753 | * | ||
754 | * @return mean of 5x5 matrix | ||
755 | * | ||
756 | * This function calculates the mean of 5x5 matrix with pixels | ||
757 | * with a factor of 32/25. | ||
758 | */ | ||
759 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean5x5m( | ||
760 | s_1w_5x5_matrix m); | ||
761 | |||
762 | /* @brief Mean of 6x6 matrix | ||
763 | * | ||
764 | * @param[in] m 6x6 matrix with pixels | ||
765 | * | ||
766 | * @return mean of 6x6 matrix | ||
767 | * | ||
768 | * This function calculates the mean of 6x6 matrix with pixels | ||
769 | * with a factor of 64/36. | ||
770 | */ | ||
771 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w mean6x6m( | ||
772 | s_1w_6x6_matrix m); | ||
773 | |||
774 | /* @brief Minimum of 4x4 matrix | ||
775 | * | ||
776 | * @param[in] m 4x4 matrix with pixels | ||
777 | * | ||
778 | * @return minimum of 4x4 matrix | ||
779 | * | ||
780 | * This function calculates the minimum of | ||
781 | * 4x4 matrix with pixels. | ||
782 | */ | ||
783 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w min4x4m( | ||
784 | s_1w_4x4_matrix m); | ||
785 | |||
786 | /* @brief Maximum of 4x4 matrix | ||
787 | * | ||
788 | * @param[in] m 4x4 matrix with pixels | ||
789 | * | ||
790 | * @return maximum of 4x4 matrix | ||
791 | * | ||
792 | * This function calculates the maximum of | ||
793 | * 4x4 matrix with pixels. | ||
794 | */ | ||
795 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w max4x4m( | ||
796 | s_1w_4x4_matrix m); | ||
797 | |||
798 | /* @brief SAD between two 3x3 matrices | ||
799 | * | ||
800 | * @param[in] a 3x3 matrix with pixels | ||
801 | * | ||
802 | * @param[in] b 3x3 matrix with pixels | ||
803 | * | ||
804 | * @return 3x3 matrix SAD | ||
805 | * | ||
806 | * This function calculates the sum of absolute difference between two matrices. | ||
807 | * Both input pixels and SAD are normalized by a factor of SAD3x3_IN_SHIFT and | ||
808 | * SAD3x3_OUT_SHIFT respectively. | ||
809 | * Computed SAD is 1/(2 ^ (SAD3x3_IN_SHIFT + SAD3x3_OUT_SHIFT)) ie 1/16 factor | ||
810 | * of original SAD and it's more precise than sad3x3m() | ||
811 | */ | ||
812 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w sad3x3m_precise( | ||
813 | s_1w_3x3_matrix a, | ||
814 | s_1w_3x3_matrix b); | ||
815 | |||
816 | /* @brief SAD between two 3x3 matrices | ||
817 | * | ||
818 | * @param[in] a 3x3 matrix with pixels | ||
819 | * | ||
820 | * @param[in] b 3x3 matrix with pixels | ||
821 | * | ||
822 | * @return 3x3 matrix SAD | ||
823 | * | ||
824 | * This function calculates the sum of absolute difference between two matrices. | ||
825 | * This version saves cycles by avoiding input normalization and wide vector | ||
826 | * operation during sum computation | ||
827 | * Input pixel differences are computed by absolute of rounded, halved | ||
828 | * subtraction. Normalized sum is computed by rounded averages. | ||
829 | * Computed SAD is (1/2)*(1/16) = 1/32 factor of original SAD. Factor 1/2 comes | ||
830 | * from input halving operation and factor 1/16 comes from mean operation | ||
831 | */ | ||
832 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w sad3x3m( | ||
833 | s_1w_3x3_matrix a, | ||
834 | s_1w_3x3_matrix b); | ||
835 | |||
836 | /* @brief SAD between two 5x5 matrices | ||
837 | * | ||
838 | * @param[in] a 5x5 matrix with pixels | ||
839 | * | ||
840 | * @param[in] b 5x5 matrix with pixels | ||
841 | * | ||
842 | * @return 5x5 matrix SAD | ||
843 | * | ||
844 | * Computed SAD is = 1/32 factor of original SAD. | ||
845 | */ | ||
846 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w sad5x5m( | ||
847 | s_1w_5x5_matrix a, | ||
848 | s_1w_5x5_matrix b); | ||
849 | |||
850 | /* @brief Absolute gradient between two sets of 1x5 matrices | ||
851 | * | ||
852 | * @param[in] m0 first set of 1x5 matrix with pixels | ||
853 | * @param[in] m1 second set of 1x5 matrix with pixels | ||
854 | * | ||
855 | * @return absolute gradient between two 1x5 matrices | ||
856 | * | ||
857 | * This function computes mean of two input 1x5 matrices and returns | ||
858 | * absolute difference between two mean values. | ||
859 | */ | ||
860 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w | ||
861 | absgrad1x5m(s_1w_1x5_matrix m0, s_1w_1x5_matrix m1); | ||
862 | |||
863 | /* @brief Bi-linear Interpolation optimized(approximate) | ||
864 | * | ||
865 | * @param[in] a input0 | ||
866 | * @param[in] b input1 | ||
867 | * @param[in] c cloned weight factor | ||
868 | * | ||
869 | * @return (a-b)*c + b | ||
870 | * | ||
871 | * This function will do bi-linear Interpolation on | ||
872 | * inputs a and b using constant weight factor c | ||
873 | * | ||
874 | * Inputs a,b are assumed in S1.15 format | ||
875 | * Weight factor has to be in range [0,1] and is assumed to be in S2.14 format | ||
876 | * | ||
877 | * The bilinear interpolation equation is (a*c) + b*(1-c), | ||
878 | * But this is implemented as (a-b)*c + b for optimization | ||
879 | */ | ||
880 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_bilinear_interpol_approx_c( | ||
881 | tvector1w a, | ||
882 | tvector1w b, | ||
883 | tscalar1w_weight c); | ||
884 | |||
885 | /* @brief Bi-linear Interpolation optimized(approximate) | ||
886 | * | ||
887 | * @param[in] a input0 | ||
888 | * @param[in] b input1 | ||
889 | * @param[in] c weight factor | ||
890 | * | ||
891 | * @return (a-b)*c + b | ||
892 | * | ||
893 | * This function will do bi-linear Interpolation on | ||
894 | * inputs a and b using weight factor c | ||
895 | * | ||
896 | * Inputs a,b are assumed in S1.15 format | ||
897 | * Weight factor has to be in range [0,1] and is assumed to be in S2.14 format | ||
898 | * | ||
899 | * The bilinear interpolation equation is (a*c) + b*(1-c), | ||
900 | * But this is implemented as (a-b)*c + b for optimization | ||
901 | */ | ||
902 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_bilinear_interpol_approx( | ||
903 | tvector1w a, | ||
904 | tvector1w b, | ||
905 | tvector1w_weight c); | ||
906 | |||
907 | /* @brief Bi-linear Interpolation | ||
908 | * | ||
909 | * @param[in] a input0 | ||
910 | * @param[in] b input1 | ||
911 | * @param[in] c weight factor | ||
912 | * | ||
913 | * @return (a*c) + b*(1-c) | ||
914 | * | ||
915 | * This function will do bi-linear Interpolation on | ||
916 | * inputs a and b using weight factor c | ||
917 | * | ||
918 | * Inputs a,b are assumed in S1.15 format | ||
919 | * Weight factor has to be in range [0,1] and is assumed to be in S2.14 format | ||
920 | * | ||
921 | * The bilinear interpolation equation is (a*c) + b*(1-c), | ||
922 | */ | ||
923 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_bilinear_interpol( | ||
924 | tvector1w a, | ||
925 | tvector1w b, | ||
926 | tscalar1w_weight c); | ||
927 | |||
928 | /* @brief Generic Block Matching Algorithm | ||
929 | * @param[in] search_window pointer to input search window of 16x16 pixels | ||
930 | * @param[in] ref_block pointer to input reference block of 8x8 pixels, where N<=M | ||
931 | * @param[in] output pointer to output sads | ||
932 | * @param[in] search_sz search size for SAD computation | ||
933 | * @param[in] ref_sz block size | ||
934 | * @param[in] pixel_shift pixel shift to search the data | ||
935 | * @param[in] search_block_sz search window block size | ||
936 | * @param[in] shift shift value, with which the output is shifted right | ||
937 | * | ||
938 | * @return 0 when the computation is successful. | ||
939 | |||
940 | * * This function compares the reference block with a block of size NxN in the search | ||
941 | * window. Sum of absolute differences for each pixel in the reference block and the | ||
942 | * corresponding pixel in the search block. Whole search window os traversed with the | ||
943 | * reference block with the given pixel shift. | ||
944 | * | ||
945 | */ | ||
946 | STORAGE_CLASS_REF_VECTOR_FUNC_H int generic_block_matching_algorithm( | ||
947 | tscalar1w **search_window, | ||
948 | tscalar1w **ref_block, | ||
949 | tscalar1w *output, | ||
950 | int search_sz, | ||
951 | int ref_sz, | ||
952 | int pixel_shift, | ||
953 | int search_block_sz, | ||
954 | tscalar1w_4bit_bma_shift shift); | ||
955 | |||
956 | #ifndef ISP2401 | ||
957 | /* @brief OP_1w_asp_bma_16_1_32way | ||
958 | #else | ||
959 | /* @brief OP_1w_asp_bma_16_1_32way_nomask | ||
960 | #endif | ||
961 | * | ||
962 | * @param[in] search_area input search window of 16x16 pixels | ||
963 | * @param[in] input_block input reference block of 8x8 pixels, where N<=M | ||
964 | * @param[in] shift shift value, with which the output is shifted right | ||
965 | * | ||
966 | * @return 81 SADs for all the search blocks. | ||
967 | |||
968 | * This function compares the reference block with a block of size 8x8 pixels in the | ||
969 | * search window of 16x16 pixels. Sum of absolute differences for each pixel in the | ||
970 | * reference block and the corresponding pixel in the search block is calculated. | ||
971 | * Whole search window is traversed with the reference block with the pixel shift of 1 | ||
972 | * pixels. The output is right shifted with the given shift value. The shift value is | ||
973 | * a 4 bit value. | ||
974 | * | ||
975 | */ | ||
976 | |||
977 | #ifndef ISP2401 | ||
978 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_16_1 OP_1w_asp_bma_16_1_32way( | ||
979 | #else | ||
980 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_16_1 OP_1w_asp_bma_16_1_32way_nomask( | ||
981 | #endif | ||
982 | bma_16x16_search_window search_area, | ||
983 | ref_block_8x8 input_block, | ||
984 | tscalar1w_4bit_bma_shift shift); | ||
985 | |||
986 | #ifndef ISP2401 | ||
987 | /* @brief OP_1w_asp_bma_16_2_32way | ||
988 | #else | ||
989 | /* @brief OP_1w_asp_bma_16_2_32way_nomask | ||
990 | #endif | ||
991 | * | ||
992 | * @param[in] search_area input search window of 16x16 pixels | ||
993 | * @param[in] input_block input reference block of 8x8 pixels, where N<=M | ||
994 | * @param[in] shift shift value, with which the output is shifted right | ||
995 | * | ||
996 | * @return 25 SADs for all the search blocks. | ||
997 | * This function compares the reference block with a block of size 8x8 in the search | ||
998 | * window of 16x61. Sum of absolute differences for each pixel in the reference block | ||
999 | * and the corresponding pixel in the search block is computed. Whole search window is | ||
1000 | * traversed with the reference block with the given pixel shift of 2 pixels. The output | ||
1001 | * is right shifted with the given shift value. The shift value is a 4 bit value. | ||
1002 | * | ||
1003 | */ | ||
1004 | |||
1005 | #ifndef ISP2401 | ||
1006 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_16_2 OP_1w_asp_bma_16_2_32way( | ||
1007 | #else | ||
1008 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_16_2 OP_1w_asp_bma_16_2_32way_nomask( | ||
1009 | #endif | ||
1010 | bma_16x16_search_window search_area, | ||
1011 | ref_block_8x8 input_block, | ||
1012 | tscalar1w_4bit_bma_shift shift); | ||
1013 | #ifndef ISP2401 | ||
1014 | /* @brief OP_1w_asp_bma_14_1_32way | ||
1015 | #else | ||
1016 | /* @brief OP_1w_asp_bma_14_1_32way_nomask | ||
1017 | #endif | ||
1018 | * | ||
1019 | * @param[in] search_area input search block of 16x16 pixels with search window of 14x14 pixels | ||
1020 | * @param[in] input_block input reference block of 8x8 pixels, where N<=M | ||
1021 | * @param[in] shift shift value, with which the output is shifted right | ||
1022 | * | ||
1023 | * @return 49 SADs for all the search blocks. | ||
1024 | * This function compares the reference block with a block of size 8x8 in the search | ||
1025 | * window of 14x14. Sum of absolute differences for each pixel in the reference block | ||
1026 | * and the corresponding pixel in the search block. Whole search window is traversed | ||
1027 | * with the reference block with 2 pixel shift. The output is right shifted with the | ||
1028 | * given shift value. The shift value is a 4 bit value. Input is always a 16x16 block | ||
1029 | * but the search window is 14x14, with last 2 pixels of row and column are not used | ||
1030 | * for computation. | ||
1031 | * | ||
1032 | */ | ||
1033 | |||
1034 | #ifndef ISP2401 | ||
1035 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_14_1 OP_1w_asp_bma_14_1_32way( | ||
1036 | #else | ||
1037 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_14_1 OP_1w_asp_bma_14_1_32way_nomask( | ||
1038 | #endif | ||
1039 | bma_16x16_search_window search_area, | ||
1040 | ref_block_8x8 input_block, | ||
1041 | tscalar1w_4bit_bma_shift shift); | ||
1042 | |||
1043 | #ifndef ISP2401 | ||
1044 | /* @brief OP_1w_asp_bma_14_2_32way | ||
1045 | #else | ||
1046 | /* @brief OP_1w_asp_bma_14_2_32way_nomask | ||
1047 | #endif | ||
1048 | * | ||
1049 | * @param[in] search_area input search block of 16x16 pixels with search window of 14x14 pixels | ||
1050 | * @param[in] input_block input reference block of 8x8 pixels, where N<=M | ||
1051 | * @param[in] shift shift value, with which the output is shifted right | ||
1052 | * | ||
1053 | * @return 16 SADs for all the search blocks. | ||
1054 | * This function compares the reference block with a block of size 8x8 in the search | ||
1055 | * window of 14x14. Sum of absolute differences for each pixel in the reference block | ||
1056 | * and the corresponding pixel in the search block. Whole search window is traversed | ||
1057 | * with the reference block with 2 pixels shift. The output is right shifted with the | ||
1058 | * given shift value. The shift value is a 4 bit value. | ||
1059 | * | ||
1060 | */ | ||
1061 | |||
1062 | #ifndef ISP2401 | ||
1063 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_14_2 OP_1w_asp_bma_14_2_32way( | ||
1064 | #else | ||
1065 | STORAGE_CLASS_REF_VECTOR_FUNC_H bma_output_14_2 OP_1w_asp_bma_14_2_32way_nomask( | ||
1066 | #endif | ||
1067 | bma_16x16_search_window search_area, | ||
1068 | ref_block_8x8 input_block, | ||
1069 | tscalar1w_4bit_bma_shift shift); | ||
1070 | |||
1071 | #ifdef ISP2401 | ||
1072 | /* @brief multiplex addition and passing | ||
1073 | * | ||
1074 | * @param[in] _a first pixel | ||
1075 | * @param[in] _b second pixel | ||
1076 | * @param[in] _c condition flag | ||
1077 | * | ||
1078 | * @return (_a + _b) if condition flag is true | ||
1079 | * _a if condition flag is false | ||
1080 | * | ||
1081 | * This function does multiplex addition depending on the input condition flag | ||
1082 | */ | ||
1083 | STORAGE_CLASS_REF_VECTOR_FUNC_H tvector1w OP_1w_cond_add( | ||
1084 | tvector1w _a, | ||
1085 | tvector1w _b, | ||
1086 | tflags _c); | ||
1087 | |||
1088 | #endif | ||
1089 | #ifdef HAS_bfa_unit | ||
1090 | /* @brief OP_1w_single_bfa_7x7 | ||
1091 | * | ||
1092 | * @param[in] weights - spatial and range weight lut | ||
1093 | * @param[in] threshold - threshold plane, for range weight scaling | ||
1094 | * @param[in] central_pix - central pixel plane | ||
1095 | * @param[in] src_plane - src pixel plane | ||
1096 | * | ||
1097 | * @return Bilateral filter output | ||
1098 | * | ||
1099 | * This function implements, 7x7 single bilateral filter. | ||
1100 | * Output = {sum(pixel * weight), sum(weight)} | ||
1101 | * Where sum is summation over 7x7 block set. | ||
1102 | * weight = spatial weight * range weight | ||
1103 | * spatial weights are loaded from spatial_weight_lut depending on src pixel | ||
1104 | * position in the 7x7 block | ||
1105 | * range weights are computed by table look up from range_weight_lut depending | ||
1106 | * on scaled absolute difference between src and central pixels. | ||
1107 | * threshold is used as scaling factor. range_weight_lut consists of | ||
1108 | * BFA_RW_LUT_SIZE numbers of LUT entries to model any distribution function. | ||
1109 | * Piecewise linear approximation technique is used to compute range weight | ||
1110 | * It computes absolute difference between central pixel and 61 src pixels. | ||
1111 | */ | ||
1112 | STORAGE_CLASS_REF_VECTOR_FUNC_H bfa_7x7_output OP_1w_single_bfa_7x7( | ||
1113 | bfa_weights weights, | ||
1114 | tvector1w threshold, | ||
1115 | tvector1w central_pix, | ||
1116 | s_1w_7x7_matrix src_plane); | ||
1117 | |||
1118 | /* @brief OP_1w_joint_bfa_7x7 | ||
1119 | * | ||
1120 | * @param[in] weights - spatial and range weight lut | ||
1121 | * @param[in] threshold0 - 1st threshold plane, for range weight scaling | ||
1122 | * @param[in] central_pix0 - 1st central pixel plane | ||
1123 | * @param[in] src0_plane - 1st pixel plane | ||
1124 | * @param[in] threshold1 - 2nd threshold plane, for range weight scaling | ||
1125 | * @param[in] central_pix1 - 2nd central pixel plane | ||
1126 | * @param[in] src1_plane - 2nd pixel plane | ||
1127 | * | ||
1128 | * @return Joint bilateral filter output | ||
1129 | * | ||
1130 | * This function implements, 7x7 joint bilateral filter. | ||
1131 | * Output = {sum(pixel * weight), sum(weight)} | ||
1132 | * Where sum is summation over 7x7 block set. | ||
1133 | * weight = spatial weight * range weight | ||
1134 | * spatial weights are loaded from spatial_weight_lut depending on src pixel | ||
1135 | * position in the 7x7 block | ||
1136 | * range weights are computed by table look up from range_weight_lut depending | ||
1137 | * on sum of scaled absolute difference between central pixel and two src pixel | ||
1138 | * planes. threshold is used as scaling factor. range_weight_lut consists of | ||
1139 | * BFA_RW_LUT_SIZE numbers of LUT entries to model any distribution function. | ||
1140 | * Piecewise linear approximation technique is used to compute range weight | ||
1141 | * It computes absolute difference between central pixel and 61 src pixels. | ||
1142 | */ | ||
1143 | STORAGE_CLASS_REF_VECTOR_FUNC_H bfa_7x7_output OP_1w_joint_bfa_7x7( | ||
1144 | bfa_weights weights, | ||
1145 | tvector1w threshold0, | ||
1146 | tvector1w central_pix0, | ||
1147 | s_1w_7x7_matrix src0_plane, | ||
1148 | tvector1w threshold1, | ||
1149 | tvector1w central_pix1, | ||
1150 | s_1w_7x7_matrix src1_plane); | ||
1151 | |||
1152 | /* @brief bbb_bfa_gen_spatial_weight_lut | ||
1153 | * | ||
1154 | * @param[in] in - 7x7 matrix of spatial weights | ||
1155 | * @param[in] out - generated LUT | ||
1156 | * | ||
1157 | * @return None | ||
1158 | * | ||
1159 | * This function implements, creates spatial weight look up table used | ||
1160 | * for bilaterl filter instruction. | ||
1161 | */ | ||
1162 | STORAGE_CLASS_REF_VECTOR_FUNC_H void bbb_bfa_gen_spatial_weight_lut( | ||
1163 | s_1w_7x7_matrix in, | ||
1164 | tvector1w out[BFA_MAX_KWAY]); | ||
1165 | |||
1166 | /* @brief bbb_bfa_gen_range_weight_lut | ||
1167 | * | ||
1168 | * @param[in] in - input range weight, | ||
1169 | * @param[in] out - generated LUT | ||
1170 | * | ||
1171 | * @return None | ||
1172 | * | ||
1173 | * This function implements, creates range weight look up table used | ||
1174 | * for bilaterl filter instruction. | ||
1175 | * 8 unsigned 7b weights are represented in 7 16bits LUT | ||
1176 | * LUT formation is done as follows: | ||
1177 | * higher 8 bit: Point(N) = Point(N+1) - Point(N) | ||
1178 | * lower 8 bit: Point(N) = Point(N) | ||
1179 | * Weight function can be any monotonic decreasing function for x >= 0 | ||
1180 | */ | ||
1181 | STORAGE_CLASS_REF_VECTOR_FUNC_H void bbb_bfa_gen_range_weight_lut( | ||
1182 | tvector1w in[BFA_RW_LUT_SIZE+1], | ||
1183 | tvector1w out[BFA_RW_LUT_SIZE]); | ||
1184 | #endif | ||
1185 | |||
1186 | #ifdef ISP2401 | ||
1187 | /* @brief OP_1w_imax32 | ||
1188 | * | ||
1189 | * @param[in] src - structure that holds an array of 32 elements. | ||
1190 | * | ||
1191 | * @return maximum element among input array. | ||
1192 | * | ||
1193 | *This function gets maximum element from an array of 32 elements. | ||
1194 | */ | ||
1195 | STORAGE_CLASS_REF_VECTOR_FUNC_H int OP_1w_imax32( | ||
1196 | imax32_ref_in_vector src); | ||
1197 | |||
1198 | /* @brief OP_1w_imaxidx32 | ||
1199 | * | ||
1200 | * @param[in] src - structure that holds a vector of elements. | ||
1201 | * | ||
1202 | * @return index of first element with maximum value among array. | ||
1203 | * | ||
1204 | * This function gets index of first element with maximum value | ||
1205 | * from 32 elements. | ||
1206 | */ | ||
1207 | STORAGE_CLASS_REF_VECTOR_FUNC_H int OP_1w_imaxidx32( | ||
1208 | imax32_ref_in_vector src); | ||
1209 | |||
1210 | #endif | ||
1211 | #ifndef INLINE_VECTOR_FUNC | ||
1212 | #define STORAGE_CLASS_REF_VECTOR_FUNC_C | ||
1213 | #define STORAGE_CLASS_REF_VECTOR_DATA_C const | ||
1214 | #else /* INLINE_VECTOR_FUNC */ | ||
1215 | #define STORAGE_CLASS_REF_VECTOR_FUNC_C STORAGE_CLASS_REF_VECTOR_FUNC_H | ||
1216 | #define STORAGE_CLASS_REF_VECTOR_DATA_C STORAGE_CLASS_REF_VECTOR_DATA_H | ||
1217 | #include "ref_vector_func.c" | ||
1218 | #define VECTOR_FUNC_INLINED | ||
1219 | #endif /* INLINE_VECTOR_FUNC */ | ||
1220 | |||
1221 | #endif /*_REF_VECTOR_FUNC_H_INCLUDED_*/ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func_types.h deleted file mode 100644 index 4dd05eba852e..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func_types.h +++ /dev/null | |||
@@ -1,385 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __REF_VECTOR_FUNC_TYPES_H_INCLUDED__ | ||
16 | #define __REF_VECTOR_FUNC_TYPES_H_INCLUDED__ | ||
17 | |||
18 | |||
19 | /* | ||
20 | * Prerequisites: | ||
21 | * | ||
22 | */ | ||
23 | #include "mpmath.h" | ||
24 | #include "bbb_config.h" | ||
25 | #include "isp_op1w_types.h" | ||
26 | #include "isp_op2w_types.h" | ||
27 | |||
28 | /* Defines for the Config Unit */ | ||
29 | #define MAX_CONFIG_POINTS 5 | ||
30 | #define INPUT_OFFSET_FACTOR 10 | ||
31 | #define INPUT_SCALE_FACTOR 10 | ||
32 | #define OUTPUT_SCALE_FACTOR 10 | ||
33 | #define SLOPE_A_RESOLUTION 10 | ||
34 | #define CONFIG_UNIT_LUT_SIZE_32 32 /*XCU works for ISP_NWAY = 32 */ | ||
35 | #define LXCU_LUT_SIZE 16 | ||
36 | #ifdef ISP2401 | ||
37 | #define IMAX32_ELEM_SIZE 32 | ||
38 | #endif | ||
39 | |||
40 | #define ONE_IN_Q14 (1<<(NUM_BITS-2)) | ||
41 | #define Q29_TO_Q15_SHIFT_VAL (NUM_BITS-2) | ||
42 | #define Q28_TO_Q15_SHIFT_VAL (NUM_BITS-3) | ||
43 | #define MAX_ELEM(width_in_bits) ((1<<(width_in_bits))-1) | ||
44 | |||
45 | /* Block matching algorithm related data */ | ||
46 | /* NUM_OF_SADS = ((SEARCH_AREA_HEIGHT - REF_BLOCK_HEIGHT)/PIXEL_SHIFT + 1)* \ | ||
47 | ((SEARCH_AREA_WIDTH - REF_BLOCK_WIDTH)/PIXEL_SHIFT + 1) */ | ||
48 | |||
49 | #define SADS(sw_h,sw_w, ref_h, ref_w, p_sh) (((sw_h - ref_h)/p_sh + 1)*((sw_w - ref_w)/p_sh + 1)) | ||
50 | #define SADS_16x16_1 SADS(16, 16, 8, 8, 1) | ||
51 | #define SADS_16x16_2 SADS(16, 16, 8, 8, 2) | ||
52 | #define SADS_14x14_1 SADS(14, 14, 8, 8, 1) | ||
53 | #define SADS_14x14_2 SADS(14, 14, 8, 8, 2) | ||
54 | |||
55 | #define BMA_OUTPUT_MATRIX_DIM(sw_h, ref_h, p_sh) ((sw_h - ref_h)/p_sh + 1) | ||
56 | #define BMA_OUT_16x16_2_32 BMA_OUTPUT_MATRIX_DIM(16, 8, 2) | ||
57 | #define BMA_OUT_14x14_2_32 BMA_OUTPUT_MATRIX_DIM(14, 8, 2) | ||
58 | #define BMA_OUT_16x16_1_32 BMA_OUTPUT_MATRIX_DIM(16, 8, 1) | ||
59 | #define BMA_OUT_14x14_1_32 BMA_OUTPUT_MATRIX_DIM(14, 8, 1) | ||
60 | #define BMA_SEARCH_BLOCK_SZ_16 16 | ||
61 | #define BMA_REF_BLOCK_SZ_8 8 | ||
62 | #define PIXEL_SHIFT_2 2 | ||
63 | #define PIXEL_SHIFT_1 1 | ||
64 | #define BMA_SEARCH_WIN_SZ_16 16 | ||
65 | #define BMA_SEARCH_WIN_SZ_14 14 | ||
66 | |||
67 | |||
68 | /* | ||
69 | * Struct type specification | ||
70 | */ | ||
71 | |||
72 | typedef unsigned short tscalar1w_3bit; /* tscalar1w in interval [0, 2^3) */ | ||
73 | typedef short tscalar1w_5bit_signed; /* tscalar1w in interval [-2^(5-1), 2^(5-1)) */ | ||
74 | typedef unsigned short tscalar1w_5bit; /* tscalar1w in interval [0, 2^5) */ | ||
75 | typedef short tscalar1w_range1wbit; /* tscalar1w in interval [-NUM_BITS, NUM_BITS] */ | ||
76 | typedef short tscalar1w_unsigned_range1wbit; /* tscalar1w in interval [0, NUM_BITS] */ | ||
77 | typedef unsigned short tvector_8bit; /* 8 bit positive number */ | ||
78 | typedef unsigned short tvector_5bit; | ||
79 | typedef unsigned short tvector_4bit; | ||
80 | typedef unsigned short tscalar1w_16bit; | ||
81 | typedef unsigned short tscalar1w_4bit_bma_shift; | ||
82 | |||
83 | typedef struct { | ||
84 | tvector1w v0 ; | ||
85 | tvector1w v1 ; | ||
86 | } s_1w_2x1_matrix; | ||
87 | |||
88 | #define S_1W_2X1_MATRIX_DEFAULT ((s_1w_2x1_matrix)\ | ||
89 | { 0, 0 }) | ||
90 | |||
91 | typedef struct { | ||
92 | tvector1w v00; | ||
93 | tvector1w v01; | ||
94 | } s_1w_1x2_matrix; | ||
95 | |||
96 | #define S_1W_1X2_MATRIX_DEFAULT ((s_1w_1x2_matrix)\ | ||
97 | { 0, 0 }) | ||
98 | |||
99 | typedef struct { | ||
100 | tvector1w v00 ; | ||
101 | tvector1w v01 ; | ||
102 | tvector1w v02 ; | ||
103 | } s_1w_1x3_matrix; | ||
104 | |||
105 | #define S_1W_1X3_MATRIX_DEFAULT ((s_1w_1x3_matrix)\ | ||
106 | { 0, 0, 0, }) | ||
107 | |||
108 | typedef struct { | ||
109 | tvector1w v00; tvector1w v01; tvector1w v02; | ||
110 | tvector1w v10; tvector1w v11; tvector1w v12; | ||
111 | } s_1w_2x3_matrix; | ||
112 | |||
113 | #define S_1W_2X3_MATRIX_DEFAULT ((s_1w_2x3_matrix)\ | ||
114 | { 0, 0, 0, \ | ||
115 | 0, 0, 0 }) | ||
116 | |||
117 | typedef struct { | ||
118 | tvector1w v00 ; tvector1w v01 ; tvector1w v02 ; | ||
119 | tvector1w v10 ; tvector1w v11 ; tvector1w v12 ; | ||
120 | tvector1w v20 ; tvector1w v21 ; tvector1w v22 ; | ||
121 | } s_1w_3x3_matrix; | ||
122 | |||
123 | #define S_1W_3X3_MATRIX_DEFAULT ((s_1w_3x3_matrix)\ | ||
124 | { 0, 0, 0, \ | ||
125 | 0, 0, 0, \ | ||
126 | 0, 0, 0 }) | ||
127 | |||
128 | typedef struct { | ||
129 | tvector1w v00 ; tvector1w v01 ; tvector1w v02 ; | ||
130 | tvector1w v10 ; tvector1w v11 ; tvector1w v12 ; | ||
131 | tvector1w v20 ; tvector1w v21 ; tvector1w v22 ; | ||
132 | tvector1w v30 ; tvector1w v31 ; tvector1w v32 ; | ||
133 | } s_1w_4x3_matrix; | ||
134 | |||
135 | #define S_1W_4X3_MATRIX_DEFAULT ((s_1w_4x3_matrix)\ | ||
136 | { 0, 0, 0, \ | ||
137 | 0, 0, 0, \ | ||
138 | 0, 0, 0, \ | ||
139 | 0, 0, 0 }) | ||
140 | |||
141 | typedef struct { | ||
142 | tvector1w v00 ; | ||
143 | tvector1w v01 ; | ||
144 | tvector1w v02 ; | ||
145 | tvector1w v03 ; | ||
146 | tvector1w v04 ; | ||
147 | } s_1w_1x5_matrix; | ||
148 | |||
149 | #define S_1W_1X5_MATRIX_DEFAULT ((s_1w_1x5_matrix)\ | ||
150 | { 0, 0, 0, 0, 0 }) | ||
151 | |||
152 | typedef struct { | ||
153 | tvector1w v00 ; tvector1w v01 ; tvector1w v02 ; tvector1w v03 ; tvector1w v04 ; | ||
154 | tvector1w v10 ; tvector1w v11 ; tvector1w v12 ; tvector1w v13 ; tvector1w v14 ; | ||
155 | tvector1w v20 ; tvector1w v21 ; tvector1w v22 ; tvector1w v23 ; tvector1w v24 ; | ||
156 | tvector1w v30 ; tvector1w v31 ; tvector1w v32 ; tvector1w v33 ; tvector1w v34 ; | ||
157 | tvector1w v40 ; tvector1w v41 ; tvector1w v42 ; tvector1w v43 ; tvector1w v44 ; | ||
158 | } s_1w_5x5_matrix; | ||
159 | |||
160 | #define S_1W_5X5_MATRIX_DEFAULT ((s_1w_5x5_matrix)\ | ||
161 | { 0, 0, 0, 0, 0, \ | ||
162 | 0, 0, 0, 0, 0, \ | ||
163 | 0, 0, 0, 0, 0, \ | ||
164 | 0, 0, 0, 0, 0, \ | ||
165 | 0, 0, 0, 0, 0 }) | ||
166 | #ifndef ISP2401 | ||
167 | |||
168 | #else | ||
169 | |||
170 | #endif | ||
171 | typedef struct { | ||
172 | tvector1w v00; | ||
173 | tvector1w v01; | ||
174 | tvector1w v02; | ||
175 | tvector1w v03; | ||
176 | tvector1w v04; | ||
177 | tvector1w v05; | ||
178 | tvector1w v06; | ||
179 | } s_1w_1x7_matrix; | ||
180 | |||
181 | #define S_1W_1X7_MATRIX_DEFAULT ((s_1w_1x7_matrix)\ | ||
182 | { 0, 0, 0, 0, 0, 0, 0 }) | ||
183 | |||
184 | typedef struct { | ||
185 | tvector1w v00; | ||
186 | tvector1w v01; | ||
187 | tvector1w v02; | ||
188 | tvector1w v03; | ||
189 | tvector1w v04; | ||
190 | tvector1w v05; | ||
191 | tvector1w v06; | ||
192 | tvector1w v07; | ||
193 | tvector1w v08; | ||
194 | } s_1w_1x9_matrix; | ||
195 | |||
196 | #define S_1W_1X9_MATRIX_DEFAULT ((s_1w_1x9_matrix)\ | ||
197 | { 0, 0, 0, 0, 0, 0, 0, 0, 0 }) | ||
198 | |||
199 | typedef struct { | ||
200 | tvector1w v00; | ||
201 | tvector1w v01; | ||
202 | tvector1w v02; | ||
203 | tvector1w v03; | ||
204 | } s_1w_1x4_matrix; | ||
205 | |||
206 | #define S_1W_1X4_MATRIX ((s_1w_1x4_matrix)\ | ||
207 | { 0, 0, 0, 0 }) | ||
208 | |||
209 | typedef struct { | ||
210 | tvector1w v00; tvector1w v01; tvector1w v02; tvector1w v03; | ||
211 | tvector1w v10; tvector1w v11; tvector1w v12; tvector1w v13; | ||
212 | tvector1w v20; tvector1w v21; tvector1w v22; tvector1w v23; | ||
213 | tvector1w v30; tvector1w v31; tvector1w v32; tvector1w v33; | ||
214 | } s_1w_4x4_matrix; | ||
215 | |||
216 | #define S_1W_4X4_MATRIX_DEFAULT ((s_1w_4x4_matrix)\ | ||
217 | { 0, 0, 0, 0, \ | ||
218 | 0, 0, 0, 0, \ | ||
219 | 0, 0, 0, 0, \ | ||
220 | 0, 0, 0, 0 }) | ||
221 | |||
222 | typedef struct { | ||
223 | tvector1w v00; | ||
224 | tvector1w v01; | ||
225 | tvector1w v02; | ||
226 | tvector1w v03; | ||
227 | tvector1w v04; | ||
228 | tvector1w v05; | ||
229 | } s_1w_1x6_matrix; | ||
230 | |||
231 | #define S_1W_1X6_MATRIX_DEFAULT ((s_1w_1x6_matrix)\ | ||
232 | { 0, 0, 0, 0, 0, 0 }) | ||
233 | |||
234 | typedef struct { | ||
235 | tvector1w v00; tvector1w v01; tvector1w v02; tvector1w v03; tvector1w v04; tvector1w v05; | ||
236 | tvector1w v10; tvector1w v11; tvector1w v12; tvector1w v13; tvector1w v14; tvector1w v15; | ||
237 | tvector1w v20; tvector1w v21; tvector1w v22; tvector1w v23; tvector1w v24; tvector1w v25; | ||
238 | tvector1w v30; tvector1w v31; tvector1w v32; tvector1w v33; tvector1w v34; tvector1w v35; | ||
239 | tvector1w v40; tvector1w v41; tvector1w v42; tvector1w v43; tvector1w v44; tvector1w v45; | ||
240 | tvector1w v50; tvector1w v51; tvector1w v52; tvector1w v53; tvector1w v54; tvector1w v55; | ||
241 | } s_1w_6x6_matrix; | ||
242 | |||
243 | #define S_1W_6X6_MATRIX_DEFAULT ((s_1w_6x6_matrix)\ | ||
244 | { 0, 0, 0, 0, 0, 0, \ | ||
245 | 0, 0, 0, 0, 0, 0, \ | ||
246 | 0, 0, 0, 0, 0, 0, \ | ||
247 | 0, 0, 0, 0, 0, 0, \ | ||
248 | 0, 0, 0, 0, 0, 0, \ | ||
249 | 0, 0, 0, 0, 0, 0 }) | ||
250 | |||
251 | typedef struct { | ||
252 | tvector1w v00; tvector1w v01; tvector1w v02; tvector1w v03; tvector1w v04; | ||
253 | tvector1w v05; tvector1w v06; tvector1w v07; tvector1w v08; | ||
254 | tvector1w v10; tvector1w v11; tvector1w v12; tvector1w v13; tvector1w v14; | ||
255 | tvector1w v15; tvector1w v16; tvector1w v17; tvector1w v18; | ||
256 | tvector1w v20; tvector1w v21; tvector1w v22; tvector1w v23; tvector1w v24; | ||
257 | tvector1w v25; tvector1w v26; tvector1w v27; tvector1w v28; | ||
258 | tvector1w v30; tvector1w v31; tvector1w v32; tvector1w v33; tvector1w v34; | ||
259 | tvector1w v35; tvector1w v36; tvector1w v37; tvector1w v38; | ||
260 | tvector1w v40; tvector1w v41; tvector1w v42; tvector1w v43; tvector1w v44; | ||
261 | tvector1w v45; tvector1w v46; tvector1w v47; tvector1w v48; | ||
262 | tvector1w v50; tvector1w v51; tvector1w v52; tvector1w v53; tvector1w v54; | ||
263 | tvector1w v55; tvector1w v56; tvector1w v57; tvector1w v58; | ||
264 | tvector1w v60; tvector1w v61; tvector1w v62; tvector1w v63; tvector1w v64; | ||
265 | tvector1w v65; tvector1w v66; tvector1w v67; tvector1w v68; | ||
266 | tvector1w v70; tvector1w v71; tvector1w v72; tvector1w v73; tvector1w v74; | ||
267 | tvector1w v75; tvector1w v76; tvector1w v77; tvector1w v78; | ||
268 | tvector1w v80; tvector1w v81; tvector1w v82; tvector1w v83; tvector1w v84; | ||
269 | tvector1w v85; tvector1w v86; tvector1w v87; tvector1w v88; | ||
270 | } s_1w_9x9_matrix; | ||
271 | |||
272 | #define S_1W_9X9_MATRIX_DEFAULT ((s_1w_9x9_matrix)\ | ||
273 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
274 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
275 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
276 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
277 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
278 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
279 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
280 | 0, 0, 0, 0, 0, 0, 0, 0, 0, \ | ||
281 | 0, 0, 0, 0, 0, 0, 0, 0, 0 }) | ||
282 | |||
283 | typedef struct { | ||
284 | tvector1w v00; tvector1w v01; tvector1w v02; tvector1w v03; tvector1w v04; | ||
285 | tvector1w v05; tvector1w v06; | ||
286 | tvector1w v10; tvector1w v11; tvector1w v12; tvector1w v13; tvector1w v14; | ||
287 | tvector1w v15; tvector1w v16; | ||
288 | tvector1w v20; tvector1w v21; tvector1w v22; tvector1w v23; tvector1w v24; | ||
289 | tvector1w v25; tvector1w v26; | ||
290 | tvector1w v30; tvector1w v31; tvector1w v32; tvector1w v33; tvector1w v34; | ||
291 | tvector1w v35; tvector1w v36; | ||
292 | tvector1w v40; tvector1w v41; tvector1w v42; tvector1w v43; tvector1w v44; | ||
293 | tvector1w v45; tvector1w v46; | ||
294 | tvector1w v50; tvector1w v51; tvector1w v52; tvector1w v53; tvector1w v54; | ||
295 | tvector1w v55; tvector1w v56; | ||
296 | tvector1w v60; tvector1w v61; tvector1w v62; tvector1w v63; tvector1w v64; | ||
297 | tvector1w v65; tvector1w v66; | ||
298 | } s_1w_7x7_matrix; | ||
299 | |||
300 | #define S_1W_7X7_MATRIX_DEFAULT ((s_1w_7x7_matrix)\ | ||
301 | { 0, 0, 0, 0, 0, 0, 0, \ | ||
302 | 0, 0, 0, 0, 0, 0, 0, \ | ||
303 | 0, 0, 0, 0, 0, 0, 0, \ | ||
304 | 0, 0, 0, 0, 0, 0, 0, \ | ||
305 | 0, 0, 0, 0, 0, 0, 0, \ | ||
306 | 0, 0, 0, 0, 0, 0, 0, \ | ||
307 | 0, 0, 0, 0, 0, 0, 0 }) | ||
308 | |||
309 | typedef struct { | ||
310 | tvector1w v0_0; | ||
311 | tvector1w v0_1; | ||
312 | tvector1w v0_2; | ||
313 | tvector1w v0_3; | ||
314 | tvector1w v0_4; | ||
315 | tvector1w v0_5; | ||
316 | tvector1w v0_6; | ||
317 | tvector1w v0_7; | ||
318 | tvector1w v0_8; | ||
319 | tvector1w v0_9; | ||
320 | tvector1w v0_10; | ||
321 | } s_1w_1x11_matrix; | ||
322 | |||
323 | #define S_1W_1X11_MATRIX_DEFAULT ((s_1w_1x11_matrix)\ | ||
324 | { 0, 0, 0, 0, 0, 0, 0, 0, 0 }) | ||
325 | |||
326 | typedef struct { | ||
327 | tvector1w x_cord[MAX_CONFIG_POINTS]; | ||
328 | tvector1w slope[MAX_CONFIG_POINTS-1]; | ||
329 | tvector1w y_offset[MAX_CONFIG_POINTS-1]; | ||
330 | } ref_config_points; | ||
331 | |||
332 | typedef struct { | ||
333 | tscalar1w_range1wbit slope_vec[CONFIG_UNIT_LUT_SIZE_32]; | ||
334 | tscalar1w_range1wbit offset_vec[CONFIG_UNIT_LUT_SIZE_32]; | ||
335 | tscalar1w_16bit x_cord_vec[CONFIG_UNIT_LUT_SIZE_32]; | ||
336 | tscalar1w_16bit x_cord_max; | ||
337 | tscalar1w_5bit exponent; | ||
338 | tscalar1w_5bit slope_resolution; | ||
339 | } xcu_ref_init_vectors; | ||
340 | |||
341 | typedef struct { | ||
342 | #ifdef ISP2401 | ||
343 | tvector1w elem[IMAX32_ELEM_SIZE]; | ||
344 | } imax32_ref_in_vector; | ||
345 | |||
346 | typedef struct { | ||
347 | #endif | ||
348 | tscalar1w search[BMA_SEARCH_BLOCK_SZ_16][BMA_SEARCH_BLOCK_SZ_16]; | ||
349 | } bma_16x16_search_window; | ||
350 | |||
351 | typedef struct { | ||
352 | tscalar1w ref[BMA_REF_BLOCK_SZ_8][BMA_REF_BLOCK_SZ_8]; | ||
353 | } ref_block_8x8; | ||
354 | |||
355 | typedef struct { | ||
356 | tscalar1w sads[SADS_16x16_1]; | ||
357 | } bma_output_16_1; | ||
358 | |||
359 | typedef struct { | ||
360 | tscalar1w sads[SADS_16x16_2]; | ||
361 | } bma_output_16_2; | ||
362 | |||
363 | typedef struct { | ||
364 | tscalar1w sads[SADS_14x14_2]; | ||
365 | } bma_output_14_2; | ||
366 | |||
367 | typedef struct { | ||
368 | tscalar1w sads[SADS_14x14_1]; | ||
369 | } bma_output_14_1; | ||
370 | |||
371 | typedef struct { | ||
372 | tvector1w spatial_weight_lut[BFA_MAX_KWAY]; /* spatial weight LUT */ | ||
373 | /* range weight LUT, (BFA_RW_LUT_SIZE + 1) numbers of LUT values are compressed in BFA_RW_LUT_SIZE buffer. | ||
374 | * range_weight_lut[k] = packed(drop[k], range_weight[k]) | ||
375 | * where, drop[k] = range_weight[k+1] - range_weight[k] | ||
376 | * pack(msb, lsb): two 8bits numbers packed in one 16bits number */ | ||
377 | tvector1w range_weight_lut[BFA_RW_LUT_SIZE]; | ||
378 | } bfa_weights; | ||
379 | |||
380 | /* Return type for BFA BBBs */ | ||
381 | typedef struct { | ||
382 | tvector2w sop; /* weighted sum of pixels */ | ||
383 | tvector1w sow; /* sum of weights */ | ||
384 | } bfa_7x7_output; | ||
385 | #endif /* __REF_VECTOR_FUNC_TYPES_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h deleted file mode 100644 index cd938375e02e..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h +++ /dev/null | |||
@@ -1,329 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __MPMATH_H_INCLUDED__ | ||
16 | #define __MPMATH_H_INCLUDED__ | ||
17 | |||
18 | |||
19 | #ifdef INLINE_MPMATH | ||
20 | #define STORAGE_CLASS_MPMATH_FUNC_H static inline | ||
21 | #define STORAGE_CLASS_MPMATH_DATA_H static inline_DATA | ||
22 | #else /* INLINE_MPMATH */ | ||
23 | #define STORAGE_CLASS_MPMATH_FUNC_H extern | ||
24 | #define STORAGE_CLASS_MPMATH_DATA_H extern_DATA | ||
25 | #endif /* INLINE_MPMATH */ | ||
26 | |||
27 | #include <type_support.h> | ||
28 | |||
29 | /* | ||
30 | * Implementation limits | ||
31 | */ | ||
32 | #define MIN_BITDEPTH 1 | ||
33 | #define MAX_BITDEPTH 64 | ||
34 | |||
35 | #define ROUND_NEAREST_EVEN 0 | ||
36 | #define ROUND_NEAREST 1 | ||
37 | |||
38 | /* | ||
39 | * The MP types | ||
40 | * | ||
41 | * "vector lane data" is scalar. With "scalar data" for limited range shift and address values | ||
42 | */ | ||
43 | typedef unsigned long long mpudata_t; /* Type of reference MP scalar / vector lane data; unsigned */ | ||
44 | typedef long long mpsdata_t; /* Type of reference MP scalar / vector lane data; signed */ | ||
45 | typedef unsigned short spudata_t; /* Type of reference SP scalar / vector lane data; unsigned */ | ||
46 | typedef short spsdata_t; /* Type of reference SP scalar / vector lane data; signed */ | ||
47 | typedef unsigned short bitdepth_t; | ||
48 | |||
49 | typedef enum { | ||
50 | mp_zero_ID, | ||
51 | mp_one_ID, | ||
52 | mp_mone_ID, | ||
53 | mp_smin_ID, | ||
54 | mp_smax_ID, | ||
55 | mp_umin_ID, | ||
56 | mp_umax_ID, | ||
57 | N_mp_const_ID | ||
58 | } mp_const_ID_t; | ||
59 | |||
60 | #ifdef ISP2401 | ||
61 | /* _isValidMpudata is for internal use by mpmath and bbb's. | ||
62 | * isValidMpudata is for external use by functions on top. | ||
63 | */ | ||
64 | #ifndef ENABLE_VALID_MP_DATA_CHECK | ||
65 | #define _isValidMpsdata(data,bitdepth) (1) | ||
66 | #define _isValidMpudata(data,bitdepth) (1) | ||
67 | #else | ||
68 | #define _isValidMpsdata(data,bitdepth) isValidMpsdata(data,bitdepth) | ||
69 | #define _isValidMpudata(data,bitdepth) isValidMpsdata(data,bitdepth) | ||
70 | |||
71 | #endif | ||
72 | #endif | ||
73 | STORAGE_CLASS_MPMATH_FUNC_H bool isValidMpsdata( | ||
74 | const mpsdata_t data, | ||
75 | const bitdepth_t bitdepth); | ||
76 | |||
77 | STORAGE_CLASS_MPMATH_FUNC_H bool isValidMpudata( | ||
78 | const mpudata_t data, | ||
79 | const bitdepth_t bitdepth); | ||
80 | |||
81 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_castd ( | ||
82 | const mpsdata_t in0, | ||
83 | const bitdepth_t bitdepth); | ||
84 | |||
85 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_casth ( | ||
86 | const mpsdata_t in0, | ||
87 | const bitdepth_t bitdepth); | ||
88 | |||
89 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_scasth ( | ||
90 | const mpsdata_t in0, | ||
91 | const bitdepth_t bitdepth); | ||
92 | |||
93 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qcastd ( | ||
94 | const mpsdata_t in0, | ||
95 | const bitdepth_t bitdepth); | ||
96 | |||
97 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qcasth ( | ||
98 | const mpsdata_t in0, | ||
99 | const bitdepth_t bitdepth); | ||
100 | |||
101 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qrcasth ( | ||
102 | const mpsdata_t in0, | ||
103 | const bitdepth_t bitdepth); | ||
104 | |||
105 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_abs ( | ||
106 | const mpsdata_t in0, | ||
107 | const bitdepth_t bitdepth); | ||
108 | |||
109 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_limit ( | ||
110 | const mpsdata_t bnd_low, | ||
111 | const mpsdata_t in0, | ||
112 | const mpsdata_t bnd_high, | ||
113 | const bitdepth_t bitdepth); | ||
114 | |||
115 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_max ( | ||
116 | const mpsdata_t in0, | ||
117 | const mpsdata_t in1, | ||
118 | const bitdepth_t bitdepth); | ||
119 | |||
120 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_min ( | ||
121 | const mpsdata_t in0, | ||
122 | const mpsdata_t in1, | ||
123 | const bitdepth_t bitdepth); | ||
124 | |||
125 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_mux ( | ||
126 | const spudata_t sel, | ||
127 | const mpsdata_t in0, | ||
128 | const mpsdata_t in1, | ||
129 | const bitdepth_t bitdepth); | ||
130 | |||
131 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_rmux ( | ||
132 | const spudata_t sel, | ||
133 | const mpsdata_t in0, | ||
134 | const mpsdata_t in1, | ||
135 | const bitdepth_t bitdepth); | ||
136 | |||
137 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_add ( | ||
138 | const mpsdata_t in0, | ||
139 | const mpsdata_t in1, | ||
140 | const bitdepth_t bitdepth); | ||
141 | |||
142 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_sadd ( | ||
143 | const mpsdata_t in0, | ||
144 | const mpsdata_t in1, | ||
145 | const bitdepth_t bitdepth); | ||
146 | |||
147 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_sub ( | ||
148 | const mpsdata_t in0, | ||
149 | const mpsdata_t in1, | ||
150 | const bitdepth_t bitdepth); | ||
151 | |||
152 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_ssub ( | ||
153 | const mpsdata_t in0, | ||
154 | const mpsdata_t in1, | ||
155 | const bitdepth_t bitdepth); | ||
156 | |||
157 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_addasr1 ( | ||
158 | const mpsdata_t in0, | ||
159 | const mpsdata_t in1, | ||
160 | const bitdepth_t bitdepth); | ||
161 | |||
162 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_subasr1 ( | ||
163 | const mpsdata_t in0, | ||
164 | const mpsdata_t in1, | ||
165 | const bitdepth_t bitdepth); | ||
166 | |||
167 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_lsr ( | ||
168 | const mpsdata_t in0, | ||
169 | const spsdata_t shft, | ||
170 | const bitdepth_t bitdepth); | ||
171 | |||
172 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_asr ( | ||
173 | const mpsdata_t in0, | ||
174 | const spsdata_t shft, | ||
175 | const bitdepth_t bitdepth); | ||
176 | |||
177 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_rasr ( | ||
178 | const mpsdata_t in0, | ||
179 | const spsdata_t shft, | ||
180 | const bitdepth_t bitdepth); | ||
181 | |||
182 | /* "mp_rasr_u()" is implemented by "mp_rasr()" */ | ||
183 | STORAGE_CLASS_MPMATH_FUNC_H mpudata_t mp_rasr_u ( | ||
184 | const mpudata_t in0, | ||
185 | const spsdata_t shft, | ||
186 | const bitdepth_t bitdepth); | ||
187 | |||
188 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_lsl ( | ||
189 | const mpsdata_t in0, | ||
190 | const spsdata_t shft, | ||
191 | const bitdepth_t bitdepth); | ||
192 | |||
193 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_asl ( | ||
194 | const mpsdata_t in0, | ||
195 | const spsdata_t shft, | ||
196 | const bitdepth_t bitdepth); | ||
197 | |||
198 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_muld ( | ||
199 | const mpsdata_t in0, | ||
200 | const mpsdata_t in1, | ||
201 | const bitdepth_t bitdepth); | ||
202 | |||
203 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_mul ( | ||
204 | const mpsdata_t in0, | ||
205 | const mpsdata_t in1, | ||
206 | const bitdepth_t bitdepth); | ||
207 | |||
208 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qmul ( | ||
209 | const mpsdata_t in0, | ||
210 | const mpsdata_t in1, | ||
211 | const bitdepth_t bitdepth); | ||
212 | |||
213 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qrmul ( | ||
214 | const mpsdata_t in0, | ||
215 | const mpsdata_t in1, | ||
216 | const bitdepth_t bitdepth); | ||
217 | |||
218 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qdiv ( | ||
219 | const mpsdata_t in0, | ||
220 | const mpsdata_t in1, | ||
221 | const bitdepth_t bitdepth); | ||
222 | |||
223 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_qdivh ( | ||
224 | const mpsdata_t in0, | ||
225 | const mpsdata_t in1, | ||
226 | const bitdepth_t bitdepth); | ||
227 | |||
228 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_div ( | ||
229 | const mpsdata_t in0, | ||
230 | const mpsdata_t in1, | ||
231 | const bitdepth_t bitdepth); | ||
232 | |||
233 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_divh ( | ||
234 | const mpsdata_t in0, | ||
235 | const mpsdata_t in1, | ||
236 | const bitdepth_t bitdepth); | ||
237 | |||
238 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_and ( | ||
239 | const mpsdata_t in0, | ||
240 | const mpsdata_t in1, | ||
241 | const bitdepth_t bitdepth); | ||
242 | |||
243 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_compl ( | ||
244 | const mpsdata_t in0, | ||
245 | const bitdepth_t bitdepth); | ||
246 | |||
247 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_or ( | ||
248 | const mpsdata_t in0, | ||
249 | const mpsdata_t in1, | ||
250 | const bitdepth_t bitdepth); | ||
251 | |||
252 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_xor ( | ||
253 | const mpsdata_t in0, | ||
254 | const mpsdata_t in1, | ||
255 | const bitdepth_t bitdepth); | ||
256 | |||
257 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isEQ ( | ||
258 | const mpsdata_t in0, | ||
259 | const mpsdata_t in1, | ||
260 | const bitdepth_t bitdepth); | ||
261 | |||
262 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isNE ( | ||
263 | const mpsdata_t in0, | ||
264 | const mpsdata_t in1, | ||
265 | const bitdepth_t bitdepth); | ||
266 | |||
267 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isGT ( | ||
268 | const mpsdata_t in0, | ||
269 | const mpsdata_t in1, | ||
270 | const bitdepth_t bitdepth); | ||
271 | |||
272 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isGE ( | ||
273 | const mpsdata_t in0, | ||
274 | const mpsdata_t in1, | ||
275 | const bitdepth_t bitdepth); | ||
276 | |||
277 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isLT ( | ||
278 | const mpsdata_t in0, | ||
279 | const mpsdata_t in1, | ||
280 | const bitdepth_t bitdepth); | ||
281 | |||
282 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isLE ( | ||
283 | const mpsdata_t in0, | ||
284 | const mpsdata_t in1, | ||
285 | const bitdepth_t bitdepth); | ||
286 | |||
287 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isEQZ ( | ||
288 | const mpsdata_t in0, | ||
289 | const bitdepth_t bitdepth); | ||
290 | |||
291 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isNEZ ( | ||
292 | const mpsdata_t in0, | ||
293 | const bitdepth_t bitdepth); | ||
294 | |||
295 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isGTZ ( | ||
296 | const mpsdata_t in0, | ||
297 | const bitdepth_t bitdepth); | ||
298 | |||
299 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isGEZ ( | ||
300 | const mpsdata_t in0, | ||
301 | const bitdepth_t bitdepth); | ||
302 | |||
303 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isLTZ ( | ||
304 | const mpsdata_t in0, | ||
305 | const bitdepth_t bitdepth); | ||
306 | |||
307 | STORAGE_CLASS_MPMATH_FUNC_H spudata_t mp_isLEZ ( | ||
308 | const mpsdata_t in0, | ||
309 | const bitdepth_t bitdepth); | ||
310 | |||
311 | STORAGE_CLASS_MPMATH_FUNC_H mpsdata_t mp_const ( | ||
312 | const mp_const_ID_t ID, | ||
313 | const bitdepth_t bitdepth); | ||
314 | |||
315 | STORAGE_CLASS_MPMATH_FUNC_H mpudata_t mp_sqrt_u( | ||
316 | const mpudata_t in0, | ||
317 | const bitdepth_t bitdepth); | ||
318 | |||
319 | #ifndef INLINE_MPMATH | ||
320 | #define STORAGE_CLASS_MPMATH_FUNC_C | ||
321 | #define STORAGE_CLASS_MPMATH_DATA_C const | ||
322 | #else /* INLINE_MPMATH */ | ||
323 | #define STORAGE_CLASS_MPMATH_FUNC_C STORAGE_CLASS_MPMATH_FUNC_H | ||
324 | #define STORAGE_CLASS_MPMATH_DATA_C STORAGE_CLASS_MPMATH_DATA_H | ||
325 | #include "mpmath.c" | ||
326 | #define MPMATH_INLINED | ||
327 | #endif /* INLINE_MPMATH */ | ||
328 | |||
329 | #endif /* __MPMATH_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h deleted file mode 100644 index a607242c5f1a..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __OSYS_H_INCLUDED__ | ||
16 | #define __OSYS_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is included on every cell {SP,ISP,host} and on every system | ||
20 | * that uses the OSYS device. It defines the API to DLI bridge | ||
21 | * | ||
22 | * System and cell specific interfaces and inline code are included | ||
23 | * conditionally through Makefile path settings. | ||
24 | * | ||
25 | * - . system and cell agnostic interfaces, constants and identifiers | ||
26 | * - public: system agnostic, cell specific interfaces | ||
27 | * - private: system dependent, cell specific interfaces & inline implementations | ||
28 | * - global: system specific constants and identifiers | ||
29 | * - local: system and cell specific constants and identifiers | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | |||
34 | #include "system_local.h" | ||
35 | #include "osys_local.h" | ||
36 | |||
37 | #ifndef __INLINE_OSYS__ | ||
38 | #define STORAGE_CLASS_OSYS_H extern | ||
39 | #define STORAGE_CLASS_OSYS_C | ||
40 | #include "osys_public.h" | ||
41 | #else /* __INLINE_OSYS__ */ | ||
42 | #define STORAGE_CLASS_OSYS_H static inline | ||
43 | #define STORAGE_CLASS_OSYS_C static inline | ||
44 | #include "osys_private.h" | ||
45 | #endif /* __INLINE_OSYS__ */ | ||
46 | |||
47 | #endif /* __OSYS_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h deleted file mode 100644 index 53d535e4f2ae..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __STREAM_BUFFER_H_INCLUDED__ | ||
16 | #define __STREAM_BUFFER_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is included on every cell {SP,ISP,host} and on every system | ||
20 | * that uses the DMA device. It defines the API to DLI bridge | ||
21 | * | ||
22 | * System and cell specific interfaces and inline code are included | ||
23 | * conditionally through Makefile path settings. | ||
24 | * | ||
25 | * - . system and cell agnostic interfaces, constants and identifiers | ||
26 | * - public: system agnostic, cell specific interfaces | ||
27 | * - private: system dependent, cell specific interfaces & inline implementations | ||
28 | * - global: system specific constants and identifiers | ||
29 | * - local: system and cell specific constants and identifiers | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | |||
34 | #include "system_local.h" | ||
35 | #include "stream_buffer_local.h" | ||
36 | |||
37 | #ifndef __INLINE_STREAM_BUFFER__ | ||
38 | #define STORAGE_CLASS_STREAM_BUFFER_H extern | ||
39 | #define STORAGE_CLASS_STREAM_BUFFER_C | ||
40 | #include "stream_buffer_public.h" | ||
41 | #else /* __INLINE_STREAM_BUFFER__ */ | ||
42 | #define STORAGE_CLASS_STREAM_BUFFER_H static inline | ||
43 | #define STORAGE_CLASS_STREAM_BUFFER_C static inline | ||
44 | #include "stream_buffer_private.h" | ||
45 | #endif /* __INLINE_STREAM_BUFFER__ */ | ||
46 | |||
47 | #endif /* __STREAM_BUFFER_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h deleted file mode 100644 index 5368b9062897..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __VECTOR_FUNC_H_INCLUDED__ | ||
16 | #define __VECTOR_FUNC_H_INCLUDED__ | ||
17 | |||
18 | |||
19 | /* TODO: Later filters will be moved to types directory, | ||
20 | * and we should only include matrix_MxN types */ | ||
21 | #include "filters/filters_1.0/filter_2x2.h" | ||
22 | #include "filters/filters_1.0/filter_3x3.h" | ||
23 | #include "filters/filters_1.0/filter_4x4.h" | ||
24 | #include "filters/filters_1.0/filter_5x5.h" | ||
25 | |||
26 | #include "vector_func_local.h" | ||
27 | |||
28 | #ifndef __INLINE_VECTOR_FUNC__ | ||
29 | #define STORAGE_CLASS_VECTOR_FUNC_H extern | ||
30 | #define STORAGE_CLASS_VECTOR_FUNC_C | ||
31 | #include "vector_func_public.h" | ||
32 | #else /* __INLINE_VECTOR_FUNC__ */ | ||
33 | #define STORAGE_CLASS_VECTOR_FUNC_H static inline | ||
34 | #define STORAGE_CLASS_VECTOR_FUNC_C static inline | ||
35 | #include "vector_func_private.h" | ||
36 | #endif /* __INLINE_VECTOR_FUNC__ */ | ||
37 | |||
38 | #endif /* __VECTOR_FUNC_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h deleted file mode 100644 index 4923f2d5518b..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __VECTOR_OPS_H_INCLUDED__ | ||
16 | #define __VECTOR_OPS_H_INCLUDED__ | ||
17 | |||
18 | |||
19 | #include "vector_ops_local.h" | ||
20 | |||
21 | #ifndef __INLINE_VECTOR_OPS__ | ||
22 | #define STORAGE_CLASS_VECTOR_OPS_H extern | ||
23 | #define STORAGE_CLASS_VECTOR_OPS_C | ||
24 | #include "vector_ops_public.h" | ||
25 | #else /* __INLINE_VECTOR_OPS__ */ | ||
26 | #define STORAGE_CLASS_VECTOR_OPS_H static inline | ||
27 | #define STORAGE_CLASS_VECTOR_OPS_C static inline | ||
28 | #include "vector_ops_private.h" | ||
29 | #endif /* __INLINE_VECTOR_OPS__ */ | ||
30 | |||
31 | #endif /* __VECTOR_OPS_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h deleted file mode 100644 index 13083fe55141..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XMEM_H_INCLUDED__ | ||
16 | #define __XMEM_H_INCLUDED__ | ||
17 | |||
18 | /* | ||
19 | * This file is included on every cell {SP,ISP,host} and on every system | ||
20 | * that uses the XMEM device. It defines the API to DLI bridge | ||
21 | * | ||
22 | * System and cell specific interfaces and inline code are included | ||
23 | * conditionally through Makefile path settings. | ||
24 | * | ||
25 | * - . system and cell agnostic interfaces, constants and identifiers | ||
26 | * - public: system agnostic, cell specific interfaces | ||
27 | * - private: system dependent, cell specific interfaces & inline implementations | ||
28 | * - global: system specific constants and identifiers | ||
29 | * - local: system and cell specific constants and identifiers | ||
30 | */ | ||
31 | |||
32 | |||
33 | #include "system_local.h" | ||
34 | #include "xmem_local.h" | ||
35 | |||
36 | #ifndef __INLINE_XMEM__ | ||
37 | #define STORAGE_CLASS_XMEM_H extern | ||
38 | #define STORAGE_CLASS_XMEM_C | ||
39 | #include "xmem_public.h" | ||
40 | #else /* __INLINE_XMEM__ */ | ||
41 | #define STORAGE_CLASS_XMEM_H static inline | ||
42 | #define STORAGE_CLASS_XMEM_C static inline | ||
43 | #include "xmem_private.h" | ||
44 | #endif /* __INLINE_XMEM__ */ | ||
45 | |||
46 | #endif /* __XMEM_H_INCLUDED__ */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_shared/socket_global.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_shared/socket_global.h deleted file mode 100644 index 2b7025e90250..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_shared/socket_global.h +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __SOCKET_GLOBAL_H_INCLUDED__ | ||
16 | #define __SOCKET_GLOBAL_H_INCLUDED__ | ||
17 | |||
18 | #include "stream_buffer.h" | ||
19 | |||
20 | /* define the socket port direction */ | ||
21 | typedef enum { | ||
22 | SOCKET_PORT_DIRECTION_NULL, | ||
23 | SOCKET_PORT_DIRECTION_IN, | ||
24 | SOCKET_PORT_DIRECTION_OUT | ||
25 | } socket_port_direction_t; | ||
26 | |||
27 | /* pointer to the port's callout function */ | ||
28 | typedef void (*socket_port_callout_fp)(void); | ||
29 | typedef struct socket_port_s socket_port_t; | ||
30 | typedef struct socket_s socket_t; | ||
31 | |||
32 | /* data structure of the socket port */ | ||
33 | struct socket_port_s { | ||
34 | unsigned channel; /* the port entity */ | ||
35 | socket_port_direction_t direction; /* the port direction */ | ||
36 | socket_port_callout_fp callout; /* the port callout function */ | ||
37 | |||
38 | socket_t *socket; /* point to the socket */ | ||
39 | |||
40 | struct { | ||
41 | unsigned data; | ||
42 | } buf; /* the buffer at the port */ | ||
43 | }; | ||
44 | |||
45 | /* data structure of the socket */ | ||
46 | struct socket_s { | ||
47 | socket_port_t *in; /* the in-direction port */ | ||
48 | socket_port_t *out; /* the out-direction port */ | ||
49 | stream_buffer_t buf; /* the buffer between in-ports and out-ports */ | ||
50 | }; | ||
51 | |||
52 | #endif /* __SOCKET_GLOBAL_H_INCLUDED__ */ | ||
53 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_shared/stream_buffer_global.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_shared/stream_buffer_global.h deleted file mode 100644 index b9664b9608dc..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_shared/stream_buffer_global.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __STREAM_BUFFER_GLOBAL_H_INCLUDED__ | ||
16 | #define __STREAM_BUFFER_GLOBAL_H_INCLUDED__ | ||
17 | |||
18 | typedef struct stream_buffer_s stream_buffer_t; | ||
19 | struct stream_buffer_s { | ||
20 | unsigned base; | ||
21 | unsigned limit; | ||
22 | unsigned top; | ||
23 | }; | ||
24 | |||
25 | #endif /* __STREAM_BUFFER_GLOBAL_H_INCLUDED__ */ | ||
26 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_frame_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_frame_public.h index ba7a076c3afa..0beb7347a4f3 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_frame_public.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_frame_public.h | |||
@@ -121,15 +121,9 @@ struct ia_css_frame_info { | |||
121 | }; | 121 | }; |
122 | 122 | ||
123 | #define IA_CSS_BINARY_DEFAULT_FRAME_INFO \ | 123 | #define IA_CSS_BINARY_DEFAULT_FRAME_INFO \ |
124 | { \ | 124 | (struct ia_css_frame_info) { \ |
125 | {0, /* width */ \ | 125 | .format = IA_CSS_FRAME_FORMAT_NUM, \ |
126 | 0}, /* height */ \ | 126 | .raw_bayer_order = IA_CSS_BAYER_ORDER_NUM, \ |
127 | 0, /* padded_width */ \ | ||
128 | IA_CSS_FRAME_FORMAT_NUM, /* format */ \ | ||
129 | 0, /* raw_bit_depth */ \ | ||
130 | IA_CSS_BAYER_ORDER_NUM, /* raw_bayer_order */ \ | ||
131 | {0, /*start col */ \ | ||
132 | 0}, /*start line */ \ | ||
133 | } | 127 | } |
134 | 128 | ||
135 | /** | 129 | /** |
@@ -190,18 +184,11 @@ struct ia_css_frame { | |||
190 | }; | 184 | }; |
191 | 185 | ||
192 | #define DEFAULT_FRAME \ | 186 | #define DEFAULT_FRAME \ |
193 | { \ | 187 | (struct ia_css_frame) { \ |
194 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, /* info */ \ | 188 | .info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
195 | 0, /* data */ \ | 189 | .dynamic_queue_id = SH_CSS_INVALID_QUEUE_ID, \ |
196 | 0, /* data_bytes */ \ | 190 | .buf_type = IA_CSS_BUFFER_TYPE_INVALID, \ |
197 | SH_CSS_INVALID_QUEUE_ID, /* dynamic_data_index */ \ | 191 | .flash_state = IA_CSS_FRAME_FLASH_STATE_NONE, \ |
198 | IA_CSS_BUFFER_TYPE_INVALID, /* buf_type */ \ | ||
199 | IA_CSS_FRAME_FLASH_STATE_NONE, /* flash_state */ \ | ||
200 | 0, /* exp_id */ \ | ||
201 | 0, /* isp_config_id */ \ | ||
202 | false, /* valid */ \ | ||
203 | false, /* contiguous */ \ | ||
204 | { 0 } /* planes */ \ | ||
205 | } | 192 | } |
206 | 193 | ||
207 | /* @brief Fill a frame with zeros | 194 | /* @brief Fill a frame with zeros |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe.h index d0c0e6b92025..f6870fa7a18c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe.h | |||
@@ -33,22 +33,17 @@ struct ia_css_preview_settings { | |||
33 | /* 2401 only for these two - do we in fact use them for anything real */ | 33 | /* 2401 only for these two - do we in fact use them for anything real */ |
34 | struct ia_css_frame *delay_frames[MAX_NUM_DELAY_FRAMES]; | 34 | struct ia_css_frame *delay_frames[MAX_NUM_DELAY_FRAMES]; |
35 | struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES]; | 35 | struct ia_css_frame *tnr_frames[NUM_TNR_FRAMES]; |
36 | 36 | ||
37 | struct ia_css_pipe *copy_pipe; | 37 | struct ia_css_pipe *copy_pipe; |
38 | struct ia_css_pipe *capture_pipe; | 38 | struct ia_css_pipe *capture_pipe; |
39 | struct ia_css_pipe *acc_pipe; | 39 | struct ia_css_pipe *acc_pipe; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #define IA_CSS_DEFAULT_PREVIEW_SETTINGS \ | 42 | #define IA_CSS_DEFAULT_PREVIEW_SETTINGS \ |
43 | { \ | 43 | (struct ia_css_preview_settings) { \ |
44 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* copy_binary */\ | 44 | .copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
45 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* preview_binary */\ | 45 | .preview_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
46 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* vf_pp_binary */\ | 46 | .vf_pp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
47 | { NULL }, /* dvs_frames */ \ | ||
48 | { NULL }, /* tnr_frames */ \ | ||
49 | NULL, /* copy_pipe */\ | ||
50 | NULL, /* capture_pipe */\ | ||
51 | NULL, /* acc_pipe */\ | ||
52 | } | 47 | } |
53 | 48 | ||
54 | struct ia_css_capture_settings { | 49 | struct ia_css_capture_settings { |
@@ -70,20 +65,15 @@ struct ia_css_capture_settings { | |||
70 | }; | 65 | }; |
71 | 66 | ||
72 | #define IA_CSS_DEFAULT_CAPTURE_SETTINGS \ | 67 | #define IA_CSS_DEFAULT_CAPTURE_SETTINGS \ |
73 | { \ | 68 | (struct ia_css_capture_settings) { \ |
74 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* copy_binary */\ | 69 | .copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
75 | {IA_CSS_BINARY_DEFAULT_SETTINGS}, /* primary_binary */\ | 70 | .primary_binary = {IA_CSS_BINARY_DEFAULT_SETTINGS}, \ |
76 | 0, /* num_primary_stage */\ | 71 | .pre_isp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
77 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* pre_isp_binary */\ | 72 | .anr_gdc_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
78 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* anr_gdc_binary */\ | 73 | .post_isp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
79 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* post_isp_binary */\ | 74 | .capture_pp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
80 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* capture_pp_binary */\ | 75 | .vf_pp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
81 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* vf_pp_binary */\ | 76 | .capture_ldc_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
82 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* capture_ldc_binary */\ | ||
83 | NULL, /* yuv_scaler_binary */ \ | ||
84 | { NULL }, /* delay_frames[ref_frames] */ \ | ||
85 | NULL, /* is_output_stage */ \ | ||
86 | 0, /* num_yuv_scaler */ \ | ||
87 | } | 77 | } |
88 | 78 | ||
89 | struct ia_css_video_settings { | 79 | struct ia_css_video_settings { |
@@ -105,18 +95,10 @@ struct ia_css_video_settings { | |||
105 | }; | 95 | }; |
106 | 96 | ||
107 | #define IA_CSS_DEFAULT_VIDEO_SETTINGS \ | 97 | #define IA_CSS_DEFAULT_VIDEO_SETTINGS \ |
108 | { \ | 98 | (struct ia_css_video_settings) { \ |
109 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* copy_binary */ \ | 99 | .copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
110 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* video_binary */ \ | 100 | .video_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
111 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* vf_pp_binary */ \ | 101 | .vf_pp_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
112 | NULL, /* yuv_scaler_binary */ \ | ||
113 | { NULL }, /* delay_frames */ \ | ||
114 | { NULL }, /* tnr_frames */ \ | ||
115 | NULL, /* vf_pp_in_frame */ \ | ||
116 | NULL, /* copy_pipe */ \ | ||
117 | NULL, /* capture_pipe */ \ | ||
118 | NULL, /* is_output_stage */ \ | ||
119 | 0, /* num_yuv_scaler */ \ | ||
120 | } | 102 | } |
121 | 103 | ||
122 | struct ia_css_yuvpp_settings { | 104 | struct ia_css_yuvpp_settings { |
@@ -130,14 +112,8 @@ struct ia_css_yuvpp_settings { | |||
130 | }; | 112 | }; |
131 | 113 | ||
132 | #define IA_CSS_DEFAULT_YUVPP_SETTINGS \ | 114 | #define IA_CSS_DEFAULT_YUVPP_SETTINGS \ |
133 | { \ | 115 | (struct ia_css_yuvpp_settings) { \ |
134 | IA_CSS_BINARY_DEFAULT_SETTINGS, /* copy_binary */ \ | 116 | .copy_binary = IA_CSS_BINARY_DEFAULT_SETTINGS, \ |
135 | NULL, /* yuv_scaler_binary */ \ | ||
136 | NULL, /* vf_pp_binary */ \ | ||
137 | NULL, /* is_output_stage */ \ | ||
138 | 0, /* num_yuv_scaler */ \ | ||
139 | 0, /* num_vf_pp */ \ | ||
140 | 0, /* num_output */ \ | ||
141 | } | 117 | } |
142 | 118 | ||
143 | struct osys_object; | 119 | struct osys_object; |
@@ -185,35 +161,26 @@ struct ia_css_pipe { | |||
185 | }; | 161 | }; |
186 | 162 | ||
187 | #define IA_CSS_DEFAULT_PIPE \ | 163 | #define IA_CSS_DEFAULT_PIPE \ |
188 | { \ | 164 | (struct ia_css_pipe) { \ |
189 | false, /* stop_requested */ \ | 165 | .config = DEFAULT_PIPE_CONFIG, \ |
190 | DEFAULT_PIPE_CONFIG, /* config */ \ | 166 | .info = DEFAULT_PIPE_INFO, \ |
191 | DEFAULT_PIPE_EXTRA_CONFIG, /* extra_config */ \ | 167 | .mode = IA_CSS_PIPE_ID_ACC, /* (pipe_id) */ \ |
192 | DEFAULT_PIPE_INFO, /* info */ \ | 168 | .pipeline = DEFAULT_PIPELINE, \ |
193 | IA_CSS_PIPE_ID_ACC, /* mode (pipe_id) */ \ | 169 | .output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
194 | NULL, /* shading_table */ \ | 170 | .bds_output_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
195 | DEFAULT_PIPELINE, /* pipeline */ \ | 171 | .vf_output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
196 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* output_info */ \ | 172 | .out_yuv_ds_input_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
197 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, /* bds_output_info */ \ | 173 | .vf_yuv_ds_input_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
198 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* vf_output_info */ \ | 174 | .required_bds_factor = SH_CSS_BDS_FACTOR_1_00, \ |
199 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, /* out_yuv_ds_input_info */ \ | 175 | .dvs_frame_delay = 1, \ |
200 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, /* vf_yuv_ds_input_info */ \ | 176 | .enable_viewfinder = {true}, \ |
201 | NULL, /* output_stage */ \ | 177 | .in_frame_struct = DEFAULT_FRAME, \ |
202 | NULL, /* vf_stage */ \ | 178 | .out_frame_struct = DEFAULT_FRAME, \ |
203 | SH_CSS_BDS_FACTOR_1_00, /* required_bds_factor */ \ | 179 | .vf_frame_struct = DEFAULT_FRAME, \ |
204 | 1, /* dvs_frame_delay */ \ | 180 | .pipe_settings = { \ |
205 | 0, /* num_invalid_frames */ \ | 181 | .preview = IA_CSS_DEFAULT_PREVIEW_SETTINGS \ |
206 | {true}, /* enable_viewfinder */ \ | 182 | }, \ |
207 | NULL, /* stream */ \ | 183 | .pipe_num = PIPE_ENTRY_EMPTY_TOKEN, \ |
208 | DEFAULT_FRAME, /* in_frame_struct */ \ | ||
209 | DEFAULT_FRAME, /* out_frame_struct */ \ | ||
210 | DEFAULT_FRAME, /* vf_frame_struct */ \ | ||
211 | { NULL }, /* continuous_frames */ \ | ||
212 | { NULL }, /* cont_md_buffers */ \ | ||
213 | { IA_CSS_DEFAULT_PREVIEW_SETTINGS }, /* pipe_settings */ \ | ||
214 | 0, /* scaler_pp_lut */ \ | ||
215 | NULL, /* osys object */ \ | ||
216 | PIPE_ENTRY_EMPTY_TOKEN, /* pipe_num */\ | ||
217 | } | 184 | } |
218 | 185 | ||
219 | void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map); | 186 | void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map); |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe_public.h index df0aad9a6ab9..11225d5ac442 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe_public.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_pipe_public.h | |||
@@ -152,82 +152,20 @@ struct ia_css_pipe_config { | |||
152 | }; | 152 | }; |
153 | 153 | ||
154 | 154 | ||
155 | #ifdef ISP2401 | ||
156 | /** | ||
157 | * Default origin of internal frame positioned on shading table. | ||
158 | */ | ||
159 | #define IA_CSS_PIPE_DEFAULT_INTERNAL_FRAME_ORIGIN_BQS_ON_SCTBL \ | ||
160 | { \ | ||
161 | 0, /* x [bqs] */ \ | ||
162 | 0 /* y [bqs] */ \ | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * Default settings for newly created pipe configurations. | ||
167 | */ | ||
168 | #define DEFAULT_PIPE_CONFIG \ | ||
169 | { \ | ||
170 | IA_CSS_PIPE_MODE_PREVIEW, /* mode */ \ | ||
171 | 1, /* isp_pipe_version */ \ | ||
172 | { 0, 0 }, /* pipe_effective_input_res */ \ | ||
173 | { 0, 0 }, /* bayer_ds_out_res */ \ | ||
174 | { 0, 0 }, /* vf_pp_in_res */ \ | ||
175 | { 0, 0 }, /* capt_pp_in_res */ \ | ||
176 | { 0, 0 }, /* output_system_in_res */ \ | ||
177 | { 0, 0 }, /* dvs_crop_out_res */ \ | ||
178 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* output_info */ \ | ||
179 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* vf_output_info */ \ | ||
180 | NULL, /* acc_extension */ \ | ||
181 | NULL, /* acc_stages */ \ | ||
182 | 0, /* num_acc_stages */ \ | ||
183 | DEFAULT_CAPTURE_CONFIG, /* default_capture_config */ \ | ||
184 | { 0, 0 }, /* dvs_envelope */ \ | ||
185 | IA_CSS_FRAME_DELAY_1, /* dvs_frame_delay */ \ | ||
186 | -1, /* acc_num_execs */ \ | ||
187 | false, /* enable_dz */ \ | ||
188 | false, /* enable_dpc */ \ | ||
189 | false, /* enable_vfpp_bci */ \ | ||
190 | false, /* enable_luma_only */ \ | ||
191 | false, /* enable_tnr */ \ | ||
192 | NULL, /* p_isp_config */\ | ||
193 | { 0, 0 }, /* gdc_in_buffer_res */ \ | ||
194 | { 0, 0 }, /* gdc_in_buffer_offset */ \ | ||
195 | IA_CSS_PIPE_DEFAULT_INTERNAL_FRAME_ORIGIN_BQS_ON_SCTBL /* internal_frame_origin_bqs_on_sctbl */ \ | ||
196 | } | ||
197 | |||
198 | #else | ||
199 | |||
200 | /** | 155 | /** |
201 | * Default settings for newly created pipe configurations. | 156 | * Default settings for newly created pipe configurations. |
202 | */ | 157 | */ |
203 | #define DEFAULT_PIPE_CONFIG \ | 158 | #define DEFAULT_PIPE_CONFIG \ |
204 | { \ | 159 | (struct ia_css_pipe_config) { \ |
205 | IA_CSS_PIPE_MODE_PREVIEW, /* mode */ \ | 160 | .mode = IA_CSS_PIPE_MODE_PREVIEW, \ |
206 | 1, /* isp_pipe_version */ \ | 161 | .isp_pipe_version = 1, \ |
207 | { 0, 0 }, /* pipe_effective_input_res */ \ | 162 | .output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
208 | { 0, 0 }, /* bayer_ds_out_res */ \ | 163 | .vf_output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
209 | { 0, 0 }, /* vf_pp_in_res */ \ | 164 | .default_capture_config = DEFAULT_CAPTURE_CONFIG, \ |
210 | { 0, 0 }, /* capt_pp_in_res */ \ | 165 | .dvs_frame_delay = IA_CSS_FRAME_DELAY_1, \ |
211 | { 0, 0 }, /* dvs_crop_out_res */ \ | 166 | .acc_num_execs = -1, \ |
212 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* output_info */ \ | ||
213 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* vf_output_info */ \ | ||
214 | NULL, /* acc_extension */ \ | ||
215 | NULL, /* acc_stages */ \ | ||
216 | 0, /* num_acc_stages */ \ | ||
217 | DEFAULT_CAPTURE_CONFIG, /* default_capture_config */ \ | ||
218 | { 0, 0 }, /* dvs_envelope */ \ | ||
219 | IA_CSS_FRAME_DELAY_1, /* dvs_frame_delay */ \ | ||
220 | -1, /* acc_num_execs */ \ | ||
221 | false, /* enable_dz */ \ | ||
222 | false, /* enable_dpc */ \ | ||
223 | false, /* enable_vfpp_bci */ \ | ||
224 | NULL, /* p_isp_config */\ | ||
225 | { 0, 0 }, /* gdc_in_buffer_res */ \ | ||
226 | { 0, 0 } /* gdc_in_buffer_offset */ \ | ||
227 | } | 167 | } |
228 | 168 | ||
229 | #endif | ||
230 | |||
231 | /* Pipe info, this struct describes properties of a pipe after it's stream has | 169 | /* Pipe info, this struct describes properties of a pipe after it's stream has |
232 | * been created. | 170 | * been created. |
233 | * ~~~** DO NOT ADD NEW FIELD **~~~ This structure will be deprecated. | 171 | * ~~~** DO NOT ADD NEW FIELD **~~~ This structure will be deprecated. |
@@ -272,33 +210,15 @@ struct ia_css_pipe_info { | |||
272 | /** | 210 | /** |
273 | * Defaults for ia_css_pipe_info structs. | 211 | * Defaults for ia_css_pipe_info structs. |
274 | */ | 212 | */ |
275 | #ifdef ISP2401 | ||
276 | |||
277 | #define DEFAULT_PIPE_INFO \ | ||
278 | { \ | ||
279 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* output_info */ \ | ||
280 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* vf_output_info */ \ | ||
281 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, /* raw_output_info */ \ | ||
282 | { 0, 0}, /* output system in res */ \ | ||
283 | DEFAULT_SHADING_INFO, /* shading_info */ \ | ||
284 | DEFAULT_GRID_INFO, /* grid_info */ \ | ||
285 | 0 /* num_invalid_frames */ \ | ||
286 | } | ||
287 | |||
288 | #else | ||
289 | |||
290 | #define DEFAULT_PIPE_INFO \ | 213 | #define DEFAULT_PIPE_INFO \ |
291 | { \ | 214 | (struct ia_css_pipe_info) { \ |
292 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* output_info */ \ | 215 | .output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
293 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, /* vf_output_info */ \ | 216 | .vf_output_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
294 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, /* raw_output_info */ \ | 217 | .raw_output_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
295 | DEFAULT_SHADING_INFO, /* shading_info */ \ | 218 | .shading_info = DEFAULT_SHADING_INFO, \ |
296 | DEFAULT_GRID_INFO, /* grid_info */ \ | 219 | .grid_info = DEFAULT_GRID_INFO, \ |
297 | 0 /* num_invalid_frames */ \ | ||
298 | } | 220 | } |
299 | 221 | ||
300 | #endif | ||
301 | |||
302 | /* @brief Load default pipe configuration | 222 | /* @brief Load default pipe configuration |
303 | * @param[out] pipe_config The pipe configuration. | 223 | * @param[out] pipe_config The pipe configuration. |
304 | * @return None | 224 | * @return None |
@@ -402,7 +322,7 @@ ia_css_pipe_set_isp_config(struct ia_css_pipe *pipe, | |||
402 | exception holds for IA_CSS_EVENT_TYPE_PORT_EOF, for this event an IRQ is always | 322 | exception holds for IA_CSS_EVENT_TYPE_PORT_EOF, for this event an IRQ is always |
403 | raised. | 323 | raised. |
404 | Note that events are still queued and the Host can poll for them. The | 324 | Note that events are still queued and the Host can poll for them. The |
405 | or_mask and and_mask may be be active at the same time\n | 325 | or_mask and and_mask may be active at the same time\n |
406 | \n | 326 | \n |
407 | Default values, for all pipe id's, after ia_css_init:\n | 327 | Default values, for all pipe id's, after ia_css_init:\n |
408 | or_mask = IA_CSS_EVENT_TYPE_ALL\n | 328 | or_mask = IA_CSS_EVENT_TYPE_ALL\n |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_types.h index 725b90072cfe..259ab3f074ba 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_types.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/ia_css_types.h | |||
@@ -370,52 +370,20 @@ struct ia_css_shading_info { | |||
370 | } info; | 370 | } info; |
371 | }; | 371 | }; |
372 | 372 | ||
373 | #ifndef ISP2401 | ||
374 | |||
375 | /* Default Shading Correction information of Shading Correction Type 1. */ | ||
376 | #define DEFAULT_SHADING_INFO_TYPE_1 \ | ||
377 | { \ | ||
378 | IA_CSS_SHADING_CORRECTION_TYPE_1, /* type */ \ | ||
379 | { /* info */ \ | ||
380 | { \ | ||
381 | 0, /* enable */ \ | ||
382 | 0, /* num_hor_grids */ \ | ||
383 | 0, /* num_ver_grids */ \ | ||
384 | 0, /* bqs_per_grid_cell */ \ | ||
385 | 1, /* bayer_scale_hor_ratio_in */ \ | ||
386 | 1, /* bayer_scale_hor_ratio_out */ \ | ||
387 | 1, /* bayer_scale_ver_ratio_in */ \ | ||
388 | 1, /* bayer_scale_ver_ratio_out */ \ | ||
389 | 0, /* sc_bayer_origin_x_bqs_on_shading_table */ \ | ||
390 | 0 /* sc_bayer_origin_y_bqs_on_shading_table */ \ | ||
391 | } \ | ||
392 | } \ | ||
393 | } | ||
394 | |||
395 | #else | ||
396 | |||
397 | /* Default Shading Correction information of Shading Correction Type 1. */ | 373 | /* Default Shading Correction information of Shading Correction Type 1. */ |
398 | #define DEFAULT_SHADING_INFO_TYPE_1 \ | 374 | #define DEFAULT_SHADING_INFO_TYPE_1 \ |
399 | { \ | 375 | (struct ia_css_shading_info) { \ |
400 | IA_CSS_SHADING_CORRECTION_TYPE_1, /* type */ \ | 376 | .type = IA_CSS_SHADING_CORRECTION_TYPE_1, \ |
401 | { /* info */ \ | 377 | .info = { \ |
402 | { \ | 378 | .type_1 = { \ |
403 | 0, /* num_hor_grids */ \ | 379 | .bayer_scale_hor_ratio_in = 1, \ |
404 | 0, /* num_ver_grids */ \ | 380 | .bayer_scale_hor_ratio_out = 1, \ |
405 | 0, /* bqs_per_grid_cell */ \ | 381 | .bayer_scale_ver_ratio_in = 1, \ |
406 | 1, /* bayer_scale_hor_ratio_in */ \ | 382 | .bayer_scale_ver_ratio_out = 1, \ |
407 | 1, /* bayer_scale_hor_ratio_out */ \ | ||
408 | 1, /* bayer_scale_ver_ratio_in */ \ | ||
409 | 1, /* bayer_scale_ver_ratio_out */ \ | ||
410 | {0, 0}, /* isp_input_sensor_data_res_bqs */ \ | ||
411 | {0, 0}, /* sensor_data_res_bqs */ \ | ||
412 | {0, 0} /* sensor_data_origin_bqs_on_sctbl */ \ | ||
413 | } \ | 383 | } \ |
414 | } \ | 384 | } \ |
415 | } | 385 | } |
416 | 386 | ||
417 | #endif | ||
418 | |||
419 | /* Default Shading Correction information. */ | 387 | /* Default Shading Correction information. */ |
420 | #define DEFAULT_SHADING_INFO DEFAULT_SHADING_INFO_TYPE_1 | 388 | #define DEFAULT_SHADING_INFO DEFAULT_SHADING_INFO_TYPE_1 |
421 | 389 | ||
@@ -438,12 +406,9 @@ struct ia_css_grid_info { | |||
438 | 406 | ||
439 | /* defaults for ia_css_grid_info structs */ | 407 | /* defaults for ia_css_grid_info structs */ |
440 | #define DEFAULT_GRID_INFO \ | 408 | #define DEFAULT_GRID_INFO \ |
441 | { \ | 409 | (struct ia_css_grid_info) { \ |
442 | 0, /* isp_in_width */ \ | 410 | .dvs_grid = DEFAULT_DVS_GRID_INFO, \ |
443 | 0, /* isp_in_height */ \ | 411 | .vamem_type = IA_CSS_VAMEM_TYPE_1 \ |
444 | DEFAULT_3A_GRID_INFO, /* s3a_grid */ \ | ||
445 | DEFAULT_DVS_GRID_INFO, /* dvs_grid */ \ | ||
446 | IA_CSS_VAMEM_TYPE_1 /* vamem_type */ \ | ||
447 | } | 412 | } |
448 | 413 | ||
449 | /* Morphing table, used for geometric distortion and chromatic abberration | 414 | /* Morphing table, used for geometric distortion and chromatic abberration |
@@ -534,11 +499,8 @@ struct ia_css_capture_config { | |||
534 | 499 | ||
535 | /* default settings for ia_css_capture_config structs */ | 500 | /* default settings for ia_css_capture_config structs */ |
536 | #define DEFAULT_CAPTURE_CONFIG \ | 501 | #define DEFAULT_CAPTURE_CONFIG \ |
537 | { \ | 502 | (struct ia_css_capture_config) { \ |
538 | IA_CSS_CAPTURE_MODE_PRIMARY, /* mode (capture) */ \ | 503 | .mode = IA_CSS_CAPTURE_MODE_PRIMARY, \ |
539 | false, /* enable_xnr */ \ | ||
540 | false, /* enable_raw_output */ \ | ||
541 | false /* enable_capture_pp_bli */ \ | ||
542 | } | 504 | } |
543 | 505 | ||
544 | 506 | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/aa/aa_2/ia_css_aa2_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/aa/aa_2/ia_css_aa2_state.h deleted file mode 100644 index cc404018b112..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/aa/aa_2/ia_css_aa2_state.h +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_AA2_STATE_H | ||
16 | #define __IA_CSS_AA2_STATE_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #include "vmem.h" /* for VMEM_ARRAY*/ | ||
20 | |||
21 | /* Denotes the maximum number of pixels per line that can be processed: | ||
22 | * MAX_AA_VECTORS_PER_LINE = maximum_line_width / ISP_NWAY */ | ||
23 | #ifndef MAX_AA_VECTORS_PER_LINE | ||
24 | #error Please define MAX_AA_VECTORS_PER_LINE. | ||
25 | #endif | ||
26 | |||
27 | /* This uses 2 history lines for both y, u and v*/ | ||
28 | #define AA_STATE_Y_BUFFER_HEIGHT 2 | ||
29 | #define AA_STATE_UV_BUFFER_HEIGHT 2 | ||
30 | #define AA_STATE_Y_BUFFER_WIDTH MAX_AA_VECTORS_PER_LINE | ||
31 | /* The number of u and v elements is half y due to yuv420 downsampling. */ | ||
32 | #define AA_STATE_UV_BUFFER_WIDTH (AA_STATE_Y_BUFFER_WIDTH/2) | ||
33 | |||
34 | |||
35 | struct ia_css_isp_aa_vmem_state { | ||
36 | VMEM_ARRAY(y[AA_STATE_Y_BUFFER_HEIGHT], AA_STATE_Y_BUFFER_WIDTH*ISP_NWAY); | ||
37 | VMEM_ARRAY(u[AA_STATE_UV_BUFFER_HEIGHT], AA_STATE_UV_BUFFER_WIDTH*ISP_NWAY); | ||
38 | VMEM_ARRAY(v[AA_STATE_UV_BUFFER_HEIGHT], AA_STATE_UV_BUFFER_WIDTH*ISP_NWAY); | ||
39 | }; | ||
40 | |||
41 | #endif /* __IA_CSS_AA2_STATE_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_load_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_load_param.h deleted file mode 100644 index 8e1f300bcd39..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_load_param.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_BAYER_LOAD_PARAM_H | ||
16 | #define __IA_CSS_BAYER_LOAD_PARAM_H | ||
17 | |||
18 | #include "ia_css_bayer_ls_param.h" | ||
19 | |||
20 | #endif /* __IA_CSS_BAYER_LOAD_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_ls_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_ls_param.h deleted file mode 100644 index a0d355454aa3..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_ls_param.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_BAYER_LS_PARAM_H | ||
16 | #define __IA_CSS_BAYER_LS_PARAM_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #ifndef ISP2401 | ||
20 | |||
21 | #define NUM_BAYER_LS 2 | ||
22 | #define BAYER_IDX_GR 0 | ||
23 | #define BAYER_IDX_R 1 | ||
24 | #define BAYER_IDX_B 2 | ||
25 | #define BAYER_IDX_GB 3 | ||
26 | #define BAYER_QUAD_WIDTH 2 | ||
27 | #define BAYER_QUAD_HEIGHT 2 | ||
28 | #define NOF_BAYER_VECTORS 4 | ||
29 | |||
30 | /* bayer load/store */ | ||
31 | struct sh_css_isp_bayer_ls_isp_config { | ||
32 | uint32_t base_address[NUM_BAYER_LS]; | ||
33 | uint32_t width[NUM_BAYER_LS]; | ||
34 | uint32_t height[NUM_BAYER_LS]; | ||
35 | uint32_t stride[NUM_BAYER_LS]; | ||
36 | }; | ||
37 | |||
38 | #else | ||
39 | #include "../../io_ls/common/ia_css_common_io_types.h" | ||
40 | #endif | ||
41 | |||
42 | #endif /* __IA_CSS_BAYER_LS_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_store_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_store_param.h deleted file mode 100644 index f330be80efa6..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bayer_ls/bayer_ls_1.0/ia_css_bayer_store_param.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_BAYER_STORE_PARAM_H | ||
16 | #define __IA_CSS_BAYER_STORE_PARAM_H | ||
17 | |||
18 | #include "ia_css_bayer_ls_param.h" | ||
19 | |||
20 | |||
21 | #endif /* __IA_CSS_BAYER_STORE_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bnlm/ia_css_bnlm_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bnlm/ia_css_bnlm_state.h deleted file mode 100644 index 79cce0e40e82..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/bnlm/ia_css_bnlm_state.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_BNLM_STATE_H | ||
16 | #define __IA_CSS_BNLM_STATE_H | ||
17 | |||
18 | |||
19 | #include "type_support.h" | ||
20 | #include "vmem.h" /* for VMEM_ARRAY*/ | ||
21 | #include "bnlm.isp.h" | ||
22 | |||
23 | struct bnlm_vmem_state { | ||
24 | /* State buffers required for BNLM */ | ||
25 | VMEM_ARRAY(buf[BNLM_STATE_BUF_HEIGHT], BNLM_STATE_BUF_WIDTH*ISP_NWAY); | ||
26 | }; | ||
27 | |||
28 | |||
29 | |||
30 | #endif /* __IA_CSS_BNLM_STATE_H */ | ||
31 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/cnr/cnr_1.0/ia_css_cnr_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/cnr/cnr_1.0/ia_css_cnr_state.h deleted file mode 100644 index 795fba76bb20..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/cnr/cnr_1.0/ia_css_cnr_state.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_CNR_STATE_H | ||
16 | #define __IA_CSS_CNR_STATE_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | |||
20 | #include "vmem.h" | ||
21 | |||
22 | typedef struct | ||
23 | { | ||
24 | VMEM_ARRAY(u, ISP_NWAY); | ||
25 | VMEM_ARRAY(v, ISP_NWAY); | ||
26 | } s_cnr_buf; | ||
27 | |||
28 | /* CNR (color noise reduction) */ | ||
29 | struct sh_css_isp_cnr_vmem_state { | ||
30 | s_cnr_buf cnr_buf[2][MAX_VECTORS_PER_BUF_LINE/2]; | ||
31 | }; | ||
32 | |||
33 | #endif /* __IA_CSS_CNR_STATE_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/cnr/cnr_2/ia_css_cnr_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/cnr/cnr_2/ia_css_cnr_state.h deleted file mode 100644 index e533e2fa8cd5..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/cnr/cnr_2/ia_css_cnr_state.h +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_CNR2_STATE_H | ||
16 | #define __IA_CSS_CNR2_STATE_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #include "vmem.h" | ||
20 | |||
21 | typedef struct | ||
22 | { | ||
23 | VMEM_ARRAY(y, (MAX_VECTORS_PER_BUF_LINE/2)*ISP_NWAY); | ||
24 | VMEM_ARRAY(u, (MAX_VECTORS_PER_BUF_LINE/2)*ISP_NWAY); | ||
25 | VMEM_ARRAY(v, (MAX_VECTORS_PER_BUF_LINE/2)*ISP_NWAY); | ||
26 | } s_cnr_buf; | ||
27 | |||
28 | /* CNR (color noise reduction) */ | ||
29 | struct sh_css_isp_cnr_vmem_state { | ||
30 | s_cnr_buf cnr_buf; | ||
31 | }; | ||
32 | |||
33 | #endif /* __IA_CSS_CNR2_STATE_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/dp/dp_1.0/ia_css_dp_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/dp/dp_1.0/ia_css_dp_state.h deleted file mode 100644 index f832b3697908..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/dp/dp_1.0/ia_css_dp_state.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_DP_STATE_H | ||
16 | #define __IA_CSS_DP_STATE_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | |||
20 | #include "vmem.h" | ||
21 | #ifndef ISP2401 | ||
22 | #if NEED_BDS_OTHER_THAN_1_00 | ||
23 | #else | ||
24 | #if ENABLE_FIXED_BAYER_DS | ||
25 | #endif | ||
26 | #define MAX_VECTORS_PER_DP_LINE MAX_VECTORS_PER_BUF_INPUT_LINE | ||
27 | #else | ||
28 | #define MAX_VECTORS_PER_DP_LINE MAX_VECTORS_PER_BUF_LINE | ||
29 | #endif | ||
30 | |||
31 | /* DP (Defect Pixel Correction) */ | ||
32 | struct sh_css_isp_dp_vmem_state { | ||
33 | VMEM_ARRAY(dp_buf[4], MAX_VECTORS_PER_DP_LINE*ISP_NWAY); | ||
34 | }; | ||
35 | |||
36 | #endif /* __IA_CSS_DP_STATE_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/dpc2/ia_css_dpc2_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/dpc2/ia_css_dpc2_state.h deleted file mode 100644 index cbf1e81e83a6..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/dpc2/ia_css_dpc2_state.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_DPC2_STATE_H | ||
16 | #define __IA_CSS_DPC2_STATE_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #include "vmem.h" /* for VMEM_ARRAY*/ | ||
20 | |||
21 | #include "ia_css_dpc2_param.h" | ||
22 | |||
23 | struct sh_css_isp_dpc2_vmem_state { | ||
24 | VMEM_ARRAY(dpc2_input_lines[DPC2_STATE_INPUT_BUFFER_HEIGHT], DPC2_STATE_INPUT_BUFFER_WIDTH*ISP_NWAY); | ||
25 | VMEM_ARRAY(dpc2_local_deviations[DPC2_STATE_LOCAL_DEVIATION_BUFFER_HEIGHT], DPC2_STATE_LOCAL_DEVIATION_BUFFER_WIDTH*ISP_NWAY); | ||
26 | VMEM_ARRAY(dpc2_second_min[DPC2_STATE_SECOND_MINMAX_BUFFER_HEIGHT], DPC2_STATE_SECOND_MINMAX_BUFFER_WIDTH*ISP_NWAY); | ||
27 | VMEM_ARRAY(dpc2_second_max[DPC2_STATE_SECOND_MINMAX_BUFFER_HEIGHT], DPC2_STATE_SECOND_MINMAX_BUFFER_WIDTH*ISP_NWAY); | ||
28 | }; | ||
29 | |||
30 | #endif /* __IA_CSS_DPC2_STATE_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8_state.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8_state.h deleted file mode 100644 index 47e451b15044..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8_state.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_EED1_8_STATE_H | ||
16 | #define __IA_CSS_EED1_8_STATE_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #include "vmem.h" /* for VMEM_ARRAY*/ | ||
20 | |||
21 | #include "ia_css_eed1_8_param.h" | ||
22 | |||
23 | struct eed1_8_vmem_state { | ||
24 | VMEM_ARRAY(eed1_8_input_lines[EED1_8_STATE_INPUT_BUFFER_HEIGHT], EED1_8_STATE_INPUT_BUFFER_WIDTH*ISP_NWAY); | ||
25 | VMEM_ARRAY(eed1_8_LD_H[EED1_8_STATE_LD_H_HEIGHT], EED1_8_STATE_LD_H_WIDTH*ISP_NWAY); | ||
26 | VMEM_ARRAY(eed1_8_LD_V[EED1_8_STATE_LD_V_HEIGHT], EED1_8_STATE_LD_V_WIDTH*ISP_NWAY); | ||
27 | VMEM_ARRAY(eed1_8_D_Hr[EED1_8_STATE_D_HR_HEIGHT], EED1_8_STATE_D_HR_WIDTH*ISP_NWAY); | ||
28 | VMEM_ARRAY(eed1_8_D_Hb[EED1_8_STATE_D_HB_HEIGHT], EED1_8_STATE_D_HB_WIDTH*ISP_NWAY); | ||
29 | VMEM_ARRAY(eed1_8_D_Vr[EED1_8_STATE_D_VR_HEIGHT], EED1_8_STATE_D_VR_WIDTH*ISP_NWAY); | ||
30 | VMEM_ARRAY(eed1_8_D_Vb[EED1_8_STATE_D_VB_HEIGHT], EED1_8_STATE_D_VB_WIDTH*ISP_NWAY); | ||
31 | VMEM_ARRAY(eed1_8_rb_zipped[EED1_8_STATE_RB_ZIPPED_HEIGHT], EED1_8_STATE_RB_ZIPPED_WIDTH*ISP_NWAY); | ||
32 | #if EED1_8_FC_ENABLE_MEDIAN | ||
33 | VMEM_ARRAY(eed1_8_Yc[EED1_8_STATE_YC_HEIGHT], EED1_8_STATE_YC_WIDTH*ISP_NWAY); | ||
34 | VMEM_ARRAY(eed1_8_Cg[EED1_8_STATE_CG_HEIGHT], EED1_8_STATE_CG_WIDTH*ISP_NWAY); | ||
35 | VMEM_ARRAY(eed1_8_Co[EED1_8_STATE_CO_HEIGHT], EED1_8_STATE_CO_WIDTH*ISP_NWAY); | ||
36 | VMEM_ARRAY(eed1_8_AbsK[EED1_8_STATE_ABSK_HEIGHT], EED1_8_STATE_ABSK_WIDTH*ISP_NWAY); | ||
37 | #endif | ||
38 | }; | ||
39 | |||
40 | #endif /* __IA_CSS_EED1_8_STATE_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/plane_io_ls/ia_css_plane_io_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/plane_io_ls/ia_css_plane_io_param.h deleted file mode 100644 index 213ef3b385aa..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/plane_io_ls/ia_css_plane_io_param.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_PLANE_IO_PARAM_H | ||
17 | #define __IA_CSS_PLANE_IO_PARAM_H | ||
18 | |||
19 | #include "../common/ia_css_common_io_param.h" | ||
20 | |||
21 | #endif /* __IA_CSS_PLANE_IO_PARAM_H */ | ||
22 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/plane_io_ls/ia_css_plane_io_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/plane_io_ls/ia_css_plane_io_types.h deleted file mode 100644 index d635741505e2..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/plane_io_ls/ia_css_plane_io_types.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_PLANE_IO_TYPES_H | ||
17 | #define __IA_CSS_PLANE_IO_TYPES_H | ||
18 | |||
19 | #include "../common/ia_css_common_io_types.h" | ||
20 | |||
21 | #define PLANE_IO_LS_NUM_PLANES 3 | ||
22 | |||
23 | struct ia_css_plane_io_config { | ||
24 | struct ia_css_common_io_config get_plane_io_config[PLANE_IO_LS_NUM_PLANES]; | ||
25 | struct ia_css_common_io_config put_plane_io_config[PLANE_IO_LS_NUM_PLANES]; | ||
26 | }; | ||
27 | |||
28 | #endif /* __IA_CSS_PLANE_IO_TYPES_H */ | ||
29 | |||
30 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/yuv420_io_ls/ia_css_yuv420_io_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/yuv420_io_ls/ia_css_yuv420_io_param.h deleted file mode 100644 index 52450a9a55a1..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/yuv420_io_ls/ia_css_yuv420_io_param.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_YUV420_IO_PARAM | ||
17 | #define __IA_CSS_YUV420_IO_PARAM | ||
18 | |||
19 | #include "../common/ia_css_common_io_param.h" | ||
20 | |||
21 | #endif | ||
22 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/yuv420_io_ls/ia_css_yuv420_io_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/yuv420_io_ls/ia_css_yuv420_io_types.h deleted file mode 100644 index 99ec1143b214..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/io_ls/yuv420_io_ls/ia_css_yuv420_io_types.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_YUV420_IO_TYPES | ||
17 | #define __IA_CSS_YUV420_IO_TYPES | ||
18 | |||
19 | #include "../common/ia_css_common_io_types.h" | ||
20 | |||
21 | #endif | ||
22 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ia_css_plane_io_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ia_css_plane_io_param.h deleted file mode 100644 index 881b7e5236dc..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ia_css_plane_io_param.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifdef ISP2401 | ||
2 | /** | ||
3 | Support for Intel Camera Imaging ISP subsystem. | ||
4 | Copyright (c) 2010 - 2015, Intel Corporation. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms and conditions of the GNU General Public License, | ||
8 | version 2, as published by the Free Software Foundation. | ||
9 | |||
10 | This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_PLANE_IO_PARAM_H | ||
17 | #define __IA_CSS_PLANE_IO_PARAM_H | ||
18 | |||
19 | #include "../common/ia_css_common_io_param.h" | ||
20 | |||
21 | #endif /* __IA_CSS_PLANE_IO_PARAM_H */ | ||
22 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ia_css_plane_io_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ia_css_plane_io_types.h deleted file mode 100644 index f4b9e8de3d8e..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/plane_io_ls/ia_css_plane_io_types.h +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #ifdef ISP2401 | ||
2 | /** | ||
3 | Support for Intel Camera Imaging ISP subsystem. | ||
4 | Copyright (c) 2010 - 2015, Intel Corporation. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms and conditions of the GNU General Public License, | ||
8 | version 2, as published by the Free Software Foundation. | ||
9 | |||
10 | This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_PLANE_IO_TYPES_H | ||
17 | #define __IA_CSS_PLANE_IO_TYPES_H | ||
18 | |||
19 | #include "../common/ia_css_common_io_types.h" | ||
20 | |||
21 | #define PLANE_IO_LS_NUM_PLANES 3 | ||
22 | |||
23 | struct ia_css_plane_io_config { | ||
24 | struct ia_css_common_io_config get_plane_io_config[PLANE_IO_LS_NUM_PLANES]; | ||
25 | struct ia_css_common_io_config put_plane_io_config[PLANE_IO_LS_NUM_PLANES]; | ||
26 | }; | ||
27 | |||
28 | #endif /* __IA_CSS_PLANE_IO_TYPES_H */ | ||
29 | |||
30 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ia_css_yuv420_io_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ia_css_yuv420_io_param.h deleted file mode 100644 index 86184b545fed..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ia_css_yuv420_io_param.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifdef ISP2401 | ||
2 | /** | ||
3 | Support for Intel Camera Imaging ISP subsystem. | ||
4 | Copyright (c) 2010 - 2015, Intel Corporation. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms and conditions of the GNU General Public License, | ||
8 | version 2, as published by the Free Software Foundation. | ||
9 | |||
10 | This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_YUV420_IO_PARAM | ||
17 | #define __IA_CSS_YUV420_IO_PARAM | ||
18 | |||
19 | #include "../common/ia_css_common_io_param.h" | ||
20 | |||
21 | #endif | ||
22 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ia_css_yuv420_io_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ia_css_yuv420_io_types.h deleted file mode 100644 index ad750f530013..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/ipu2_io_ls/yuv420_io_ls/ia_css_yuv420_io_types.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifdef ISP2401 | ||
2 | /** | ||
3 | Support for Intel Camera Imaging ISP subsystem. | ||
4 | Copyright (c) 2010 - 2015, Intel Corporation. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms and conditions of the GNU General Public License, | ||
8 | version 2, as published by the Free Software Foundation. | ||
9 | |||
10 | This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef __IA_CSS_YUV420_IO_TYPES | ||
17 | #define __IA_CSS_YUV420_IO_TYPES | ||
18 | |||
19 | #include "../common/ia_css_common_io_types.h" | ||
20 | |||
21 | #endif | ||
22 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/norm/norm_1.0/ia_css_norm_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/norm/norm_1.0/ia_css_norm_types.h deleted file mode 100644 index 5581bddf9f9b..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/norm/norm_1.0/ia_css_norm_types.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_NORM_TYPES_H | ||
16 | #define __IA_CSS_NORM_TYPES_H | ||
17 | |||
18 | |||
19 | #endif /* __IA_CSS_NORM_TYPES_H */ | ||
20 | |||
21 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h index 8d674d2c6427..63e70669f085 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a_types.h | |||
@@ -28,7 +28,7 @@ | |||
28 | /* 3A configuration. This configures the 3A statistics collection | 28 | /* 3A configuration. This configures the 3A statistics collection |
29 | * module. | 29 | * module. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* 3A statistics grid | 32 | /* 3A statistics grid |
33 | * | 33 | * |
34 | * ISP block: S3A1 (3A Support for 3A ver.1 (Histogram is not used for AE)) | 34 | * ISP block: S3A1 (3A Support for 3A ver.1 (Histogram is not used for AE)) |
@@ -54,7 +54,7 @@ struct ia_css_3a_grid_info { | |||
54 | uint32_t awb_fr_enable; /** awb_fr enabled in binary, | 54 | uint32_t awb_fr_enable; /** awb_fr enabled in binary, |
55 | 0:disabled, 1:enabled */ | 55 | 0:disabled, 1:enabled */ |
56 | struct awb_fr_public_grid_config awb_fr_grd_info;/** see description in awb_fr_public.h*/ | 56 | struct awb_fr_public_grid_config awb_fr_grd_info;/** see description in awb_fr_public.h*/ |
57 | 57 | ||
58 | uint32_t elem_bit_depth; /** TODO:Taken from BYT - need input from AIQ | 58 | uint32_t elem_bit_depth; /** TODO:Taken from BYT - need input from AIQ |
59 | if needed for SKC | 59 | if needed for SKC |
60 | Bit depth of element used | 60 | Bit depth of element used |
@@ -98,52 +98,6 @@ struct ia_css_3a_grid_info { | |||
98 | }; | 98 | }; |
99 | 99 | ||
100 | 100 | ||
101 | #if defined(SYSTEM_css_skycam_c0_system) | ||
102 | #if defined USE_NEW_AE_STRUCT || defined USE_NEW_AWB_STRUCT | ||
103 | #define DEFAULT_3A_GRID_INFO \ | ||
104 | { \ | ||
105 | 0, /* ae_enable */ \ | ||
106 | {0,0,0,0,0,0,0}, /* AE: width,height,b_width,b_height,x_start,y_start*/ \ | ||
107 | 0, /* awb_enable */ \ | ||
108 | {0,0,0,0,0,0}, /* AWB: width,height,b_width,b_height,x_start,y_start*/ \ | ||
109 | 0, /* af_enable */ \ | ||
110 | {0,0,0,0,0,0,0}, /* AF: width,height,b_width,b_height,x_start,y_start,ff_en*/ \ | ||
111 | 0, /* awb_fr_enable */ \ | ||
112 | {0,0,0,0,0,0,0}, /* AWB_FR: width,height,b_width,b_height,x_start,y_start,ff_en*/ \ | ||
113 | 0, /* elem_bit_depth */ \ | ||
114 | } | ||
115 | #else | ||
116 | #define DEFAULT_3A_GRID_INFO \ | ||
117 | { \ | ||
118 | 0, /* ae_enable */ \ | ||
119 | {0,0,0,0,0,0,0,0,0}, /* AE: width,height,b_width,b_height,x_start,y_start,x_end,y_end*/ \ | ||
120 | 0, /* awb_enable */ \ | ||
121 | {0,0,0,0,0,0,0,0}, /* AWB: width,height,b_width,b_height,x_start,y_start,x_end,y_end*/ \ | ||
122 | 0, /* af_enable */ \ | ||
123 | {0,0,0,0,0,0,0}, /* AF: width,height,b_width,b_height,x_start,y_start,ff_en*/ \ | ||
124 | 0, /* awb_fr_enable */ \ | ||
125 | {0,0,0,0,0,0,0}, /* AWB_FR: width,height,b_width,b_height,x_start,y_start,ff_en*/ \ | ||
126 | 0, /* elem_bit_depth */ \ | ||
127 | } | ||
128 | #endif /* USE_NEW_AE_STRUCT || defined USE_NEW_AWB_STRUCT */ | ||
129 | |||
130 | #else | ||
131 | #define DEFAULT_3A_GRID_INFO \ | ||
132 | { \ | ||
133 | 0, /* enable */ \ | ||
134 | 0, /* use_dmem */ \ | ||
135 | 0, /* has_histogram */ \ | ||
136 | 0, /* width */ \ | ||
137 | 0, /* height */ \ | ||
138 | 0, /* aligned_width */ \ | ||
139 | 0, /* aligned_height */ \ | ||
140 | 0, /* bqs_per_grid_cell */ \ | ||
141 | 0, /* deci_factor_log2 */ \ | ||
142 | 0, /* elem_bit_depth */ \ | ||
143 | } | ||
144 | |||
145 | #endif | ||
146 | |||
147 | /* This struct should be split into 3, for AE, AWB and AF. | 101 | /* This struct should be split into 3, for AE, AWB and AF. |
148 | * However, that will require driver/ 3A lib modifications. | 102 | * However, that will require driver/ 3A lib modifications. |
149 | */ | 103 | */ |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a_stat_ls/ia_css_s3a_stat_ls_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a_stat_ls/ia_css_s3a_stat_ls_param.h deleted file mode 100644 index 9aa019539f47..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a_stat_ls/ia_css_s3a_stat_ls_param.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_S3A_STAT_LS_PARAM_H | ||
16 | #define __IA_CSS_S3A_STAT_LS_PARAM_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #ifdef ISP2401 | ||
20 | #include "../../io_ls/common/ia_css_common_io_types.h" | ||
21 | #endif | ||
22 | |||
23 | #define NUM_S3A_LS 1 | ||
24 | |||
25 | /* s3a statistics store */ | ||
26 | #ifdef ISP2401 | ||
27 | struct ia_css_s3a_stat_ls_configuration { | ||
28 | uint32_t s3a_grid_size_log2; | ||
29 | }; | ||
30 | |||
31 | #endif | ||
32 | struct sh_css_isp_s3a_stat_ls_isp_config { | ||
33 | #ifndef ISP2401 | ||
34 | uint32_t base_address[NUM_S3A_LS]; | ||
35 | uint32_t width[NUM_S3A_LS]; | ||
36 | uint32_t height[NUM_S3A_LS]; | ||
37 | uint32_t stride[NUM_S3A_LS]; | ||
38 | #endif | ||
39 | uint32_t s3a_grid_size_log2[NUM_S3A_LS]; | ||
40 | }; | ||
41 | |||
42 | #ifndef ISP2401 | ||
43 | |||
44 | #endif | ||
45 | #endif /* __IA_CSS_S3A_STAT_LS_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a_stat_ls/ia_css_s3a_stat_store_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a_stat_ls/ia_css_s3a_stat_store_param.h deleted file mode 100644 index 676b42d364e8..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a_stat_ls/ia_css_s3a_stat_store_param.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_S3A_STAT_STORE_PARAM_H | ||
16 | #define __IA_CSS_S3A_STAT_STORE_PARAM_H | ||
17 | |||
18 | #include "ia_css_s3a_stat_ls_param.h" | ||
19 | |||
20 | |||
21 | #endif /* __IA_CSS_S3A_STAT_STORE_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/scale/scale_1.0/ia_css_scale_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/scale/scale_1.0/ia_css_scale_param.h deleted file mode 100644 index fd19f008ff91..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/scale/scale_1.0/ia_css_scale_param.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _IA_CSS_SCALE_PARAM_H | ||
16 | #define _IA_CSS_SCALE_PARAM_H | ||
17 | |||
18 | #include "uds/uds_1.0/ia_css_uds_param.h" | ||
19 | |||
20 | #endif /* _IA_CSS_SCALE_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_common_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_common_types.h index 031983c357e4..381e5730d405 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_common_types.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_common_types.h | |||
@@ -41,20 +41,6 @@ struct ia_css_sdis_info { | |||
41 | uint32_t deci_factor_log2; | 41 | uint32_t deci_factor_log2; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #define IA_CSS_DEFAULT_SDIS_INFO \ | ||
45 | { \ | ||
46 | { { 0, 0 }, /* dim */ \ | ||
47 | { 0, 0 }, /* pad */ \ | ||
48 | }, /* grid */ \ | ||
49 | { { 0, 0 }, /* dim */ \ | ||
50 | { 0, 0 }, /* pad */ \ | ||
51 | }, /* coef */ \ | ||
52 | { { 0, 0 }, /* dim */ \ | ||
53 | { 0, 0 }, /* pad */ \ | ||
54 | }, /* proj */ \ | ||
55 | 0, /* dis_deci_factor_log2 */ \ | ||
56 | } | ||
57 | |||
58 | /* DVS statistics grid | 44 | /* DVS statistics grid |
59 | * | 45 | * |
60 | * ISP block: SDVS1 (DIS/DVS Support for DIS/DVS ver.1 (2-axes)) | 46 | * ISP block: SDVS1 (DIS/DVS Support for DIS/DVS ver.1 (2-axes)) |
@@ -209,16 +195,17 @@ struct ia_css_dvs_stat_grid_info { | |||
209 | 195 | ||
210 | /* DVS statistics generated by accelerator default grid info | 196 | /* DVS statistics generated by accelerator default grid info |
211 | */ | 197 | */ |
212 | #define DEFAULT_DVS_GRID_INFO { \ | 198 | #define DEFAULT_DVS_GRID_INFO \ |
213 | { \ | 199 | (union ia_css_dvs_grid_u) { \ |
214 | { 0, 0, 0}, /* GBL CFG reg: kappa, match_shifrt, binning mode*/ \ | 200 | .dvs_stat_grid_info = (struct ia_css_dvs_stat_grid_info) { \ |
215 | {{{0, 0, 0, 0}, {0, 0, 0}, {0, 0} }, \ | 201 | .fe_roi_cfg = { \ |
216 | {{0, 0, 0, 0}, {0, 0, 0}, {0, 0} }, \ | 202 | [1] = (struct dvs_stat_public_dvs_level_fe_roi_cfg) { \ |
217 | {{0, 0, 0, 0}, {0, 0, 0}, {0, 0} } }, \ | 203 | .x_start = 4 \ |
218 | {{0, 0, 0, 0}, {4, 0, 0, 0}, {0, 0, 0, 0} } } \ | 204 | } \ |
205 | } \ | ||
206 | } \ | ||
219 | } | 207 | } |
220 | 208 | ||
221 | |||
222 | /* Union that holds all types of DVS statistics grid info in | 209 | /* Union that holds all types of DVS statistics grid info in |
223 | * CSS format | 210 | * CSS format |
224 | * */ | 211 | * */ |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_param.h deleted file mode 100644 index 586cc4315c1f..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/common/ia_css_sdis_param.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_SDIS_PARAM_COMMON_H | ||
16 | #define __IA_CSS_SDIS_PARAM_COMMON_H | ||
17 | |||
18 | |||
19 | #include "sdis/common/ia_css_sdis_common.host.h" | ||
20 | |||
21 | #endif /* __IA_CSS_SDIS_PARAM_COMMON_H */ | ||
22 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c index 9478c12abe89..0fdd696bf654 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c | |||
@@ -169,8 +169,7 @@ ia_css_sdis_init_info( | |||
169 | unsigned enabled) | 169 | unsigned enabled) |
170 | { | 170 | { |
171 | if (!enabled) { | 171 | if (!enabled) { |
172 | struct ia_css_sdis_info default_dis = IA_CSS_DEFAULT_SDIS_INFO; | 172 | *dis = (struct ia_css_sdis_info) { }; |
173 | *dis = default_dis; | ||
174 | return; | 173 | return; |
175 | } | 174 | } |
176 | 175 | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis_param.h deleted file mode 100644 index 2dd8696802d0..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis_param.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_SDIS_PARAM_H | ||
16 | #define __IA_CSS_SDIS_PARAM_H | ||
17 | |||
18 | #include "sdis.isp.h" | ||
19 | |||
20 | #endif /* __IA_CSS_SDIS_PARAM_H */ | ||
21 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_2/ia_css_sdis_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_2/ia_css_sdis_param.h deleted file mode 100644 index cea352e45713..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_2/ia_css_sdis_param.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_SDIS2_PARAM_H | ||
16 | #define __IA_CSS_SDIS2_PARAM_H | ||
17 | |||
18 | #include "sdis.isp.h" | ||
19 | |||
20 | #endif /* __IA_CSS_SDIS2_PARAM_H */ | ||
21 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_wrapper_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_wrapper_param.h deleted file mode 100644 index 1a98555fd5d9..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_wrapper_param.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_XNR3_WRAPPER_PARAM_H | ||
16 | #define __IA_CSS_XNR3_WRAPPER_PARAM_H | ||
17 | |||
18 | #include "ia_css_xnr3_param.h" | ||
19 | |||
20 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_load_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_load_param.h deleted file mode 100644 index 400c6790cbf5..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_load_param.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_YUV_LOAD_PARAM_H | ||
16 | #define __IA_CSS_YUV_LOAD_PARAM_H | ||
17 | |||
18 | #include "ia_css_yuv_ls_param.h" | ||
19 | |||
20 | #endif /* __IA_CSS_YUV_LOAD_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_ls_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_ls_param.h deleted file mode 100644 index c9ff0cb2493a..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_ls_param.h +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_YUV_LS_PARAM_H | ||
16 | #define __IA_CSS_YUV_LS_PARAM_H | ||
17 | |||
18 | #include "type_support.h" | ||
19 | #ifndef ISP2401 | ||
20 | |||
21 | /* The number of load/store kernels in a pipeline can be greater than one. | ||
22 | * A kernel can consume more than one input or can produce more | ||
23 | * than one output. | ||
24 | */ | ||
25 | #define NUM_YUV_LS 2 | ||
26 | |||
27 | /* YUV load/store */ | ||
28 | struct sh_css_isp_yuv_ls_isp_config { | ||
29 | unsigned base_address[NUM_YUV_LS]; | ||
30 | unsigned width[NUM_YUV_LS]; | ||
31 | unsigned height[NUM_YUV_LS]; | ||
32 | unsigned stride[NUM_YUV_LS]; | ||
33 | }; | ||
34 | |||
35 | #else | ||
36 | #include "../../io_ls/common/ia_css_common_io_types.h" | ||
37 | #endif | ||
38 | |||
39 | #endif /* __IA_CSS_YUV_LS_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_store_param.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_store_param.h deleted file mode 100644 index 69c474ea1ffd..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/yuv_ls/yuv_ls_1.0/ia_css_yuv_store_param.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Intel Camera Imaging ISP subsystem. | ||
3 | * Copyright (c) 2015, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __IA_CSS_YUV_STORE_PARAM_H | ||
16 | #define __IA_CSS_YUV_STORE_PARAM_H | ||
17 | |||
18 | #include "ia_css_yuv_ls_param.h" | ||
19 | |||
20 | |||
21 | #endif /* __IA_CSS_YUV_STORE_PARAM_H */ | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/modes/interface/isp_exprs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/modes/interface/isp_exprs.h deleted file mode 100644 index e625ba62cc15..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/modes/interface/isp_exprs.h +++ /dev/null | |||
@@ -1,286 +0,0 @@ | |||
1 | #ifndef ISP2401 | ||
2 | /* | ||
3 | * Support for Intel Camera Imaging ISP subsystem. | ||
4 | * Copyright (c) 2015, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | #else | ||
16 | /** | ||
17 | Support for Intel Camera Imaging ISP subsystem. | ||
18 | Copyright (c) 2010 - 2015, Intel Corporation. | ||
19 | |||
20 | This program is free software; you can redistribute it and/or modify it | ||
21 | under the terms and conditions of the GNU General Public License, | ||
22 | version 2, as published by the Free Software Foundation. | ||
23 | |||
24 | This program is distributed in the hope it will be useful, but WITHOUT | ||
25 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
26 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
27 | more details. | ||
28 | */ | ||
29 | #endif | ||
30 | |||
31 | #ifndef _COMMON_ISP_EXPRS_H_ | ||
32 | #define _COMMON_ISP_EXPRS_H_ | ||
33 | |||
34 | /* Binary independent pre-processor expressions */ | ||
35 | |||
36 | #include "sh_css_defs.h" | ||
37 | #include "isp_const.h" | ||
38 | |||
39 | #ifdef __HOST | ||
40 | #error "isp_exprs.h: Do not include on HOST, contains ISP specific defines" | ||
41 | #endif | ||
42 | |||
43 | #ifndef __ISP | ||
44 | #if defined(MODE) | ||
45 | #define MODE aap | ||
46 | #error "isp_exprs.h: is mode independent, but MODE is set" | ||
47 | #endif | ||
48 | #if defined(VARIABLE_RESOLUTION) | ||
49 | #define VARIABLE_RESOLUTION noot | ||
50 | #error "isp_exprs.h: is mode independent, but VARIABLE_RESOLUTION is set" | ||
51 | #endif | ||
52 | #if defined(DECI_FACTOR_LOG2) | ||
53 | #define DECI_FACTOR_LOG2 mies | ||
54 | #error "isp_exprs.h: is mode independent, but DECI_FACTOR_LOG2 is set" | ||
55 | #endif | ||
56 | #endif | ||
57 | |||
58 | #define LOG_VECTOR_STEP _ISP_LOG_VECTOR_STEP(MODE) | ||
59 | /* should be even and multiple of vf downscaling */ | ||
60 | #define ISP_OUTPUT_CHUNK_LOG_FACTOR (MAX_VF_LOG_DOWNSCALE<=1 ? LOG_VECTOR_STEP : \ | ||
61 | umax(VF_LOG_DOWNSCALE, LOG_VECTOR_STEP)) | ||
62 | |||
63 | #define CEIL_DIV_CHUNKS(n,c) ((c) == 1 ? (n) \ | ||
64 | : CEIL_SHIFT(CEIL_DIV((n), (c)), ISP_OUTPUT_CHUNK_LOG_FACTOR)<<ISP_OUTPUT_CHUNK_LOG_FACTOR) | ||
65 | |||
66 | |||
67 | #define ISP_VARIABLE_INPUT (ISP_INPUT == IA_CSS_BINARY_INPUT_VARIABLE) | ||
68 | |||
69 | /* Binary independent versions, see isp_defs.h for binary dependent ones */ | ||
70 | #ifndef __ISP | ||
71 | #define IMAGEFORMAT_IS_RAW(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_RAW) | ||
72 | |||
73 | #define IMAGEFORMAT_IS_RAW_INTERLEAVED(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_RAW) | ||
74 | |||
75 | #define IMAGEFORMAT_IS_RGB(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_RGBA888 || (fmt) == IA_CSS_FRAME_FORMAT_PLANAR_RGB888 || \ | ||
76 | (fmt) == IA_CSS_FRAME_FORMAT_RGB565) | ||
77 | |||
78 | #define IMAGEFORMAT_IS_RGB_INTERLEAVED(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_RGBA888 || (fmt) == IA_CSS_FRAME_FORMAT_RGB565) | ||
79 | |||
80 | #define IMAGEFORMAT_UV_INTERLEAVED(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_NV11 || \ | ||
81 | (fmt) == IA_CSS_FRAME_FORMAT_NV12 || (fmt) == IA_CSS_FRAME_FORMAT_NV21 || \ | ||
82 | (fmt) == IA_CSS_FRAME_FORMAT_NV16 || (fmt) == IA_CSS_FRAME_FORMAT_NV61 || \ | ||
83 | (fmt) == IA_CSS_FRAME_FORMAT_UYVY || (fmt) == IA_CSS_FRAME_FORMAT_YUYV || \ | ||
84 | (fmt) == IA_CSS_FRAME_FORMAT_NV12_16 || (fmt) == IA_CSS_FRAME_FORMAT_NV12_TILEY) | ||
85 | |||
86 | #define IMAGEFORMAT_YUV_INTERLEAVED(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_UYVY || (fmt) == IA_CSS_FRAME_FORMAT_YUYV) | ||
87 | |||
88 | #define IMAGEFORMAT_INTERLEAVED(fmt) (IMAGEFORMAT_UV_INTERLEAVED(fmt) || IMAGEFORMAT_IS_RGB_INTERLEAVED(fmt)) | ||
89 | |||
90 | #define IMAGEFORMAT_SUB_SAMPL_420(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_YUV420 || (fmt) == IA_CSS_FRAME_FORMAT_YV12 || \ | ||
91 | (fmt) == IA_CSS_FRAME_FORMAT_NV12 || (fmt) == IA_CSS_FRAME_FORMAT_NV21 || \ | ||
92 | (fmt) == IA_CSS_FRAME_FORMAT_NV12_16 || (fmt) == IA_CSS_FRAME_FORMAT_NV12TILEY) | ||
93 | |||
94 | #define IMAGEFORMAT_SUB_SAMPL_422(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_YUV422 || (fmt) == IA_CSS_FRAME_FORMAT_YV16 || \ | ||
95 | (fmt) == IA_CSS_FRAME_FORMAT_NV16 || (fmt) == IA_CSS_FRAME_FORMAT_NV61) | ||
96 | |||
97 | #define IMAGEFORMAT_SUB_SAMPL_444(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_YUV444) | ||
98 | |||
99 | #define IMAGEFORMAT_UV_SWAPPED(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_NV21 || (fmt) == IA_CSS_FRAME_FORMAT_NV61) | ||
100 | |||
101 | #define IMAGEFORMAT_IS_RGBA(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_RGBA888) | ||
102 | |||
103 | #define IMAGEFORMAT_IS_NV11(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_NV11) | ||
104 | |||
105 | #define IMAGEFORMAT_IS_16BIT(fmt) ((fmt) == IA_CSS_FRAME_FORMAT_YUV420_16 || (fmt) == IA_CSS_FRAME_FORMAT_NV12_16 || (fmt) == IA_CSS_FRAME_FORMAT_YUV422_16) | ||
106 | |||
107 | #endif | ||
108 | |||
109 | |||
110 | /******** GDCAC settings *******/ | ||
111 | #define GDCAC_BPP ISP_VEC_ELEMBITS /* We use 14 bits per pixel component for the GDCAC mode */ | ||
112 | #define GDC_INPUT_BLOCK_WIDTH 2 /* Two vectors are needed */ | ||
113 | #define GDC_OUTPUT_BLOCK_WIDTH 1 /* One vector is produced */ | ||
114 | |||
115 | #if ISP_VEC_NELEMS == 16 | ||
116 | /* For 16*16 output block, the distortion fits in 13.312 lines __ALWAYS__ */ | ||
117 | #define GDC_INPUT_BLOCK_HEIGHT 14 | ||
118 | #elif ISP_VEC_NELEMS == 64 | ||
119 | /* For 64*64 output block, the distortion fits in 47. lines __ALWAYS__ */ | ||
120 | #define GDC_INPUT_BLOCK_HEIGHT 48 | ||
121 | #endif | ||
122 | /*******************************/ | ||
123 | |||
124 | |||
125 | #define ENABLE_HUP ((isp_input_width - isp_envelope_width) < isp_output_width) | ||
126 | #define ENABLE_VUP ((isp_input_height - isp_envelope_height) < isp_output_height) | ||
127 | |||
128 | #define ISP_INPUT_WIDTH (ENABLE_DS | ENABLE_HUP ? isp_input_width : ISP_INTERNAL_WIDTH) | ||
129 | #define ISP_INPUT_HEIGHT (ENABLE_DS | ENABLE_VUP ? isp_input_height : isp_internal_height) | ||
130 | |||
131 | #define DECI_FACTOR_LOG2 (ISP_FIXED_S3A_DECI_LOG ? ISP_FIXED_S3A_DECI_LOG : isp_deci_log_factor) | ||
132 | |||
133 | #define ISP_S3ATBL_WIDTH \ | ||
134 | _ISP_S3ATBL_ISP_WIDTH(_ISP_S3A_ELEMS_ISP_WIDTH((ENABLE_HUP ? ISP_INTERNAL_WIDTH : ISP_INPUT_WIDTH), ISP_LEFT_CROPPING), \ | ||
135 | DECI_FACTOR_LOG2) | ||
136 | #define S3ATBL_WIDTH_BYTES (sizeof(struct ia_css_3a_output) * ISP_S3ATBL_WIDTH) | ||
137 | #define S3ATBL_WIDTH_SHORTS (S3ATBL_WIDTH_BYTES / sizeof(short)) | ||
138 | |||
139 | /* should be even?? */ | ||
140 | #define ISP_UV_OUTPUT_CHUNK_VECS CEIL_DIV(ISP_OUTPUT_CHUNK_VECS, 2) | ||
141 | |||
142 | |||
143 | #if defined(__ISP) || defined(INIT_VARS) | ||
144 | |||
145 | #define ISP_USE_IF (ISP_INPUT == IA_CSS_BINARY_INPUT_MEMORY ? 0 : \ | ||
146 | ISP_INPUT == IA_CSS_BINARY_INPUT_SENSOR ? 1 : \ | ||
147 | isp_online) | ||
148 | |||
149 | #define ISP_DVS_ENVELOPE_WIDTH 0 | ||
150 | #define ISP_DVS_ENVELOPE_HEIGHT 0 | ||
151 | |||
152 | #define _ISP_INPUT_WIDTH_VECS _ISP_VECS(ISP_INPUT_WIDTH) | ||
153 | |||
154 | #if !defined(__ISP) || (VARIABLE_RESOLUTION && !__HOST) | ||
155 | #define ISP_INPUT_WIDTH_VECS isp_vectors_per_input_line | ||
156 | #else | ||
157 | #define ISP_INPUT_WIDTH_VECS _ISP_INPUT_WIDTH_VECS | ||
158 | #endif | ||
159 | |||
160 | #if !defined(__ISP) || VARIABLE_RESOLUTION | ||
161 | #define ISP_INTERNAL_WIDTH_VECS isp_vectors_per_line | ||
162 | #else | ||
163 | #define ISP_INTERNAL_WIDTH_VECS _ISP_INTERNAL_WIDTH_VECS | ||
164 | #endif | ||
165 | |||
166 | #define _ISP_INTERNAL_HEIGHT __ISP_INTERNAL_HEIGHT(isp_output_height, ISP_TOP_CROPPING, ISP_DVS_ENVELOPE_HEIGHT) | ||
167 | |||
168 | #define ISP_INTERNAL_HEIGHT isp_internal_height | ||
169 | |||
170 | #define _ISP_INTERNAL_WIDTH __ISP_INTERNAL_WIDTH(ISP_OUTPUT_WIDTH, ISP_DVS_ENVELOPE_WIDTH, \ | ||
171 | ISP_LEFT_CROPPING, MODE, ISP_C_SUBSAMPLING, \ | ||
172 | OUTPUT_NUM_CHUNKS, ISP_PIPELINING) | ||
173 | |||
174 | #define ISP_UV_INTERNAL_WIDTH (ISP_INTERNAL_WIDTH / 2) | ||
175 | #define ISP_UV_INTERNAL_HEIGHT (ISP_INTERNAL_HEIGHT / 2) | ||
176 | |||
177 | #define _ISP_INTERNAL_WIDTH_VECS (_ISP_INTERNAL_WIDTH / ISP_VEC_NELEMS) | ||
178 | #define _ISP_UV_INTERNAL_WIDTH_VECS CEIL_DIV(ISP_UV_INTERNAL_WIDTH, ISP_VEC_NELEMS) | ||
179 | |||
180 | #define ISP_VF_OUTPUT_WIDTH _ISP_VF_OUTPUT_WIDTH(ISP_VF_OUTPUT_WIDTH_VECS) | ||
181 | #define ISP_VF_OUTPUT_HEIGHT _ISP_VF_OUTPUT_HEIGHT(isp_output_height, VF_LOG_DOWNSCALE) | ||
182 | |||
183 | #if defined (__ISP) && !VARIABLE_RESOLUTION | ||
184 | #define ISP_INTERNAL_WIDTH _ISP_INTERNAL_WIDTH | ||
185 | #define ISP_VF_OUTPUT_WIDTH_VECS _ISP_VF_OUTPUT_WIDTH_VECS | ||
186 | #else | ||
187 | #define ISP_INTERNAL_WIDTH (VARIABLE_RESOLUTION ? isp_internal_width : _ISP_INTERNAL_WIDTH) | ||
188 | #define ISP_VF_OUTPUT_WIDTH_VECS (VARIABLE_RESOLUTION ? isp_vf_output_width_vecs : _ISP_VF_OUTPUT_WIDTH_VECS) | ||
189 | #endif | ||
190 | |||
191 | #if defined(__ISP) && !VARIABLE_RESOLUTION | ||
192 | #define ISP_OUTPUT_WIDTH ISP_MAX_OUTPUT_WIDTH | ||
193 | #define VF_LOG_DOWNSCALE MAX_VF_LOG_DOWNSCALE | ||
194 | #else | ||
195 | #define ISP_OUTPUT_WIDTH isp_output_width | ||
196 | #define VF_LOG_DOWNSCALE isp_vf_downscale_bits | ||
197 | #endif | ||
198 | |||
199 | #if !defined(__ISP) || VARIABLE_RESOLUTION | ||
200 | #define _ISP_MAX_VF_OUTPUT_WIDTH __ISP_MAX_VF_OUTPUT_WIDTH(2*SH_CSS_MAX_VF_WIDTH, ISP_LEFT_CROPPING) | ||
201 | #elif defined(MODE) && MODE == IA_CSS_BINARY_MODE_PRIMARY && ISP_OUTPUT_WIDTH > 3328 | ||
202 | /* Because of vmem issues, should be fixed later */ | ||
203 | #define _ISP_MAX_VF_OUTPUT_WIDTH (SH_CSS_MAX_VF_WIDTH - 2*ISP_VEC_NELEMS + (ISP_LEFT_CROPPING ? 2 * ISP_VEC_NELEMS : 0)) | ||
204 | #else | ||
205 | #define _ISP_MAX_VF_OUTPUT_WIDTH (ISP_VF_OUTPUT_WIDTH + (ISP_LEFT_CROPPING ? (2 >> VF_LOG_DOWNSCALE) * ISP_VEC_NELEMS : 0)) | ||
206 | #endif | ||
207 | |||
208 | #define ISP_MAX_VF_OUTPUT_VECS CEIL_DIV(_ISP_MAX_VF_OUTPUT_WIDTH, ISP_VEC_NELEMS) | ||
209 | |||
210 | |||
211 | |||
212 | #define ISP_MIN_STRIPE_WIDTH (ISP_PIPELINING * (1<<_ISP_LOG_VECTOR_STEP(MODE))) | ||
213 | |||
214 | /******* STRIPING-RELATED MACROS *******/ | ||
215 | #define NO_STRIPING (ISP_NUM_STRIPES == 1) | ||
216 | |||
217 | #define ISP_OUTPUT_CHUNK_VECS \ | ||
218 | (NO_STRIPING ? CEIL_DIV_CHUNKS(ISP_OUTPUT_VECS_EXTRA_CROP, OUTPUT_NUM_CHUNKS) \ | ||
219 | : ISP_IO_STRIPE_WIDTH_VECS(ISP_OUTPUT_VECS_EXTRA_CROP, ISP_LEFT_PADDING_VECS, ISP_NUM_STRIPES, ISP_MIN_STRIPE_WIDTH) ) | ||
220 | |||
221 | #define VECTORS_PER_LINE \ | ||
222 | (NO_STRIPING ? ISP_INTERNAL_WIDTH_VECS \ | ||
223 | : ISP_IO_STRIPE_WIDTH_VECS(ISP_INTERNAL_WIDTH_VECS, ISP_LEFT_PADDING_VECS, ISP_NUM_STRIPES, ISP_MIN_STRIPE_WIDTH) ) | ||
224 | |||
225 | #define VECTORS_PER_INPUT_LINE \ | ||
226 | (NO_STRIPING ? ISP_INPUT_WIDTH_VECS \ | ||
227 | : ISP_IO_STRIPE_WIDTH_VECS(ISP_INPUT_WIDTH_VECS, ISP_LEFT_PADDING_VECS, ISP_NUM_STRIPES, ISP_MIN_STRIPE_WIDTH)+_ISP_EXTRA_PADDING_VECS) | ||
228 | |||
229 | |||
230 | #define ISP_MAX_VF_OUTPUT_STRIPE_VECS \ | ||
231 | (NO_STRIPING ? ISP_MAX_VF_OUTPUT_VECS \ | ||
232 | : CEIL_MUL(CEIL_DIV(ISP_MAX_VF_OUTPUT_VECS, ISP_NUM_STRIPES), 2)) | ||
233 | #define _ISP_VF_OUTPUT_WIDTH_VECS \ | ||
234 | (NO_STRIPING ? __ISP_VF_OUTPUT_WIDTH_VECS(ISP_OUTPUT_WIDTH, VF_LOG_DOWNSCALE) \ | ||
235 | : __ISP_VF_OUTPUT_WIDTH_VECS(CEIL_DIV(ISP_OUTPUT_WIDTH, ISP_NUM_STRIPES), VF_LOG_DOWNSCALE)) | ||
236 | |||
237 | #define ISP_IO_STRIPE_WIDTH_VECS(width, padding, num_stripes, min_stripe) \ | ||
238 | MAX(CEIL_MUL(padding + CEIL_DIV(width-padding, num_stripes) \ | ||
239 | , 2) \ | ||
240 | , min_stripe) | ||
241 | ////////// INPUT & INTERNAL | ||
242 | /* should be even */ | ||
243 | #define INPUT_NUM_CHUNKS OUTPUT_NUM_CHUNKS | ||
244 | |||
245 | #define INPUT_VECTORS_PER_CHUNK CEIL_DIV_CHUNKS(VECTORS_PER_INPUT_LINE, INPUT_NUM_CHUNKS) | ||
246 | |||
247 | /* only for ISP code, will be removed: */ | ||
248 | #define VECTORS_PER_FULL_LINE ISP_INTERNAL_WIDTH_VECS | ||
249 | #define VECTORS_PER_INPUT_FULL_LINE ISP_INPUT_WIDTH_VECS | ||
250 | |||
251 | ////////// OUTPUT | ||
252 | /* should at least even and also multiple of vf scaling */ | ||
253 | #define ISP_OUTPUT_VECS_EXTRA_CROP CEIL_DIV(ISP_OUTPUT_WIDTH_EXTRA_CROP, ISP_VEC_NELEMS) | ||
254 | |||
255 | /* Output is decoupled from input */ | ||
256 | #define ISP_OUTPUT_WIDTH_EXTRA_CROP CEIL_MUL(CEIL_MUL((ENABLE_DVS_ENVELOPE ? ISP_OUTPUT_WIDTH : ISP_INTERNAL_WIDTH), 2*ISP_VEC_NELEMS), \ | ||
257 | ISP_C_SUBSAMPLING * OUTPUT_NUM_CHUNKS * HIVE_ISP_DDR_WORD_BYTES) | ||
258 | |||
259 | #define ISP_MAX_VF_OUTPUT_CHUNK_VECS \ | ||
260 | (NO_CHUNKING ? ISP_MAX_VF_OUTPUT_STRIPE_VECS \ | ||
261 | : 2*CEIL_DIV(ISP_MAX_VF_OUTPUT_STRIPE_VECS, 2*OUTPUT_NUM_CHUNKS)) | ||
262 | |||
263 | #define OUTPUT_VECTORS_PER_CHUNK CEIL_DIV_CHUNKS(VECTORS_PER_LINE,OUTPUT_NUM_CHUNKS) | ||
264 | |||
265 | /* should be even?? */ | ||
266 | #define OUTPUT_C_VECTORS_PER_CHUNK CEIL_DIV(OUTPUT_VECTORS_PER_CHUNK, 2) | ||
267 | |||
268 | #ifndef ISP2401 | ||
269 | /**** SCTBL defs *******/ | ||
270 | #define ISP_SCTBL_HEIGHT \ | ||
271 | _ISP_SCTBL_HEIGHT(ISP_INPUT_HEIGHT, DECI_FACTOR_LOG2) | ||
272 | |||
273 | #endif | ||
274 | /**** UDS defs *********/ | ||
275 | #define UDS_DMACH_STRIDE_B_IN_Y (( ISP_INTERNAL_WIDTH /BITS8_ELEMENTS_PER_XMEM_ADDR)*HIVE_ISP_DDR_WORD_BYTES) | ||
276 | #define UDS_DMACH_STRIDE_B_IN_C (((ISP_INTERNAL_WIDTH/2)/BITS8_ELEMENTS_PER_XMEM_ADDR)*HIVE_ISP_DDR_WORD_BYTES) | ||
277 | |||
278 | #else /* defined(__ISP) || defined(INIT_VARS) */ | ||
279 | |||
280 | #define ISP_INTERNAL_WIDTH isp_internal_width | ||
281 | #define ISP_INTERNAL_HEIGHT isp_internal_height | ||
282 | |||
283 | #endif /* defined(__ISP) || defined(INIT_VARS) */ | ||
284 | |||
285 | #endif /* _COMMON_ISP_EXPRS_H_ */ | ||
286 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/interface/ia_css_binary.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/interface/ia_css_binary.h index 5a58abe2b233..732e49a241eb 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/interface/ia_css_binary.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/interface/ia_css_binary.h | |||
@@ -93,17 +93,6 @@ struct ia_css_cas_binary_descr { | |||
93 | bool *is_output_stage; | 93 | bool *is_output_stage; |
94 | }; | 94 | }; |
95 | 95 | ||
96 | #define IA_CSS_DEFAULT_CAS_BINARY_DESCR \ | ||
97 | { \ | ||
98 | 0, \ | ||
99 | 0, \ | ||
100 | NULL, \ | ||
101 | NULL, \ | ||
102 | NULL, \ | ||
103 | NULL, \ | ||
104 | NULL, \ | ||
105 | } | ||
106 | |||
107 | struct ia_css_binary_descr { | 96 | struct ia_css_binary_descr { |
108 | int mode; | 97 | int mode; |
109 | bool online; | 98 | bool online; |
@@ -171,80 +160,15 @@ struct ia_css_binary { | |||
171 | struct ia_css_isp_param_css_segments css_params; | 160 | struct ia_css_isp_param_css_segments css_params; |
172 | }; | 161 | }; |
173 | 162 | ||
174 | #ifdef ISP2401 | ||
175 | |||
176 | #define IA_CSS_BINARY_DEFAULT_SETTINGS \ | 163 | #define IA_CSS_BINARY_DEFAULT_SETTINGS \ |
177 | { \ | 164 | (struct ia_css_binary) { \ |
178 | NULL, \ | 165 | .input_format = IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY, \ |
179 | IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY, \ | 166 | .in_frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
180 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ | 167 | .internal_frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
181 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ | 168 | .out_frame_info = {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ |
182 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ | 169 | .vf_frame_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ |
183 | { 0, 0},/* effective_in_frame_res */ \ | ||
184 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ | ||
185 | 0, /* input_buf_vectors */ \ | ||
186 | 0, /* deci_factor_log2 */ \ | ||
187 | 0, /* vf_downscale_log2 */ \ | ||
188 | 0, /* s3atbl_width */ \ | ||
189 | 0, /* s3atbl_height */ \ | ||
190 | 0, /* s3atbl_isp_width */ \ | ||
191 | 0, /* s3atbl_isp_height */ \ | ||
192 | 0, /* morph_tbl_width */ \ | ||
193 | 0, /* morph_tbl_aligned_width */ \ | ||
194 | 0, /* morph_tbl_height */ \ | ||
195 | 0, /* sctbl_width_per_color */ \ | ||
196 | 0, /* sctbl_aligned_width_per_color */ \ | ||
197 | 0, /* sctbl_height */ \ | ||
198 | 0, /* sctbl_legacy_width_per_color */ \ | ||
199 | 0, /* sctbl_legacy_height */ \ | ||
200 | IA_CSS_DEFAULT_SDIS_INFO, /* dis */ \ | ||
201 | { 0, 0},/* dvs_envelope_info */ \ | ||
202 | false, /* online */ \ | ||
203 | 0, /* uds_xc */ \ | ||
204 | 0, /* uds_yc */ \ | ||
205 | 0, /* left_padding */ \ | ||
206 | DEFAULT_BINARY_METRICS, /* metrics */ \ | ||
207 | IA_CSS_DEFAULT_ISP_MEM_PARAMS, /* mem_params */ \ | ||
208 | IA_CSS_DEFAULT_ISP_CSS_PARAMS, /* css_params */ \ | ||
209 | } | 170 | } |
210 | 171 | ||
211 | #else | ||
212 | |||
213 | #define IA_CSS_BINARY_DEFAULT_SETTINGS \ | ||
214 | { \ | ||
215 | NULL, \ | ||
216 | IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY, \ | ||
217 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ | ||
218 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ | ||
219 | {IA_CSS_BINARY_DEFAULT_FRAME_INFO}, \ | ||
220 | { 0, 0},/* effective_in_frame_res */ \ | ||
221 | IA_CSS_BINARY_DEFAULT_FRAME_INFO, \ | ||
222 | 0, /* input_buf_vectors */ \ | ||
223 | 0, /* deci_factor_log2 */ \ | ||
224 | 0, /* vf_downscale_log2 */ \ | ||
225 | 0, /* s3atbl_width */ \ | ||
226 | 0, /* s3atbl_height */ \ | ||
227 | 0, /* s3atbl_isp_width */ \ | ||
228 | 0, /* s3atbl_isp_height */ \ | ||
229 | 0, /* morph_tbl_width */ \ | ||
230 | 0, /* morph_tbl_aligned_width */ \ | ||
231 | 0, /* morph_tbl_height */ \ | ||
232 | 0, /* sctbl_width_per_color */ \ | ||
233 | 0, /* sctbl_aligned_width_per_color */ \ | ||
234 | 0, /* sctbl_height */ \ | ||
235 | IA_CSS_DEFAULT_SDIS_INFO, /* dis */ \ | ||
236 | { 0, 0},/* dvs_envelope_info */ \ | ||
237 | false, /* online */ \ | ||
238 | 0, /* uds_xc */ \ | ||
239 | 0, /* uds_yc */ \ | ||
240 | 0, /* left_padding */ \ | ||
241 | DEFAULT_BINARY_METRICS, /* metrics */ \ | ||
242 | IA_CSS_DEFAULT_ISP_MEM_PARAMS, /* mem_params */ \ | ||
243 | IA_CSS_DEFAULT_ISP_CSS_PARAMS, /* css_params */ \ | ||
244 | } | ||
245 | |||
246 | #endif | ||
247 | |||
248 | enum ia_css_err | 172 | enum ia_css_err |
249 | ia_css_binary_init_infos(void); | 173 | ia_css_binary_init_infos(void); |
250 | 174 | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c index 295e07049393..a0f0e9062c4c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c | |||
@@ -490,7 +490,6 @@ ia_css_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in | |||
490 | struct sh_css_shading_table_bayer_origin_compute_results res; | 490 | struct sh_css_shading_table_bayer_origin_compute_results res; |
491 | #else | 491 | #else |
492 | struct sh_css_binary_sc_requirements scr; | 492 | struct sh_css_binary_sc_requirements scr; |
493 | struct ia_css_shading_info default_shading_info_type_1 = DEFAULT_SHADING_INFO_TYPE_1; | ||
494 | #endif | 493 | #endif |
495 | 494 | ||
496 | #ifndef ISP2401 | 495 | #ifndef ISP2401 |
@@ -542,7 +541,7 @@ ia_css_binary_get_shading_info_type_1(const struct ia_css_binary *binary, /* [in | |||
542 | &res); | 541 | &res); |
543 | if (err != IA_CSS_SUCCESS) | 542 | if (err != IA_CSS_SUCCESS) |
544 | #else | 543 | #else |
545 | *shading_info = default_shading_info_type_1; | 544 | *shading_info = DEFAULT_SHADING_INFO_TYPE_1; |
546 | 545 | ||
547 | err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr); | 546 | err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr); |
548 | if (err != IA_CSS_SUCCESS) { | 547 | if (err != IA_CSS_SUCCESS) { |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c index f22d73b56bc6..60395904f89a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c | |||
@@ -2858,13 +2858,7 @@ ia_css_debug_pipe_graph_dump_stage( | |||
2858 | if (l && enable_info[l-1] == ',') | 2858 | if (l && enable_info[l-1] == ',') |
2859 | enable_info[--l] = '\0'; | 2859 | enable_info[--l] = '\0'; |
2860 | 2860 | ||
2861 | if (l <= ENABLE_LINE_MAX_LENGTH) { | 2861 | if (l > ENABLE_LINE_MAX_LENGTH) { |
2862 | /* It fits on one line, copy string and init */ | ||
2863 | /* other helper strings with empty string */ | ||
2864 | strcpy_s(enable_info, | ||
2865 | sizeof(enable_info), | ||
2866 | ei); | ||
2867 | } else { | ||
2868 | /* Too big for one line, find last comma */ | 2862 | /* Too big for one line, find last comma */ |
2869 | p = ENABLE_LINE_MAX_LENGTH; | 2863 | p = ENABLE_LINE_MAX_LENGTH; |
2870 | while (ei[p] != ',') | 2864 | while (ei[p] != ',') |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/frame/src/frame.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/frame/src/frame.c index 5faa89ad8a23..7562beadabef 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/frame/src/frame.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/frame/src/frame.c | |||
@@ -196,7 +196,7 @@ enum ia_css_err ia_css_frame_map(struct ia_css_frame **frame, | |||
196 | attribute, context); | 196 | attribute, context); |
197 | if (me->data == mmgr_NULL) | 197 | if (me->data == mmgr_NULL) |
198 | err = IA_CSS_ERR_INVALID_ARGUMENTS; | 198 | err = IA_CSS_ERR_INVALID_ARGUMENTS; |
199 | }; | 199 | } |
200 | 200 | ||
201 | if (err != IA_CSS_SUCCESS) { | 201 | if (err != IA_CSS_SUCCESS) { |
202 | sh_css_free(me); | 202 | sh_css_free(me); |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h index fa3f09347b22..9d111793bb65 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h | |||
@@ -94,14 +94,5 @@ union ia_css_all_memory_offsets { | |||
94 | } array[IA_CSS_NUM_PARAM_CLASSES]; | 94 | } array[IA_CSS_NUM_PARAM_CLASSES]; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | #define IA_CSS_DEFAULT_ISP_MEM_PARAMS \ | ||
98 | { { { { NULL, 0 } } } } | ||
99 | |||
100 | #define IA_CSS_DEFAULT_ISP_CSS_PARAMS \ | ||
101 | { { { { 0, 0 } } } } | ||
102 | |||
103 | #define IA_CSS_DEFAULT_ISP_ISP_PARAMS \ | ||
104 | { { { { 0, 0 } } } } | ||
105 | |||
106 | #endif /* _IA_CSS_ISP_PARAM_TYPES_H_ */ | 97 | #endif /* _IA_CSS_ISP_PARAM_TYPES_H_ */ |
107 | 98 | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/interface/ia_css_pipeline.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/interface/ia_css_pipeline.h index e64936e2d46e..85ed7db0af55 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/interface/ia_css_pipeline.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/interface/ia_css_pipeline.h | |||
@@ -74,21 +74,15 @@ struct ia_css_pipeline { | |||
74 | }; | 74 | }; |
75 | 75 | ||
76 | #define DEFAULT_PIPELINE \ | 76 | #define DEFAULT_PIPELINE \ |
77 | { \ | 77 | (struct ia_css_pipeline) { \ |
78 | IA_CSS_PIPE_ID_PREVIEW, /* pipe_id */ \ | 78 | .pipe_id = IA_CSS_PIPE_ID_PREVIEW, \ |
79 | 0, /* pipe_num */ \ | 79 | .in_frame = DEFAULT_FRAME, \ |
80 | false, /* stop_requested */ \ | 80 | .out_frame = {DEFAULT_FRAME}, \ |
81 | NULL, /* stages */ \ | 81 | .vf_frame = {DEFAULT_FRAME}, \ |
82 | NULL, /* current_stage */ \ | 82 | .dvs_frame_delay = IA_CSS_FRAME_DELAY_1, \ |
83 | 0, /* num_stages */ \ | 83 | .num_execs = -1, \ |
84 | DEFAULT_FRAME, /* in_frame */ \ | 84 | .acquire_isp_each_stage = true, \ |
85 | {DEFAULT_FRAME}, /* out_frame */ \ | 85 | .pipe_qos_config = QOS_INVALID \ |
86 | {DEFAULT_FRAME}, /* vf_frame */ \ | ||
87 | IA_CSS_FRAME_DELAY_1, /* frame_delay */ \ | ||
88 | 0, /* inout_port_config */ \ | ||
89 | -1, /* num_execs */ \ | ||
90 | true, /* acquire_isp_each_stage */\ | ||
91 | QOS_INVALID /* pipe_qos_config */\ | ||
92 | } | 86 | } |
93 | 87 | ||
94 | /* Stage descriptor used to create a new stage in the pipeline */ | 88 | /* Stage descriptor used to create a new stage in the pipeline */ |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c index 8f93d29d1c51..81a50c73ad0b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c | |||
@@ -692,17 +692,16 @@ static void pipeline_init_defaults( | |||
692 | unsigned int pipe_num, | 692 | unsigned int pipe_num, |
693 | unsigned int dvs_frame_delay) | 693 | unsigned int dvs_frame_delay) |
694 | { | 694 | { |
695 | struct ia_css_frame init_frame = DEFAULT_FRAME; | ||
696 | unsigned int i; | 695 | unsigned int i; |
697 | 696 | ||
698 | pipeline->pipe_id = pipe_id; | 697 | pipeline->pipe_id = pipe_id; |
699 | pipeline->stages = NULL; | 698 | pipeline->stages = NULL; |
700 | pipeline->stop_requested = false; | 699 | pipeline->stop_requested = false; |
701 | pipeline->current_stage = NULL; | 700 | pipeline->current_stage = NULL; |
702 | pipeline->in_frame = init_frame; | 701 | pipeline->in_frame = DEFAULT_FRAME; |
703 | for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { | 702 | for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) { |
704 | pipeline->out_frame[i] = init_frame; | 703 | pipeline->out_frame[i] = DEFAULT_FRAME; |
705 | pipeline->vf_frame[i] = init_frame; | 704 | pipeline->vf_frame[i] = DEFAULT_FRAME; |
706 | } | 705 | } |
707 | pipeline->num_execs = -1; | 706 | pipeline->num_execs = -1; |
708 | pipeline->acquire_isp_each_stage = true; | 707 | pipeline->acquire_isp_each_stage = true; |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c index 322bb3de6098..37116faab631 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c | |||
@@ -112,8 +112,6 @@ static int thread_alive; | |||
112 | #define STATS_ENABLED(stage) (stage && stage->binary && stage->binary->info && \ | 112 | #define STATS_ENABLED(stage) (stage && stage->binary && stage->binary->info && \ |
113 | (stage->binary->info->sp.enable.s3a || stage->binary->info->sp.enable.dis)) | 113 | (stage->binary->info->sp.enable.s3a || stage->binary->info->sp.enable.dis)) |
114 | 114 | ||
115 | #define DEFAULT_PLANES { {0, 0, 0, 0} } | ||
116 | |||
117 | struct sh_css my_css; | 115 | struct sh_css my_css; |
118 | 116 | ||
119 | int (*sh_css_printf) (const char *fmt, va_list args) = NULL; | 117 | int (*sh_css_printf) (const char *fmt, va_list args) = NULL; |
@@ -194,7 +192,7 @@ sh_css_pipe_start(struct ia_css_stream *stream); | |||
194 | * @param[in] stream Point to the target "ia_css_stream" instance. | 192 | * @param[in] stream Point to the target "ia_css_stream" instance. |
195 | * | 193 | * |
196 | * @return | 194 | * @return |
197 | * - IA_CSS_SUCCESS, if the "stop" requests have been sucessfully sent out. | 195 | * - IA_CSS_SUCCESS, if the "stop" requests have been successfully sent out. |
198 | * - CSS error code, otherwise. | 196 | * - CSS error code, otherwise. |
199 | * | 197 | * |
200 | * | 198 | * |
@@ -1054,7 +1052,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) | |||
1054 | if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) { | 1052 | if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) { |
1055 | /* | 1053 | /* |
1056 | * We need to poll the ISYS HW in capture_indication itself | 1054 | * We need to poll the ISYS HW in capture_indication itself |
1057 | * for "non-continous" capture usecase for getting accurate | 1055 | * for "non-continuous" capture usecase for getting accurate |
1058 | * isys frame capture timestamps. | 1056 | * isys frame capture timestamps. |
1059 | * This is because the capturepipe propcessing takes longer | 1057 | * This is because the capturepipe propcessing takes longer |
1060 | * to execute than the input system frame capture. | 1058 | * to execute than the input system frame capture. |
@@ -2291,25 +2289,19 @@ init_pipe_defaults(enum ia_css_pipe_mode mode, | |||
2291 | struct ia_css_pipe *pipe, | 2289 | struct ia_css_pipe *pipe, |
2292 | bool copy_pipe) | 2290 | bool copy_pipe) |
2293 | { | 2291 | { |
2294 | static struct ia_css_pipe default_pipe = IA_CSS_DEFAULT_PIPE; | ||
2295 | static struct ia_css_preview_settings prev = IA_CSS_DEFAULT_PREVIEW_SETTINGS; | ||
2296 | static struct ia_css_capture_settings capt = IA_CSS_DEFAULT_CAPTURE_SETTINGS; | ||
2297 | static struct ia_css_video_settings video = IA_CSS_DEFAULT_VIDEO_SETTINGS; | ||
2298 | static struct ia_css_yuvpp_settings yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS; | ||
2299 | |||
2300 | if (pipe == NULL) { | 2292 | if (pipe == NULL) { |
2301 | IA_CSS_ERROR("NULL pipe parameter"); | 2293 | IA_CSS_ERROR("NULL pipe parameter"); |
2302 | return IA_CSS_ERR_INVALID_ARGUMENTS; | 2294 | return IA_CSS_ERR_INVALID_ARGUMENTS; |
2303 | } | 2295 | } |
2304 | 2296 | ||
2305 | /* Initialize pipe to pre-defined defaults */ | 2297 | /* Initialize pipe to pre-defined defaults */ |
2306 | *pipe = default_pipe; | 2298 | *pipe = IA_CSS_DEFAULT_PIPE; |
2307 | 2299 | ||
2308 | /* TODO: JB should not be needed, but temporary backward reference */ | 2300 | /* TODO: JB should not be needed, but temporary backward reference */ |
2309 | switch (mode) { | 2301 | switch (mode) { |
2310 | case IA_CSS_PIPE_MODE_PREVIEW: | 2302 | case IA_CSS_PIPE_MODE_PREVIEW: |
2311 | pipe->mode = IA_CSS_PIPE_ID_PREVIEW; | 2303 | pipe->mode = IA_CSS_PIPE_ID_PREVIEW; |
2312 | pipe->pipe_settings.preview = prev; | 2304 | pipe->pipe_settings.preview = IA_CSS_DEFAULT_PREVIEW_SETTINGS; |
2313 | break; | 2305 | break; |
2314 | case IA_CSS_PIPE_MODE_CAPTURE: | 2306 | case IA_CSS_PIPE_MODE_CAPTURE: |
2315 | if (copy_pipe) { | 2307 | if (copy_pipe) { |
@@ -2317,11 +2309,11 @@ init_pipe_defaults(enum ia_css_pipe_mode mode, | |||
2317 | } else { | 2309 | } else { |
2318 | pipe->mode = IA_CSS_PIPE_ID_CAPTURE; | 2310 | pipe->mode = IA_CSS_PIPE_ID_CAPTURE; |
2319 | } | 2311 | } |
2320 | pipe->pipe_settings.capture = capt; | 2312 | pipe->pipe_settings.capture = IA_CSS_DEFAULT_CAPTURE_SETTINGS; |
2321 | break; | 2313 | break; |
2322 | case IA_CSS_PIPE_MODE_VIDEO: | 2314 | case IA_CSS_PIPE_MODE_VIDEO: |
2323 | pipe->mode = IA_CSS_PIPE_ID_VIDEO; | 2315 | pipe->mode = IA_CSS_PIPE_ID_VIDEO; |
2324 | pipe->pipe_settings.video = video; | 2316 | pipe->pipe_settings.video = IA_CSS_DEFAULT_VIDEO_SETTINGS; |
2325 | break; | 2317 | break; |
2326 | case IA_CSS_PIPE_MODE_ACC: | 2318 | case IA_CSS_PIPE_MODE_ACC: |
2327 | pipe->mode = IA_CSS_PIPE_ID_ACC; | 2319 | pipe->mode = IA_CSS_PIPE_ID_ACC; |
@@ -2331,7 +2323,7 @@ init_pipe_defaults(enum ia_css_pipe_mode mode, | |||
2331 | break; | 2323 | break; |
2332 | case IA_CSS_PIPE_MODE_YUVPP: | 2324 | case IA_CSS_PIPE_MODE_YUVPP: |
2333 | pipe->mode = IA_CSS_PIPE_ID_YUVPP; | 2325 | pipe->mode = IA_CSS_PIPE_ID_YUVPP; |
2334 | pipe->pipe_settings.yuvpp = yuvpp; | 2326 | pipe->pipe_settings.yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS; |
2335 | break; | 2327 | break; |
2336 | default: | 2328 | default: |
2337 | return IA_CSS_ERR_INVALID_ARGUMENTS; | 2329 | return IA_CSS_ERR_INVALID_ARGUMENTS; |
@@ -3657,7 +3649,7 @@ static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe) | |||
3657 | in_frame = me->stages->args.out_frame[0]; | 3649 | in_frame = me->stages->args.out_frame[0]; |
3658 | } else if (pipe->stream->config.continuous) { | 3650 | } else if (pipe->stream->config.continuous) { |
3659 | #ifdef USE_INPUT_SYSTEM_VERSION_2401 | 3651 | #ifdef USE_INPUT_SYSTEM_VERSION_2401 |
3660 | /* When continous is enabled, configure in_frame with the | 3652 | /* When continuous is enabled, configure in_frame with the |
3661 | * last pipe, which is the copy pipe. | 3653 | * last pipe, which is the copy pipe. |
3662 | */ | 3654 | */ |
3663 | in_frame = pipe->stream->last_pipe->continuous_frames[0]; | 3655 | in_frame = pipe->stream->last_pipe->continuous_frames[0]; |
@@ -3854,7 +3846,7 @@ create_host_preview_pipeline(struct ia_css_pipe *pipe) | |||
3854 | * - Direct Sensor Mode Online Preview | 3846 | * - Direct Sensor Mode Online Preview |
3855 | * - Buffered Sensor Mode Online Preview | 3847 | * - Buffered Sensor Mode Online Preview |
3856 | * - Direct Sensor Mode Continuous Preview | 3848 | * - Direct Sensor Mode Continuous Preview |
3857 | * - Buffered Sensor Mode Continous Preview | 3849 | * - Buffered Sensor Mode Continuous Preview |
3858 | */ | 3850 | */ |
3859 | sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR); | 3851 | sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR); |
3860 | buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR); | 3852 | buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR); |
@@ -4715,7 +4707,7 @@ ia_css_dequeue_psys_event(struct ia_css_event *event) | |||
4715 | event->timer_subcode = payload[2]; | 4707 | event->timer_subcode = payload[2]; |
4716 | } | 4708 | } |
4717 | /* It's a non timer event. So clear first half of the timer event data. | 4709 | /* It's a non timer event. So clear first half of the timer event data. |
4718 | * If the second part of the TIMER event is not recieved, we discard | 4710 | * If the second part of the TIMER event is not received, we discard |
4719 | * the first half of the timer data and process the non timer event without | 4711 | * the first half of the timer data and process the non timer event without |
4720 | * affecting the flow. So the non timer event falls through | 4712 | * affecting the flow. So the non timer event falls through |
4721 | * the code. */ | 4713 | * the code. */ |
@@ -5588,8 +5580,7 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe) | |||
5588 | /* we build up the pipeline starting at the end */ | 5580 | /* we build up the pipeline starting at the end */ |
5589 | /* YUV post-processing if needed */ | 5581 | /* YUV post-processing if needed */ |
5590 | if (need_scaler) { | 5582 | if (need_scaler) { |
5591 | struct ia_css_cas_binary_descr cas_scaler_descr | 5583 | struct ia_css_cas_binary_descr cas_scaler_descr = { }; |
5592 | = IA_CSS_DEFAULT_CAS_BINARY_DESCR; | ||
5593 | 5584 | ||
5594 | /* NV12 is the common format that is supported by both */ | 5585 | /* NV12 is the common format that is supported by both */ |
5595 | /* yuv_scaler and the video_xx_isp2_min binaries. */ | 5586 | /* yuv_scaler and the video_xx_isp2_min binaries. */ |
@@ -6244,8 +6235,8 @@ static enum ia_css_err load_primary_binaries( | |||
6244 | pipe_out_info->res); | 6235 | pipe_out_info->res); |
6245 | 6236 | ||
6246 | if (need_extra_yuv_scaler) { | 6237 | if (need_extra_yuv_scaler) { |
6247 | struct ia_css_cas_binary_descr cas_scaler_descr | 6238 | struct ia_css_cas_binary_descr cas_scaler_descr = { }; |
6248 | = IA_CSS_DEFAULT_CAS_BINARY_DESCR; | 6239 | |
6249 | err = ia_css_pipe_create_cas_scaler_desc_single_output( | 6240 | err = ia_css_pipe_create_cas_scaler_desc_single_output( |
6250 | &capt_pp_out_info, | 6241 | &capt_pp_out_info, |
6251 | pipe_out_info, | 6242 | pipe_out_info, |
@@ -6958,7 +6949,7 @@ static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output( | |||
6958 | unsigned int i; | 6949 | unsigned int i; |
6959 | unsigned int hor_ds_factor = 0, ver_ds_factor = 0; | 6950 | unsigned int hor_ds_factor = 0, ver_ds_factor = 0; |
6960 | enum ia_css_err err = IA_CSS_SUCCESS; | 6951 | enum ia_css_err err = IA_CSS_SUCCESS; |
6961 | struct ia_css_frame_info tmp_in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO; | 6952 | struct ia_css_frame_info tmp_in_info; |
6962 | 6953 | ||
6963 | unsigned max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP; | 6954 | unsigned max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP; |
6964 | 6955 | ||
@@ -7232,7 +7223,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) | |||
7232 | struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE]; | 7223 | struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE]; |
7233 | struct ia_css_yuvpp_settings *mycs; | 7224 | struct ia_css_yuvpp_settings *mycs; |
7234 | struct ia_css_binary *next_binary; | 7225 | struct ia_css_binary *next_binary; |
7235 | struct ia_css_cas_binary_descr cas_scaler_descr = IA_CSS_DEFAULT_CAS_BINARY_DESCR; | 7226 | struct ia_css_cas_binary_descr cas_scaler_descr = { }; |
7236 | unsigned int i, j; | 7227 | unsigned int i, j; |
7237 | bool need_isp_copy_binary = false; | 7228 | bool need_isp_copy_binary = false; |
7238 | 7229 | ||
@@ -7610,7 +7601,7 @@ create_host_yuvpp_pipeline(struct ia_css_pipe *pipe) | |||
7610 | * except for the following: | 7601 | * except for the following: |
7611 | * - Direct Sensor Mode Online Capture | 7602 | * - Direct Sensor Mode Online Capture |
7612 | * - Direct Sensor Mode Continuous Capture | 7603 | * - Direct Sensor Mode Continuous Capture |
7613 | * - Buffered Sensor Mode Continous Capture | 7604 | * - Buffered Sensor Mode Continuous Capture |
7614 | */ | 7605 | */ |
7615 | sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR; | 7606 | sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR; |
7616 | buffered_sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR; | 7607 | buffered_sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR; |
@@ -7950,7 +7941,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) | |||
7950 | * - Direct Sensor Mode Online Capture | 7941 | * - Direct Sensor Mode Online Capture |
7951 | * - Direct Sensor Mode Online Capture | 7942 | * - Direct Sensor Mode Online Capture |
7952 | * - Direct Sensor Mode Continuous Capture | 7943 | * - Direct Sensor Mode Continuous Capture |
7953 | * - Buffered Sensor Mode Continous Capture | 7944 | * - Buffered Sensor Mode Continuous Capture |
7954 | */ | 7945 | */ |
7955 | sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR); | 7946 | sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR); |
7956 | buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR); | 7947 | buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR); |
@@ -8827,10 +8818,8 @@ sh_css_init_host_sp_control_vars(void) | |||
8827 | */ | 8818 | */ |
8828 | void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config) | 8819 | void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config) |
8829 | { | 8820 | { |
8830 | struct ia_css_pipe_config def_config = DEFAULT_PIPE_CONFIG; | ||
8831 | |||
8832 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_config_defaults()\n"); | 8821 | ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_config_defaults()\n"); |
8833 | *pipe_config = def_config; | 8822 | *pipe_config = DEFAULT_PIPE_CONFIG; |
8834 | } | 8823 | } |
8835 | 8824 | ||
8836 | void | 8825 | void |
@@ -8915,7 +8904,7 @@ ia_css_pipe_create(const struct ia_css_pipe_config *config, | |||
8915 | err = ia_css_pipe_create_extra(config, NULL, pipe); | 8904 | err = ia_css_pipe_create_extra(config, NULL, pipe); |
8916 | 8905 | ||
8917 | if(err == IA_CSS_SUCCESS) { | 8906 | if(err == IA_CSS_SUCCESS) { |
8918 | IA_CSS_LOG("pipe created successfuly = %p", *pipe); | 8907 | IA_CSS_LOG("pipe created successfully = %p", *pipe); |
8919 | } | 8908 | } |
8920 | 8909 | ||
8921 | IA_CSS_LEAVE_ERR_PRIVATE(err); | 8910 | IA_CSS_LEAVE_ERR_PRIVATE(err); |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_legacy.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_legacy.h index 4bcc35d219f8..4fd25ba2cd0d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_legacy.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_legacy.h | |||
@@ -52,17 +52,6 @@ struct ia_css_pipe_extra_config { | |||
52 | bool disable_vf_pp; | 52 | bool disable_vf_pp; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #define DEFAULT_PIPE_EXTRA_CONFIG \ | ||
56 | { \ | ||
57 | false, /* enable_raw_binning */ \ | ||
58 | false, /* enable_yuv_ds */ \ | ||
59 | false, /* enable_high_speed */ \ | ||
60 | false, /* enable_dvs_6axis */ \ | ||
61 | false, /* enable_reduced_pipe */ \ | ||
62 | false, /* enable_fractional_ds */ \ | ||
63 | false, /* disable_vf_pp */ \ | ||
64 | } | ||
65 | |||
66 | enum ia_css_err | 55 | enum ia_css_err |
67 | ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, | 56 | ia_css_pipe_create_extra(const struct ia_css_pipe_config *config, |
68 | const struct ia_css_pipe_extra_config *extra_config, | 57 | const struct ia_css_pipe_extra_config *extra_config, |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_metrics.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_metrics.h index 40840ea318ab..2ef9238d95ad 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_metrics.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_metrics.h | |||
@@ -24,16 +24,6 @@ struct sh_css_pc_histogram { | |||
24 | unsigned *msink; | 24 | unsigned *msink; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | #if !defined(__USE_DESIGNATED_INITIALISERS__) | ||
28 | #define DEFAULT_PC_HISTOGRAM \ | ||
29 | { \ | ||
30 | 0, \ | ||
31 | NULL, \ | ||
32 | NULL, \ | ||
33 | NULL \ | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | struct sh_css_binary_metrics { | 27 | struct sh_css_binary_metrics { |
38 | unsigned mode; | 28 | unsigned mode; |
39 | unsigned id; | 29 | unsigned id; |
@@ -42,17 +32,6 @@ struct sh_css_binary_metrics { | |||
42 | struct sh_css_binary_metrics *next; | 32 | struct sh_css_binary_metrics *next; |
43 | }; | 33 | }; |
44 | 34 | ||
45 | #if !defined(__USE_DESIGNATED_INITIALISERS__) | ||
46 | #define DEFAULT_BINARY_METRICS \ | ||
47 | { \ | ||
48 | 0, \ | ||
49 | 0, \ | ||
50 | DEFAULT_PC_HISTOGRAM, \ | ||
51 | DEFAULT_PC_HISTOGRAM, \ | ||
52 | NULL \ | ||
53 | } | ||
54 | #endif | ||
55 | |||
56 | struct ia_css_frame_metrics { | 35 | struct ia_css_frame_metrics { |
57 | unsigned num_frames; | 36 | unsigned num_frames; |
58 | }; | 37 | }; |
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h deleted file mode 100644 index 9e51a657ece4..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Medifield PNW Camera Imaging ISP subsystem. | ||
3 | * | ||
4 | * Copyright (c) 2010 Intel Corporation. All Rights Reserved. | ||
5 | * | ||
6 | * Copyright (c) 2010 Silicon Hive www.siliconhive.com. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #ifndef __HMM_BO_DEV_H__ | ||
21 | #define __HMM_BO_DEV_H__ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include "mmu/isp_mmu.h" | ||
29 | #include "hmm/hmm_common.h" | ||
30 | #include "hmm/hmm_vm.h" | ||
31 | #include "ia_css_types.h" | ||
32 | |||
33 | #define check_bodev_null_return(bdev, exp) \ | ||
34 | check_null_return(bdev, exp, \ | ||
35 | "NULL hmm_bo_device.\n") | ||
36 | |||
37 | #define check_bodev_null_return_void(bdev) \ | ||
38 | check_null_return_void(bdev, \ | ||
39 | "NULL hmm_bo_device.\n") | ||
40 | |||
41 | #define HMM_BO_DEVICE_INITED 0x1 | ||
42 | |||
43 | #define HMM_BO_CACHE_SIZE 2 | ||
44 | |||
45 | |||
46 | struct hmm_buffer_object; | ||
47 | |||
48 | struct hmm_bo_device { | ||
49 | /* isp_mmu provides lock itself */ | ||
50 | struct isp_mmu mmu; | ||
51 | |||
52 | /* hmm_vm provides lock itself */ | ||
53 | struct hmm_vm vaddr_space; | ||
54 | |||
55 | struct list_head free_bo_list; | ||
56 | struct list_head active_bo_list; | ||
57 | |||
58 | /* list lock is used to protect both of the buffer object lists */ | ||
59 | spinlock_t list_lock; | ||
60 | #ifdef CONFIG_ION | ||
61 | struct ion_client *iclient; | ||
62 | #endif | ||
63 | int flag; | ||
64 | }; | ||
65 | |||
66 | int hmm_bo_device_init(struct hmm_bo_device *bdev, | ||
67 | struct isp_mmu_client *mmu_driver, | ||
68 | unsigned int vaddr_start, unsigned int size); | ||
69 | |||
70 | /* | ||
71 | * clean up all hmm_bo_device related things. | ||
72 | */ | ||
73 | void hmm_bo_device_exit(struct hmm_bo_device *bdev); | ||
74 | |||
75 | /* | ||
76 | * whether the bo device is inited or not. | ||
77 | */ | ||
78 | int hmm_bo_device_inited(struct hmm_bo_device *bdev); | ||
79 | |||
80 | /* | ||
81 | * find the buffer object with virtual address vaddr. | ||
82 | * return NULL if no such buffer object found. | ||
83 | */ | ||
84 | struct hmm_buffer_object *hmm_bo_device_search_start( | ||
85 | struct hmm_bo_device *bdev, ia_css_ptr vaddr); | ||
86 | |||
87 | /* | ||
88 | * find the buffer object with virtual address vaddr. | ||
89 | * return NULL if no such buffer object found. | ||
90 | */ | ||
91 | struct hmm_buffer_object *hmm_bo_device_search_in_range( | ||
92 | struct hmm_bo_device *bdev, ia_css_ptr vaddr); | ||
93 | |||
94 | /* | ||
95 | * find the buffer object with kernel virtual address vaddr. | ||
96 | * return NULL if no such buffer object found. | ||
97 | */ | ||
98 | struct hmm_buffer_object *hmm_bo_device_search_vmap_start( | ||
99 | struct hmm_bo_device *bdev, const void *vaddr); | ||
100 | |||
101 | /* | ||
102 | * find a buffer object with pgnr pages from free_bo_list and | ||
103 | * activate it (remove from free_bo_list and add to | ||
104 | * active_bo_list) | ||
105 | * | ||
106 | * return NULL if no such buffer object found. | ||
107 | */ | ||
108 | struct hmm_buffer_object *hmm_bo_device_get_bo( | ||
109 | struct hmm_bo_device *bdev, unsigned int pgnr); | ||
110 | |||
111 | /* | ||
112 | * destroy all buffer objects in the free_bo_list. | ||
113 | */ | ||
114 | void hmm_bo_device_destroy_free_bo_list(struct hmm_bo_device *bdev); | ||
115 | /* | ||
116 | * destroy buffer object with start virtual address vaddr. | ||
117 | */ | ||
118 | void hmm_bo_device_destroy_free_bo_addr(struct hmm_bo_device *bdev, | ||
119 | ia_css_ptr vaddr); | ||
120 | /* | ||
121 | * destroy all buffer objects with pgnr pages. | ||
122 | */ | ||
123 | void hmm_bo_device_destroy_free_bo_size(struct hmm_bo_device *bdev, | ||
124 | unsigned int pgnr); | ||
125 | |||
126 | #endif | ||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h deleted file mode 100644 index 031c0398bf65..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* | ||
2 | * Support for Medifield PNW Camera Imaging ISP subsystem. | ||
3 | * | ||
4 | * Copyright (c) 2010 Intel Corporation. All Rights Reserved. | ||
5 | * | ||
6 | * Copyright (c) 2010 Silicon Hive www.siliconhive.com. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * | ||
18 | */ | ||
19 | #ifndef SH_MMU_H_ | ||
20 | #define SH_MMU_H_ | ||
21 | |||
22 | |||
23 | #include <sh_css.h> | ||
24 | |||
25 | #include "mmu/isp_mmu.h" | ||
26 | |||
27 | |||
28 | /* | ||
29 | * include SH header file here | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * set page directory base address (physical address). | ||
34 | * | ||
35 | * must be provided. | ||
36 | */ | ||
37 | static int sh_set_pd_base(struct isp_mmu *mmu, | ||
38 | unsigned int phys) | ||
39 | { | ||
40 | sh_css_mmu_set_page_table_base_address((void *)phys); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * callback to flush tlb. | ||
46 | * | ||
47 | * tlb_flush_range will at least flush TLBs containing | ||
48 | * address mapping from addr to addr + size. | ||
49 | * | ||
50 | * tlb_flush_all will flush all TLBs. | ||
51 | * | ||
52 | * tlb_flush_all is must be provided. if tlb_flush_range is | ||
53 | * not valid, it will set to tlb_flush_all by default. | ||
54 | */ | ||
55 | static void sh_tlb_flush(struct isp_mmu *mmu) | ||
56 | { | ||
57 | sh_css_mmu_invalidate_cache(); | ||
58 | } | ||
59 | |||
60 | static struct isp_mmu_driver sh_mmu_driver = { | ||
61 | .name = "Silicon Hive ISP3000 MMU", | ||
62 | .pte_valid_mask = 0x1, | ||
63 | .set_pd_base = sh_set_pd_base, | ||
64 | .tlb_flush_all = sh_tlb_flush, | ||
65 | }; | ||
66 | |||
67 | #define ISP_VM_START 0x0 | ||
68 | #define ISP_VM_SIZE (1 << 30) /* 1G address space */ | ||
69 | #define ISP_PTR_NULL NULL | ||
70 | |||
71 | #endif /* SH_MMU_H_ */ | ||
72 | |||
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c b/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c index e36c2a33b41a..f21075c1e503 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c | |||
@@ -450,7 +450,7 @@ static void mmu_l1_unmap(struct isp_mmu *mmu, phys_addr_t l1_pt, | |||
450 | ptr = end; | 450 | ptr = end; |
451 | } | 451 | } |
452 | /* | 452 | /* |
453 | * use the same L2 page next time, so we dont | 453 | * use the same L2 page next time, so we don't |
454 | * need to invalidate and free this PT. | 454 | * need to invalidate and free this PT. |
455 | */ | 455 | */ |
456 | /* atomisp_set_pte(l1_pt, idx, NULL_PTE); */ | 456 | /* atomisp_set_pte(l1_pt, idx, NULL_PTE); */ |
diff --git a/drivers/staging/media/cxd2099/Kconfig b/drivers/staging/media/cxd2099/Kconfig deleted file mode 100644 index b48aefddc84c..000000000000 --- a/drivers/staging/media/cxd2099/Kconfig +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | config DVB_CXD2099 | ||
2 | tristate "CXD2099AR Common Interface driver" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | ---help--- | ||
5 | Support for the CI module found on cards based on | ||
6 | - Micronas ngene PCIe bridge: cineS2 etc. | ||
7 | - Digital Devices PCIe bridge: Octopus series | ||
8 | |||
9 | For now, data is passed through '/dev/dvb/adapterX/sec0': | ||
10 | - Encrypted data must be written to 'sec0'. | ||
11 | - Decrypted data can be read from 'sec0'. | ||
12 | - Setup the CAM using device 'ca0'. | ||
diff --git a/drivers/staging/media/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile deleted file mode 100644 index 30432c9aabc4..000000000000 --- a/drivers/staging/media/cxd2099/Makefile +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | obj-$(CONFIG_DVB_CXD2099) += cxd2099.o | ||
2 | |||
3 | ccflags-y += -Idrivers/media/dvb-frontends/ | ||
4 | ccflags-y += -Idrivers/media/tuners/ | ||
diff --git a/drivers/staging/media/cxd2099/TODO b/drivers/staging/media/cxd2099/TODO deleted file mode 100644 index 375bb6f8ee2c..000000000000 --- a/drivers/staging/media/cxd2099/TODO +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | For now, data is passed through '/dev/dvb/adapterX/sec0': | ||
2 | - Encrypted data must be written to 'sec0'. | ||
3 | - Decrypted data can be read from 'sec0'. | ||
4 | - Setup the CAM using device 'ca0'. | ||
5 | |||
6 | But this is wrong. There are some discussions about the proper way for | ||
7 | doing it, as seen at: | ||
8 | http://www.mail-archive.com/linux-media@vger.kernel.org/msg22196.html | ||
9 | |||
10 | While there's no proper fix for it, the driver should be kept in staging. | ||
11 | |||
12 | Patches should be submitted to: linux-media@vger.kernel.org. | ||
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index bffe2153b910..634d38c4bea1 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c | |||
@@ -444,7 +444,7 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev) | |||
444 | for (i = 0; i < vpfe_dev->num_ext_subdevs; i++) | 444 | for (i = 0; i < vpfe_dev->num_ext_subdevs; i++) |
445 | /* | 445 | /* |
446 | * if entity has no pads (ex: amplifier), | 446 | * if entity has no pads (ex: amplifier), |
447 | * cant establish link | 447 | * can't establish link |
448 | */ | 448 | */ |
449 | if (vpfe_dev->sd[i]->entity.num_pads) { | 449 | if (vpfe_dev->sd[i]->entity.num_pads) { |
450 | ret = media_create_pad_link(&vpfe_dev->sd[i]->entity, | 450 | ret = media_create_pad_link(&vpfe_dev->sd[i]->entity, |
diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index 2be921cd0d55..bfc17de56b17 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig | |||
@@ -1,7 +1,9 @@ | |||
1 | config VIDEO_IMX_MEDIA | 1 | config VIDEO_IMX_MEDIA |
2 | tristate "i.MX5/6 V4L2 media core driver" | 2 | tristate "i.MX5/6 V4L2 media core driver" |
3 | depends on MEDIA_CONTROLLER && VIDEO_V4L2 && ARCH_MXC && IMX_IPUV3_CORE | 3 | depends on ARCH_MXC || COMPILE_TEST |
4 | depends on MEDIA_CONTROLLER && VIDEO_V4L2 && IMX_IPUV3_CORE | ||
4 | depends on VIDEO_V4L2_SUBDEV_API | 5 | depends on VIDEO_V4L2_SUBDEV_API |
6 | depends on HAS_DMA | ||
5 | select VIDEOBUF2_DMA_CONTIG | 7 | select VIDEOBUF2_DMA_CONTIG |
6 | select V4L2_FWNODE | 8 | select V4L2_FWNODE |
7 | ---help--- | 9 | ---help--- |
diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index c6d7e80932ad..98923fc844ce 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c | |||
@@ -462,6 +462,7 @@ static int prp_registered(struct v4l2_subdev *sd) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | static const struct v4l2_subdev_pad_ops prp_pad_ops = { | 464 | static const struct v4l2_subdev_pad_ops prp_pad_ops = { |
465 | .init_cfg = imx_media_init_cfg, | ||
465 | .enum_mbus_code = prp_enum_mbus_code, | 466 | .enum_mbus_code = prp_enum_mbus_code, |
466 | .get_fmt = prp_get_fmt, | 467 | .get_fmt = prp_get_fmt, |
467 | .set_fmt = prp_set_fmt, | 468 | .set_fmt = prp_set_fmt, |
diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 143038c6c403..ae453fd422f0 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c | |||
@@ -923,7 +923,7 @@ static int prp_enum_frame_size(struct v4l2_subdev *sd, | |||
923 | struct v4l2_subdev_frame_size_enum *fse) | 923 | struct v4l2_subdev_frame_size_enum *fse) |
924 | { | 924 | { |
925 | struct prp_priv *priv = sd_to_priv(sd); | 925 | struct prp_priv *priv = sd_to_priv(sd); |
926 | struct v4l2_subdev_format format = {0}; | 926 | struct v4l2_subdev_format format = {}; |
927 | const struct imx_media_pixfmt *cc; | 927 | const struct imx_media_pixfmt *cc; |
928 | int ret = 0; | 928 | int ret = 0; |
929 | 929 | ||
@@ -1253,6 +1253,7 @@ static void prp_unregistered(struct v4l2_subdev *sd) | |||
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | static const struct v4l2_subdev_pad_ops prp_pad_ops = { | 1255 | static const struct v4l2_subdev_pad_ops prp_pad_ops = { |
1256 | .init_cfg = imx_media_init_cfg, | ||
1256 | .enum_mbus_code = prp_enum_mbus_code, | 1257 | .enum_mbus_code = prp_enum_mbus_code, |
1257 | .enum_frame_size = prp_enum_frame_size, | 1258 | .enum_frame_size = prp_enum_frame_size, |
1258 | .get_fmt = prp_get_fmt, | 1259 | .get_fmt = prp_get_fmt, |
diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index 576bdc7e9c42..0ccabe04b0e1 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c | |||
@@ -141,7 +141,8 @@ static int capture_enum_frameintervals(struct file *file, void *fh, | |||
141 | 141 | ||
142 | fie.code = cc->codes[0]; | 142 | fie.code = cc->codes[0]; |
143 | 143 | ||
144 | ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_interval, NULL, &fie); | 144 | ret = v4l2_subdev_call(priv->src_sd, pad, enum_frame_interval, |
145 | NULL, &fie); | ||
145 | if (ret) | 146 | if (ret) |
146 | return ret; | 147 | return ret; |
147 | 148 | ||
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index eb7be5093a9d..1aa2be891704 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c | |||
@@ -400,6 +400,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) | |||
400 | case V4L2_PIX_FMT_SGBRG8: | 400 | case V4L2_PIX_FMT_SGBRG8: |
401 | case V4L2_PIX_FMT_SGRBG8: | 401 | case V4L2_PIX_FMT_SGRBG8: |
402 | case V4L2_PIX_FMT_SRGGB8: | 402 | case V4L2_PIX_FMT_SRGGB8: |
403 | case V4L2_PIX_FMT_GREY: | ||
403 | burst_size = 16; | 404 | burst_size = 16; |
404 | passthrough = true; | 405 | passthrough = true; |
405 | passthrough_bits = 8; | 406 | passthrough_bits = 8; |
@@ -668,11 +669,10 @@ static int csi_setup(struct csi_priv *priv) | |||
668 | 669 | ||
669 | static int csi_start(struct csi_priv *priv) | 670 | static int csi_start(struct csi_priv *priv) |
670 | { | 671 | { |
671 | struct v4l2_fract *output_fi, *input_fi; | 672 | struct v4l2_fract *output_fi; |
672 | int ret; | 673 | int ret; |
673 | 674 | ||
674 | output_fi = &priv->frame_interval[priv->active_output_pad]; | 675 | output_fi = &priv->frame_interval[priv->active_output_pad]; |
675 | input_fi = &priv->frame_interval[CSI_SINK_PAD]; | ||
676 | 676 | ||
677 | if (priv->dest == IPU_CSI_DEST_IDMAC) { | 677 | if (priv->dest == IPU_CSI_DEST_IDMAC) { |
678 | ret = csi_idmac_start(priv); | 678 | ret = csi_idmac_start(priv); |
@@ -1715,6 +1715,7 @@ static const struct v4l2_subdev_video_ops csi_video_ops = { | |||
1715 | }; | 1715 | }; |
1716 | 1716 | ||
1717 | static const struct v4l2_subdev_pad_ops csi_pad_ops = { | 1717 | static const struct v4l2_subdev_pad_ops csi_pad_ops = { |
1718 | .init_cfg = imx_media_init_cfg, | ||
1718 | .enum_mbus_code = csi_enum_mbus_code, | 1719 | .enum_mbus_code = csi_enum_mbus_code, |
1719 | .enum_frame_size = csi_enum_frame_size, | 1720 | .enum_frame_size = csi_enum_frame_size, |
1720 | .enum_frame_interval = csi_enum_frame_interval, | 1721 | .enum_frame_interval = csi_enum_frame_interval, |
@@ -1797,6 +1798,10 @@ static int imx_csi_probe(struct platform_device *pdev) | |||
1797 | */ | 1798 | */ |
1798 | priv->dev->of_node = pdata->of_node; | 1799 | priv->dev->of_node = pdata->of_node; |
1799 | pinctrl = devm_pinctrl_get_select_default(priv->dev); | 1800 | pinctrl = devm_pinctrl_get_select_default(priv->dev); |
1801 | if (IS_ERR(pinctrl)) { | ||
1802 | ret = PTR_ERR(priv->vdev); | ||
1803 | goto free; | ||
1804 | } | ||
1800 | 1805 | ||
1801 | ret = v4l2_async_register_subdev(&priv->sd); | 1806 | ret = v4l2_async_register_subdev(&priv->sd); |
1802 | if (ret) | 1807 | if (ret) |
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c index 70833fe503b5..daf66c2d69ab 100644 --- a/drivers/staging/media/imx/imx-media-internal-sd.c +++ b/drivers/staging/media/imx/imx-media-internal-sd.c | |||
@@ -271,7 +271,7 @@ static int add_internal_subdev(struct imx_media_dev *imxmd, | |||
271 | int ipu_id) | 271 | int ipu_id) |
272 | { | 272 | { |
273 | struct imx_media_internal_sd_platformdata pdata; | 273 | struct imx_media_internal_sd_platformdata pdata; |
274 | struct platform_device_info pdevinfo = {0}; | 274 | struct platform_device_info pdevinfo = {}; |
275 | struct platform_device *pdev; | 275 | struct platform_device *pdev; |
276 | 276 | ||
277 | pdata.grp_id = isd->id->grp_id; | 277 | pdata.grp_id = isd->id->grp_id; |
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 13dafa77a2eb..fab98fc0d6a0 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c | |||
@@ -93,7 +93,7 @@ static const struct imx_media_pixfmt rgb_formats[] = { | |||
93 | .bpp = 32, | 93 | .bpp = 32, |
94 | .ipufmt = true, | 94 | .ipufmt = true, |
95 | }, | 95 | }, |
96 | /*** raw bayer formats start here ***/ | 96 | /*** raw bayer and grayscale formats start here ***/ |
97 | { | 97 | { |
98 | .fourcc = V4L2_PIX_FMT_SBGGR8, | 98 | .fourcc = V4L2_PIX_FMT_SBGGR8, |
99 | .codes = {MEDIA_BUS_FMT_SBGGR8_1X8}, | 99 | .codes = {MEDIA_BUS_FMT_SBGGR8_1X8}, |
@@ -162,6 +162,12 @@ static const struct imx_media_pixfmt rgb_formats[] = { | |||
162 | .cs = IPUV3_COLORSPACE_RGB, | 162 | .cs = IPUV3_COLORSPACE_RGB, |
163 | .bpp = 16, | 163 | .bpp = 16, |
164 | .bayer = true, | 164 | .bayer = true, |
165 | }, { | ||
166 | .fourcc = V4L2_PIX_FMT_GREY, | ||
167 | .codes = {MEDIA_BUS_FMT_Y8_1X8}, | ||
168 | .cs = IPUV3_COLORSPACE_RGB, | ||
169 | .bpp = 8, | ||
170 | .bayer = true, | ||
165 | }, | 171 | }, |
166 | /*** | 172 | /*** |
167 | * non-mbus RGB formats start here. NOTE! when adding non-mbus | 173 | * non-mbus RGB formats start here. NOTE! when adding non-mbus |
@@ -219,58 +225,63 @@ static void init_mbus_colorimetry(struct v4l2_mbus_framefmt *mbus, | |||
219 | mbus->ycbcr_enc); | 225 | mbus->ycbcr_enc); |
220 | } | 226 | } |
221 | 227 | ||
228 | static const | ||
229 | struct imx_media_pixfmt *__find_format(u32 fourcc, | ||
230 | u32 code, | ||
231 | bool allow_non_mbus, | ||
232 | bool allow_bayer, | ||
233 | const struct imx_media_pixfmt *array, | ||
234 | u32 array_size) | ||
235 | { | ||
236 | const struct imx_media_pixfmt *fmt; | ||
237 | int i, j; | ||
238 | |||
239 | for (i = 0; i < array_size; i++) { | ||
240 | fmt = &array[i]; | ||
241 | |||
242 | if ((!allow_non_mbus && !fmt->codes[0]) || | ||
243 | (!allow_bayer && fmt->bayer)) | ||
244 | continue; | ||
245 | |||
246 | if (fourcc && fmt->fourcc == fourcc) | ||
247 | return fmt; | ||
248 | |||
249 | if (!code) | ||
250 | continue; | ||
251 | |||
252 | for (j = 0; fmt->codes[j]; j++) { | ||
253 | if (code == fmt->codes[j]) | ||
254 | return fmt; | ||
255 | } | ||
256 | } | ||
257 | return NULL; | ||
258 | } | ||
259 | |||
222 | static const struct imx_media_pixfmt *find_format(u32 fourcc, | 260 | static const struct imx_media_pixfmt *find_format(u32 fourcc, |
223 | u32 code, | 261 | u32 code, |
224 | enum codespace_sel cs_sel, | 262 | enum codespace_sel cs_sel, |
225 | bool allow_non_mbus, | 263 | bool allow_non_mbus, |
226 | bool allow_bayer) | 264 | bool allow_bayer) |
227 | { | 265 | { |
228 | const struct imx_media_pixfmt *array, *fmt, *ret = NULL; | 266 | const struct imx_media_pixfmt *ret; |
229 | u32 array_size; | ||
230 | int i, j; | ||
231 | 267 | ||
232 | switch (cs_sel) { | 268 | switch (cs_sel) { |
233 | case CS_SEL_YUV: | 269 | case CS_SEL_YUV: |
234 | array_size = NUM_YUV_FORMATS; | 270 | return __find_format(fourcc, code, allow_non_mbus, allow_bayer, |
235 | array = yuv_formats; | 271 | yuv_formats, NUM_YUV_FORMATS); |
236 | break; | ||
237 | case CS_SEL_RGB: | 272 | case CS_SEL_RGB: |
238 | array_size = NUM_RGB_FORMATS; | 273 | return __find_format(fourcc, code, allow_non_mbus, allow_bayer, |
239 | array = rgb_formats; | 274 | rgb_formats, NUM_RGB_FORMATS); |
240 | break; | ||
241 | case CS_SEL_ANY: | 275 | case CS_SEL_ANY: |
242 | array_size = NUM_YUV_FORMATS + NUM_RGB_FORMATS; | 276 | ret = __find_format(fourcc, code, allow_non_mbus, allow_bayer, |
243 | array = yuv_formats; | 277 | yuv_formats, NUM_YUV_FORMATS); |
244 | break; | 278 | if (ret) |
279 | return ret; | ||
280 | return __find_format(fourcc, code, allow_non_mbus, allow_bayer, | ||
281 | rgb_formats, NUM_RGB_FORMATS); | ||
245 | default: | 282 | default: |
246 | return NULL; | 283 | return NULL; |
247 | } | 284 | } |
248 | |||
249 | for (i = 0; i < array_size; i++) { | ||
250 | if (cs_sel == CS_SEL_ANY && i >= NUM_YUV_FORMATS) | ||
251 | fmt = &rgb_formats[i - NUM_YUV_FORMATS]; | ||
252 | else | ||
253 | fmt = &array[i]; | ||
254 | |||
255 | if ((!allow_non_mbus && fmt->codes[0] == 0) || | ||
256 | (!allow_bayer && fmt->bayer)) | ||
257 | continue; | ||
258 | |||
259 | if (fourcc && fmt->fourcc == fourcc) { | ||
260 | ret = fmt; | ||
261 | goto out; | ||
262 | } | ||
263 | |||
264 | for (j = 0; code && fmt->codes[j]; j++) { | ||
265 | if (code == fmt->codes[j]) { | ||
266 | ret = fmt; | ||
267 | goto out; | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | out: | ||
273 | return ret; | ||
274 | } | 285 | } |
275 | 286 | ||
276 | static int enum_format(u32 *fourcc, u32 *code, u32 index, | 287 | static int enum_format(u32 *fourcc, u32 *code, u32 index, |
@@ -465,6 +476,35 @@ int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, | |||
465 | EXPORT_SYMBOL_GPL(imx_media_init_mbus_fmt); | 476 | EXPORT_SYMBOL_GPL(imx_media_init_mbus_fmt); |
466 | 477 | ||
467 | /* | 478 | /* |
479 | * Initializes the TRY format to the ACTIVE format on all pads | ||
480 | * of a subdev. Can be used as the .init_cfg pad operation. | ||
481 | */ | ||
482 | int imx_media_init_cfg(struct v4l2_subdev *sd, | ||
483 | struct v4l2_subdev_pad_config *cfg) | ||
484 | { | ||
485 | struct v4l2_mbus_framefmt *mf_try; | ||
486 | struct v4l2_subdev_format format; | ||
487 | unsigned int pad; | ||
488 | int ret; | ||
489 | |||
490 | for (pad = 0; pad < sd->entity.num_pads; pad++) { | ||
491 | memset(&format, 0, sizeof(format)); | ||
492 | |||
493 | format.pad = pad; | ||
494 | format.which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
495 | ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &format); | ||
496 | if (ret) | ||
497 | continue; | ||
498 | |||
499 | mf_try = v4l2_subdev_get_try_format(sd, cfg, pad); | ||
500 | *mf_try = format.format; | ||
501 | } | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | EXPORT_SYMBOL_GPL(imx_media_init_cfg); | ||
506 | |||
507 | /* | ||
468 | * Check whether the field and colorimetry parameters in tryfmt are | 508 | * Check whether the field and colorimetry parameters in tryfmt are |
469 | * uninitialized, and if so fill them with the values from fmt, | 509 | * uninitialized, and if so fill them with the values from fmt, |
470 | * or if tryfmt->colorspace has been initialized, all the default | 510 | * or if tryfmt->colorspace has been initialized, all the default |
diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 433474d58e3e..482250d47e7c 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c | |||
@@ -177,7 +177,7 @@ static int vdic_get_ipu_resources(struct vdic_priv *priv) | |||
177 | priv->vdi_in_ch = ch; | 177 | priv->vdi_in_ch = ch; |
178 | 178 | ||
179 | ch = ipu_idmac_get(priv->ipu, IPUV3_CHANNEL_MEM_VDI_NEXT); | 179 | ch = ipu_idmac_get(priv->ipu, IPUV3_CHANNEL_MEM_VDI_NEXT); |
180 | if (IS_ERR(priv->vdi_in_ch_n)) { | 180 | if (IS_ERR(ch)) { |
181 | err_chan = IPUV3_CHANNEL_MEM_VDI_NEXT; | 181 | err_chan = IPUV3_CHANNEL_MEM_VDI_NEXT; |
182 | ret = PTR_ERR(ch); | 182 | ret = PTR_ERR(ch); |
183 | goto out_err_chan; | 183 | goto out_err_chan; |
@@ -909,6 +909,7 @@ static void vdic_unregistered(struct v4l2_subdev *sd) | |||
909 | } | 909 | } |
910 | 910 | ||
911 | static const struct v4l2_subdev_pad_ops vdic_pad_ops = { | 911 | static const struct v4l2_subdev_pad_ops vdic_pad_ops = { |
912 | .init_cfg = imx_media_init_cfg, | ||
912 | .enum_mbus_code = vdic_enum_mbus_code, | 913 | .enum_mbus_code = vdic_enum_mbus_code, |
913 | .get_fmt = vdic_get_fmt, | 914 | .get_fmt = vdic_get_fmt, |
914 | .set_fmt = vdic_set_fmt, | 915 | .set_fmt = vdic_set_fmt, |
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index 2fd6dfdf37d6..e945e0ed6dd6 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h | |||
@@ -172,6 +172,8 @@ int imx_media_enum_ipu_format(u32 *code, u32 index, enum codespace_sel cs_sel); | |||
172 | int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, | 172 | int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus, |
173 | u32 width, u32 height, u32 code, u32 field, | 173 | u32 width, u32 height, u32 code, u32 field, |
174 | const struct imx_media_pixfmt **cc); | 174 | const struct imx_media_pixfmt **cc); |
175 | int imx_media_init_cfg(struct v4l2_subdev *sd, | ||
176 | struct v4l2_subdev_pad_config *cfg); | ||
175 | void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, | 177 | void imx_media_fill_default_mbus_fields(struct v4l2_mbus_framefmt *tryfmt, |
176 | struct v4l2_mbus_framefmt *fmt, | 178 | struct v4l2_mbus_framefmt *fmt, |
177 | bool ic_route); | 179 | bool ic_route); |
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c index 477d191c568b..ceeeb3069a02 100644 --- a/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/drivers/staging/media/imx/imx6-mipi-csi2.c | |||
@@ -447,6 +447,16 @@ out: | |||
447 | return ret; | 447 | return ret; |
448 | } | 448 | } |
449 | 449 | ||
450 | static struct v4l2_mbus_framefmt * | ||
451 | __csi2_get_fmt(struct csi2_dev *csi2, struct v4l2_subdev_pad_config *cfg, | ||
452 | unsigned int pad, enum v4l2_subdev_format_whence which) | ||
453 | { | ||
454 | if (which == V4L2_SUBDEV_FORMAT_TRY) | ||
455 | return v4l2_subdev_get_try_format(&csi2->sd, cfg, pad); | ||
456 | else | ||
457 | return &csi2->format_mbus; | ||
458 | } | ||
459 | |||
450 | static int csi2_get_fmt(struct v4l2_subdev *sd, | 460 | static int csi2_get_fmt(struct v4l2_subdev *sd, |
451 | struct v4l2_subdev_pad_config *cfg, | 461 | struct v4l2_subdev_pad_config *cfg, |
452 | struct v4l2_subdev_format *sdformat) | 462 | struct v4l2_subdev_format *sdformat) |
@@ -456,11 +466,7 @@ static int csi2_get_fmt(struct v4l2_subdev *sd, | |||
456 | 466 | ||
457 | mutex_lock(&csi2->lock); | 467 | mutex_lock(&csi2->lock); |
458 | 468 | ||
459 | if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) | 469 | fmt = __csi2_get_fmt(csi2, cfg, sdformat->pad, sdformat->which); |
460 | fmt = v4l2_subdev_get_try_format(&csi2->sd, cfg, | ||
461 | sdformat->pad); | ||
462 | else | ||
463 | fmt = &csi2->format_mbus; | ||
464 | 470 | ||
465 | sdformat->format = *fmt; | 471 | sdformat->format = *fmt; |
466 | 472 | ||
@@ -474,6 +480,7 @@ static int csi2_set_fmt(struct v4l2_subdev *sd, | |||
474 | struct v4l2_subdev_format *sdformat) | 480 | struct v4l2_subdev_format *sdformat) |
475 | { | 481 | { |
476 | struct csi2_dev *csi2 = sd_to_dev(sd); | 482 | struct csi2_dev *csi2 = sd_to_dev(sd); |
483 | struct v4l2_mbus_framefmt *fmt; | ||
477 | int ret = 0; | 484 | int ret = 0; |
478 | 485 | ||
479 | if (sdformat->pad >= CSI2_NUM_PADS) | 486 | if (sdformat->pad >= CSI2_NUM_PADS) |
@@ -490,10 +497,9 @@ static int csi2_set_fmt(struct v4l2_subdev *sd, | |||
490 | if (sdformat->pad != CSI2_SINK_PAD) | 497 | if (sdformat->pad != CSI2_SINK_PAD) |
491 | sdformat->format = csi2->format_mbus; | 498 | sdformat->format = csi2->format_mbus; |
492 | 499 | ||
493 | if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY) | 500 | fmt = __csi2_get_fmt(csi2, cfg, sdformat->pad, sdformat->which); |
494 | cfg->try_fmt = sdformat->format; | 501 | |
495 | else | 502 | *fmt = sdformat->format; |
496 | csi2->format_mbus = sdformat->format; | ||
497 | out: | 503 | out: |
498 | mutex_unlock(&csi2->lock); | 504 | mutex_unlock(&csi2->lock); |
499 | return ret; | 505 | return ret; |
@@ -531,6 +537,7 @@ static const struct v4l2_subdev_video_ops csi2_video_ops = { | |||
531 | }; | 537 | }; |
532 | 538 | ||
533 | static const struct v4l2_subdev_pad_ops csi2_pad_ops = { | 539 | static const struct v4l2_subdev_pad_ops csi2_pad_ops = { |
540 | .init_cfg = imx_media_init_cfg, | ||
534 | .get_fmt = csi2_get_fmt, | 541 | .get_fmt = csi2_get_fmt, |
535 | .set_fmt = csi2_set_fmt, | 542 | .set_fmt = csi2_set_fmt, |
536 | }; | 543 | }; |
diff --git a/drivers/staging/media/imx074/Kconfig b/drivers/staging/media/imx074/Kconfig new file mode 100644 index 000000000000..229cbeea580b --- /dev/null +++ b/drivers/staging/media/imx074/Kconfig | |||
@@ -0,0 +1,5 @@ | |||
1 | config SOC_CAMERA_IMX074 | ||
2 | tristate "imx074 support (DEPRECATED)" | ||
3 | depends on SOC_CAMERA && I2C | ||
4 | help | ||
5 | This driver supports IMX074 cameras from Sony | ||
diff --git a/drivers/staging/media/imx074/Makefile b/drivers/staging/media/imx074/Makefile new file mode 100644 index 000000000000..7d183574aa84 --- /dev/null +++ b/drivers/staging/media/imx074/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o | |||
diff --git a/drivers/staging/media/imx074/TODO b/drivers/staging/media/imx074/TODO new file mode 100644 index 000000000000..15580a4f950c --- /dev/null +++ b/drivers/staging/media/imx074/TODO | |||
@@ -0,0 +1,5 @@ | |||
1 | This sensor driver needs to be converted to a regular | ||
2 | v4l2 subdev driver. The soc_camera framework is deprecated and | ||
3 | will be removed in the future. Unless someone does this work this | ||
4 | sensor driver will be deleted when the soc_camera framework is | ||
5 | deleted. | ||
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/staging/media/imx074/imx074.c index 77f1e0243d6e..77f1e0243d6e 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/staging/media/imx074/imx074.c | |||
diff --git a/drivers/staging/media/mt9t031/Kconfig b/drivers/staging/media/mt9t031/Kconfig new file mode 100644 index 000000000000..f48e06a03cdb --- /dev/null +++ b/drivers/staging/media/mt9t031/Kconfig | |||
@@ -0,0 +1,11 @@ | |||
1 | config SOC_CAMERA_IMX074 | ||
2 | tristate "imx074 support (DEPRECATED)" | ||
3 | depends on SOC_CAMERA && I2C | ||
4 | help | ||
5 | This driver supports IMX074 cameras from Sony | ||
6 | |||
7 | config SOC_CAMERA_MT9T031 | ||
8 | tristate "mt9t031 support (DEPRECATED)" | ||
9 | depends on SOC_CAMERA && I2C | ||
10 | help | ||
11 | This driver supports MT9T031 cameras from Micron. | ||
diff --git a/drivers/staging/media/mt9t031/Makefile b/drivers/staging/media/mt9t031/Makefile new file mode 100644 index 000000000000..bfd24c442b33 --- /dev/null +++ b/drivers/staging/media/mt9t031/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | |||
diff --git a/drivers/staging/media/mt9t031/TODO b/drivers/staging/media/mt9t031/TODO new file mode 100644 index 000000000000..15580a4f950c --- /dev/null +++ b/drivers/staging/media/mt9t031/TODO | |||
@@ -0,0 +1,5 @@ | |||
1 | This sensor driver needs to be converted to a regular | ||
2 | v4l2 subdev driver. The soc_camera framework is deprecated and | ||
3 | will be removed in the future. Unless someone does this work this | ||
4 | sensor driver will be deleted when the soc_camera framework is | ||
5 | deleted. | ||
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/staging/media/mt9t031/mt9t031.c index 4802d30e47de..4802d30e47de 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/staging/media/mt9t031/mt9t031.c | |||
diff --git a/include/dt-bindings/media/tda1997x.h b/include/dt-bindings/media/tda1997x.h new file mode 100644 index 000000000000..bd9fbd718ec9 --- /dev/null +++ b/include/dt-bindings/media/tda1997x.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Gateworks Corporation | ||
4 | */ | ||
5 | #ifndef _DT_BINDINGS_MEDIA_TDA1997X_H | ||
6 | #define _DT_BINDINGS_MEDIA_TDA1997X_H | ||
7 | |||
8 | /* TDA19973 36bit Video Port control registers */ | ||
9 | #define TDA1997X_VP36_35_32 0 | ||
10 | #define TDA1997X_VP36_31_28 1 | ||
11 | #define TDA1997X_VP36_27_24 2 | ||
12 | #define TDA1997X_VP36_23_20 3 | ||
13 | #define TDA1997X_VP36_19_16 4 | ||
14 | #define TDA1997X_VP36_15_12 5 | ||
15 | #define TDA1997X_VP36_11_08 6 | ||
16 | #define TDA1997X_VP36_07_04 7 | ||
17 | #define TDA1997X_VP36_03_00 8 | ||
18 | |||
19 | /* TDA19971 24bit Video Port control registers */ | ||
20 | #define TDA1997X_VP24_V23_20 0 | ||
21 | #define TDA1997X_VP24_V19_16 1 | ||
22 | #define TDA1997X_VP24_V15_12 3 | ||
23 | #define TDA1997X_VP24_V11_08 4 | ||
24 | #define TDA1997X_VP24_V07_04 6 | ||
25 | #define TDA1997X_VP24_V03_00 7 | ||
26 | |||
27 | /* Pin groups */ | ||
28 | #define TDA1997X_VP_OUT_EN 0x80 /* enable output group */ | ||
29 | #define TDA1997X_VP_HIZ 0x40 /* hi-Z output group when not used */ | ||
30 | #define TDA1997X_VP_SWP 0x10 /* pin-swap output group */ | ||
31 | #define TDA1997X_R_CR_CBCR_3_0 (0 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
32 | #define TDA1997X_R_CR_CBCR_7_4 (1 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
33 | #define TDA1997X_R_CR_CBCR_11_8 (2 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
34 | #define TDA1997X_B_CB_3_0 (3 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
35 | #define TDA1997X_B_CB_7_4 (4 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
36 | #define TDA1997X_B_CB_11_8 (5 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
37 | #define TDA1997X_G_Y_3_0 (6 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
38 | #define TDA1997X_G_Y_7_4 (7 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
39 | #define TDA1997X_G_Y_11_8 (8 | TDA1997X_VP_OUT_EN | TDA1997X_VP_HIZ) | ||
40 | /* pinswapped groups */ | ||
41 | #define TDA1997X_R_CR_CBCR_3_0_S (TDA1997X_R_CR_CBCR_3_0 | TDA1997X_VP_SWAP) | ||
42 | #define TDA1997X_R_CR_CBCR_7_4_S (TDA1997X_R_CR_CBCR_7_4 | TDA1997X_VP_SWAP) | ||
43 | #define TDA1997X_R_CR_CBCR_11_8_S (TDA1997X_R_CR_CBCR_11_8 | TDA1997X_VP_SWAP) | ||
44 | #define TDA1997X_B_CB_3_0_S (TDA1997X_B_CB_3_0 | TDA1997X_VP_SWAP) | ||
45 | #define TDA1997X_B_CB_7_4_S (TDA1997X_B_CB_7_4 | TDA1997X_VP_SWAP) | ||
46 | #define TDA1997X_B_CB_11_8_S (TDA1997X_B_CB_11_8 | TDA1997X_VP_SWAP) | ||
47 | #define TDA1997X_G_Y_3_0_S (TDA1997X_G_Y_3_0 | TDA1997X_VP_SWAP) | ||
48 | #define TDA1997X_G_Y_7_4_S (TDA1997X_G_Y_7_4 | TDA1997X_VP_SWAP) | ||
49 | #define TDA1997X_G_Y_11_8_S (TDA1997X_G_Y_11_8 | TDA1997X_VP_SWAP) | ||
50 | |||
51 | /* Audio bus DAI format */ | ||
52 | #define TDA1997X_I2S16 1 /* I2S 16bit */ | ||
53 | #define TDA1997X_I2S32 2 /* I2S 32bit */ | ||
54 | #define TDA1997X_SPDIF 3 /* SPDIF */ | ||
55 | #define TDA1997X_OBA 4 /* One Bit Audio */ | ||
56 | #define TDA1997X_DST 5 /* Direct Stream Transfer */ | ||
57 | #define TDA1997X_I2S16_HBR 6 /* HBR straight in I2S 16bit mode */ | ||
58 | #define TDA1997X_I2S16_HBR_DEMUX 7 /* HBR demux in I2S 16bit mode */ | ||
59 | #define TDA1997X_I2S32_HBR_DEMUX 8 /* HBR demux in I2S 32bit mode */ | ||
60 | #define TDA1997X_SPDIF_HBR_DEMUX 9 /* HBR demux in SPDIF mode */ | ||
61 | |||
62 | /* Audio bus channel layout */ | ||
63 | #define TDA1997X_LAYOUT0 0 /* 2-channel */ | ||
64 | #define TDA1997X_LAYOUT1 1 /* 8-channel */ | ||
65 | |||
66 | /* Audio bus clock */ | ||
67 | #define TDA1997X_ACLK_16FS 0 | ||
68 | #define TDA1997X_ACLK_32FS 1 | ||
69 | #define TDA1997X_ACLK_64FS 2 | ||
70 | #define TDA1997X_ACLK_128FS 3 | ||
71 | #define TDA1997X_ACLK_256FS 4 | ||
72 | #define TDA1997X_ACLK_512FS 5 | ||
73 | |||
74 | #endif /* _DT_BINDINGS_MEDIA_TDA1997X_H */ | ||
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index 57ec319a7f44..cf0add70b0e7 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h | |||
@@ -1,21 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cec-notifier.h - notify CEC drivers of physical address changes | 3 | * cec-notifier.h - notify CEC drivers of physical address changes |
3 | * | 4 | * |
4 | * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk> | 5 | * Copyright 2016 Russell King <rmk+kernel@arm.linux.org.uk> |
5 | * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 6 | * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | */ | 7 | */ |
20 | 8 | ||
21 | #ifndef LINUX_CEC_NOTIFIER_H | 9 | #ifndef LINUX_CEC_NOTIFIER_H |
diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h index 83b3e17e0a07..ed16c6dde0ba 100644 --- a/include/media/cec-pin.h +++ b/include/media/cec-pin.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cec-pin.h - low-level CEC pin control | 3 | * cec-pin.h - low-level CEC pin control |
3 | * | 4 | * |
4 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef LINUX_CEC_PIN_H | 8 | #ifndef LINUX_CEC_PIN_H |
diff --git a/include/media/cec.h b/include/media/cec.h index 7cdf71d7125a..580ab1042898 100644 --- a/include/media/cec.h +++ b/include/media/cec.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * cec - HDMI Consumer Electronics Control support header | 3 | * cec - HDMI Consumer Electronics Control support header |
3 | * | 4 | * |
4 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _MEDIA_CEC_H | 8 | #ifndef _MEDIA_CEC_H |
@@ -104,7 +92,7 @@ struct cec_fh { | |||
104 | wait_queue_head_t wait; | 92 | wait_queue_head_t wait; |
105 | struct mutex lock; | 93 | struct mutex lock; |
106 | struct list_head events[CEC_NUM_EVENTS]; /* queued events */ | 94 | struct list_head events[CEC_NUM_EVENTS]; /* queued events */ |
107 | u8 queued_events[CEC_NUM_EVENTS]; | 95 | u16 queued_events[CEC_NUM_EVENTS]; |
108 | unsigned int total_queued_events; | 96 | unsigned int total_queued_events; |
109 | struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS]; | 97 | struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS]; |
110 | struct list_head msgs; /* queued messages */ | 98 | struct list_head msgs; /* queued messages */ |
@@ -129,6 +117,10 @@ struct cec_adap_ops { | |||
129 | void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); | 117 | void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); |
130 | void (*adap_free)(struct cec_adapter *adap); | 118 | void (*adap_free)(struct cec_adapter *adap); |
131 | 119 | ||
120 | /* Error injection callbacks */ | ||
121 | int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); | ||
122 | bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); | ||
123 | |||
132 | /* High-level CEC message callback */ | 124 | /* High-level CEC message callback */ |
133 | int (*received)(struct cec_adapter *adap, struct cec_msg *msg); | 125 | int (*received)(struct cec_adapter *adap, struct cec_msg *msg); |
134 | }; | 126 | }; |
@@ -201,6 +193,7 @@ struct cec_adapter { | |||
201 | 193 | ||
202 | struct dentry *cec_dir; | 194 | struct dentry *cec_dir; |
203 | struct dentry *status_file; | 195 | struct dentry *status_file; |
196 | struct dentry *error_inj_file; | ||
204 | 197 | ||
205 | u16 phys_addrs[15]; | 198 | u16 phys_addrs[15]; |
206 | u32 sequence; | 199 | u32 sequence; |
@@ -298,11 +291,12 @@ static inline void cec_received_msg(struct cec_adapter *adap, | |||
298 | * | 291 | * |
299 | * @adap: pointer to the cec adapter | 292 | * @adap: pointer to the cec adapter |
300 | * @is_high: when true the CEC pin is high, otherwise it is low | 293 | * @is_high: when true the CEC pin is high, otherwise it is low |
294 | * @dropped_events: when true some events were dropped | ||
301 | * @ts: the timestamp for this event | 295 | * @ts: the timestamp for this event |
302 | * | 296 | * |
303 | */ | 297 | */ |
304 | void cec_queue_pin_cec_event(struct cec_adapter *adap, | 298 | void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, |
305 | bool is_high, ktime_t ts); | 299 | bool dropped_events, ktime_t ts); |
306 | 300 | ||
307 | /** | 301 | /** |
308 | * cec_queue_pin_hpd_event() - queue a pin event with a given timestamp. | 302 | * cec_queue_pin_hpd_event() - queue a pin event with a given timestamp. |
diff --git a/include/media/drv-intf/renesas-ceu.h b/include/media/drv-intf/renesas-ceu.h new file mode 100644 index 000000000000..52841d1b4763 --- /dev/null +++ b/include/media/drv-intf/renesas-ceu.h | |||
@@ -0,0 +1,26 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * renesas-ceu.h - Renesas CEU driver interface | ||
4 | * | ||
5 | * Copyright 2017-2018 Jacopo Mondi <jacopo+renesas@jmondi.org> | ||
6 | */ | ||
7 | |||
8 | #ifndef __MEDIA_DRV_INTF_RENESAS_CEU_H__ | ||
9 | #define __MEDIA_DRV_INTF_RENESAS_CEU_H__ | ||
10 | |||
11 | #define CEU_MAX_SUBDEVS 2 | ||
12 | |||
13 | struct ceu_async_subdev { | ||
14 | unsigned long flags; | ||
15 | unsigned char bus_width; | ||
16 | unsigned char bus_shift; | ||
17 | unsigned int i2c_adapter_id; | ||
18 | unsigned int i2c_address; | ||
19 | }; | ||
20 | |||
21 | struct ceu_platform_data { | ||
22 | unsigned int num_subdevs; | ||
23 | struct ceu_async_subdev subdevs[CEU_MAX_SUBDEVS]; | ||
24 | }; | ||
25 | |||
26 | #endif /* ___MEDIA_DRV_INTF_RENESAS_CEU_H__ */ | ||
diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h index 554db879527f..ee91516ad074 100644 --- a/include/media/dvbdev.h +++ b/include/media/dvbdev.h | |||
@@ -358,7 +358,61 @@ long dvb_generic_ioctl(struct file *file, | |||
358 | int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | 358 | int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, |
359 | int (*func)(struct file *file, unsigned int cmd, void *arg)); | 359 | int (*func)(struct file *file, unsigned int cmd, void *arg)); |
360 | 360 | ||
361 | /** generic DVB attach function. */ | 361 | #if IS_ENABLED(CONFIG_I2C) |
362 | |||
363 | struct i2c_adapter; | ||
364 | struct i2c_client; | ||
365 | /** | ||
366 | * dvb_module_probe - helper routine to probe an I2C module | ||
367 | * | ||
368 | * @module_name: | ||
369 | * Name of the I2C module to be probed | ||
370 | * @name: | ||
371 | * Optional name for the I2C module. Used for debug purposes. | ||
372 | * If %NULL, defaults to @module_name. | ||
373 | * @adap: | ||
374 | * pointer to &struct i2c_adapter that describes the I2C adapter where | ||
375 | * the module will be bound. | ||
376 | * @addr: | ||
377 | * I2C address of the adapter, in 7-bit notation. | ||
378 | * @platform_data: | ||
379 | * Platform data to be passed to the I2C module probed. | ||
380 | * | ||
381 | * This function binds an I2C device into the DVB core. Should be used by | ||
382 | * all drivers that use I2C bus to control the hardware. A module bound | ||
383 | * with dvb_module_probe() should use dvb_module_release() to unbind. | ||
384 | * | ||
385 | * Return: | ||
386 | * On success, return an &struct i2c_client, pointing the the bound | ||
387 | * I2C device. %NULL otherwise. | ||
388 | * | ||
389 | * .. note:: | ||
390 | * | ||
391 | * In the past, DVB modules (mainly, frontends) were bound via dvb_attach() | ||
392 | * macro, with does an ugly hack, using I2C low level functions. Such | ||
393 | * usage is deprecated and will be removed soon. Instead, use this routine. | ||
394 | */ | ||
395 | struct i2c_client *dvb_module_probe(const char *module_name, | ||
396 | const char *name, | ||
397 | struct i2c_adapter *adap, | ||
398 | unsigned char addr, | ||
399 | void *platform_data); | ||
400 | |||
401 | /** | ||
402 | * dvb_module_release - releases an I2C device allocated with | ||
403 | * dvb_module_probe(). | ||
404 | * | ||
405 | * @client: pointer to &struct i2c_client with the I2C client to be released. | ||
406 | * can be %NULL. | ||
407 | * | ||
408 | * This function should be used to free all resources reserved by | ||
409 | * dvb_module_probe() and unbinding the I2C hardware. | ||
410 | */ | ||
411 | void dvb_module_release(struct i2c_client *client); | ||
412 | |||
413 | #endif /* CONFIG_I2C */ | ||
414 | |||
415 | /* Legacy generic DVB attach function. */ | ||
362 | #ifdef CONFIG_MEDIA_ATTACH | 416 | #ifdef CONFIG_MEDIA_ATTACH |
363 | 417 | ||
364 | /** | 418 | /** |
@@ -371,6 +425,13 @@ int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
371 | * the @FUNCTION function there, with @ARGS. | 425 | * the @FUNCTION function there, with @ARGS. |
372 | * As it increments symbol usage cont, at unregister, dvb_detach() | 426 | * As it increments symbol usage cont, at unregister, dvb_detach() |
373 | * should be called. | 427 | * should be called. |
428 | * | ||
429 | * .. note:: | ||
430 | * | ||
431 | * In the past, DVB modules (mainly, frontends) were bound via dvb_attach() | ||
432 | * macro, with does an ugly hack, using I2C low level functions. Such | ||
433 | * usage is deprecated and will be removed soon. Instead, you should use | ||
434 | * dvb_module_probe(). | ||
374 | */ | 435 | */ |
375 | #define dvb_attach(FUNCTION, ARGS...) ({ \ | 436 | #define dvb_attach(FUNCTION, ARGS...) ({ \ |
376 | void *__r = NULL; \ | 437 | void *__r = NULL; \ |
@@ -402,6 +463,6 @@ int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | |||
402 | 463 | ||
403 | #define dvb_detach(FUNC) {} | 464 | #define dvb_detach(FUNC) {} |
404 | 465 | ||
405 | #endif | 466 | #endif /* CONFIG_MEDIA_ATTACH */ |
406 | 467 | ||
407 | #endif /* #ifndef _DVBDEV_H_ */ | 468 | #endif /* #ifndef _DVBDEV_H_ */ |
diff --git a/include/media/i2c/ad9389b.h b/include/media/i2c/ad9389b.h index 5ba9af869b8b..30f9ea9a1273 100644 --- a/include/media/i2c/ad9389b.h +++ b/include/media/i2c/ad9389b.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Analog Devices AD9389B/AD9889B video encoder driver header | 3 | * Analog Devices AD9389B/AD9889B video encoder driver header |
3 | * | 4 | * |
4 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef AD9389B_H | 8 | #ifndef AD9389B_H |
diff --git a/include/media/i2c/adv7511.h b/include/media/i2c/adv7511.h index 61c3d711cc69..1874c05f486f 100644 --- a/include/media/i2c/adv7511.h +++ b/include/media/i2c/adv7511.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Analog Devices ADV7511 HDMI Transmitter Device Driver | 3 | * Analog Devices ADV7511 HDMI Transmitter Device Driver |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef ADV7511_H | 8 | #ifndef ADV7511_H |
diff --git a/include/media/i2c/adv7604.h b/include/media/i2c/adv7604.h index 2e6857dee0cc..77a9799128b6 100644 --- a/include/media/i2c/adv7604.h +++ b/include/media/i2c/adv7604.h | |||
@@ -1,21 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * adv7604 - Analog Devices ADV7604 video decoder driver | 3 | * adv7604 - Analog Devices ADV7604 video decoder driver |
3 | * | 4 | * |
4 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 6 | */ |
20 | 7 | ||
21 | #ifndef _ADV7604_ | 8 | #ifndef _ADV7604_ |
diff --git a/include/media/i2c/adv7842.h b/include/media/i2c/adv7842.h index 7f53ada9bdf1..05e01f0dd3c2 100644 --- a/include/media/i2c/adv7842.h +++ b/include/media/i2c/adv7842.h | |||
@@ -1,21 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * adv7842 - Analog Devices ADV7842 video decoder driver | 3 | * adv7842 - Analog Devices ADV7842 video decoder driver |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 6 | */ |
20 | 7 | ||
21 | #ifndef _ADV7842_ | 8 | #ifndef _ADV7842_ |
diff --git a/include/media/i2c/mt9t112.h b/include/media/i2c/mt9t112.h index a43c74ab05ec..cc80d5cc2104 100644 --- a/include/media/i2c/mt9t112.h +++ b/include/media/i2c/mt9t112.h | |||
@@ -1,28 +1,25 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* mt9t112 Camera | 2 | /* mt9t112 Camera |
2 | * | 3 | * |
3 | * Copyright (C) 2009 Renesas Solutions Corp. | 4 | * Copyright (C) 2009 Renesas Solutions Corp. |
4 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | 5 | * Kuninori Morimoto <morimoto.kuninori@renesas.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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | 6 | */ |
10 | 7 | ||
11 | #ifndef __MT9T112_H__ | 8 | #ifndef __MT9T112_H__ |
12 | #define __MT9T112_H__ | 9 | #define __MT9T112_H__ |
13 | 10 | ||
14 | #define MT9T112_FLAG_PCLK_RISING_EDGE (1 << 0) | ||
15 | #define MT9T112_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */ | ||
16 | |||
17 | struct mt9t112_pll_divider { | 11 | struct mt9t112_pll_divider { |
18 | u8 m, n; | 12 | u8 m, n; |
19 | u8 p1, p2, p3, p4, p5, p6, p7; | 13 | u8 p1, p2, p3, p4, p5, p6, p7; |
20 | }; | 14 | }; |
21 | 15 | ||
22 | /* | 16 | /** |
23 | * mt9t112 camera info | 17 | * mt9t112_platform_data - mt9t112 driver interface |
18 | * @flags: Sensor media bus configuration. | ||
19 | * @divider: Sensor PLL configuration | ||
24 | */ | 20 | */ |
25 | struct mt9t112_camera_info { | 21 | struct mt9t112_platform_data { |
22 | #define MT9T112_FLAG_PCLK_RISING_EDGE BIT(0) | ||
26 | u32 flags; | 23 | u32 flags; |
27 | struct mt9t112_pll_divider divider; | 24 | struct mt9t112_pll_divider divider; |
28 | }; | 25 | }; |
diff --git a/include/media/i2c/ov772x.h b/include/media/i2c/ov772x.h index 00dbb7c4feae..27d087baffc5 100644 --- a/include/media/i2c/ov772x.h +++ b/include/media/i2c/ov772x.h | |||
@@ -48,8 +48,10 @@ struct ov772x_edge_ctrl { | |||
48 | .threshold = (t & OV772X_EDGE_THRESHOLD_MASK), \ | 48 | .threshold = (t & OV772X_EDGE_THRESHOLD_MASK), \ |
49 | } | 49 | } |
50 | 50 | ||
51 | /* | 51 | /** |
52 | * ov772x camera info | 52 | * ov772x_camera_info - ov772x driver interface structure |
53 | * @flags: Sensor configuration flags | ||
54 | * @edgectrl: Sensor edge control | ||
53 | */ | 55 | */ |
54 | struct ov772x_camera_info { | 56 | struct ov772x_camera_info { |
55 | unsigned long flags; | 57 | unsigned long flags; |
diff --git a/include/media/i2c/tc358743.h b/include/media/i2c/tc358743.h index 4513f2f9cfbc..b343650c2948 100644 --- a/include/media/i2c/tc358743.h +++ b/include/media/i2c/tc358743.h | |||
@@ -1,22 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * tc358743 - Toshiba HDMI to CSI-2 bridge | 3 | * tc358743 - Toshiba HDMI to CSI-2 bridge |
3 | * | 4 | * |
4 | * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights | 5 | * Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * reserved. | ||
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
12 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
13 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
15 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
17 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
18 | * SOFTWARE. | ||
19 | * | ||
20 | */ | 6 | */ |
21 | 7 | ||
22 | /* | 8 | /* |
diff --git a/include/media/i2c/tda1997x.h b/include/media/i2c/tda1997x.h new file mode 100644 index 000000000000..c6c2a8ae413d --- /dev/null +++ b/include/media/i2c/tda1997x.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * tda1997x - NXP HDMI receiver | ||
4 | * | ||
5 | * Copyright 2017 Tim Harvey <tharvey@gateworks.com> | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #ifndef _TDA1997X_ | ||
10 | #define _TDA1997X_ | ||
11 | |||
12 | /* Platform Data */ | ||
13 | struct tda1997x_platform_data { | ||
14 | enum v4l2_mbus_type vidout_bus_type; | ||
15 | u32 vidout_bus_width; | ||
16 | u8 vidout_port_cfg[9]; | ||
17 | /* pin polarity (1=invert) */ | ||
18 | bool vidout_inv_de; | ||
19 | bool vidout_inv_hs; | ||
20 | bool vidout_inv_vs; | ||
21 | bool vidout_inv_pclk; | ||
22 | /* clock delays (0=-8, 1=-7 ... 15=+7 pixels) */ | ||
23 | u8 vidout_delay_hs; | ||
24 | u8 vidout_delay_vs; | ||
25 | u8 vidout_delay_de; | ||
26 | u8 vidout_delay_pclk; | ||
27 | /* sync selections (controls how sync pins are derived) */ | ||
28 | u8 vidout_sel_hs; | ||
29 | u8 vidout_sel_vs; | ||
30 | u8 vidout_sel_de; | ||
31 | |||
32 | /* Audio Port Output */ | ||
33 | int audout_format; | ||
34 | u32 audout_mclk_fs; /* clock multiplier */ | ||
35 | u32 audout_width; /* 13 or 32 bit */ | ||
36 | u32 audout_layout; /* layout0=AP0 layout1=AP0,AP1,AP2,AP3 */ | ||
37 | bool audout_layoutauto; /* audio layout dictated by pkt header */ | ||
38 | bool audout_invert_clk; /* data valid on rising edge of BCLK */ | ||
39 | bool audio_auto_mute; /* enable hardware audio auto-mute */ | ||
40 | }; | ||
41 | |||
42 | #endif | ||
diff --git a/include/media/i2c/ths7303.h b/include/media/i2c/ths7303.h index 834e2f95b630..95492d12786d 100644 --- a/include/media/i2c/ths7303.h +++ b/include/media/i2c/ths7303.h | |||
@@ -1,3 +1,4 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * Copyright (C) 2013 Texas Instruments Inc | 3 | * Copyright (C) 2013 Texas Instruments Inc |
3 | * | 4 | * |
@@ -7,15 +8,6 @@ | |||
7 | * Hans Verkuil <hans.verkuil@cisco.com> | 8 | * Hans Verkuil <hans.verkuil@cisco.com> |
8 | * Lad, Prabhakar <prabhakar.lad@ti.com> | 9 | * Lad, Prabhakar <prabhakar.lad@ti.com> |
9 | * Martin Bugge <marbugge@cisco.com> | 10 | * Martin Bugge <marbugge@cisco.com> |
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation version 2. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | 11 | */ |
20 | 12 | ||
21 | #ifndef THS7353_H | 13 | #ifndef THS7353_H |
diff --git a/include/media/i2c/tw9910.h b/include/media/i2c/tw9910.h index 90bcf1fa5421..bec8f7bce745 100644 --- a/include/media/i2c/tw9910.h +++ b/include/media/i2c/tw9910.h | |||
@@ -18,6 +18,9 @@ | |||
18 | 18 | ||
19 | #include <media/soc_camera.h> | 19 | #include <media/soc_camera.h> |
20 | 20 | ||
21 | /** | ||
22 | * tw9910_mpout_pin - MPOUT (multi-purpose output) pin functions | ||
23 | */ | ||
21 | enum tw9910_mpout_pin { | 24 | enum tw9910_mpout_pin { |
22 | TW9910_MPO_VLOSS, | 25 | TW9910_MPO_VLOSS, |
23 | TW9910_MPO_HLOCK, | 26 | TW9910_MPO_HLOCK, |
@@ -29,6 +32,12 @@ enum tw9910_mpout_pin { | |||
29 | TW9910_MPO_RTCO, | 32 | TW9910_MPO_RTCO, |
30 | }; | 33 | }; |
31 | 34 | ||
35 | /** | ||
36 | * tw9910_video_info - tw9910 driver interface structure | ||
37 | * @buswidth: Parallel data bus width (8 or 16). | ||
38 | * @mpout: Selected function of MPOUT (multi-purpose output) pin. | ||
39 | * See &enum tw9910_mpout_pin | ||
40 | */ | ||
32 | struct tw9910_video_info { | 41 | struct tw9910_video_info { |
33 | unsigned long buswidth; | 42 | unsigned long buswidth; |
34 | enum tw9910_mpout_pin mpout; | 43 | enum tw9910_mpout_pin mpout; |
diff --git a/include/media/i2c/uda1342.h b/include/media/i2c/uda1342.h index cd156403a368..cb412d4c1088 100644 --- a/include/media/i2c/uda1342.h +++ b/include/media/i2c/uda1342.h | |||
@@ -1,21 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * uda1342.h - definition for uda1342 inputs | 3 | * uda1342.h - definition for uda1342 inputs |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 6 | */ |
20 | 7 | ||
21 | #ifndef _UDA1342_H_ | 8 | #ifndef _UDA1342_H_ |
diff --git a/include/media/rc-core.h b/include/media/rc-core.h index aed4272d47f5..6742fd86ff65 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h | |||
@@ -23,13 +23,6 @@ | |||
23 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
24 | #include <media/rc-map.h> | 24 | #include <media/rc-map.h> |
25 | 25 | ||
26 | extern int rc_core_debug; | ||
27 | #define IR_dprintk(level, fmt, ...) \ | ||
28 | do { \ | ||
29 | if (rc_core_debug >= level) \ | ||
30 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | ||
31 | } while (0) | ||
32 | |||
33 | /** | 26 | /** |
34 | * enum rc_driver_type - type of the RC driver. | 27 | * enum rc_driver_type - type of the RC driver. |
35 | * | 28 | * |
@@ -341,7 +334,9 @@ void ir_raw_event_handle(struct rc_dev *dev); | |||
341 | int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); | 334 | int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); |
342 | int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse); | 335 | int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse); |
343 | int ir_raw_event_store_with_filter(struct rc_dev *dev, | 336 | int ir_raw_event_store_with_filter(struct rc_dev *dev, |
344 | struct ir_raw_event *ev); | 337 | struct ir_raw_event *ev); |
338 | int ir_raw_event_store_with_timeout(struct rc_dev *dev, | ||
339 | struct ir_raw_event *ev); | ||
345 | void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); | 340 | void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); |
346 | int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, | 341 | int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, |
347 | struct ir_raw_event *events, unsigned int max); | 342 | struct ir_raw_event *events, unsigned int max); |
diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 7046734b3895..bfa3017cecba 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #define RC_PROTO_BIT_SHARP BIT_ULL(RC_PROTO_SHARP) | 36 | #define RC_PROTO_BIT_SHARP BIT_ULL(RC_PROTO_SHARP) |
37 | #define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP) | 37 | #define RC_PROTO_BIT_XMP BIT_ULL(RC_PROTO_XMP) |
38 | #define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) | 38 | #define RC_PROTO_BIT_CEC BIT_ULL(RC_PROTO_CEC) |
39 | #define RC_PROTO_BIT_IMON BIT_ULL(RC_PROTO_IMON) | ||
39 | 40 | ||
40 | #define RC_PROTO_BIT_ALL \ | 41 | #define RC_PROTO_BIT_ALL \ |
41 | (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ | 42 | (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ |
@@ -49,7 +50,8 @@ | |||
49 | RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ | 50 | RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ |
50 | RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ | 51 | RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ |
51 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ | 52 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ |
52 | RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC) | 53 | RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ |
54 | RC_PROTO_BIT_IMON) | ||
53 | /* All rc protocols for which we have decoders */ | 55 | /* All rc protocols for which we have decoders */ |
54 | #define RC_PROTO_BIT_ALL_IR_DECODER \ | 56 | #define RC_PROTO_BIT_ALL_IR_DECODER \ |
55 | (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ | 57 | (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ |
@@ -62,7 +64,7 @@ | |||
62 | RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ | 64 | RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ |
63 | RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ | 65 | RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \ |
64 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ | 66 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ |
65 | RC_PROTO_BIT_XMP) | 67 | RC_PROTO_BIT_XMP | RC_PROTO_BIT_IMON) |
66 | 68 | ||
67 | #define RC_PROTO_BIT_ALL_IR_ENCODER \ | 69 | #define RC_PROTO_BIT_ALL_IR_ENCODER \ |
68 | (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ | 70 | (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ |
@@ -75,7 +77,7 @@ | |||
75 | RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ | 77 | RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \ |
76 | RC_PROTO_BIT_RC6_6A_24 | \ | 78 | RC_PROTO_BIT_RC6_6A_24 | \ |
77 | RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ | 79 | RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | \ |
78 | RC_PROTO_BIT_SHARP) | 80 | RC_PROTO_BIT_SHARP | RC_PROTO_BIT_IMON) |
79 | 81 | ||
80 | #define RC_SCANCODE_UNKNOWN(x) (x) | 82 | #define RC_SCANCODE_UNKNOWN(x) (x) |
81 | #define RC_SCANCODE_OTHER(x) (x) | 83 | #define RC_SCANCODE_OTHER(x) (x) |
@@ -211,6 +213,7 @@ struct rc_map *rc_map_get(const char *name); | |||
211 | #define RC_MAP_HISI_TV_DEMO "rc-hisi-tv-demo" | 213 | #define RC_MAP_HISI_TV_DEMO "rc-hisi-tv-demo" |
212 | #define RC_MAP_IMON_MCE "rc-imon-mce" | 214 | #define RC_MAP_IMON_MCE "rc-imon-mce" |
213 | #define RC_MAP_IMON_PAD "rc-imon-pad" | 215 | #define RC_MAP_IMON_PAD "rc-imon-pad" |
216 | #define RC_MAP_IMON_RSC "rc-imon-rsc" | ||
214 | #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" | 217 | #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" |
215 | #define RC_MAP_IT913X_V1 "rc-it913x-v1" | 218 | #define RC_MAP_IT913X_V1 "rc-it913x-v1" |
216 | #define RC_MAP_IT913X_V2 "rc-it913x-v2" | 219 | #define RC_MAP_IT913X_V2 "rc-it913x-v2" |
diff --git a/include/media/tpg/v4l2-tpg.h b/include/media/tpg/v4l2-tpg.h index 823fadede7bf..eb191e85d363 100644 --- a/include/media/tpg/v4l2-tpg.h +++ b/include/media/tpg/v4l2-tpg.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * v4l2-tpg.h - Test Pattern Generator | 3 | * v4l2-tpg.h - Test Pattern Generator |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _V4L2_TPG_H_ | 8 | #ifndef _V4L2_TPG_H_ |
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index e0d95a7c5d48..54b689247937 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
@@ -316,21 +316,37 @@ void v4l_bound_align_image(unsigned int *width, unsigned int wmin, | |||
316 | unsigned int salign); | 316 | unsigned int salign); |
317 | 317 | ||
318 | /** | 318 | /** |
319 | * v4l2_find_nearest_format - find the nearest format size among a discrete | 319 | * v4l2_find_nearest_size - Find the nearest size among a discrete |
320 | * set of resolutions. | 320 | * set of resolutions contained in an array of a driver specific struct. |
321 | * | 321 | * |
322 | * @sizes: array of &struct v4l2_frmsize_discrete image sizes. | 322 | * @array: a driver specific array of image sizes |
323 | * @num_sizes: length of @sizes array. | 323 | * @width_field: the name of the width field in the driver specific struct |
324 | * @height_field: the name of the height field in the driver specific struct | ||
324 | * @width: desired width. | 325 | * @width: desired width. |
325 | * @height: desired height. | 326 | * @height: desired height. |
326 | * | 327 | * |
327 | * Finds the closest resolution to minimize the width and height differences | 328 | * Finds the closest resolution to minimize the width and height differences |
328 | * between what requested and the supported resolutions. | 329 | * between what requested and the supported resolutions. The size of the width |
330 | * and height fields in the driver specific must equal to that of u32, i.e. four | ||
331 | * bytes. | ||
332 | * | ||
333 | * Returns the best match or NULL if the length of the array is zero. | ||
329 | */ | 334 | */ |
330 | const struct v4l2_frmsize_discrete * | 335 | #define v4l2_find_nearest_size(array, width_field, height_field, \ |
331 | v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes, | 336 | width, height) \ |
332 | const size_t num_sizes, | 337 | ({ \ |
333 | s32 width, s32 height); | 338 | BUILD_BUG_ON(sizeof((array)->width_field) != sizeof(u32) || \ |
339 | sizeof((array)->height_field) != sizeof(u32)); \ | ||
340 | (typeof(&(*(array))))__v4l2_find_nearest_size( \ | ||
341 | (array), ARRAY_SIZE(array), sizeof(*(array)), \ | ||
342 | offsetof(typeof(*(array)), width_field), \ | ||
343 | offsetof(typeof(*(array)), height_field), \ | ||
344 | width, height); \ | ||
345 | }) | ||
346 | const void * | ||
347 | __v4l2_find_nearest_size(const void *array, size_t array_size, | ||
348 | size_t entry_size, size_t width_offset, | ||
349 | size_t height_offset, s32 width, s32 height); | ||
334 | 350 | ||
335 | /** | 351 | /** |
336 | * v4l2_get_timestamp - helper routine to get a timestamp to be used when | 352 | * v4l2_get_timestamp - helper routine to get a timestamp to be used when |
@@ -341,4 +357,30 @@ v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes, | |||
341 | */ | 357 | */ |
342 | void v4l2_get_timestamp(struct timeval *tv); | 358 | void v4l2_get_timestamp(struct timeval *tv); |
343 | 359 | ||
360 | /** | ||
361 | * v4l2_g_parm_cap - helper routine for vidioc_g_parm to fill this in by | ||
362 | * calling the g_frame_interval op of the given subdev. It only works | ||
363 | * for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the | ||
364 | * function name. | ||
365 | * | ||
366 | * @vdev: the struct video_device pointer. Used to determine the device caps. | ||
367 | * @sd: the sub-device pointer. | ||
368 | * @a: the VIDIOC_G_PARM argument. | ||
369 | */ | ||
370 | int v4l2_g_parm_cap(struct video_device *vdev, | ||
371 | struct v4l2_subdev *sd, struct v4l2_streamparm *a); | ||
372 | |||
373 | /** | ||
374 | * v4l2_s_parm_cap - helper routine for vidioc_s_parm to fill this in by | ||
375 | * calling the s_frame_interval op of the given subdev. It only works | ||
376 | * for V4L2_BUF_TYPE_VIDEO_CAPTURE(_MPLANE), hence the _cap in the | ||
377 | * function name. | ||
378 | * | ||
379 | * @vdev: the struct video_device pointer. Used to determine the device caps. | ||
380 | * @sd: the sub-device pointer. | ||
381 | * @a: the VIDIOC_S_PARM argument. | ||
382 | */ | ||
383 | int v4l2_s_parm_cap(struct video_device *vdev, | ||
384 | struct v4l2_subdev *sd, struct v4l2_streamparm *a); | ||
385 | |||
344 | #endif /* V4L2_COMMON_H_ */ | 386 | #endif /* V4L2_COMMON_H_ */ |
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 05ebb9ef9e73..5b445b5654f7 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h | |||
@@ -761,8 +761,8 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); | |||
761 | * An error is returned if one of the range arguments is invalid for this | 761 | * An error is returned if one of the range arguments is invalid for this |
762 | * control type. | 762 | * control type. |
763 | * | 763 | * |
764 | * This function assumes that the control handler is not locked and will | 764 | * The caller is responsible for acquiring the control handler mutex on behalf |
765 | * take the lock itself. | 765 | * of __v4l2_ctrl_modify_range(). |
766 | */ | 766 | */ |
767 | int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, | 767 | int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, |
768 | s64 min, s64 max, u64 step, s64 def); | 768 | s64 min, s64 max, u64 step, s64 def); |
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 53f32022fabe..27634e8d2585 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -298,10 +298,10 @@ struct video_device | |||
298 | * media_entity_to_video_device - Returns a &struct video_device from | 298 | * media_entity_to_video_device - Returns a &struct video_device from |
299 | * the &struct media_entity embedded on it. | 299 | * the &struct media_entity embedded on it. |
300 | * | 300 | * |
301 | * @entity: pointer to &struct media_entity | 301 | * @__entity: pointer to &struct media_entity |
302 | */ | 302 | */ |
303 | #define media_entity_to_video_device(entity) \ | 303 | #define media_entity_to_video_device(__entity) \ |
304 | container_of(entity, struct video_device, entity) | 304 | container_of(__entity, struct video_device, entity) |
305 | 305 | ||
306 | /** | 306 | /** |
307 | * to_video_device - Returns a &struct video_device from the | 307 | * to_video_device - Returns a &struct video_device from the |
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index ebf00e07a515..17cb27df1b81 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h | |||
@@ -1,21 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * v4l2-dv-timings - Internal header with dv-timings helper functions | 3 | * v4l2-dv-timings - Internal header with dv-timings helper functions |
3 | * | 4 | * |
4 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | * | ||
19 | */ | 6 | */ |
20 | 7 | ||
21 | #ifndef __V4L2_DV_TIMINGS_H | 8 | #ifndef __V4L2_DV_TIMINGS_H |
@@ -225,5 +212,26 @@ static inline bool can_reduce_fps(struct v4l2_bt_timings *bt) | |||
225 | return false; | 212 | return false; |
226 | } | 213 | } |
227 | 214 | ||
215 | /** | ||
216 | * struct v4l2_hdmi_rx_colorimetry - describes the HDMI colorimetry information | ||
217 | * @colorspace: enum v4l2_colorspace, the colorspace | ||
218 | * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding | ||
219 | * @quantization: enum v4l2_quantization, colorspace quantization | ||
220 | * @xfer_func: enum v4l2_xfer_func, colorspace transfer function | ||
221 | */ | ||
222 | struct v4l2_hdmi_colorimetry { | ||
223 | enum v4l2_colorspace colorspace; | ||
224 | enum v4l2_ycbcr_encoding ycbcr_enc; | ||
225 | enum v4l2_quantization quantization; | ||
226 | enum v4l2_xfer_func xfer_func; | ||
227 | }; | ||
228 | |||
229 | struct hdmi_avi_infoframe; | ||
230 | struct hdmi_vendor_infoframe; | ||
231 | |||
232 | struct v4l2_hdmi_colorimetry | ||
233 | v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi, | ||
234 | const struct hdmi_vendor_infoframe *hdmi, | ||
235 | unsigned int height); | ||
228 | 236 | ||
229 | #endif | 237 | #endif |
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h index 62633e7d2630..ea73fef8bdc0 100644 --- a/include/media/v4l2-fh.h +++ b/include/media/v4l2-fh.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define V4L2_FH_H | 22 | #define V4L2_FH_H |
23 | 23 | ||
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/kconfig.h> | ||
25 | #include <linux/list.h> | 26 | #include <linux/list.h> |
26 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
27 | 28 | ||
diff --git a/include/media/v4l2-rect.h b/include/media/v4l2-rect.h index d2125f0cc7cd..595c3ba05f23 100644 --- a/include/media/v4l2-rect.h +++ b/include/media/v4l2-rect.h | |||
@@ -1,20 +1,8 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
1 | /* | 2 | /* |
2 | * v4l2-rect.h - v4l2_rect helper functions | 3 | * v4l2-rect.h - v4l2_rect helper functions |
3 | * | 4 | * |
4 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
5 | * | ||
6 | * This program is free software; you may redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
17 | * SOFTWARE. | ||
18 | */ | 6 | */ |
19 | 7 | ||
20 | #ifndef _V4L2_RECT_H_ | 8 | #ifndef _V4L2_RECT_H_ |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 980a86c08fce..9102d6ca566e 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
@@ -224,6 +224,9 @@ struct v4l2_subdev_core_ops { | |||
224 | * struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened | 224 | * struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened |
225 | * in radio mode. | 225 | * in radio mode. |
226 | * | 226 | * |
227 | * @standby: puts the tuner in standby mode. It will be woken up | ||
228 | * automatically the next time it is used. | ||
229 | * | ||
227 | * @s_radio: callback that switches the tuner to radio mode. | 230 | * @s_radio: callback that switches the tuner to radio mode. |
228 | * drivers should explicitly call it when a tuner ops should | 231 | * drivers should explicitly call it when a tuner ops should |
229 | * operate on radio mode, before being able to handle it. | 232 | * operate on radio mode, before being able to handle it. |
@@ -268,6 +271,7 @@ struct v4l2_subdev_core_ops { | |||
268 | * } | 271 | * } |
269 | */ | 272 | */ |
270 | struct v4l2_subdev_tuner_ops { | 273 | struct v4l2_subdev_tuner_ops { |
274 | int (*standby)(struct v4l2_subdev *sd); | ||
271 | int (*s_radio)(struct v4l2_subdev *sd); | 275 | int (*s_radio)(struct v4l2_subdev *sd); |
272 | int (*s_frequency)(struct v4l2_subdev *sd, const struct v4l2_frequency *freq); | 276 | int (*s_frequency)(struct v4l2_subdev *sd, const struct v4l2_frequency *freq); |
273 | int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); | 277 | int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); |
@@ -393,10 +397,6 @@ struct v4l2_mbus_frame_desc { | |||
393 | * | 397 | * |
394 | * @g_pixelaspect: callback to return the pixelaspect ratio. | 398 | * @g_pixelaspect: callback to return the pixelaspect ratio. |
395 | * | 399 | * |
396 | * @g_parm: callback for VIDIOC_G_PARM() ioctl handler code. | ||
397 | * | ||
398 | * @s_parm: callback for VIDIOC_S_PARM() ioctl handler code. | ||
399 | * | ||
400 | * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL() | 400 | * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL() |
401 | * ioctl handler code. | 401 | * ioctl handler code. |
402 | * | 402 | * |
@@ -434,8 +434,6 @@ struct v4l2_subdev_video_ops { | |||
434 | int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); | 434 | int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); |
435 | int (*s_stream)(struct v4l2_subdev *sd, int enable); | 435 | int (*s_stream)(struct v4l2_subdev *sd, int enable); |
436 | int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect); | 436 | int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect); |
437 | int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); | ||
438 | int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); | ||
439 | int (*g_frame_interval)(struct v4l2_subdev *sd, | 437 | int (*g_frame_interval)(struct v4l2_subdev *sd, |
440 | struct v4l2_subdev_frame_interval *interval); | 438 | struct v4l2_subdev_frame_interval *interval); |
441 | int (*s_frame_interval)(struct v4l2_subdev *sd, | 439 | int (*s_frame_interval)(struct v4l2_subdev *sd, |
@@ -867,6 +865,13 @@ struct v4l2_subdev { | |||
867 | struct v4l2_subdev_platform_data *pdata; | 865 | struct v4l2_subdev_platform_data *pdata; |
868 | }; | 866 | }; |
869 | 867 | ||
868 | |||
869 | /** | ||
870 | * media_entity_to_v4l2_subdev - Returns a &struct v4l2_subdev from | ||
871 | * the &struct media_entity embedded in it. | ||
872 | * | ||
873 | * @ent: pointer to &struct media_entity. | ||
874 | */ | ||
870 | #define media_entity_to_v4l2_subdev(ent) \ | 875 | #define media_entity_to_v4l2_subdev(ent) \ |
871 | ({ \ | 876 | ({ \ |
872 | typeof(ent) __me_sd_ent = (ent); \ | 877 | typeof(ent) __me_sd_ent = (ent); \ |
@@ -876,14 +881,20 @@ struct v4l2_subdev { | |||
876 | NULL; \ | 881 | NULL; \ |
877 | }) | 882 | }) |
878 | 883 | ||
884 | /** | ||
885 | * vdev_to_v4l2_subdev - Returns a &struct v4l2_subdev from | ||
886 | * the &struct video_device embedded on it. | ||
887 | * | ||
888 | * @vdev: pointer to &struct video_device | ||
889 | */ | ||
879 | #define vdev_to_v4l2_subdev(vdev) \ | 890 | #define vdev_to_v4l2_subdev(vdev) \ |
880 | ((struct v4l2_subdev *)video_get_drvdata(vdev)) | 891 | ((struct v4l2_subdev *)video_get_drvdata(vdev)) |
881 | 892 | ||
882 | /** | 893 | /** |
883 | * struct v4l2_subdev_fh - Used for storing subdev information per file handle | 894 | * struct v4l2_subdev_fh - Used for storing subdev information per file handle |
884 | * | 895 | * |
885 | * @vfh: pointer to struct v4l2_fh | 896 | * @vfh: pointer to &struct v4l2_fh |
886 | * @pad: pointer to v4l2_subdev_pad_config | 897 | * @pad: pointer to &struct v4l2_subdev_pad_config |
887 | */ | 898 | */ |
888 | struct v4l2_subdev_fh { | 899 | struct v4l2_subdev_fh { |
889 | struct v4l2_fh vfh; | 900 | struct v4l2_fh vfh; |
@@ -892,23 +903,70 @@ struct v4l2_subdev_fh { | |||
892 | #endif | 903 | #endif |
893 | }; | 904 | }; |
894 | 905 | ||
906 | /** | ||
907 | * to_v4l2_subdev_fh - Returns a &struct v4l2_subdev_fh from | ||
908 | * the &struct v4l2_fh embedded on it. | ||
909 | * | ||
910 | * @fh: pointer to &struct v4l2_fh | ||
911 | */ | ||
895 | #define to_v4l2_subdev_fh(fh) \ | 912 | #define to_v4l2_subdev_fh(fh) \ |
896 | container_of(fh, struct v4l2_subdev_fh, vfh) | 913 | container_of(fh, struct v4l2_subdev_fh, vfh) |
897 | 914 | ||
898 | #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) | 915 | #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) |
899 | #define __V4L2_SUBDEV_MK_GET_TRY(rtype, fun_name, field_name) \ | 916 | |
900 | static inline struct rtype * \ | 917 | /** |
901 | fun_name(struct v4l2_subdev *sd, \ | 918 | * v4l2_subdev_get_try_format - ancillary routine to call |
902 | struct v4l2_subdev_pad_config *cfg, \ | 919 | * &struct v4l2_subdev_pad_config->try_fmt |
903 | unsigned int pad) \ | 920 | * |
904 | { \ | 921 | * @sd: pointer to &struct v4l2_subdev |
905 | BUG_ON(pad >= sd->entity.num_pads); \ | 922 | * @cfg: pointer to &struct v4l2_subdev_pad_config array. |
906 | return &cfg[pad].field_name; \ | 923 | * @pad: index of the pad in the @cfg array. |
907 | } | 924 | */ |
908 | 925 | static inline struct v4l2_mbus_framefmt | |
909 | __V4L2_SUBDEV_MK_GET_TRY(v4l2_mbus_framefmt, v4l2_subdev_get_try_format, try_fmt) | 926 | *v4l2_subdev_get_try_format(struct v4l2_subdev *sd, |
910 | __V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, v4l2_subdev_get_try_crop, try_crop) | 927 | struct v4l2_subdev_pad_config *cfg, |
911 | __V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, v4l2_subdev_get_try_compose, try_compose) | 928 | unsigned int pad) |
929 | { | ||
930 | if (WARN_ON(pad >= sd->entity.num_pads)) | ||
931 | pad = 0; | ||
932 | return &cfg[pad].try_fmt; | ||
933 | } | ||
934 | |||
935 | /** | ||
936 | * v4l2_subdev_get_try_crop - ancillary routine to call | ||
937 | * &struct v4l2_subdev_pad_config->try_crop | ||
938 | * | ||
939 | * @sd: pointer to &struct v4l2_subdev | ||
940 | * @cfg: pointer to &struct v4l2_subdev_pad_config array. | ||
941 | * @pad: index of the pad in the @cfg array. | ||
942 | */ | ||
943 | static inline struct v4l2_rect | ||
944 | *v4l2_subdev_get_try_crop(struct v4l2_subdev *sd, | ||
945 | struct v4l2_subdev_pad_config *cfg, | ||
946 | unsigned int pad) | ||
947 | { | ||
948 | if (WARN_ON(pad >= sd->entity.num_pads)) | ||
949 | pad = 0; | ||
950 | return &cfg[pad].try_crop; | ||
951 | } | ||
952 | |||
953 | /** | ||
954 | * v4l2_subdev_get_try_crop - ancillary routine to call | ||
955 | * &struct v4l2_subdev_pad_config->try_compose | ||
956 | * | ||
957 | * @sd: pointer to &struct v4l2_subdev | ||
958 | * @cfg: pointer to &struct v4l2_subdev_pad_config array. | ||
959 | * @pad: index of the pad in the @cfg array. | ||
960 | */ | ||
961 | static inline struct v4l2_rect | ||
962 | *v4l2_subdev_get_try_compose(struct v4l2_subdev *sd, | ||
963 | struct v4l2_subdev_pad_config *cfg, | ||
964 | unsigned int pad) | ||
965 | { | ||
966 | if (WARN_ON(pad >= sd->entity.num_pads)) | ||
967 | pad = 0; | ||
968 | return &cfg[pad].try_compose; | ||
969 | } | ||
912 | #endif | 970 | #endif |
913 | 971 | ||
914 | extern const struct v4l2_file_operations v4l2_subdev_fops; | 972 | extern const struct v4l2_file_operations v4l2_subdev_fops; |
@@ -1016,9 +1074,16 @@ void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg); | |||
1016 | void v4l2_subdev_init(struct v4l2_subdev *sd, | 1074 | void v4l2_subdev_init(struct v4l2_subdev *sd, |
1017 | const struct v4l2_subdev_ops *ops); | 1075 | const struct v4l2_subdev_ops *ops); |
1018 | 1076 | ||
1019 | /* | 1077 | /** |
1020 | * Call an ops of a v4l2_subdev, doing the right checks against | 1078 | * v4l2_subdev_call - call an operation of a v4l2_subdev. |
1021 | * NULL pointers. | 1079 | * |
1080 | * @sd: pointer to the &struct v4l2_subdev | ||
1081 | * @o: name of the element at &struct v4l2_subdev_ops that contains @f. | ||
1082 | * Each element there groups a set of callbacks functions. | ||
1083 | * @f: callback function that will be called if @cond matches. | ||
1084 | * The callback functions are defined in groups, according to | ||
1085 | * each element at &struct v4l2_subdev_ops. | ||
1086 | * @args...: arguments for @f. | ||
1022 | * | 1087 | * |
1023 | * Example: err = v4l2_subdev_call(sd, video, s_std, norm); | 1088 | * Example: err = v4l2_subdev_call(sd, video, s_std, norm); |
1024 | */ | 1089 | */ |
@@ -1034,6 +1099,14 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, | |||
1034 | __result; \ | 1099 | __result; \ |
1035 | }) | 1100 | }) |
1036 | 1101 | ||
1102 | /** | ||
1103 | * v4l2_subdev_has_op - Checks if a subdev defines a certain operation. | ||
1104 | * | ||
1105 | * @sd: pointer to the &struct v4l2_subdev | ||
1106 | * @o: The group of callback functions in &struct v4l2_subdev_ops | ||
1107 | * which @f is a part of. | ||
1108 | * @f: callback function to be checked for its existence. | ||
1109 | */ | ||
1037 | #define v4l2_subdev_has_op(sd, o, f) \ | 1110 | #define v4l2_subdev_has_op(sd, o, f) \ |
1038 | ((sd)->ops->o && (sd)->ops->o->f) | 1111 | ((sd)->ops->o && (sd)->ops->o->f) |
1039 | 1112 | ||
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 5b6c541e4e1b..f6818f732f34 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h | |||
@@ -296,6 +296,9 @@ struct vb2_buffer { | |||
296 | /** | 296 | /** |
297 | * struct vb2_ops - driver-specific callbacks. | 297 | * struct vb2_ops - driver-specific callbacks. |
298 | * | 298 | * |
299 | * These operations are not called from interrupt context except where | ||
300 | * mentioned specifically. | ||
301 | * | ||
299 | * @queue_setup: called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS() | 302 | * @queue_setup: called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS() |
300 | * handlers before memory allocation. It can be called | 303 | * handlers before memory allocation. It can be called |
301 | * twice: if the original number of requested buffers | 304 | * twice: if the original number of requested buffers |
@@ -358,12 +361,12 @@ struct vb2_buffer { | |||
358 | * driver can return an error if hardware fails, in that | 361 | * driver can return an error if hardware fails, in that |
359 | * case all buffers that have been already given by | 362 | * case all buffers that have been already given by |
360 | * the @buf_queue callback are to be returned by the driver | 363 | * the @buf_queue callback are to be returned by the driver |
361 | * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED. | 364 | * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED |
362 | * If you need a minimum number of buffers before you can | 365 | * or %VB2_BUF_STATE_REQUEUEING. If you need a minimum |
363 | * start streaming, then set | 366 | * number of buffers before you can start streaming, then |
364 | * &vb2_queue->min_buffers_needed. If that is non-zero then | 367 | * set &vb2_queue->min_buffers_needed. If that is non-zero |
365 | * @start_streaming won't be called until at least that | 368 | * then @start_streaming won't be called until at least |
366 | * many buffers have been queued up by userspace. | 369 | * that many buffers have been queued up by userspace. |
367 | * @stop_streaming: called when 'streaming' state must be disabled; driver | 370 | * @stop_streaming: called when 'streaming' state must be disabled; driver |
368 | * should stop any DMA transactions or wait until they | 371 | * should stop any DMA transactions or wait until they |
369 | * finish and give back all buffers it got from &buf_queue | 372 | * finish and give back all buffers it got from &buf_queue |
@@ -601,10 +604,9 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); | |||
601 | * @state: state of the buffer, as defined by &enum vb2_buffer_state. | 604 | * @state: state of the buffer, as defined by &enum vb2_buffer_state. |
602 | * Either %VB2_BUF_STATE_DONE if the operation finished | 605 | * Either %VB2_BUF_STATE_DONE if the operation finished |
603 | * successfully, %VB2_BUF_STATE_ERROR if the operation finished | 606 | * successfully, %VB2_BUF_STATE_ERROR if the operation finished |
604 | * with an error or %VB2_BUF_STATE_QUEUED if the driver wants to | 607 | * with an error or any of %VB2_BUF_STATE_QUEUED or |
605 | * requeue buffers. If start_streaming fails then it should return | 608 | * %VB2_BUF_STATE_REQUEUEING if the driver wants to |
606 | * buffers with state %VB2_BUF_STATE_QUEUED to put them back into | 609 | * requeue buffers (see below). |
607 | * the queue. | ||
608 | * | 610 | * |
609 | * This function should be called by the driver after a hardware operation on | 611 | * This function should be called by the driver after a hardware operation on |
610 | * a buffer is finished and the buffer may be returned to userspace. The driver | 612 | * a buffer is finished and the buffer may be returned to userspace. The driver |
@@ -613,9 +615,14 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); | |||
613 | * to the driver by &vb2_ops->buf_queue can be passed to this function. | 615 | * to the driver by &vb2_ops->buf_queue can be passed to this function. |
614 | * | 616 | * |
615 | * While streaming a buffer can only be returned in state DONE or ERROR. | 617 | * While streaming a buffer can only be returned in state DONE or ERROR. |
616 | * The start_streaming op can also return them in case the DMA engine cannot | 618 | * The &vb2_ops->start_streaming op can also return them in case the DMA engine |
617 | * be started for some reason. In that case the buffers should be returned with | 619 | * cannot be started for some reason. In that case the buffers should be |
618 | * state QUEUED. | 620 | * returned with state QUEUED or REQUEUEING to put them back into the queue. |
621 | * | ||
622 | * %VB2_BUF_STATE_REQUEUEING is like %VB2_BUF_STATE_QUEUED, but it also calls | ||
623 | * &vb2_ops->buf_queue to queue buffers back to the driver. Note that calling | ||
624 | * vb2_buffer_done(..., VB2_BUF_STATE_REQUEUEING) from interrupt context will | ||
625 | * result in &vb2_ops->buf_queue being called in interrupt context as well. | ||
619 | */ | 626 | */ |
620 | void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); | 627 | void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); |
621 | 628 | ||
diff --git a/include/uapi/linux/cec-funcs.h b/include/uapi/linux/cec-funcs.h index 28e8a2a86e16..8997d5068c08 100644 --- a/include/uapi/linux/cec-funcs.h +++ b/include/uapi/linux/cec-funcs.h | |||
@@ -3,35 +3,6 @@ | |||
3 | * cec - HDMI Consumer Electronics Control message functions | 3 | * cec - HDMI Consumer Electronics Control message functions |
4 | * | 4 | * |
5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * Alternatively you can redistribute this file under the terms of the | ||
12 | * BSD license as stated below: | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * 2. Redistributions in binary form must reproduce the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer in | ||
21 | * the documentation and/or other materials provided with the | ||
22 | * distribution. | ||
23 | * 3. The names of its contributors may not be used to endorse or promote | ||
24 | * products derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
28 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
30 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
31 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
32 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
33 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
34 | * SOFTWARE. | ||
35 | */ | 6 | */ |
36 | 7 | ||
37 | #ifndef _CEC_UAPI_FUNCS_H | 8 | #ifndef _CEC_UAPI_FUNCS_H |
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index b51fbe1941a7..20fe091b7e96 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h | |||
@@ -3,35 +3,6 @@ | |||
3 | * cec - HDMI Consumer Electronics Control public header | 3 | * cec - HDMI Consumer Electronics Control public header |
4 | * | 4 | * |
5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. | 5 | * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. |
6 | * | ||
7 | * This program is free software; you may redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * Alternatively you can redistribute this file under the terms of the | ||
12 | * BSD license as stated below: | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * 2. Redistributions in binary form must reproduce the above copyright | ||
20 | * notice, this list of conditions and the following disclaimer in | ||
21 | * the documentation and/or other materials provided with the | ||
22 | * distribution. | ||
23 | * 3. The names of its contributors may not be used to endorse or promote | ||
24 | * products derived from this software without specific prior written | ||
25 | * permission. | ||
26 | * | ||
27 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
28 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
30 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
31 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
32 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
33 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
34 | * SOFTWARE. | ||
35 | */ | 6 | */ |
36 | 7 | ||
37 | #ifndef _CEC_UAPI_H | 8 | #ifndef _CEC_UAPI_H |
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index f5bf06ecd87d..f189931042a7 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h | |||
@@ -185,6 +185,7 @@ struct lirc_scancode { | |||
185 | * @RC_PROTO_SHARP: Sharp protocol | 185 | * @RC_PROTO_SHARP: Sharp protocol |
186 | * @RC_PROTO_XMP: XMP protocol | 186 | * @RC_PROTO_XMP: XMP protocol |
187 | * @RC_PROTO_CEC: CEC protocol | 187 | * @RC_PROTO_CEC: CEC protocol |
188 | * @RC_PROTO_IMON: iMon Pad protocol | ||
188 | */ | 189 | */ |
189 | enum rc_proto { | 190 | enum rc_proto { |
190 | RC_PROTO_UNKNOWN = 0, | 191 | RC_PROTO_UNKNOWN = 0, |
@@ -210,6 +211,7 @@ enum rc_proto { | |||
210 | RC_PROTO_SHARP = 20, | 211 | RC_PROTO_SHARP = 20, |
211 | RC_PROTO_XMP = 21, | 212 | RC_PROTO_XMP = 21, |
212 | RC_PROTO_CEC = 22, | 213 | RC_PROTO_CEC = 22, |
214 | RC_PROTO_IMON = 23, | ||
213 | }; | 215 | }; |
214 | 216 | ||
215 | #endif | 217 | #endif |
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index b9b9446095e9..c7e9a5cba24e 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h | |||
@@ -15,10 +15,6 @@ | |||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. | 17 | * GNU General Public License for more details. |
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | 18 | */ |
23 | 19 | ||
24 | #ifndef __LINUX_MEDIA_H | 20 | #ifndef __LINUX_MEDIA_H |
@@ -42,108 +38,66 @@ struct media_device_info { | |||
42 | __u32 reserved[31]; | 38 | __u32 reserved[31]; |
43 | }; | 39 | }; |
44 | 40 | ||
45 | #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) | ||
46 | |||
47 | /* | ||
48 | * Initial value to be used when a new entity is created | ||
49 | * Drivers should change it to something useful | ||
50 | */ | ||
51 | #define MEDIA_ENT_F_UNKNOWN 0x00000000 | ||
52 | |||
53 | /* | 41 | /* |
54 | * Base number ranges for entity functions | 42 | * Base number ranges for entity functions |
55 | * | 43 | * |
56 | * NOTE: those ranges and entity function number are phased just to | 44 | * NOTE: Userspace should not rely on these ranges to identify a group |
57 | * make it easier to maintain this file. Userspace should not rely on | 45 | * of function types, as newer functions can be added with any name within |
58 | * the ranges to identify a group of function types, as newer | 46 | * the full u32 range. |
59 | * functions can be added with any name within the full u32 range. | 47 | * |
60 | */ | 48 | * Some older functions use the MEDIA_ENT_F_OLD_*_BASE range. Do not |
61 | #define MEDIA_ENT_F_BASE 0x00000000 | 49 | * change this, this is for backwards compatibility. When adding new |
62 | #define MEDIA_ENT_F_OLD_BASE 0x00010000 | 50 | * functions always use MEDIA_ENT_F_BASE. |
63 | #define MEDIA_ENT_F_OLD_SUBDEV_BASE 0x00020000 | ||
64 | |||
65 | /* | ||
66 | * DVB entities | ||
67 | */ | 51 | */ |
68 | #define MEDIA_ENT_F_DTV_DEMOD (MEDIA_ENT_F_BASE + 0x00001) | 52 | #define MEDIA_ENT_F_BASE 0x00000000 |
69 | #define MEDIA_ENT_F_TS_DEMUX (MEDIA_ENT_F_BASE + 0x00002) | 53 | #define MEDIA_ENT_F_OLD_BASE 0x00010000 |
70 | #define MEDIA_ENT_F_DTV_CA (MEDIA_ENT_F_BASE + 0x00003) | 54 | #define MEDIA_ENT_F_OLD_SUBDEV_BASE 0x00020000 |
71 | #define MEDIA_ENT_F_DTV_NET_DECAP (MEDIA_ENT_F_BASE + 0x00004) | ||
72 | 55 | ||
73 | /* | 56 | /* |
74 | * I/O entities | 57 | * Initial value to be used when a new entity is created |
58 | * Drivers should change it to something useful. | ||
75 | */ | 59 | */ |
76 | #define MEDIA_ENT_F_IO_DTV (MEDIA_ENT_F_BASE + 0x01001) | 60 | #define MEDIA_ENT_F_UNKNOWN MEDIA_ENT_F_BASE |
77 | #define MEDIA_ENT_F_IO_VBI (MEDIA_ENT_F_BASE + 0x01002) | ||
78 | #define MEDIA_ENT_F_IO_SWRADIO (MEDIA_ENT_F_BASE + 0x01003) | ||
79 | 61 | ||
80 | /* | 62 | /* |
81 | * Analog TV IF-PLL decoders | 63 | * Subdevs are initialized with MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN in order |
82 | * | 64 | * to preserve backward compatibility. Drivers must change to the proper |
83 | * It is a responsibility of the master/bridge drivers to create links | 65 | * subdev type before registering the entity. |
84 | * for MEDIA_ENT_F_IF_VID_DECODER and MEDIA_ENT_F_IF_AUD_DECODER. | ||
85 | */ | 66 | */ |
86 | #define MEDIA_ENT_F_IF_VID_DECODER (MEDIA_ENT_F_BASE + 0x02001) | 67 | #define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE |
87 | #define MEDIA_ENT_F_IF_AUD_DECODER (MEDIA_ENT_F_BASE + 0x02002) | ||
88 | 68 | ||
89 | /* | 69 | /* |
90 | * Audio Entity Functions | 70 | * DVB entity functions |
91 | */ | 71 | */ |
92 | #define MEDIA_ENT_F_AUDIO_CAPTURE (MEDIA_ENT_F_BASE + 0x03001) | 72 | #define MEDIA_ENT_F_DTV_DEMOD (MEDIA_ENT_F_BASE + 0x00001) |
93 | #define MEDIA_ENT_F_AUDIO_PLAYBACK (MEDIA_ENT_F_BASE + 0x03002) | 73 | #define MEDIA_ENT_F_TS_DEMUX (MEDIA_ENT_F_BASE + 0x00002) |
94 | #define MEDIA_ENT_F_AUDIO_MIXER (MEDIA_ENT_F_BASE + 0x03003) | 74 | #define MEDIA_ENT_F_DTV_CA (MEDIA_ENT_F_BASE + 0x00003) |
75 | #define MEDIA_ENT_F_DTV_NET_DECAP (MEDIA_ENT_F_BASE + 0x00004) | ||
95 | 76 | ||
96 | /* | 77 | /* |
97 | * Processing entities | 78 | * I/O entity functions |
98 | */ | 79 | */ |
99 | #define MEDIA_ENT_F_PROC_VIDEO_COMPOSER (MEDIA_ENT_F_BASE + 0x4001) | 80 | #define MEDIA_ENT_F_IO_V4L (MEDIA_ENT_F_OLD_BASE + 1) |
100 | #define MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER (MEDIA_ENT_F_BASE + 0x4002) | 81 | #define MEDIA_ENT_F_IO_DTV (MEDIA_ENT_F_BASE + 0x01001) |
101 | #define MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV (MEDIA_ENT_F_BASE + 0x4003) | 82 | #define MEDIA_ENT_F_IO_VBI (MEDIA_ENT_F_BASE + 0x01002) |
102 | #define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004) | 83 | #define MEDIA_ENT_F_IO_SWRADIO (MEDIA_ENT_F_BASE + 0x01003) |
103 | #define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005) | ||
104 | #define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006) | ||
105 | 84 | ||
106 | /* | 85 | /* |
107 | * Switch and bridge entitites | 86 | * Sensor functions |
108 | */ | 87 | */ |
109 | #define MEDIA_ENT_F_VID_MUX (MEDIA_ENT_F_BASE + 0x5001) | 88 | #define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1) |
110 | #define MEDIA_ENT_F_VID_IF_BRIDGE (MEDIA_ENT_F_BASE + 0x5002) | 89 | #define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) |
90 | #define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) | ||
111 | 91 | ||
112 | /* | 92 | /* |
113 | * Connectors | 93 | * Video decoder functions |
114 | */ | 94 | */ |
115 | /* It is a responsibility of the entity drivers to add connectors and links */ | 95 | #define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) |
116 | #ifdef __KERNEL__ | 96 | #define MEDIA_ENT_F_DTV_DECODER (MEDIA_ENT_F_BASE + 0x6001) |
117 | /* | ||
118 | * For now, it should not be used in userspace, as some | ||
119 | * definitions may change | ||
120 | */ | ||
121 | |||
122 | #define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 0x30001) | ||
123 | #define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 0x30002) | ||
124 | #define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 0x30003) | ||
125 | |||
126 | #endif | ||
127 | 97 | ||
128 | /* | 98 | /* |
129 | * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and | 99 | * Digital TV, analog TV, radio and/or software defined radio tuner functions. |
130 | * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility | ||
131 | * with the legacy v1 API.The number range is out of range by purpose: | ||
132 | * several previously reserved numbers got excluded from this range. | ||
133 | * | 100 | * |
134 | * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, | ||
135 | * in order to preserve backward compatibility. | ||
136 | * Drivers must change to the proper subdev type before | ||
137 | * registering the entity. | ||
138 | */ | ||
139 | |||
140 | #define MEDIA_ENT_F_IO_V4L (MEDIA_ENT_F_OLD_BASE + 1) | ||
141 | |||
142 | #define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1) | ||
143 | #define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) | ||
144 | #define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) | ||
145 | #define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) | ||
146 | /* | ||
147 | * It is a responsibility of the master/bridge drivers to add connectors | 101 | * It is a responsibility of the master/bridge drivers to add connectors |
148 | * and links for MEDIA_ENT_F_TUNER. Please notice that some old tuners | 102 | * and links for MEDIA_ENT_F_TUNER. Please notice that some old tuners |
149 | * may require the usage of separate I2C chips to decode analog TV signals, | 103 | * may require the usage of separate I2C chips to decode analog TV signals, |
@@ -151,49 +105,46 @@ struct media_device_info { | |||
151 | * On such cases, the IF-PLL staging is mapped via one or two entities: | 105 | * On such cases, the IF-PLL staging is mapped via one or two entities: |
152 | * MEDIA_ENT_F_IF_VID_DECODER and/or MEDIA_ENT_F_IF_AUD_DECODER. | 106 | * MEDIA_ENT_F_IF_VID_DECODER and/or MEDIA_ENT_F_IF_AUD_DECODER. |
153 | */ | 107 | */ |
154 | #define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) | 108 | #define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) |
155 | 109 | ||
156 | #define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE | 110 | /* |
111 | * Analog TV IF-PLL decoder functions | ||
112 | * | ||
113 | * It is a responsibility of the master/bridge drivers to create links | ||
114 | * for MEDIA_ENT_F_IF_VID_DECODER and MEDIA_ENT_F_IF_AUD_DECODER. | ||
115 | */ | ||
116 | #define MEDIA_ENT_F_IF_VID_DECODER (MEDIA_ENT_F_BASE + 0x02001) | ||
117 | #define MEDIA_ENT_F_IF_AUD_DECODER (MEDIA_ENT_F_BASE + 0x02002) | ||
157 | 118 | ||
158 | #if !defined(__KERNEL__) || defined(__NEED_MEDIA_LEGACY_API) | 119 | /* |
120 | * Audio entity functions | ||
121 | */ | ||
122 | #define MEDIA_ENT_F_AUDIO_CAPTURE (MEDIA_ENT_F_BASE + 0x03001) | ||
123 | #define MEDIA_ENT_F_AUDIO_PLAYBACK (MEDIA_ENT_F_BASE + 0x03002) | ||
124 | #define MEDIA_ENT_F_AUDIO_MIXER (MEDIA_ENT_F_BASE + 0x03003) | ||
159 | 125 | ||
160 | /* | 126 | /* |
161 | * Legacy symbols used to avoid userspace compilation breakages | 127 | * Processing entity functions |
162 | * | ||
163 | * Those symbols map the entity function into types and should be | ||
164 | * used only on legacy programs for legacy hardware. Don't rely | ||
165 | * on those for MEDIA_IOC_G_TOPOLOGY. | ||
166 | */ | 128 | */ |
167 | #define MEDIA_ENT_TYPE_SHIFT 16 | 129 | #define MEDIA_ENT_F_PROC_VIDEO_COMPOSER (MEDIA_ENT_F_BASE + 0x4001) |
168 | #define MEDIA_ENT_TYPE_MASK 0x00ff0000 | 130 | #define MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER (MEDIA_ENT_F_BASE + 0x4002) |
169 | #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff | 131 | #define MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV (MEDIA_ENT_F_BASE + 0x4003) |
170 | 132 | #define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004) | |
171 | /* End of the old subdev reserved numberspace */ | 133 | #define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005) |
172 | #define MEDIA_ENT_T_DEVNODE_UNKNOWN (MEDIA_ENT_T_DEVNODE | \ | 134 | #define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006) |
173 | MEDIA_ENT_SUBTYPE_MASK) | ||
174 | |||
175 | #define MEDIA_ENT_T_DEVNODE MEDIA_ENT_F_OLD_BASE | ||
176 | #define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO_V4L | ||
177 | #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) | ||
178 | #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) | ||
179 | #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) | ||
180 | |||
181 | #define MEDIA_ENT_T_UNKNOWN MEDIA_ENT_F_UNKNOWN | ||
182 | #define MEDIA_ENT_T_V4L2_VIDEO MEDIA_ENT_F_IO_V4L | ||
183 | #define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN | ||
184 | #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR MEDIA_ENT_F_CAM_SENSOR | ||
185 | #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH MEDIA_ENT_F_FLASH | ||
186 | #define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS | ||
187 | #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER | ||
188 | #define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER | ||
189 | 135 | ||
190 | /* Obsolete symbol for media_version, no longer used in the kernel */ | 136 | /* |
191 | #define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) | 137 | * Switch and bridge entity functions |
192 | #endif | 138 | */ |
139 | #define MEDIA_ENT_F_VID_MUX (MEDIA_ENT_F_BASE + 0x5001) | ||
140 | #define MEDIA_ENT_F_VID_IF_BRIDGE (MEDIA_ENT_F_BASE + 0x5002) | ||
193 | 141 | ||
194 | /* Entity flags */ | 142 | /* Entity flags */ |
195 | #define MEDIA_ENT_FL_DEFAULT (1 << 0) | 143 | #define MEDIA_ENT_FL_DEFAULT (1 << 0) |
196 | #define MEDIA_ENT_FL_CONNECTOR (1 << 1) | 144 | #define MEDIA_ENT_FL_CONNECTOR (1 << 1) |
145 | |||
146 | /* OR with the entity id value to find the next entity */ | ||
147 | #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) | ||
197 | 148 | ||
198 | struct media_entity_desc { | 149 | struct media_entity_desc { |
199 | __u32 id; | 150 | __u32 id; |
@@ -214,7 +165,7 @@ struct media_entity_desc { | |||
214 | __u32 minor; | 165 | __u32 minor; |
215 | } dev; | 166 | } dev; |
216 | 167 | ||
217 | #if 1 | 168 | #if !defined(__KERNEL__) |
218 | /* | 169 | /* |
219 | * TODO: this shouldn't have been added without | 170 | * TODO: this shouldn't have been added without |
220 | * actual drivers that use this. When the first real driver | 171 | * actual drivers that use this. When the first real driver |
@@ -225,24 +176,17 @@ struct media_entity_desc { | |||
225 | * contain the subdevice information. In addition, struct dev | 176 | * contain the subdevice information. In addition, struct dev |
226 | * can only refer to a single device, and not to multiple (e.g. | 177 | * can only refer to a single device, and not to multiple (e.g. |
227 | * pcm and mixer devices). | 178 | * pcm and mixer devices). |
228 | * | ||
229 | * So for now mark this as a to do. | ||
230 | */ | 179 | */ |
231 | struct { | 180 | struct { |
232 | __u32 card; | 181 | __u32 card; |
233 | __u32 device; | 182 | __u32 device; |
234 | __u32 subdevice; | 183 | __u32 subdevice; |
235 | } alsa; | 184 | } alsa; |
236 | #endif | ||
237 | 185 | ||
238 | #if 1 | ||
239 | /* | 186 | /* |
240 | * DEPRECATED: previous node specifications. Kept just to | 187 | * DEPRECATED: previous node specifications. Kept just to |
241 | * avoid breaking compilation, but media_entity_desc.dev | 188 | * avoid breaking compilation. Use media_entity_desc.dev |
242 | * should be used instead. In particular, alsa and dvb | 189 | * instead. |
243 | * fields below are wrong: for all devnodes, there should | ||
244 | * be just major/minor inside the struct, as this is enough | ||
245 | * to represent any devnode, no matter what type. | ||
246 | */ | 190 | */ |
247 | struct { | 191 | struct { |
248 | __u32 major; | 192 | __u32 major; |
@@ -261,9 +205,9 @@ struct media_entity_desc { | |||
261 | }; | 205 | }; |
262 | }; | 206 | }; |
263 | 207 | ||
264 | #define MEDIA_PAD_FL_SINK (1 << 0) | 208 | #define MEDIA_PAD_FL_SINK (1 << 0) |
265 | #define MEDIA_PAD_FL_SOURCE (1 << 1) | 209 | #define MEDIA_PAD_FL_SOURCE (1 << 1) |
266 | #define MEDIA_PAD_FL_MUST_CONNECT (1 << 2) | 210 | #define MEDIA_PAD_FL_MUST_CONNECT (1 << 2) |
267 | 211 | ||
268 | struct media_pad_desc { | 212 | struct media_pad_desc { |
269 | __u32 entity; /* entity ID */ | 213 | __u32 entity; /* entity ID */ |
@@ -272,13 +216,13 @@ struct media_pad_desc { | |||
272 | __u32 reserved[2]; | 216 | __u32 reserved[2]; |
273 | }; | 217 | }; |
274 | 218 | ||
275 | #define MEDIA_LNK_FL_ENABLED (1 << 0) | 219 | #define MEDIA_LNK_FL_ENABLED (1 << 0) |
276 | #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) | 220 | #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) |
277 | #define MEDIA_LNK_FL_DYNAMIC (1 << 2) | 221 | #define MEDIA_LNK_FL_DYNAMIC (1 << 2) |
278 | 222 | ||
279 | #define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) | 223 | #define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) |
280 | # define MEDIA_LNK_FL_DATA_LINK (0 << 28) | 224 | # define MEDIA_LNK_FL_DATA_LINK (0 << 28) |
281 | # define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) | 225 | # define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) |
282 | 226 | ||
283 | struct media_link_desc { | 227 | struct media_link_desc { |
284 | struct media_pad_desc source; | 228 | struct media_pad_desc source; |
@@ -298,57 +242,47 @@ struct media_links_enum { | |||
298 | 242 | ||
299 | /* Interface type ranges */ | 243 | /* Interface type ranges */ |
300 | 244 | ||
301 | #define MEDIA_INTF_T_DVB_BASE 0x00000100 | 245 | #define MEDIA_INTF_T_DVB_BASE 0x00000100 |
302 | #define MEDIA_INTF_T_V4L_BASE 0x00000200 | 246 | #define MEDIA_INTF_T_V4L_BASE 0x00000200 |
303 | #define MEDIA_INTF_T_ALSA_BASE 0x00000300 | ||
304 | 247 | ||
305 | /* Interface types */ | 248 | /* Interface types */ |
306 | 249 | ||
307 | #define MEDIA_INTF_T_DVB_FE (MEDIA_INTF_T_DVB_BASE) | 250 | #define MEDIA_INTF_T_DVB_FE (MEDIA_INTF_T_DVB_BASE) |
308 | #define MEDIA_INTF_T_DVB_DEMUX (MEDIA_INTF_T_DVB_BASE + 1) | 251 | #define MEDIA_INTF_T_DVB_DEMUX (MEDIA_INTF_T_DVB_BASE + 1) |
309 | #define MEDIA_INTF_T_DVB_DVR (MEDIA_INTF_T_DVB_BASE + 2) | 252 | #define MEDIA_INTF_T_DVB_DVR (MEDIA_INTF_T_DVB_BASE + 2) |
310 | #define MEDIA_INTF_T_DVB_CA (MEDIA_INTF_T_DVB_BASE + 3) | 253 | #define MEDIA_INTF_T_DVB_CA (MEDIA_INTF_T_DVB_BASE + 3) |
311 | #define MEDIA_INTF_T_DVB_NET (MEDIA_INTF_T_DVB_BASE + 4) | 254 | #define MEDIA_INTF_T_DVB_NET (MEDIA_INTF_T_DVB_BASE + 4) |
312 | 255 | ||
313 | #define MEDIA_INTF_T_V4L_VIDEO (MEDIA_INTF_T_V4L_BASE) | 256 | #define MEDIA_INTF_T_V4L_VIDEO (MEDIA_INTF_T_V4L_BASE) |
314 | #define MEDIA_INTF_T_V4L_VBI (MEDIA_INTF_T_V4L_BASE + 1) | 257 | #define MEDIA_INTF_T_V4L_VBI (MEDIA_INTF_T_V4L_BASE + 1) |
315 | #define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) | 258 | #define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) |
316 | #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) | 259 | #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) |
317 | #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) | 260 | #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) |
318 | #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) | 261 | #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) |
319 | 262 | ||
320 | #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) | 263 | #if defined(__KERNEL__) |
321 | #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) | ||
322 | #define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) | ||
323 | #define MEDIA_INTF_T_ALSA_COMPRESS (MEDIA_INTF_T_ALSA_BASE + 3) | ||
324 | #define MEDIA_INTF_T_ALSA_RAWMIDI (MEDIA_INTF_T_ALSA_BASE + 4) | ||
325 | #define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5) | ||
326 | #define MEDIA_INTF_T_ALSA_SEQUENCER (MEDIA_INTF_T_ALSA_BASE + 6) | ||
327 | #define MEDIA_INTF_T_ALSA_TIMER (MEDIA_INTF_T_ALSA_BASE + 7) | ||
328 | 264 | ||
329 | /* | 265 | /* |
330 | * MC next gen API definitions | 266 | * Connector functions |
331 | * | 267 | * |
332 | * NOTE: The declarations below are close to the MC RFC for the Media | 268 | * For now these should not be used in userspace, as some definitions may |
333 | * Controller, the next generation. Yet, there are a few adjustments | 269 | * change. |
334 | * to do, as we want to be able to have a functional API before | ||
335 | * the MC properties change. Those will be properly marked below. | ||
336 | * Please also notice that I removed "num_pads", "num_links", | ||
337 | * from the proposal, as a proper userspace application will likely | ||
338 | * use lists for pads/links, just as we intend to do in Kernelspace. | ||
339 | * The API definition should be freed from fields that are bound to | ||
340 | * some specific data structure. | ||
341 | * | 270 | * |
342 | * FIXME: Currently, I opted to name the new types as "media_v2", as this | 271 | * It is the responsibility of the entity drivers to add connectors and links. |
343 | * won't cause any conflict with the Kernelspace namespace, nor with | ||
344 | * the previous kAPI media_*_desc namespace. This can be changed | ||
345 | * later, before the adding this API upstream. | ||
346 | */ | 272 | */ |
273 | #define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 0x30001) | ||
274 | #define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 0x30002) | ||
275 | #define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 0x30003) | ||
347 | 276 | ||
277 | #endif | ||
278 | |||
279 | /* | ||
280 | * MC next gen API definitions | ||
281 | */ | ||
348 | 282 | ||
349 | struct media_v2_entity { | 283 | struct media_v2_entity { |
350 | __u32 id; | 284 | __u32 id; |
351 | char name[64]; /* FIXME: move to a property? (RFC says so) */ | 285 | char name[64]; |
352 | __u32 function; /* Main function of the entity */ | 286 | __u32 function; /* Main function of the entity */ |
353 | __u32 reserved[6]; | 287 | __u32 reserved[6]; |
354 | } __attribute__ ((packed)); | 288 | } __attribute__ ((packed)); |
@@ -408,10 +342,62 @@ struct media_v2_topology { | |||
408 | 342 | ||
409 | /* ioctls */ | 343 | /* ioctls */ |
410 | 344 | ||
411 | #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) | 345 | #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) |
412 | #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) | 346 | #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) |
413 | #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) | 347 | #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) |
414 | #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) | 348 | #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) |
415 | #define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology) | 349 | #define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology) |
350 | |||
351 | #if !defined(__KERNEL__) || defined(__NEED_MEDIA_LEGACY_API) | ||
352 | |||
353 | /* | ||
354 | * Legacy symbols used to avoid userspace compilation breakages. | ||
355 | * Do not use any of this in new applications! | ||
356 | * | ||
357 | * Those symbols map the entity function into types and should be | ||
358 | * used only on legacy programs for legacy hardware. Don't rely | ||
359 | * on those for MEDIA_IOC_G_TOPOLOGY. | ||
360 | */ | ||
361 | #define MEDIA_ENT_TYPE_SHIFT 16 | ||
362 | #define MEDIA_ENT_TYPE_MASK 0x00ff0000 | ||
363 | #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff | ||
364 | |||
365 | #define MEDIA_ENT_T_DEVNODE_UNKNOWN (MEDIA_ENT_F_OLD_BASE | \ | ||
366 | MEDIA_ENT_SUBTYPE_MASK) | ||
367 | |||
368 | #define MEDIA_ENT_T_DEVNODE MEDIA_ENT_F_OLD_BASE | ||
369 | #define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO_V4L | ||
370 | #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_F_OLD_BASE + 2) | ||
371 | #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_F_OLD_BASE + 3) | ||
372 | #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_F_OLD_BASE + 4) | ||
373 | |||
374 | #define MEDIA_ENT_T_UNKNOWN MEDIA_ENT_F_UNKNOWN | ||
375 | #define MEDIA_ENT_T_V4L2_VIDEO MEDIA_ENT_F_IO_V4L | ||
376 | #define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN | ||
377 | #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR MEDIA_ENT_F_CAM_SENSOR | ||
378 | #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH MEDIA_ENT_F_FLASH | ||
379 | #define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS | ||
380 | #define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER | ||
381 | #define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER | ||
382 | |||
383 | /* | ||
384 | * There is still no ALSA support in the media controller. These | ||
385 | * defines should not have been added and we leave them here only | ||
386 | * in case some application tries to use these defines. | ||
387 | */ | ||
388 | #define MEDIA_INTF_T_ALSA_BASE 0x00000300 | ||
389 | #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) | ||
390 | #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) | ||
391 | #define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) | ||
392 | #define MEDIA_INTF_T_ALSA_COMPRESS (MEDIA_INTF_T_ALSA_BASE + 3) | ||
393 | #define MEDIA_INTF_T_ALSA_RAWMIDI (MEDIA_INTF_T_ALSA_BASE + 4) | ||
394 | #define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5) | ||
395 | #define MEDIA_INTF_T_ALSA_SEQUENCER (MEDIA_INTF_T_ALSA_BASE + 6) | ||
396 | #define MEDIA_INTF_T_ALSA_TIMER (MEDIA_INTF_T_ALSA_BASE + 7) | ||
397 | |||
398 | /* Obsolete symbol for media_version, no longer used in the kernel */ | ||
399 | #define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0) | ||
400 | |||
401 | #endif | ||
416 | 402 | ||
417 | #endif /* __LINUX_MEDIA_H */ | 403 | #endif /* __LINUX_MEDIA_H */ |
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index cbbb750d87d1..8d473c979b61 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h | |||
@@ -589,6 +589,98 @@ enum v4l2_vp8_golden_frame_sel { | |||
589 | #define V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (V4L2_CID_MPEG_BASE+510) | 589 | #define V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP (V4L2_CID_MPEG_BASE+510) |
590 | #define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511) | 590 | #define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511) |
591 | 591 | ||
592 | /* CIDs for HEVC encoding. */ | ||
593 | |||
594 | #define V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP (V4L2_CID_MPEG_BASE + 600) | ||
595 | #define V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP (V4L2_CID_MPEG_BASE + 601) | ||
596 | #define V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP (V4L2_CID_MPEG_BASE + 602) | ||
597 | #define V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP (V4L2_CID_MPEG_BASE + 603) | ||
598 | #define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP (V4L2_CID_MPEG_BASE + 604) | ||
599 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP (V4L2_CID_MPEG_BASE + 605) | ||
600 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE (V4L2_CID_MPEG_BASE + 606) | ||
601 | enum v4l2_mpeg_video_hevc_hier_coding_type { | ||
602 | V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B = 0, | ||
603 | V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P = 1, | ||
604 | }; | ||
605 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER (V4L2_CID_MPEG_BASE + 607) | ||
606 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP (V4L2_CID_MPEG_BASE + 608) | ||
607 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP (V4L2_CID_MPEG_BASE + 609) | ||
608 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP (V4L2_CID_MPEG_BASE + 610) | ||
609 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP (V4L2_CID_MPEG_BASE + 611) | ||
610 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP (V4L2_CID_MPEG_BASE + 612) | ||
611 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP (V4L2_CID_MPEG_BASE + 613) | ||
612 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP (V4L2_CID_MPEG_BASE + 614) | ||
613 | #define V4L2_CID_MPEG_VIDEO_HEVC_PROFILE (V4L2_CID_MPEG_BASE + 615) | ||
614 | enum v4l2_mpeg_video_hevc_profile { | ||
615 | V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN = 0, | ||
616 | V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE = 1, | ||
617 | V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 = 2, | ||
618 | }; | ||
619 | #define V4L2_CID_MPEG_VIDEO_HEVC_LEVEL (V4L2_CID_MPEG_BASE + 616) | ||
620 | enum v4l2_mpeg_video_hevc_level { | ||
621 | V4L2_MPEG_VIDEO_HEVC_LEVEL_1 = 0, | ||
622 | V4L2_MPEG_VIDEO_HEVC_LEVEL_2 = 1, | ||
623 | V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 = 2, | ||
624 | V4L2_MPEG_VIDEO_HEVC_LEVEL_3 = 3, | ||
625 | V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 = 4, | ||
626 | V4L2_MPEG_VIDEO_HEVC_LEVEL_4 = 5, | ||
627 | V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 = 6, | ||
628 | V4L2_MPEG_VIDEO_HEVC_LEVEL_5 = 7, | ||
629 | V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 = 8, | ||
630 | V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 = 9, | ||
631 | V4L2_MPEG_VIDEO_HEVC_LEVEL_6 = 10, | ||
632 | V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 = 11, | ||
633 | V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 = 12, | ||
634 | }; | ||
635 | #define V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION (V4L2_CID_MPEG_BASE + 617) | ||
636 | #define V4L2_CID_MPEG_VIDEO_HEVC_TIER (V4L2_CID_MPEG_BASE + 618) | ||
637 | enum v4l2_mpeg_video_hevc_tier { | ||
638 | V4L2_MPEG_VIDEO_HEVC_TIER_MAIN = 0, | ||
639 | V4L2_MPEG_VIDEO_HEVC_TIER_HIGH = 1, | ||
640 | }; | ||
641 | #define V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH (V4L2_CID_MPEG_BASE + 619) | ||
642 | #define V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE + 620) | ||
643 | enum v4l2_cid_mpeg_video_hevc_loop_filter_mode { | ||
644 | V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED = 0, | ||
645 | V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_ENABLED = 1, | ||
646 | V4L2_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, | ||
647 | }; | ||
648 | #define V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2 (V4L2_CID_MPEG_BASE + 621) | ||
649 | #define V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2 (V4L2_CID_MPEG_BASE + 622) | ||
650 | #define V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE (V4L2_CID_MPEG_BASE + 623) | ||
651 | enum v4l2_cid_mpeg_video_hevc_refresh_type { | ||
652 | V4L2_MPEG_VIDEO_HEVC_REFRESH_NONE = 0, | ||
653 | V4L2_MPEG_VIDEO_HEVC_REFRESH_CRA = 1, | ||
654 | V4L2_MPEG_VIDEO_HEVC_REFRESH_IDR = 2, | ||
655 | }; | ||
656 | #define V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD (V4L2_CID_MPEG_BASE + 624) | ||
657 | #define V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU (V4L2_CID_MPEG_BASE + 625) | ||
658 | #define V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED (V4L2_CID_MPEG_BASE + 626) | ||
659 | #define V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT (V4L2_CID_MPEG_BASE + 627) | ||
660 | #define V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB (V4L2_CID_MPEG_BASE + 628) | ||
661 | #define V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID (V4L2_CID_MPEG_BASE + 629) | ||
662 | #define V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING (V4L2_CID_MPEG_BASE + 630) | ||
663 | #define V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1 (V4L2_CID_MPEG_BASE + 631) | ||
664 | #define V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT (V4L2_CID_MPEG_BASE + 632) | ||
665 | #define V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION (V4L2_CID_MPEG_BASE + 633) | ||
666 | #define V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE (V4L2_CID_MPEG_BASE + 634) | ||
667 | #define V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD (V4L2_CID_MPEG_BASE + 635) | ||
668 | enum v4l2_cid_mpeg_video_hevc_size_of_length_field { | ||
669 | V4L2_MPEG_VIDEO_HEVC_SIZE_0 = 0, | ||
670 | V4L2_MPEG_VIDEO_HEVC_SIZE_1 = 1, | ||
671 | V4L2_MPEG_VIDEO_HEVC_SIZE_2 = 2, | ||
672 | V4L2_MPEG_VIDEO_HEVC_SIZE_4 = 3, | ||
673 | }; | ||
674 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR (V4L2_CID_MPEG_BASE + 636) | ||
675 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR (V4L2_CID_MPEG_BASE + 637) | ||
676 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR (V4L2_CID_MPEG_BASE + 638) | ||
677 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR (V4L2_CID_MPEG_BASE + 639) | ||
678 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR (V4L2_CID_MPEG_BASE + 640) | ||
679 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR (V4L2_CID_MPEG_BASE + 641) | ||
680 | #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (V4L2_CID_MPEG_BASE + 642) | ||
681 | #define V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_BASE + 643) | ||
682 | #define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_BASE + 644) | ||
683 | |||
592 | /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ | 684 | /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ |
593 | #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) | 685 | #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) |
594 | #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) | 686 | #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) |
@@ -657,7 +749,6 @@ enum v4l2_mpeg_mfc51_video_force_frame_type { | |||
657 | #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) | 749 | #define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) |
658 | #define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) | 750 | #define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) |
659 | 751 | ||
660 | |||
661 | /* Camera class control IDs */ | 752 | /* Camera class control IDs */ |
662 | 753 | ||
663 | #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) | 754 | #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) |
diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h index 6e20de63ec59..123a231001a8 100644 --- a/include/uapi/linux/v4l2-mediabus.h +++ b/include/uapi/linux/v4l2-mediabus.h | |||
@@ -18,8 +18,8 @@ | |||
18 | 18 | ||
19 | /** | 19 | /** |
20 | * struct v4l2_mbus_framefmt - frame format on the media bus | 20 | * struct v4l2_mbus_framefmt - frame format on the media bus |
21 | * @width: frame width | 21 | * @width: image width |
22 | * @height: frame height | 22 | * @height: image height |
23 | * @code: data format code (from enum v4l2_mbus_pixelcode) | 23 | * @code: data format code (from enum v4l2_mbus_pixelcode) |
24 | * @field: used interlacing type (from enum v4l2_field) | 24 | * @field: used interlacing type (from enum v4l2_field) |
25 | * @colorspace: colorspace of the data (from enum v4l2_colorspace) | 25 | * @colorspace: colorspace of the data (from enum v4l2_colorspace) |
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 982718965180..600877be5c22 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h | |||
@@ -635,6 +635,7 @@ struct v4l2_pix_format { | |||
635 | #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ | 635 | #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ |
636 | #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ | 636 | #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ |
637 | #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ | 637 | #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ |
638 | #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */ | ||
638 | 639 | ||
639 | /* Vendor-specific formats */ | 640 | /* Vendor-specific formats */ |
640 | #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ | 641 | #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ |