aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@linaro.org>2016-07-29 03:38:55 -0400
committerBenjamin Gaignard <benjamin.gaignard@linaro.org>2016-07-29 03:38:55 -0400
commit62c2cd0f49333a2bb53602ec23039ca99a19cb9d (patch)
tree82ce682c6902ebe63275a60bdc3d406b26f09c84
parenta1f5524a66ff6284d1380cdd7723de82698ff9d3 (diff)
parent894dde5c5d1c6d33c4bd3d4384c6cf0aff3f8015 (diff)
Merge remote-tracking branch 'media_tree/vsp1' into generic-zpos-v8
-rw-r--r--Documentation/DocBook/media/v4l/media-types.xml64
-rw-r--r--Documentation/devicetree/bindings/media/mediatek-vpu.txt31
-rw-r--r--Documentation/devicetree/bindings/media/renesas,fcp.txt32
-rw-r--r--Documentation/devicetree/bindings/media/renesas,vsp1.txt5
-rw-r--r--Documentation/devicetree/bindings/media/s5p-mfc.txt39
-rw-r--r--MAINTAINERS28
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.c45
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_vsp.h2
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c17
-rw-r--r--drivers/media/dvb-frontends/Kconfig15
-rw-r--r--drivers/media/dvb-frontends/Makefile2
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c1467
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.h24
-rw-r--r--drivers/media/dvb-frontends/cxd2841er_priv.h1
-rw-r--r--drivers/media/dvb-frontends/ds3000.c9
-rw-r--r--drivers/media/dvb-frontends/helene.c1042
-rw-r--r--drivers/media/dvb-frontends/helene.h79
-rw-r--r--drivers/media/dvb-frontends/horus3a.c26
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.c2
-rw-r--r--drivers/media/dvb-frontends/mn88472.c (renamed from drivers/staging/media/mn88472/mn88472.c)519
-rw-r--r--drivers/media/dvb-frontends/mn88472.h45
-rw-r--r--drivers/media/dvb-frontends/mn88472_priv.h (renamed from drivers/staging/media/mn88472/mn88472_priv.h)11
-rw-r--r--drivers/media/dvb-frontends/mn88473.c7
-rw-r--r--drivers/media/dvb-frontends/rtl2832.c25
-rw-r--r--drivers/media/dvb-frontends/rtl2832_priv.h1
-rw-r--r--drivers/media/media-device.c47
-rw-r--r--drivers/media/media-devnode.c149
-rw-r--r--drivers/media/pci/netup_unidvb/Kconfig7
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb.h10
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_ci.c4
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c170
-rw-r--r--drivers/media/platform/Kconfig15
-rw-r--r--drivers/media/platform/Makefile3
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-core.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.c2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c2
-rw-r--r--drivers/media/platform/rcar-fcp.c181
-rw-r--r--drivers/media/platform/rcar-vin/Kconfig11
-rw-r--r--drivers/media/platform/rcar-vin/Makefile3
-rw-r--r--drivers/media/platform/rcar-vin/rcar-core.c334
-rw-r--r--drivers/media/platform/rcar-vin/rcar-dma.c1196
-rw-r--r--drivers/media/platform/rcar-vin/rcar-v4l2.c768
-rw-r--r--drivers/media/platform/rcar-vin/rcar-vin.h163
-rw-r--r--drivers/media/platform/s5p-g2d/g2d.c2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c198
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_dec.c3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c12
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h79
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_pm.c1
-rw-r--r--drivers/media/platform/s5p-tv/mixer_video.c2
-rw-r--r--drivers/media/platform/soc_camera/Kconfig4
-rw-r--r--drivers/media/platform/soc_camera/Makefile2
-rw-r--r--drivers/media/platform/vsp1/Makefile3
-rw-r--r--drivers/media/platform/vsp1/vsp1.h11
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c12
-rw-r--r--drivers/media/platform/vsp1/vsp1_clu.c292
-rw-r--r--drivers/media/platform/vsp1/vsp1_clu.h48
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.c72
-rw-r--r--drivers/media/platform/vsp1/vsp1_drm.c74
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c189
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c92
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h17
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c14
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c16
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.c101
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.h7
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.c58
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.h8
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h24
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c38
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.c6
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h14
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c14
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c16
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.h2
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c18
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c161
-rw-r--r--drivers/media/tuners/mt2063.c30
-rw-r--r--drivers/media/usb/au0828/au0828-core.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig13
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c227
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.h1
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c5
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c2
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c19
-rw-r--r--drivers/media/usb/uvc/uvc_video.c1
-rw-r--r--drivers/media/v4l2-core/videobuf2-core.c10
-rw-r--r--drivers/media/v4l2-core/videobuf2-dma-contig.c53
-rw-r--r--drivers/media/v4l2-core/videobuf2-v4l2.c6
-rw-r--r--drivers/of/of_reserved_mem.c83
-rw-r--r--drivers/staging/media/Kconfig10
-rw-r--r--drivers/staging/media/Makefile5
-rw-r--r--drivers/staging/media/mn88472/Kconfig7
-rw-r--r--drivers/staging/media/mn88472/Makefile5
-rw-r--r--drivers/staging/media/mn88472/TODO21
-rw-r--r--drivers/staging/media/mx2/Kconfig15
-rw-r--r--drivers/staging/media/mx2/Makefile3
-rw-r--r--drivers/staging/media/mx2/TODO10
-rw-r--r--drivers/staging/media/mx2/mx2_camera.c1636
-rw-r--r--drivers/staging/media/mx3/Kconfig15
-rw-r--r--drivers/staging/media/mx3/Makefile3
-rw-r--r--drivers/staging/media/mx3/TODO10
-rw-r--r--drivers/staging/media/mx3/mx3_camera.c1264
-rw-r--r--drivers/staging/media/omap1/Kconfig13
-rw-r--r--drivers/staging/media/omap1/Makefile3
-rw-r--r--drivers/staging/media/omap1/TODO8
-rw-r--r--drivers/staging/media/omap1/omap1_camera.c1702
-rw-r--r--drivers/staging/media/timb/Kconfig11
-rw-r--r--drivers/staging/media/timb/Makefile1
-rw-r--r--drivers/staging/media/timb/timblogiw.c870
-rw-r--r--include/linux/of_reserved_mem.h25
-rw-r--r--include/media/media-device.h5
-rw-r--r--include/media/media-devnode.h46
-rw-r--r--include/media/rcar-fcp.h37
-rw-r--r--include/media/videobuf2-dma-contig.h2
-rw-r--r--include/media/vsp1.h29
-rw-r--r--include/uapi/linux/media.h10
-rw-r--r--include/uapi/linux/vsp1.h34
122 files changed, 7425 insertions, 7051 deletions
diff --git a/Documentation/DocBook/media/v4l/media-types.xml b/Documentation/DocBook/media/v4l/media-types.xml
index 5e3f20fdcf17..95aa1f9c836a 100644
--- a/Documentation/DocBook/media/v4l/media-types.xml
+++ b/Documentation/DocBook/media/v4l/media-types.xml
@@ -121,6 +121,70 @@
121 <entry><constant>MEDIA_ENT_F_AUDIO_MIXER</constant></entry> 121 <entry><constant>MEDIA_ENT_F_AUDIO_MIXER</constant></entry>
122 <entry>Audio Mixer Function Entity.</entry> 122 <entry>Audio Mixer Function Entity.</entry>
123 </row> 123 </row>
124 <row>
125 <entry><constant>MEDIA_ENT_F_PROC_VIDEO_COMPOSER</constant></entry>
126 <entry>Video composer (blender). An entity capable of video
127 composing must have at least two sink pads and one source
128 pad, and composes input video frames onto output video
129 frames. Composition can be performed using alpha blending,
130 color keying, raster operations (ROP), stitching or any other
131 means.
132 </entry>
133 </row>
134 <row>
135 <entry><constant>MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER</constant></entry>
136 <entry>Video pixel formatter. An entity capable of pixel formatting
137 must have at least one sink pad and one source pad. Read
138 pixel formatters read pixels from memory and perform a subset
139 of unpacking, cropping, color keying, alpha multiplication
140 and pixel encoding conversion. Write pixel formatters perform
141 a subset of dithering, pixel encoding conversion and packing
142 and write pixels to memory.
143 </entry>
144 </row>
145 <row>
146 <entry><constant>MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV</constant></entry>
147 <entry>Video pixel encoding converter. An entity capable of pixel
148 enconding conversion must have at least one sink pad and one
149 source pad, and convert the encoding of pixels received on
150 its sink pad(s) to a different encoding output on its source
151 pad(s). Pixel encoding conversion includes but isn't limited
152 to RGB to/from HSV, RGB to/from YUV and CFA (Bayer) to RGB
153 conversions.
154 </entry>
155 </row>
156 <row>
157 <entry><constant>MEDIA_ENT_F_PROC_VIDEO_LUT</constant></entry>
158 <entry>Video look-up table. An entity capable of video lookup table
159 processing must have one sink pad and one source pad. It uses
160 the values of the pixels received on its sink pad to look up
161 entries in internal tables and output them on its source pad.
162 The lookup processing can be performed on all components
163 separately or combine them for multi-dimensional table
164 lookups.
165 </entry>
166 </row>
167 <row>
168 <entry><constant>MEDIA_ENT_F_PROC_VIDEO_SCALER</constant></entry>
169 <entry>Video scaler. An entity capable of video scaling must have
170 at least one sink pad and one source pad, and scale the
171 video frame(s) received on its sink pad(s) to a different
172 resolution output on its source pad(s). The range of
173 supported scaling ratios is entity-specific and can differ
174 between the horizontal and vertical directions (in particular
175 scaling can be supported in one direction only). Binning and
176 skipping are considered as scaling.
177 </entry>
178 </row>
179 <row>
180 <entry><constant>MEDIA_ENT_F_PROC_VIDEO_STATISTICS</constant></entry>
181 <entry>Video statistics computation (histogram, 3A, ...). An entity
182 capable of statistics computation must have one sink pad and
183 one source pad. It computes statistics over the frames
184 received on its sink pad and outputs the statistics data on
185 its source pad.
186 </entry>
187 </row>
124 </tbody> 188 </tbody>
125 </tgroup> 189 </tgroup>
126 </table> 190 </table>
diff --git a/Documentation/devicetree/bindings/media/mediatek-vpu.txt b/Documentation/devicetree/bindings/media/mediatek-vpu.txt
new file mode 100644
index 000000000000..2a5bac37f9a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek-vpu.txt
@@ -0,0 +1,31 @@
1* Mediatek Video Processor Unit
2
3Video Processor Unit is a HW video controller. It controls HW Codec including
4H.264/VP8/VP9 Decode, H.264/VP8 Encode and Image Processor (scale/rotate/color convert).
5
6Required properties:
7 - compatible: "mediatek,mt8173-vpu"
8 - reg: Must contain an entry for each entry in reg-names.
9 - reg-names: Must include the following entries:
10 "tcm": tcm base
11 "cfg_reg": Main configuration registers base
12 - interrupts: interrupt number to the cpu.
13 - clocks : clock name from clock manager
14 - clock-names: must be main. It is the main clock of VPU
15
16Optional properties:
17 - memory-region: phandle to a node describing memory (see
18 Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt)
19 to be used for VPU extended memory; if not present, VPU may be located
20 anywhere in the memory
21
22Example:
23 vpu: vpu@10020000 {
24 compatible = "mediatek,mt8173-vpu";
25 reg = <0 0x10020000 0 0x30000>,
26 <0 0x10050000 0 0x100>;
27 reg-names = "tcm", "cfg_reg";
28 interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
29 clocks = <&topckgen TOP_SCP_SEL>;
30 clock-names = "main";
31 };
diff --git a/Documentation/devicetree/bindings/media/renesas,fcp.txt b/Documentation/devicetree/bindings/media/renesas,fcp.txt
new file mode 100644
index 000000000000..6a12960609d8
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/renesas,fcp.txt
@@ -0,0 +1,32 @@
1Renesas R-Car Frame Compression Processor (FCP)
2-----------------------------------------------
3
4The FCP is a companion module of video processing modules in the Renesas R-Car
5Gen3 SoCs. It provides data compression and decompression, data caching, and
6conversion of AXI transactions in order to reduce the memory bandwidth.
7
8There are three types of FCP: FCP for Codec (FCPC), FCP for VSP (FCPV) and FCP
9for FDP (FCPF). Their configuration and behaviour depend on the module they
10are paired with. These DT bindings currently support the FCPV only.
11
12 - compatible: Must be one or more of the following
13
14 - "renesas,r8a7795-fcpv" for R8A7795 (R-Car H3) compatible 'FCP for VSP'
15 - "renesas,fcpv" for generic compatible 'FCP for VSP'
16
17 When compatible with the generic version, nodes must list the
18 SoC-specific version corresponding to the platform first, followed by the
19 family-specific and/or generic versions.
20
21 - reg: the register base and size for the device registers
22 - clocks: Reference to the functional clock
23
24
25Device node example
26-------------------
27
28 fcpvd1: fcp@fea2f000 {
29 compatible = "renesas,r8a7795-fcpv", "renesas,fcpv";
30 reg = <0 0xfea2f000 0 0x200>;
31 clocks = <&cpg CPG_MOD 602>;
32 };
diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
index 627405abd144..9b695bcbf219 100644
--- a/Documentation/devicetree/bindings/media/renesas,vsp1.txt
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
@@ -14,6 +14,11 @@ Required properties:
14 - interrupts: VSP interrupt specifier. 14 - interrupts: VSP interrupt specifier.
15 - clocks: A phandle + clock-specifier pair for the VSP functional clock. 15 - clocks: A phandle + clock-specifier pair for the VSP functional clock.
16 16
17Optional properties:
18
19 - renesas,fcp: A phandle referencing the FCP that handles memory accesses
20 for the VSP. Not needed on Gen2, mandatory on Gen3.
21
17 22
18Example: R8A7790 (R-Car H2) VSP1-S node 23Example: R8A7790 (R-Car H2) VSP1-S node
19 24
diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt
index 2d5787eac91a..92c94f5ecbf1 100644
--- a/Documentation/devicetree/bindings/media/s5p-mfc.txt
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -21,15 +21,18 @@ Required properties:
21 - clock-names : from common clock binding: must contain "mfc", 21 - clock-names : from common clock binding: must contain "mfc",
22 corresponding to entry in the clocks property. 22 corresponding to entry in the clocks property.
23 23
24 - samsung,mfc-r : Base address of the first memory bank used by MFC
25 for DMA contiguous memory allocation and its size.
26
27 - samsung,mfc-l : Base address of the second memory bank used by MFC
28 for DMA contiguous memory allocation and its size.
29
30Optional properties: 24Optional properties:
31 - power-domains : power-domain property defined with a phandle 25 - power-domains : power-domain property defined with a phandle
32 to respective power domain. 26 to respective power domain.
27 - memory-region : from reserved memory binding: phandles to two reserved
28 memory regions, first is for "left" mfc memory bus interfaces,
29 second if for the "right" mfc memory bus, used when no SYSMMU
30 support is available
31
32Obsolete properties:
33 - samsung,mfc-r, samsung,mfc-l : support removed, please use memory-region
34 property instead
35
33 36
34Example: 37Example:
35SoC specific DT entry: 38SoC specific DT entry:
@@ -43,9 +46,29 @@ mfc: codec@13400000 {
43 clock-names = "mfc"; 46 clock-names = "mfc";
44}; 47};
45 48
49Reserved memory specific DT entry for given board (see reserved memory binding
50for more information):
51
52reserved-memory {
53 #address-cells = <1>;
54 #size-cells = <1>;
55 ranges;
56
57 mfc_left: region@51000000 {
58 compatible = "shared-dma-pool";
59 no-map;
60 reg = <0x51000000 0x800000>;
61 };
62
63 mfc_right: region@43000000 {
64 compatible = "shared-dma-pool";
65 no-map;
66 reg = <0x43000000 0x800000>;
67 };
68};
69
46Board specific DT entry: 70Board specific DT entry:
47 71
48codec@13400000 { 72codec@13400000 {
49 samsung,mfc-r = <0x43000000 0x800000>; 73 memory-region = <&mfc_left>, <&mfc_right>;
50 samsung,mfc-l = <0x51000000 0x800000>;
51}; 74};
diff --git a/MAINTAINERS b/MAINTAINERS
index ea8c7ab56cf5..6fc95411d705 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7357,6 +7357,16 @@ L: linux-iio@vger.kernel.org
7357S: Maintained 7357S: Maintained
7358F: drivers/iio/potentiometer/mcp4531.c 7358F: drivers/iio/potentiometer/mcp4531.c
7359 7359
7360MEDIA DRIVERS FOR RENESAS - FCP
7361M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7362L: linux-media@vger.kernel.org
7363L: linux-renesas-soc@vger.kernel.org
7364T: git git://linuxtv.org/media_tree.git
7365S: Supported
7366F: Documentation/devicetree/bindings/media/renesas,fcp.txt
7367F: drivers/media/platform/rcar-fcp.c
7368F: include/media/rcar-fcp.h
7369
7360MEDIA DRIVERS FOR RENESAS - VSP1 7370MEDIA DRIVERS FOR RENESAS - VSP1
7361M: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 7371M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7362L: linux-media@vger.kernel.org 7372L: linux-media@vger.kernel.org
@@ -7366,8 +7376,18 @@ S: Supported
7366F: Documentation/devicetree/bindings/media/renesas,vsp1.txt 7376F: Documentation/devicetree/bindings/media/renesas,vsp1.txt
7367F: drivers/media/platform/vsp1/ 7377F: drivers/media/platform/vsp1/
7368 7378
7379MEDIA DRIVERS FOR HELENE
7380M: Abylay Ospan <aospan@netup.ru>
7381L: linux-media@vger.kernel.org
7382W: https://linuxtv.org
7383W: http://netup.tv/
7384T: git git://linuxtv.org/media_tree.git
7385S: Supported
7386F: drivers/media/dvb-frontends/helene*
7387
7369MEDIA DRIVERS FOR ASCOT2E 7388MEDIA DRIVERS FOR ASCOT2E
7370M: Sergey Kozlov <serjk@netup.ru> 7389M: Sergey Kozlov <serjk@netup.ru>
7390M: Abylay Ospan <aospan@netup.ru>
7371L: linux-media@vger.kernel.org 7391L: linux-media@vger.kernel.org
7372W: https://linuxtv.org 7392W: https://linuxtv.org
7373W: http://netup.tv/ 7393W: http://netup.tv/
@@ -7377,6 +7397,7 @@ F: drivers/media/dvb-frontends/ascot2e*
7377 7397
7378MEDIA DRIVERS FOR CXD2841ER 7398MEDIA DRIVERS FOR CXD2841ER
7379M: Sergey Kozlov <serjk@netup.ru> 7399M: Sergey Kozlov <serjk@netup.ru>
7400M: Abylay Ospan <aospan@netup.ru>
7380L: linux-media@vger.kernel.org 7401L: linux-media@vger.kernel.org
7381W: https://linuxtv.org 7402W: https://linuxtv.org
7382W: http://netup.tv/ 7403W: http://netup.tv/
@@ -7386,6 +7407,7 @@ F: drivers/media/dvb-frontends/cxd2841er*
7386 7407
7387MEDIA DRIVERS FOR HORUS3A 7408MEDIA DRIVERS FOR HORUS3A
7388M: Sergey Kozlov <serjk@netup.ru> 7409M: Sergey Kozlov <serjk@netup.ru>
7410M: Abylay Ospan <aospan@netup.ru>
7389L: linux-media@vger.kernel.org 7411L: linux-media@vger.kernel.org
7390W: https://linuxtv.org 7412W: https://linuxtv.org
7391W: http://netup.tv/ 7413W: http://netup.tv/
@@ -7395,6 +7417,7 @@ F: drivers/media/dvb-frontends/horus3a*
7395 7417
7396MEDIA DRIVERS FOR LNBH25 7418MEDIA DRIVERS FOR LNBH25
7397M: Sergey Kozlov <serjk@netup.ru> 7419M: Sergey Kozlov <serjk@netup.ru>
7420M: Abylay Ospan <aospan@netup.ru>
7398L: linux-media@vger.kernel.org 7421L: linux-media@vger.kernel.org
7399W: https://linuxtv.org 7422W: https://linuxtv.org
7400W: http://netup.tv/ 7423W: http://netup.tv/
@@ -7404,6 +7427,7 @@ F: drivers/media/dvb-frontends/lnbh25*
7404 7427
7405MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices 7428MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
7406M: Sergey Kozlov <serjk@netup.ru> 7429M: Sergey Kozlov <serjk@netup.ru>
7430M: Abylay Ospan <aospan@netup.ru>
7407L: linux-media@vger.kernel.org 7431L: linux-media@vger.kernel.org
7408W: https://linuxtv.org 7432W: https://linuxtv.org
7409W: http://netup.tv/ 7433W: http://netup.tv/
@@ -7653,10 +7677,8 @@ L: linux-media@vger.kernel.org
7653W: https://linuxtv.org 7677W: https://linuxtv.org
7654W: http://palosaari.fi/linux/ 7678W: http://palosaari.fi/linux/
7655Q: http://patchwork.linuxtv.org/project/linux-media/list/ 7679Q: http://patchwork.linuxtv.org/project/linux-media/list/
7656T: git git://linuxtv.org/anttip/media_tree.git
7657S: Maintained 7680S: Maintained
7658F: drivers/staging/media/mn88472/ 7681F: drivers/media/dvb-frontends/mn88472*
7659F: drivers/media/dvb-frontends/mn88472.h
7660 7682
7661MN88473 MEDIA DRIVER 7683MN88473 MEDIA DRIVER
7662M: Antti Palosaari <crope@iki.fi> 7684M: Antti Palosaari <crope@iki.fi>
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index e671a7cd3463..6ac717f2056f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -148,40 +148,39 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
148 struct rcar_du_vsp_plane_state *state = 148 struct rcar_du_vsp_plane_state *state =
149 to_rcar_vsp_plane_state(plane->plane.state); 149 to_rcar_vsp_plane_state(plane->plane.state);
150 struct drm_framebuffer *fb = plane->plane.state->fb; 150 struct drm_framebuffer *fb = plane->plane.state->fb;
151 struct v4l2_rect src; 151 struct vsp1_du_atomic_config cfg = {
152 struct v4l2_rect dst; 152 .pixelformat = 0,
153 dma_addr_t paddr[2] = { 0, }; 153 .pitch = fb->pitches[0],
154 u32 pixelformat = 0; 154 .alpha = state->alpha,
155 .zpos = state->zpos,
156 };
155 unsigned int i; 157 unsigned int i;
156 158
157 src.left = state->state.src_x >> 16; 159 cfg.src.left = state->state.src_x >> 16;
158 src.top = state->state.src_y >> 16; 160 cfg.src.top = state->state.src_y >> 16;
159 src.width = state->state.src_w >> 16; 161 cfg.src.width = state->state.src_w >> 16;
160 src.height = state->state.src_h >> 16; 162 cfg.src.height = state->state.src_h >> 16;
161 163
162 dst.left = state->state.crtc_x; 164 cfg.dst.left = state->state.crtc_x;
163 dst.top = state->state.crtc_y; 165 cfg.dst.top = state->state.crtc_y;
164 dst.width = state->state.crtc_w; 166 cfg.dst.width = state->state.crtc_w;
165 dst.height = state->state.crtc_h; 167 cfg.dst.height = state->state.crtc_h;
166 168
167 for (i = 0; i < state->format->planes; ++i) { 169 for (i = 0; i < state->format->planes; ++i) {
168 struct drm_gem_cma_object *gem; 170 struct drm_gem_cma_object *gem;
169 171
170 gem = drm_fb_cma_get_gem_obj(fb, i); 172 gem = drm_fb_cma_get_gem_obj(fb, i);
171 paddr[i] = gem->paddr + fb->offsets[i]; 173 cfg.mem[i] = gem->paddr + fb->offsets[i];
172 } 174 }
173 175
174 for (i = 0; i < ARRAY_SIZE(formats_kms); ++i) { 176 for (i = 0; i < ARRAY_SIZE(formats_kms); ++i) {
175 if (formats_kms[i] == state->format->fourcc) { 177 if (formats_kms[i] == state->format->fourcc) {
176 pixelformat = formats_v4l2[i]; 178 cfg.pixelformat = formats_v4l2[i];
177 break; 179 break;
178 } 180 }
179 } 181 }
180 182
181 WARN_ON(!pixelformat); 183 vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
182
183 vsp1_du_atomic_update(plane->vsp->vsp, plane->index, pixelformat,
184 fb->pitches[0], paddr, &src, &dst);
185} 184}
186 185
187static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane, 186static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
@@ -220,8 +219,7 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
220 if (plane->state->crtc) 219 if (plane->state->crtc)
221 rcar_du_vsp_plane_setup(rplane); 220 rcar_du_vsp_plane_setup(rplane);
222 else 221 else
223 vsp1_du_atomic_update(rplane->vsp->vsp, rplane->index, 0, 0, 0, 222 vsp1_du_atomic_update(rplane->vsp->vsp, rplane->index, NULL);
224 NULL, NULL);
225} 223}
226 224
227static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = { 225static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
@@ -269,6 +267,7 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
269 return; 267 return;
270 268
271 state->alpha = 255; 269 state->alpha = 255;
270 state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
272 271
273 plane->state = &state->state; 272 plane->state = &state->state;
274 plane->state->plane = plane; 273 plane->state->plane = plane;
@@ -283,6 +282,8 @@ static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
283 282
284 if (property == rcdu->props.alpha) 283 if (property == rcdu->props.alpha)
285 rstate->alpha = val; 284 rstate->alpha = val;
285 else if (property == rcdu->props.zpos)
286 rstate->zpos = val;
286 else 287 else
287 return -EINVAL; 288 return -EINVAL;
288 289
@@ -299,6 +300,8 @@ static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
299 300
300 if (property == rcdu->props.alpha) 301 if (property == rcdu->props.alpha)
301 *val = rstate->alpha; 302 *val = rstate->alpha;
303 else if (property == rcdu->props.zpos)
304 *val = rstate->zpos;
302 else 305 else
303 return -EINVAL; 306 return -EINVAL;
304 307
@@ -378,6 +381,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
378 381
379 drm_object_attach_property(&plane->plane.base, 382 drm_object_attach_property(&plane->plane.base,
380 rcdu->props.alpha, 255); 383 rcdu->props.alpha, 255);
384 drm_object_attach_property(&plane->plane.base,
385 rcdu->props.zpos, 1);
381 } 386 }
382 387
383 return 0; 388 return 0;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
index df3bf3805c69..510dcc9c6816 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
@@ -44,6 +44,7 @@ static inline struct rcar_du_vsp_plane *to_rcar_vsp_plane(struct drm_plane *p)
44 * @state: base DRM plane state 44 * @state: base DRM plane state
45 * @format: information about the pixel format used by the plane 45 * @format: information about the pixel format used by the plane
46 * @alpha: value of the plane alpha property 46 * @alpha: value of the plane alpha property
47 * @zpos: value of the plane zpos property
47 */ 48 */
48struct rcar_du_vsp_plane_state { 49struct rcar_du_vsp_plane_state {
49 struct drm_plane_state state; 50 struct drm_plane_state state;
@@ -51,6 +52,7 @@ struct rcar_du_vsp_plane_state {
51 const struct rcar_du_format_info *format; 52 const struct rcar_du_format_info *format;
52 53
53 unsigned int alpha; 54 unsigned int alpha;
55 unsigned int zpos;
54}; 56};
55 57
56static inline struct rcar_du_vsp_plane_state * 58static inline struct rcar_du_vsp_plane_state *
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index f82cd1ff4f3a..b1e3a26b1431 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -161,6 +161,18 @@ struct dvb_ca_private {
161 struct mutex ioctl_mutex; 161 struct mutex ioctl_mutex;
162}; 162};
163 163
164static void dvb_ca_private_free(struct dvb_ca_private *ca)
165{
166 unsigned int i;
167
168 dvb_unregister_device(ca->dvbdev);
169 for (i = 0; i < ca->slot_count; i++)
170 vfree(ca->slot_info[i].rx_buffer.data);
171
172 kfree(ca->slot_info);
173 kfree(ca);
174}
175
164static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca); 176static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
165static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount); 177static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
166static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount); 178static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount);
@@ -1759,10 +1771,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1759 1771
1760 for (i = 0; i < ca->slot_count; i++) { 1772 for (i = 0; i < ca->slot_count; i++) {
1761 dvb_ca_en50221_slot_shutdown(ca, i); 1773 dvb_ca_en50221_slot_shutdown(ca, i);
1762 vfree(ca->slot_info[i].rx_buffer.data);
1763 } 1774 }
1764 kfree(ca->slot_info); 1775 dvb_ca_private_free(ca);
1765 dvb_unregister_device(ca->dvbdev);
1766 kfree(ca);
1767 pubca->private = NULL; 1776 pubca->private = NULL;
1768} 1777}
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index a82f77c49bd5..c645aa81f423 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -73,6 +73,14 @@ config DVB_SI2165
73 73
74 Say Y when you want to support this frontend. 74 Say Y when you want to support this frontend.
75 75
76config DVB_MN88472
77 tristate "Panasonic MN88472"
78 depends on DVB_CORE && I2C
79 select REGMAP_I2C
80 default m if !MEDIA_SUBDRV_AUTOSELECT
81 help
82 Say Y when you want to support this frontend.
83
76config DVB_MN88473 84config DVB_MN88473
77 tristate "Panasonic MN88473" 85 tristate "Panasonic MN88473"
78 depends on DVB_CORE && I2C 86 depends on DVB_CORE && I2C
@@ -853,6 +861,13 @@ config DVB_ASCOT2E
853 help 861 help
854 Say Y when you want to support this frontend. 862 Say Y when you want to support this frontend.
855 863
864config DVB_HELENE
865 tristate "Sony HELENE Sat/Ter tuner (CXD2858ER)"
866 depends on DVB_CORE && I2C
867 default m if !MEDIA_SUBDRV_AUTOSELECT
868 help
869 Say Y when you want to support this frontend.
870
856comment "Tools to develop new frontends" 871comment "Tools to develop new frontends"
857 872
858config DVB_DUMMY_FE 873config DVB_DUMMY_FE
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index eb7191f4219d..e90165ad361b 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_DVB_STV0900) += stv0900.o
95obj-$(CONFIG_DVB_STV090x) += stv090x.o 95obj-$(CONFIG_DVB_STV090x) += stv090x.o
96obj-$(CONFIG_DVB_STV6110x) += stv6110x.o 96obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
97obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o 97obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
98obj-$(CONFIG_DVB_MN88472) += mn88472.o
98obj-$(CONFIG_DVB_MN88473) += mn88473.o 99obj-$(CONFIG_DVB_MN88473) += mn88473.o
99obj-$(CONFIG_DVB_ISL6423) += isl6423.o 100obj-$(CONFIG_DVB_ISL6423) += isl6423.o
100obj-$(CONFIG_DVB_EC100) += ec100.o 101obj-$(CONFIG_DVB_EC100) += ec100.o
@@ -123,3 +124,4 @@ obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
123obj-$(CONFIG_DVB_TC90522) += tc90522.o 124obj-$(CONFIG_DVB_TC90522) += tc90522.o
124obj-$(CONFIG_DVB_HORUS3A) += horus3a.o 125obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
125obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o 126obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
127obj-$(CONFIG_DVB_HELENE) += helene.o
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 900186ba8e62..d369a7567d18 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -1,7 +1,9 @@
1/* 1/*
2 * cxd2841er.c 2 * cxd2841er.c
3 * 3 *
4 * Sony CXD2441ER digital demodulator driver 4 * Sony digital demodulator driver for
5 * CXD2841ER - DVB-S/S2/T/T2/C/C2
6 * CXD2854ER - DVB-S/S2/T/T2/C/C2, ISDB-T/S
5 * 7 *
6 * Copyright 2012 Sony Corporation 8 * Copyright 2012 Sony Corporation
7 * Copyright (C) 2014 NetUP Inc. 9 * Copyright (C) 2014 NetUP Inc.
@@ -51,6 +53,8 @@ struct cxd2841er_priv {
51 const struct cxd2841er_config *config; 53 const struct cxd2841er_config *config;
52 enum cxd2841er_state state; 54 enum cxd2841er_state state;
53 u8 system; 55 u8 system;
56 enum cxd2841er_xtal xtal;
57 enum fe_caps caps;
54}; 58};
55 59
56static const struct cxd2841er_cnr_data s_cn_data[] = { 60static const struct cxd2841er_cnr_data s_cn_data[] = {
@@ -188,6 +192,9 @@ static const struct cxd2841er_cnr_data s2_cn_data[] = {
188}; 192};
189 193
190#define MAKE_IFFREQ_CONFIG(iffreq) ((u32)(((iffreq)/41.0)*16777216.0 + 0.5)) 194#define MAKE_IFFREQ_CONFIG(iffreq) ((u32)(((iffreq)/41.0)*16777216.0 + 0.5))
195#define MAKE_IFFREQ_CONFIG_XTAL(xtal, iffreq) ((xtal == SONY_XTAL_24000) ? \
196 (u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \
197 (u32)(((iffreq)/41.0)*16777216.0 + 0.5))
191 198
192static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv, 199static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv,
193 u8 addr, u8 reg, u8 write, 200 u8 addr, u8 reg, u8 write,
@@ -217,7 +224,7 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
217 }; 224 };
218 225
219 if (len + 1 >= sizeof(buf)) { 226 if (len + 1 >= sizeof(buf)) {
220 dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n", 227 dev_warn(&priv->i2c->dev, "wr reg=%04x: len=%d is too big!\n",
221 reg, len + 1); 228 reg, len + 1);
222 return -E2BIG; 229 return -E2BIG;
223 } 230 }
@@ -282,6 +289,7 @@ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
282 KBUILD_MODNAME, ret, i2c_addr, reg); 289 KBUILD_MODNAME, ret, i2c_addr, reg);
283 return ret; 290 return ret;
284 } 291 }
292 cxd2841er_i2c_debug(priv, i2c_addr, reg, 0, val, len);
285 return 0; 293 return 0;
286} 294}
287 295
@@ -427,6 +435,15 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
427static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv, 435static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
428 u32 bandwidth); 436 u32 bandwidth);
429 437
438static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
439 u32 bandwidth);
440
441static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv);
442
443static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv);
444
445static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv);
446
430static int cxd2841er_retune_active(struct cxd2841er_priv *priv, 447static int cxd2841er_retune_active(struct cxd2841er_priv *priv,
431 struct dtv_frontend_properties *p) 448 struct dtv_frontend_properties *p)
432{ 449{
@@ -454,7 +471,13 @@ static int cxd2841er_retune_active(struct cxd2841er_priv *priv,
454 priv, p->bandwidth_hz); 471 priv, p->bandwidth_hz);
455 case SYS_DVBC_ANNEX_A: 472 case SYS_DVBC_ANNEX_A:
456 return cxd2841er_sleep_tc_to_active_c_band( 473 return cxd2841er_sleep_tc_to_active_c_band(
457 priv, 8000000); 474 priv, p->bandwidth_hz);
475 case SYS_ISDBT:
476 cxd2841er_active_i_to_sleep_tc(priv);
477 cxd2841er_sleep_tc_to_shutdown(priv);
478 cxd2841er_shutdown_to_sleep_tc(priv);
479 return cxd2841er_sleep_tc_to_active_i(
480 priv, p->bandwidth_hz);
458 } 481 }
459 } 482 }
460 dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n", 483 dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
@@ -669,6 +692,45 @@ static int cxd2841er_active_c_to_sleep_tc(struct cxd2841er_priv *priv)
669 return 0; 692 return 0;
670} 693}
671 694
695static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv)
696{
697 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
698 if (priv->state != STATE_ACTIVE_TC) {
699 dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
700 __func__, priv->state);
701 return -EINVAL;
702 }
703 /* Set SLV-T Bank : 0x00 */
704 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
705 /* disable TS output */
706 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
707 /* enable Hi-Z setting 1 */
708 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
709 /* enable Hi-Z setting 2 */
710 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
711
712 /* TODO: Cancel demod parameter */
713
714 /* Set SLV-X Bank : 0x00 */
715 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
716 /* disable ADC 1 */
717 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
718 /* Set SLV-T Bank : 0x00 */
719 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
720 /* Disable ADC 2 */
721 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
722 /* Disable ADC 3 */
723 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
724 /* Disable ADC clock */
725 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
726 /* Disable RF level monitor */
727 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
728 /* Disable demod clock */
729 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
730 priv->state = STATE_SLEEP_TC;
731 return 0;
732}
733
672static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv) 734static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv)
673{ 735{
674 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 736 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
@@ -686,8 +748,25 @@ static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv)
686 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 748 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
687 /* Set demod SW reset */ 749 /* Set demod SW reset */
688 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01); 750 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01);
689 /* Set X'tal clock to 20.5Mhz */ 751
690 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x00); 752 switch (priv->xtal) {
753 case SONY_XTAL_20500:
754 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x00);
755 break;
756 case SONY_XTAL_24000:
757 /* Select demod frequency */
758 cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
759 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x03);
760 break;
761 case SONY_XTAL_41000:
762 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x01);
763 break;
764 default:
765 dev_dbg(&priv->i2c->dev, "%s(): invalid demod xtal %d\n",
766 __func__, priv->xtal);
767 return -EINVAL;
768 }
769
691 /* Set demod mode */ 770 /* Set demod mode */
692 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x0a); 771 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x0a);
693 /* Clear demod SW reset */ 772 /* Clear demod SW reset */
@@ -712,6 +791,8 @@ static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv)
712 791
713static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv) 792static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv)
714{ 793{
794 u8 data = 0;
795
715 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 796 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
716 if (priv->state != STATE_SHUTDOWN) { 797 if (priv->state != STATE_SHUTDOWN) {
717 dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n", 798 dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
@@ -727,9 +808,24 @@ static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv)
727 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 808 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
728 /* Set demod SW reset */ 809 /* Set demod SW reset */
729 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01); 810 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01);
730 /* Set X'tal clock to 20.5Mhz */ 811 /* Select ADC clock mode */
731 cxd2841er_write_reg(priv, I2C_SLVX, 0x13, 0x00); 812 cxd2841er_write_reg(priv, I2C_SLVX, 0x13, 0x00);
732 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x00); 813
814 switch (priv->xtal) {
815 case SONY_XTAL_20500:
816 data = 0x0;
817 break;
818 case SONY_XTAL_24000:
819 /* Select demod frequency */
820 cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
821 data = 0x3;
822 break;
823 case SONY_XTAL_41000:
824 cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
825 data = 0x1;
826 break;
827 }
828 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, data);
733 /* Clear demod SW reset */ 829 /* Clear demod SW reset */
734 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00); 830 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00);
735 usleep_range(1000, 2000); 831 usleep_range(1000, 2000);
@@ -809,11 +905,14 @@ static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
809 905
810static u8 cxd2841er_chip_id(struct cxd2841er_priv *priv) 906static u8 cxd2841er_chip_id(struct cxd2841er_priv *priv)
811{ 907{
812 u8 chip_id; 908 u8 chip_id = 0;
813 909
814 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 910 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
815 cxd2841er_write_reg(priv, I2C_SLVT, 0, 0); 911 if (cxd2841er_write_reg(priv, I2C_SLVT, 0, 0) == 0)
816 cxd2841er_read_reg(priv, I2C_SLVT, 0xfd, &chip_id); 912 cxd2841er_read_reg(priv, I2C_SLVT, 0xfd, &chip_id);
913 else if (cxd2841er_write_reg(priv, I2C_SLVX, 0, 0) == 0)
914 cxd2841er_read_reg(priv, I2C_SLVX, 0xfd, &chip_id);
915
817 return chip_id; 916 return chip_id;
818} 917}
819 918
@@ -896,6 +995,25 @@ static int cxd2841er_read_status_c(struct cxd2841er_priv *priv, u8 *tslock)
896 return 0; 995 return 0;
897} 996}
898 997
998static int cxd2841er_read_status_i(struct cxd2841er_priv *priv,
999 u8 *sync, u8 *tslock, u8 *unlock)
1000{
1001 u8 data = 0;
1002
1003 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1004 if (priv->state != STATE_ACTIVE_TC)
1005 return -EINVAL;
1006 /* Set SLV-T Bank : 0x60 */
1007 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1008 cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
1009 dev_dbg(&priv->i2c->dev,
1010 "%s(): lock=0x%x\n", __func__, data);
1011 *sync = ((data & 0x02) ? 1 : 0);
1012 *tslock = ((data & 0x01) ? 1 : 0);
1013 *unlock = ((data & 0x10) ? 1 : 0);
1014 return 0;
1015}
1016
899static int cxd2841er_read_status_tc(struct dvb_frontend *fe, 1017static int cxd2841er_read_status_tc(struct dvb_frontend *fe,
900 enum fe_status *status) 1018 enum fe_status *status)
901{ 1019{
@@ -921,6 +1039,20 @@ static int cxd2841er_read_status_tc(struct dvb_frontend *fe,
921 FE_HAS_SYNC; 1039 FE_HAS_SYNC;
922 if (tslock) 1040 if (tslock)
923 *status |= FE_HAS_LOCK; 1041 *status |= FE_HAS_LOCK;
1042 } else if (priv->system == SYS_ISDBT) {
1043 ret = cxd2841er_read_status_i(
1044 priv, &sync, &tslock, &unlock);
1045 if (ret)
1046 goto done;
1047 if (unlock)
1048 goto done;
1049 if (sync)
1050 *status = FE_HAS_SIGNAL |
1051 FE_HAS_CARRIER |
1052 FE_HAS_VITERBI |
1053 FE_HAS_SYNC;
1054 if (tslock)
1055 *status |= FE_HAS_LOCK;
924 } else if (priv->system == SYS_DVBC_ANNEX_A) { 1056 } else if (priv->system == SYS_DVBC_ANNEX_A) {
925 ret = cxd2841er_read_status_c(priv, &tslock); 1057 ret = cxd2841er_read_status_c(priv, &tslock);
926 if (ret) 1058 if (ret)
@@ -997,6 +1129,76 @@ static int cxd2841er_get_carrier_offset_s_s2(struct cxd2841er_priv *priv,
997 return 0; 1129 return 0;
998} 1130}
999 1131
1132static int cxd2841er_get_carrier_offset_i(struct cxd2841er_priv *priv,
1133 u32 bandwidth, int *offset)
1134{
1135 u8 data[4];
1136
1137 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1138 if (priv->state != STATE_ACTIVE_TC) {
1139 dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1140 __func__, priv->state);
1141 return -EINVAL;
1142 }
1143 if (priv->system != SYS_ISDBT) {
1144 dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
1145 __func__, priv->system);
1146 return -EINVAL;
1147 }
1148 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1149 cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
1150 *offset = -1 * sign_extend32(
1151 ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
1152 ((u32)data[2] << 8) | (u32)data[3], 29);
1153
1154 switch (bandwidth) {
1155 case 6000000:
1156 *offset = -1 * ((*offset) * 8/264);
1157 break;
1158 case 7000000:
1159 *offset = -1 * ((*offset) * 8/231);
1160 break;
1161 case 8000000:
1162 *offset = -1 * ((*offset) * 8/198);
1163 break;
1164 default:
1165 dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
1166 __func__, bandwidth);
1167 return -EINVAL;
1168 }
1169
1170 dev_dbg(&priv->i2c->dev, "%s(): bandwidth %d offset %d\n",
1171 __func__, bandwidth, *offset);
1172
1173 return 0;
1174}
1175
1176static int cxd2841er_get_carrier_offset_t(struct cxd2841er_priv *priv,
1177 u32 bandwidth, int *offset)
1178{
1179 u8 data[4];
1180
1181 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1182 if (priv->state != STATE_ACTIVE_TC) {
1183 dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1184 __func__, priv->state);
1185 return -EINVAL;
1186 }
1187 if (priv->system != SYS_DVBT) {
1188 dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
1189 __func__, priv->system);
1190 return -EINVAL;
1191 }
1192 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1193 cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
1194 *offset = -1 * sign_extend32(
1195 ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
1196 ((u32)data[2] << 8) | (u32)data[3], 29);
1197 *offset *= (bandwidth / 1000000);
1198 *offset /= 235;
1199 return 0;
1200}
1201
1000static int cxd2841er_get_carrier_offset_t2(struct cxd2841er_priv *priv, 1202static int cxd2841er_get_carrier_offset_t2(struct cxd2841er_priv *priv,
1001 u32 bandwidth, int *offset) 1203 u32 bandwidth, int *offset)
1002{ 1204{
@@ -1096,6 +1298,38 @@ static int cxd2841er_read_packet_errors_t2(
1096 return 0; 1298 return 0;
1097} 1299}
1098 1300
1301static int cxd2841er_read_packet_errors_i(
1302 struct cxd2841er_priv *priv, u32 *penum)
1303{
1304 u8 data[2];
1305
1306 *penum = 0;
1307 if (priv->state != STATE_ACTIVE_TC) {
1308 dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1309 __func__, priv->state);
1310 return -EINVAL;
1311 }
1312 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1313 cxd2841er_read_regs(priv, I2C_SLVT, 0xA1, data, 1);
1314
1315 if (!(data[0] & 0x01))
1316 return 0;
1317
1318 /* Layer A */
1319 cxd2841er_read_regs(priv, I2C_SLVT, 0xA2, data, sizeof(data));
1320 *penum = ((u32)data[0] << 8) | (u32)data[1];
1321
1322 /* Layer B */
1323 cxd2841er_read_regs(priv, I2C_SLVT, 0xA4, data, sizeof(data));
1324 *penum += ((u32)data[0] << 8) | (u32)data[1];
1325
1326 /* Layer C */
1327 cxd2841er_read_regs(priv, I2C_SLVT, 0xA6, data, sizeof(data));
1328 *penum += ((u32)data[0] << 8) | (u32)data[1];
1329
1330 return 0;
1331}
1332
1099static u32 cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv) 1333static u32 cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv)
1100{ 1334{
1101 u8 data[11]; 1335 u8 data[11];
@@ -1391,6 +1625,37 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
1391 return 0; 1625 return 0;
1392} 1626}
1393 1627
1628static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
1629{
1630 u32 reg;
1631 u8 data[2];
1632
1633 *snr = 0;
1634 if (priv->state != STATE_ACTIVE_TC) {
1635 dev_dbg(&priv->i2c->dev,
1636 "%s(): invalid state %d\n", __func__,
1637 priv->state);
1638 return -EINVAL;
1639 }
1640
1641 /* Freeze all registers */
1642 cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
1643
1644
1645 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1646 cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
1647 reg = ((u32)data[0] << 8) | (u32)data[1];
1648 if (reg == 0) {
1649 dev_dbg(&priv->i2c->dev,
1650 "%s(): reg value out of range\n", __func__);
1651 return 0;
1652 }
1653 if (reg > 4996)
1654 reg = 4996;
1655 *snr = 100 * intlog10(reg) - 9031;
1656 return 0;
1657}
1658
1394static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv, 1659static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv,
1395 u8 delsys) 1660 u8 delsys)
1396{ 1661{
@@ -1399,6 +1664,26 @@ static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv,
1399 cxd2841er_write_reg( 1664 cxd2841er_write_reg(
1400 priv, I2C_SLVT, 0x00, (delsys == SYS_DVBT ? 0x10 : 0x20)); 1665 priv, I2C_SLVT, 0x00, (delsys == SYS_DVBT ? 0x10 : 0x20));
1401 cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2); 1666 cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2);
1667 dev_dbg(&priv->i2c->dev,
1668 "%s(): AGC value=%u\n",
1669 __func__, (((u16)data[0] & 0x0F) << 8) |
1670 (u16)(data[1] & 0xFF));
1671 return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
1672}
1673
1674static u16 cxd2841er_read_agc_gain_i(struct cxd2841er_priv *priv,
1675 u8 delsys)
1676{
1677 u8 data[2];
1678
1679 cxd2841er_write_reg(
1680 priv, I2C_SLVT, 0x00, 0x60);
1681 cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2);
1682
1683 dev_dbg(&priv->i2c->dev,
1684 "%s(): AGC value=%u\n",
1685 __func__, (((u16)data[0] & 0x0F) << 8) |
1686 (u16)(data[1] & 0xFF));
1402 return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4; 1687 return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
1403} 1688}
1404 1689
@@ -1455,6 +1740,10 @@ static int cxd2841er_read_signal_strength(struct dvb_frontend *fe,
1455 *strength = 65535 - cxd2841er_read_agc_gain_t_t2( 1740 *strength = 65535 - cxd2841er_read_agc_gain_t_t2(
1456 priv, p->delivery_system); 1741 priv, p->delivery_system);
1457 break; 1742 break;
1743 case SYS_ISDBT:
1744 *strength = 65535 - cxd2841er_read_agc_gain_i(
1745 priv, p->delivery_system);
1746 break;
1458 case SYS_DVBS: 1747 case SYS_DVBS:
1459 case SYS_DVBS2: 1748 case SYS_DVBS2:
1460 *strength = 65535 - cxd2841er_read_agc_gain_s(priv); 1749 *strength = 65535 - cxd2841er_read_agc_gain_s(priv);
@@ -1480,6 +1769,9 @@ static int cxd2841er_read_snr(struct dvb_frontend *fe, u16 *snr)
1480 case SYS_DVBT2: 1769 case SYS_DVBT2:
1481 cxd2841er_read_snr_t2(priv, &tmp); 1770 cxd2841er_read_snr_t2(priv, &tmp);
1482 break; 1771 break;
1772 case SYS_ISDBT:
1773 cxd2841er_read_snr_i(priv, &tmp);
1774 break;
1483 case SYS_DVBS: 1775 case SYS_DVBS:
1484 case SYS_DVBS2: 1776 case SYS_DVBS2:
1485 tmp = cxd2841er_dvbs_read_snr(priv, p->delivery_system); 1777 tmp = cxd2841er_dvbs_read_snr(priv, p->delivery_system);
@@ -1506,6 +1798,9 @@ static int cxd2841er_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1506 case SYS_DVBT2: 1798 case SYS_DVBT2:
1507 cxd2841er_read_packet_errors_t2(priv, ucblocks); 1799 cxd2841er_read_packet_errors_t2(priv, ucblocks);
1508 break; 1800 break;
1801 case SYS_ISDBT:
1802 cxd2841er_read_packet_errors_i(priv, ucblocks);
1803 break;
1509 default: 1804 default:
1510 *ucblocks = 0; 1805 *ucblocks = 0;
1511 break; 1806 break;
@@ -1524,15 +1819,18 @@ static int cxd2841er_dvbt2_set_profile(
1524 switch (profile) { 1819 switch (profile) {
1525 case DVBT2_PROFILE_BASE: 1820 case DVBT2_PROFILE_BASE:
1526 tune_mode = 0x01; 1821 tune_mode = 0x01;
1527 seq_not2d_time = 12; 1822 /* Set early unlock time */
1823 seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x0E:0x0C;
1528 break; 1824 break;
1529 case DVBT2_PROFILE_LITE: 1825 case DVBT2_PROFILE_LITE:
1530 tune_mode = 0x05; 1826 tune_mode = 0x05;
1531 seq_not2d_time = 40; 1827 /* Set early unlock time */
1828 seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28;
1532 break; 1829 break;
1533 case DVBT2_PROFILE_ANY: 1830 case DVBT2_PROFILE_ANY:
1534 tune_mode = 0x00; 1831 tune_mode = 0x00;
1535 seq_not2d_time = 40; 1832 /* Set early unlock time */
1833 seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28;
1536 break; 1834 break;
1537 default: 1835 default:
1538 return -EINVAL; 1836 return -EINVAL;
@@ -1574,254 +1872,617 @@ static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
1574 u32 bandwidth) 1872 u32 bandwidth)
1575{ 1873{
1576 u32 iffreq; 1874 u32 iffreq;
1577 u8 b20_9f[5]; 1875 u8 data[MAX_WRITE_REGSIZE];
1578 u8 b10_a6[14]; 1876
1579 u8 b10_b6[3]; 1877 const uint8_t nominalRate8bw[3][5] = {
1580 u8 b10_d7; 1878 /* TRCG Nominal Rate [37:0] */
1879 {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
1880 {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
1881 {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */
1882 };
1883
1884 const uint8_t nominalRate7bw[3][5] = {
1885 /* TRCG Nominal Rate [37:0] */
1886 {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
1887 {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
1888 {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */
1889 };
1890
1891 const uint8_t nominalRate6bw[3][5] = {
1892 /* TRCG Nominal Rate [37:0] */
1893 {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */
1894 {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
1895 {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */
1896 };
1897
1898 const uint8_t nominalRate5bw[3][5] = {
1899 /* TRCG Nominal Rate [37:0] */
1900 {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */
1901 {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */
1902 {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */
1903 };
1904
1905 const uint8_t nominalRate17bw[3][5] = {
1906 /* TRCG Nominal Rate [37:0] */
1907 {0x58, 0xE2, 0xAF, 0xE0, 0xBC}, /* 20.5MHz XTal */
1908 {0x68, 0x0F, 0xA2, 0x32, 0xD0}, /* 24MHz XTal */
1909 {0x58, 0xE2, 0xAF, 0xE0, 0xBC} /* 41MHz XTal */
1910 };
1911
1912 const uint8_t itbCoef8bw[3][14] = {
1913 {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA,
1914 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */
1915 {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1,
1916 0x29, 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */
1917 {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA,
1918 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */
1919 };
1920
1921 const uint8_t itbCoef7bw[3][14] = {
1922 {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6,
1923 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */
1924 {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0,
1925 0x29, 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */
1926 {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6,
1927 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */
1928 };
1929
1930 const uint8_t itbCoef6bw[3][14] = {
1931 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
1932 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
1933 {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E,
1934 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
1935 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
1936 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
1937 };
1938
1939 const uint8_t itbCoef5bw[3][14] = {
1940 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
1941 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
1942 {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E,
1943 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
1944 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
1945 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
1946 };
1947
1948 const uint8_t itbCoef17bw[3][14] = {
1949 {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B,
1950 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99}, /* 20.5MHz XTal */
1951 {0x33, 0x8E, 0x2B, 0x97, 0x2D, 0x95, 0x37, 0x8B,
1952 0x30, 0x97, 0x2D, 0x9A, 0x21, 0xA4}, /* 24MHz XTal */
1953 {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B,
1954 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99} /* 41MHz XTal */
1955 };
1956
1957 /* Set SLV-T Bank : 0x20 */
1958 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
1581 1959
1582 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1583 switch (bandwidth) { 1960 switch (bandwidth) {
1584 case 8000000: 1961 case 8000000:
1585 /* bank 0x20, reg 0x9f */ 1962 /* <Timing Recovery setting> */
1586 b20_9f[0] = 0x11; 1963 cxd2841er_write_regs(priv, I2C_SLVT,
1587 b20_9f[1] = 0xf0; 1964 0x9F, nominalRate8bw[priv->xtal], 5);
1588 b20_9f[2] = 0x00; 1965
1589 b20_9f[3] = 0x00; 1966 /* Set SLV-T Bank : 0x27 */
1590 b20_9f[4] = 0x00; 1967 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
1591 /* bank 0x10, reg 0xa6 */ 1968 cxd2841er_set_reg_bits(priv, I2C_SLVT,
1592 b10_a6[0] = 0x26; 1969 0x7a, 0x00, 0x0f);
1593 b10_a6[1] = 0xaf; 1970
1594 b10_a6[2] = 0x06; 1971 /* Set SLV-T Bank : 0x10 */
1595 b10_a6[3] = 0xcd; 1972 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1596 b10_a6[4] = 0x13; 1973
1597 b10_a6[5] = 0xbb; 1974 /* Group delay equaliser settings for
1598 b10_a6[6] = 0x28; 1975 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1599 b10_a6[7] = 0xba; 1976 */
1600 b10_a6[8] = 0x23; 1977 cxd2841er_write_regs(priv, I2C_SLVT,
1601 b10_a6[9] = 0xa9; 1978 0xA6, itbCoef8bw[priv->xtal], 14);
1602 b10_a6[10] = 0x1f; 1979 /* <IF freq setting> */
1603 b10_a6[11] = 0xa8; 1980 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
1604 b10_a6[12] = 0x2c; 1981 data[0] = (u8) ((iffreq >> 16) & 0xff);
1605 b10_a6[13] = 0xc8; 1982 data[1] = (u8)((iffreq >> 8) & 0xff);
1606 iffreq = MAKE_IFFREQ_CONFIG(4.80); 1983 data[2] = (u8)(iffreq & 0xff);
1607 b10_d7 = 0x00; 1984 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
1985 /* System bandwidth setting */
1986 cxd2841er_set_reg_bits(
1987 priv, I2C_SLVT, 0xD7, 0x00, 0x07);
1608 break; 1988 break;
1609 case 7000000: 1989 case 7000000:
1610 /* bank 0x20, reg 0x9f */ 1990 /* <Timing Recovery setting> */
1611 b20_9f[0] = 0x14; 1991 cxd2841er_write_regs(priv, I2C_SLVT,
1612 b20_9f[1] = 0x80; 1992 0x9F, nominalRate7bw[priv->xtal], 5);
1613 b20_9f[2] = 0x00; 1993
1614 b20_9f[3] = 0x00; 1994 /* Set SLV-T Bank : 0x27 */
1615 b20_9f[4] = 0x00; 1995 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
1616 /* bank 0x10, reg 0xa6 */ 1996 cxd2841er_set_reg_bits(priv, I2C_SLVT,
1617 b10_a6[0] = 0x2C; 1997 0x7a, 0x00, 0x0f);
1618 b10_a6[1] = 0xBD; 1998
1619 b10_a6[2] = 0x02; 1999 /* Set SLV-T Bank : 0x10 */
1620 b10_a6[3] = 0xCF; 2000 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1621 b10_a6[4] = 0x04; 2001
1622 b10_a6[5] = 0xF8; 2002 /* Group delay equaliser settings for
1623 b10_a6[6] = 0x23; 2003 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1624 b10_a6[7] = 0xA6; 2004 */
1625 b10_a6[8] = 0x29; 2005 cxd2841er_write_regs(priv, I2C_SLVT,
1626 b10_a6[9] = 0xB0; 2006 0xA6, itbCoef7bw[priv->xtal], 14);
1627 b10_a6[10] = 0x26; 2007 /* <IF freq setting> */
1628 b10_a6[11] = 0xA9; 2008 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
1629 b10_a6[12] = 0x21; 2009 data[0] = (u8) ((iffreq >> 16) & 0xff);
1630 b10_a6[13] = 0xA5; 2010 data[1] = (u8)((iffreq >> 8) & 0xff);
1631 iffreq = MAKE_IFFREQ_CONFIG(4.2); 2011 data[2] = (u8)(iffreq & 0xff);
1632 b10_d7 = 0x02; 2012 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2013 /* System bandwidth setting */
2014 cxd2841er_set_reg_bits(
2015 priv, I2C_SLVT, 0xD7, 0x02, 0x07);
1633 break; 2016 break;
1634 case 6000000: 2017 case 6000000:
1635 /* bank 0x20, reg 0x9f */ 2018 /* <Timing Recovery setting> */
1636 b20_9f[0] = 0x17; 2019 cxd2841er_write_regs(priv, I2C_SLVT,
1637 b20_9f[1] = 0xEA; 2020 0x9F, nominalRate6bw[priv->xtal], 5);
1638 b20_9f[2] = 0xAA; 2021
1639 b20_9f[3] = 0xAA; 2022 /* Set SLV-T Bank : 0x27 */
1640 b20_9f[4] = 0xAA; 2023 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
1641 /* bank 0x10, reg 0xa6 */ 2024 cxd2841er_set_reg_bits(priv, I2C_SLVT,
1642 b10_a6[0] = 0x27; 2025 0x7a, 0x00, 0x0f);
1643 b10_a6[1] = 0xA7; 2026
1644 b10_a6[2] = 0x28; 2027 /* Set SLV-T Bank : 0x10 */
1645 b10_a6[3] = 0xB3; 2028 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1646 b10_a6[4] = 0x02; 2029
1647 b10_a6[5] = 0xF0; 2030 /* Group delay equaliser settings for
1648 b10_a6[6] = 0x01; 2031 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1649 b10_a6[7] = 0xE8; 2032 */
1650 b10_a6[8] = 0x00; 2033 cxd2841er_write_regs(priv, I2C_SLVT,
1651 b10_a6[9] = 0xCF; 2034 0xA6, itbCoef6bw[priv->xtal], 14);
1652 b10_a6[10] = 0x00; 2035 /* <IF freq setting> */
1653 b10_a6[11] = 0xE6; 2036 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
1654 b10_a6[12] = 0x23; 2037 data[0] = (u8) ((iffreq >> 16) & 0xff);
1655 b10_a6[13] = 0xA4; 2038 data[1] = (u8)((iffreq >> 8) & 0xff);
1656 iffreq = MAKE_IFFREQ_CONFIG(3.6); 2039 data[2] = (u8)(iffreq & 0xff);
1657 b10_d7 = 0x04; 2040 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2041 /* System bandwidth setting */
2042 cxd2841er_set_reg_bits(
2043 priv, I2C_SLVT, 0xD7, 0x04, 0x07);
1658 break; 2044 break;
1659 case 5000000: 2045 case 5000000:
1660 /* bank 0x20, reg 0x9f */ 2046 /* <Timing Recovery setting> */
1661 b20_9f[0] = 0x1C; 2047 cxd2841er_write_regs(priv, I2C_SLVT,
1662 b20_9f[1] = 0xB3; 2048 0x9F, nominalRate5bw[priv->xtal], 5);
1663 b20_9f[2] = 0x33; 2049
1664 b20_9f[3] = 0x33; 2050 /* Set SLV-T Bank : 0x27 */
1665 b20_9f[4] = 0x33; 2051 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
1666 /* bank 0x10, reg 0xa6 */ 2052 cxd2841er_set_reg_bits(priv, I2C_SLVT,
1667 b10_a6[0] = 0x27; 2053 0x7a, 0x00, 0x0f);
1668 b10_a6[1] = 0xA7; 2054
1669 b10_a6[2] = 0x28; 2055 /* Set SLV-T Bank : 0x10 */
1670 b10_a6[3] = 0xB3; 2056 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1671 b10_a6[4] = 0x02; 2057
1672 b10_a6[5] = 0xF0; 2058 /* Group delay equaliser settings for
1673 b10_a6[6] = 0x01; 2059 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1674 b10_a6[7] = 0xE8; 2060 */
1675 b10_a6[8] = 0x00; 2061 cxd2841er_write_regs(priv, I2C_SLVT,
1676 b10_a6[9] = 0xCF; 2062 0xA6, itbCoef5bw[priv->xtal], 14);
1677 b10_a6[10] = 0x00; 2063 /* <IF freq setting> */
1678 b10_a6[11] = 0xE6; 2064 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
1679 b10_a6[12] = 0x23; 2065 data[0] = (u8) ((iffreq >> 16) & 0xff);
1680 b10_a6[13] = 0xA4; 2066 data[1] = (u8)((iffreq >> 8) & 0xff);
1681 iffreq = MAKE_IFFREQ_CONFIG(3.6); 2067 data[2] = (u8)(iffreq & 0xff);
1682 b10_d7 = 0x06; 2068 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2069 /* System bandwidth setting */
2070 cxd2841er_set_reg_bits(
2071 priv, I2C_SLVT, 0xD7, 0x06, 0x07);
1683 break; 2072 break;
1684 case 1712000: 2073 case 1712000:
1685 /* bank 0x20, reg 0x9f */ 2074 /* <Timing Recovery setting> */
1686 b20_9f[0] = 0x58; 2075 cxd2841er_write_regs(priv, I2C_SLVT,
1687 b20_9f[1] = 0xE2; 2076 0x9F, nominalRate17bw[priv->xtal], 5);
1688 b20_9f[2] = 0xAF; 2077
1689 b20_9f[3] = 0xE0; 2078 /* Set SLV-T Bank : 0x27 */
1690 b20_9f[4] = 0xBC; 2079 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
1691 /* bank 0x10, reg 0xa6 */ 2080 cxd2841er_set_reg_bits(priv, I2C_SLVT,
1692 b10_a6[0] = 0x25; 2081 0x7a, 0x03, 0x0f);
1693 b10_a6[1] = 0xA0; 2082
1694 b10_a6[2] = 0x36; 2083 /* Set SLV-T Bank : 0x10 */
1695 b10_a6[3] = 0x8D; 2084 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1696 b10_a6[4] = 0x2E; 2085
1697 b10_a6[5] = 0x94; 2086 /* Group delay equaliser settings for
1698 b10_a6[6] = 0x28; 2087 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1699 b10_a6[7] = 0x9B; 2088 */
1700 b10_a6[8] = 0x32; 2089 cxd2841er_write_regs(priv, I2C_SLVT,
1701 b10_a6[9] = 0x90; 2090 0xA6, itbCoef17bw[priv->xtal], 14);
1702 b10_a6[10] = 0x2C; 2091 /* <IF freq setting> */
1703 b10_a6[11] = 0x9D; 2092 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.50);
1704 b10_a6[12] = 0x29; 2093 data[0] = (u8) ((iffreq >> 16) & 0xff);
1705 b10_a6[13] = 0x99; 2094 data[1] = (u8)((iffreq >> 8) & 0xff);
1706 iffreq = MAKE_IFFREQ_CONFIG(3.5); 2095 data[2] = (u8)(iffreq & 0xff);
1707 b10_d7 = 0x03; 2096 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2097 /* System bandwidth setting */
2098 cxd2841er_set_reg_bits(
2099 priv, I2C_SLVT, 0xD7, 0x03, 0x07);
1708 break; 2100 break;
1709 default: 2101 default:
1710 return -EINVAL; 2102 return -EINVAL;
1711 } 2103 }
1712 /* Set SLV-T Bank : 0x20 */
1713 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x20);
1714 cxd2841er_write_regs(priv, I2C_SLVT, 0x9f, b20_9f, sizeof(b20_9f));
1715 /* Set SLV-T Bank : 0x27 */
1716 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
1717 cxd2841er_set_reg_bits(
1718 priv, I2C_SLVT, 0x7a,
1719 (bandwidth == 1712000 ? 0x03 : 0x00), 0x0f);
1720 /* Set SLV-T Bank : 0x10 */
1721 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1722 /* Group delay equaliser sett. for ASCOT2E */
1723 cxd2841er_write_regs(priv, I2C_SLVT, 0xa6, b10_a6, sizeof(b10_a6));
1724 /* <IF freq setting> */
1725 b10_b6[0] = (u8) ((iffreq >> 16) & 0xff);
1726 b10_b6[1] = (u8)((iffreq >> 8) & 0xff);
1727 b10_b6[2] = (u8)(iffreq & 0xff);
1728 cxd2841er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6));
1729 /* System bandwidth setting */
1730 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, b10_d7, 0x07);
1731 return 0; 2104 return 0;
1732} 2105}
1733 2106
1734static int cxd2841er_sleep_tc_to_active_t_band( 2107static int cxd2841er_sleep_tc_to_active_t_band(
1735 struct cxd2841er_priv *priv, u32 bandwidth) 2108 struct cxd2841er_priv *priv, u32 bandwidth)
1736{ 2109{
1737 u8 b13_9c[2] = { 0x01, 0x14 }; 2110 u8 data[MAX_WRITE_REGSIZE];
1738 u8 bw8mhz_b10_9f[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
1739 u8 bw8mhz_b10_a6[] = { 0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB,
1740 0x28, 0xBA, 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8 };
1741 u8 bw8mhz_b10_d9[] = { 0x01, 0xE0 };
1742 u8 bw8mhz_b17_38[] = { 0x01, 0x02 };
1743 u8 bw7mhz_b10_9f[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
1744 u8 bw7mhz_b10_a6[] = { 0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8,
1745 0x23, 0xA6, 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5 };
1746 u8 bw7mhz_b10_d9[] = { 0x12, 0xF8 };
1747 u8 bw7mhz_b17_38[] = { 0x00, 0x03 };
1748 u8 bw6mhz_b10_9f[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
1749 u8 bw6mhz_b10_a6[] = { 0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0,
1750 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 };
1751 u8 bw6mhz_b10_d9[] = { 0x1F, 0xDC };
1752 u8 bw6mhz_b17_38[] = { 0x00, 0x03 };
1753 u8 bw5mhz_b10_9f[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
1754 u8 bw5mhz_b10_a6[] = { 0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0,
1755 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 };
1756 u8 bw5mhz_b10_d9[] = { 0x26, 0x3C };
1757 u8 bw5mhz_b17_38[] = { 0x00, 0x03 };
1758 u8 b10_b6[3];
1759 u8 d7val;
1760 u32 iffreq; 2111 u32 iffreq;
1761 u8 *b10_9f; 2112 u8 nominalRate8bw[3][5] = {
1762 u8 *b10_a6; 2113 /* TRCG Nominal Rate [37:0] */
1763 u8 *b10_d9; 2114 {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
1764 u8 *b17_38; 2115 {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2116 {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */
2117 };
2118 u8 nominalRate7bw[3][5] = {
2119 /* TRCG Nominal Rate [37:0] */
2120 {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2121 {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2122 {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */
2123 };
2124 u8 nominalRate6bw[3][5] = {
2125 /* TRCG Nominal Rate [37:0] */
2126 {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */
2127 {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2128 {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */
2129 };
2130 u8 nominalRate5bw[3][5] = {
2131 /* TRCG Nominal Rate [37:0] */
2132 {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */
2133 {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */
2134 {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */
2135 };
1765 2136
1766 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2137 u8 itbCoef8bw[3][14] = {
2138 {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9,
2139 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */
2140 {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 0xA5,
2141 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */
2142 {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9,
2143 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */
2144 };
2145 u8 itbCoef7bw[3][14] = {
2146 {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0,
2147 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */
2148 {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 0xA2,
2149 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */
2150 {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0,
2151 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */
2152 };
2153 u8 itbCoef6bw[3][14] = {
2154 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2155 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2156 {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4,
2157 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
2158 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2159 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
2160 };
2161 u8 itbCoef5bw[3][14] = {
2162 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2163 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2164 {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4,
2165 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
2166 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2167 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
2168 };
2169
2170 /* Set SLV-T Bank : 0x13 */
1767 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13); 2171 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13);
1768 /* Echo performance optimization setting */ 2172 /* Echo performance optimization setting */
1769 cxd2841er_write_regs(priv, I2C_SLVT, 0x9c, b13_9c, sizeof(b13_9c)); 2173 data[0] = 0x01;
2174 data[1] = 0x14;
2175 cxd2841er_write_regs(priv, I2C_SLVT, 0x9C, data, 2);
2176
2177 /* Set SLV-T Bank : 0x10 */
1770 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 2178 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1771 2179
1772 switch (bandwidth) { 2180 switch (bandwidth) {
1773 case 8000000: 2181 case 8000000:
1774 b10_9f = bw8mhz_b10_9f; 2182 /* <Timing Recovery setting> */
1775 b10_a6 = bw8mhz_b10_a6; 2183 cxd2841er_write_regs(priv, I2C_SLVT,
1776 b10_d9 = bw8mhz_b10_d9; 2184 0x9F, nominalRate8bw[priv->xtal], 5);
1777 b17_38 = bw8mhz_b17_38; 2185 /* Group delay equaliser settings for
1778 d7val = 0; 2186 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1779 iffreq = MAKE_IFFREQ_CONFIG(4.80); 2187 */
2188 cxd2841er_write_regs(priv, I2C_SLVT,
2189 0xA6, itbCoef8bw[priv->xtal], 14);
2190 /* <IF freq setting> */
2191 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80);
2192 data[0] = (u8) ((iffreq >> 16) & 0xff);
2193 data[1] = (u8)((iffreq >> 8) & 0xff);
2194 data[2] = (u8)(iffreq & 0xff);
2195 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2196 /* System bandwidth setting */
2197 cxd2841er_set_reg_bits(
2198 priv, I2C_SLVT, 0xD7, 0x00, 0x07);
2199
2200 /* Demod core latency setting */
2201 if (priv->xtal == SONY_XTAL_24000) {
2202 data[0] = 0x15;
2203 data[1] = 0x28;
2204 } else {
2205 data[0] = 0x01;
2206 data[1] = 0xE0;
2207 }
2208 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2209
2210 /* Notch filter setting */
2211 data[0] = 0x01;
2212 data[1] = 0x02;
2213 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2214 cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
1780 break; 2215 break;
1781 case 7000000: 2216 case 7000000:
1782 b10_9f = bw7mhz_b10_9f; 2217 /* <Timing Recovery setting> */
1783 b10_a6 = bw7mhz_b10_a6; 2218 cxd2841er_write_regs(priv, I2C_SLVT,
1784 b10_d9 = bw7mhz_b10_d9; 2219 0x9F, nominalRate7bw[priv->xtal], 5);
1785 b17_38 = bw7mhz_b17_38; 2220 /* Group delay equaliser settings for
1786 d7val = 2; 2221 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1787 iffreq = MAKE_IFFREQ_CONFIG(4.20); 2222 */
2223 cxd2841er_write_regs(priv, I2C_SLVT,
2224 0xA6, itbCoef7bw[priv->xtal], 14);
2225 /* <IF freq setting> */
2226 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20);
2227 data[0] = (u8) ((iffreq >> 16) & 0xff);
2228 data[1] = (u8)((iffreq >> 8) & 0xff);
2229 data[2] = (u8)(iffreq & 0xff);
2230 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2231 /* System bandwidth setting */
2232 cxd2841er_set_reg_bits(
2233 priv, I2C_SLVT, 0xD7, 0x02, 0x07);
2234
2235 /* Demod core latency setting */
2236 if (priv->xtal == SONY_XTAL_24000) {
2237 data[0] = 0x1F;
2238 data[1] = 0xF8;
2239 } else {
2240 data[0] = 0x12;
2241 data[1] = 0xF8;
2242 }
2243 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2244
2245 /* Notch filter setting */
2246 data[0] = 0x00;
2247 data[1] = 0x03;
2248 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2249 cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
1788 break; 2250 break;
1789 case 6000000: 2251 case 6000000:
1790 b10_9f = bw6mhz_b10_9f; 2252 /* <Timing Recovery setting> */
1791 b10_a6 = bw6mhz_b10_a6; 2253 cxd2841er_write_regs(priv, I2C_SLVT,
1792 b10_d9 = bw6mhz_b10_d9; 2254 0x9F, nominalRate6bw[priv->xtal], 5);
1793 b17_38 = bw6mhz_b17_38; 2255 /* Group delay equaliser settings for
1794 d7val = 4; 2256 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1795 iffreq = MAKE_IFFREQ_CONFIG(3.60); 2257 */
2258 cxd2841er_write_regs(priv, I2C_SLVT,
2259 0xA6, itbCoef6bw[priv->xtal], 14);
2260 /* <IF freq setting> */
2261 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
2262 data[0] = (u8) ((iffreq >> 16) & 0xff);
2263 data[1] = (u8)((iffreq >> 8) & 0xff);
2264 data[2] = (u8)(iffreq & 0xff);
2265 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2266 /* System bandwidth setting */
2267 cxd2841er_set_reg_bits(
2268 priv, I2C_SLVT, 0xD7, 0x04, 0x07);
2269
2270 /* Demod core latency setting */
2271 if (priv->xtal == SONY_XTAL_24000) {
2272 data[0] = 0x25;
2273 data[1] = 0x4C;
2274 } else {
2275 data[0] = 0x1F;
2276 data[1] = 0xDC;
2277 }
2278 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2279
2280 /* Notch filter setting */
2281 data[0] = 0x00;
2282 data[1] = 0x03;
2283 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2284 cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
1796 break; 2285 break;
1797 case 5000000: 2286 case 5000000:
1798 b10_9f = bw5mhz_b10_9f; 2287 /* <Timing Recovery setting> */
1799 b10_a6 = bw5mhz_b10_a6; 2288 cxd2841er_write_regs(priv, I2C_SLVT,
1800 b10_d9 = bw5mhz_b10_d9; 2289 0x9F, nominalRate5bw[priv->xtal], 5);
1801 b17_38 = bw5mhz_b17_38; 2290 /* Group delay equaliser settings for
1802 d7val = 6; 2291 * ASCOT2D, ASCOT2E and ASCOT3 tuners
1803 iffreq = MAKE_IFFREQ_CONFIG(3.60); 2292 */
2293 cxd2841er_write_regs(priv, I2C_SLVT,
2294 0xA6, itbCoef5bw[priv->xtal], 14);
2295 /* <IF freq setting> */
2296 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60);
2297 data[0] = (u8) ((iffreq >> 16) & 0xff);
2298 data[1] = (u8)((iffreq >> 8) & 0xff);
2299 data[2] = (u8)(iffreq & 0xff);
2300 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2301 /* System bandwidth setting */
2302 cxd2841er_set_reg_bits(
2303 priv, I2C_SLVT, 0xD7, 0x06, 0x07);
2304
2305 /* Demod core latency setting */
2306 if (priv->xtal == SONY_XTAL_24000) {
2307 data[0] = 0x2C;
2308 data[1] = 0xC2;
2309 } else {
2310 data[0] = 0x26;
2311 data[1] = 0x3C;
2312 }
2313 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2314
2315 /* Notch filter setting */
2316 data[0] = 0x00;
2317 data[1] = 0x03;
2318 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2319 cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
2320 break;
2321 }
2322
2323 return 0;
2324}
2325
2326static int cxd2841er_sleep_tc_to_active_i_band(
2327 struct cxd2841er_priv *priv, u32 bandwidth)
2328{
2329 u32 iffreq;
2330 u8 data[3];
2331
2332 /* TRCG Nominal Rate */
2333 u8 nominalRate8bw[3][5] = {
2334 {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2335 {0x11, 0xB8, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2336 {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */
2337 };
2338
2339 u8 nominalRate7bw[3][5] = {
2340 {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2341 {0x14, 0x40, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2342 {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */
2343 };
2344
2345 u8 nominalRate6bw[3][5] = {
2346 {0x14, 0x2E, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2347 {0x17, 0xA0, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2348 {0x14, 0x2E, 0x00, 0x00, 0x00} /* 41MHz XTal */
2349 };
2350
2351 u8 itbCoef8bw[3][14] = {
2352 {0x00}, /* 20.5MHz XTal */
2353 {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29,
2354 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz Xtal */
2355 {0x0}, /* 41MHz XTal */
2356 };
2357
2358 u8 itbCoef7bw[3][14] = {
2359 {0x00}, /* 20.5MHz XTal */
2360 {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29,
2361 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz Xtal */
2362 {0x00}, /* 41MHz XTal */
2363 };
2364
2365 u8 itbCoef6bw[3][14] = {
2366 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00,
2367 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2368 {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29,
2369 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz Xtal */
2370 {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00,
2371 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 41MHz XTal */
2372 };
2373
2374 dev_dbg(&priv->i2c->dev, "%s() bandwidth=%u\n", __func__, bandwidth);
2375 /* Set SLV-T Bank : 0x10 */
2376 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2377
2378 /* 20.5/41MHz Xtal support is not available
2379 * on ISDB-T 7MHzBW and 8MHzBW
2380 */
2381 if (priv->xtal != SONY_XTAL_24000 && bandwidth > 6000000) {
2382 dev_err(&priv->i2c->dev,
2383 "%s(): bandwidth %d supported only for 24MHz xtal\n",
2384 __func__, bandwidth);
2385 return -EINVAL;
2386 }
2387
2388 switch (bandwidth) {
2389 case 8000000:
2390 /* TRCG Nominal Rate */
2391 cxd2841er_write_regs(priv, I2C_SLVT,
2392 0x9F, nominalRate8bw[priv->xtal], 5);
2393 /* Group delay equaliser settings for ASCOT tuners optimized */
2394 cxd2841er_write_regs(priv, I2C_SLVT,
2395 0xA6, itbCoef8bw[priv->xtal], 14);
2396
2397 /* IF freq setting */
2398 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.75);
2399 data[0] = (u8) ((iffreq >> 16) & 0xff);
2400 data[1] = (u8)((iffreq >> 8) & 0xff);
2401 data[2] = (u8)(iffreq & 0xff);
2402 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2403
2404 /* System bandwidth setting */
2405 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x0, 0x7);
2406
2407 /* Demod core latency setting */
2408 data[0] = 0x13;
2409 data[1] = 0xFC;
2410 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2411
2412 /* Acquisition optimization setting */
2413 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12);
2414 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07);
2415 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2416 cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x03);
2417 break;
2418 case 7000000:
2419 /* TRCG Nominal Rate */
2420 cxd2841er_write_regs(priv, I2C_SLVT,
2421 0x9F, nominalRate7bw[priv->xtal], 5);
2422 /* Group delay equaliser settings for ASCOT tuners optimized */
2423 cxd2841er_write_regs(priv, I2C_SLVT,
2424 0xA6, itbCoef7bw[priv->xtal], 14);
2425
2426 /* IF freq setting */
2427 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.15);
2428 data[0] = (u8) ((iffreq >> 16) & 0xff);
2429 data[1] = (u8)((iffreq >> 8) & 0xff);
2430 data[2] = (u8)(iffreq & 0xff);
2431 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2432
2433 /* System bandwidth setting */
2434 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x02, 0x7);
2435
2436 /* Demod core latency setting */
2437 data[0] = 0x1A;
2438 data[1] = 0xFA;
2439 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2440
2441 /* Acquisition optimization setting */
2442 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12);
2443 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07);
2444 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2445 cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02);
2446 break;
2447 case 6000000:
2448 /* TRCG Nominal Rate */
2449 cxd2841er_write_regs(priv, I2C_SLVT,
2450 0x9F, nominalRate6bw[priv->xtal], 5);
2451 /* Group delay equaliser settings for ASCOT tuners optimized */
2452 cxd2841er_write_regs(priv, I2C_SLVT,
2453 0xA6, itbCoef6bw[priv->xtal], 14);
2454
2455 /* IF freq setting */
2456 iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.55);
2457 data[0] = (u8) ((iffreq >> 16) & 0xff);
2458 data[1] = (u8)((iffreq >> 8) & 0xff);
2459 data[2] = (u8)(iffreq & 0xff);
2460 cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2461
2462 /* System bandwidth setting */
2463 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x04, 0x7);
2464
2465 /* Demod core latency setting */
2466 if (priv->xtal == SONY_XTAL_24000) {
2467 data[0] = 0x1F;
2468 data[1] = 0x79;
2469 } else {
2470 data[0] = 0x1A;
2471 data[1] = 0xE2;
2472 }
2473 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2474
2475 /* Acquisition optimization setting */
2476 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12);
2477 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x07, 0x07);
2478 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2479 cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02);
1804 break; 2480 break;
1805 default: 2481 default:
1806 dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n", 2482 dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
1807 __func__, bandwidth); 2483 __func__, bandwidth);
1808 return -EINVAL; 2484 return -EINVAL;
1809 } 2485 }
1810 /* <IF freq setting> */
1811 b10_b6[0] = (u8) ((iffreq >> 16) & 0xff);
1812 b10_b6[1] = (u8)((iffreq >> 8) & 0xff);
1813 b10_b6[2] = (u8)(iffreq & 0xff);
1814 cxd2841er_write_regs(
1815 priv, I2C_SLVT, 0x9f, b10_9f, sizeof(bw8mhz_b10_9f));
1816 cxd2841er_write_regs(
1817 priv, I2C_SLVT, 0xa6, b10_a6, sizeof(bw8mhz_b10_a6));
1818 cxd2841er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6));
1819 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, d7val, 0x7);
1820 cxd2841er_write_regs(
1821 priv, I2C_SLVT, 0xd9, b10_d9, sizeof(bw8mhz_b10_d9));
1822 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
1823 cxd2841er_write_regs(
1824 priv, I2C_SLVT, 0x38, b17_38, sizeof(bw8mhz_b17_38));
1825 return 0; 2486 return 0;
1826} 2487}
1827 2488
@@ -1837,7 +2498,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
1837 u8 b10_b6[3]; 2498 u8 b10_b6[3];
1838 u32 iffreq; 2499 u32 iffreq;
1839 2500
1840 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2501 dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth);
1841 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 2502 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1842 switch (bandwidth) { 2503 switch (bandwidth) {
1843 case 8000000: 2504 case 8000000:
@@ -1854,7 +2515,7 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
1854 iffreq = MAKE_IFFREQ_CONFIG(3.7); 2515 iffreq = MAKE_IFFREQ_CONFIG(3.7);
1855 break; 2516 break;
1856 default: 2517 default:
1857 dev_dbg(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n", 2518 dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
1858 __func__, bandwidth); 2519 __func__, bandwidth);
1859 return -EINVAL; 2520 return -EINVAL;
1860 } 2521 }
@@ -1902,6 +2563,7 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
1902 u32 bandwidth) 2563 u32 bandwidth)
1903{ 2564{
1904 u8 data[2] = { 0x09, 0x54 }; 2565 u8 data[2] = { 0x09, 0x54 };
2566 u8 data24m[3] = {0xDC, 0x6C, 0x00};
1905 2567
1906 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2568 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1907 cxd2841er_set_ts_clock_mode(priv, SYS_DVBT); 2569 cxd2841er_set_ts_clock_mode(priv, SYS_DVBT);
@@ -1919,7 +2581,11 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
1919 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 2581 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
1920 /* Enable ADC 1 */ 2582 /* Enable ADC 1 */
1921 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); 2583 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
1922 /* xtal freq 20.5MHz */ 2584 /* Enable ADC 2 & 3 */
2585 if (priv->xtal == SONY_XTAL_41000) {
2586 data[0] = 0x0A;
2587 data[1] = 0xD4;
2588 }
1923 cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); 2589 cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
1924 /* Enable ADC 4 */ 2590 /* Enable ADC 4 */
1925 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 2591 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
@@ -1947,6 +2613,15 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
1947 /* TSIF setting */ 2613 /* TSIF setting */
1948 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); 2614 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01);
1949 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); 2615 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01);
2616
2617 if (priv->xtal == SONY_XTAL_24000) {
2618 /* Set SLV-T Bank : 0x10 */
2619 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2620 cxd2841er_write_reg(priv, I2C_SLVT, 0xBF, 0x60);
2621 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18);
2622 cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data24m, 3);
2623 }
2624
1950 cxd2841er_sleep_tc_to_active_t_band(priv, bandwidth); 2625 cxd2841er_sleep_tc_to_active_t_band(priv, bandwidth);
1951 /* Set SLV-T Bank : 0x00 */ 2626 /* Set SLV-T Bank : 0x00 */
1952 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2627 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
@@ -1961,7 +2636,7 @@ static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
1961static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv, 2636static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
1962 u32 bandwidth) 2637 u32 bandwidth)
1963{ 2638{
1964 u8 data[2] = { 0x09, 0x54 }; 2639 u8 data[MAX_WRITE_REGSIZE];
1965 2640
1966 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2641 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1967 cxd2841er_set_ts_clock_mode(priv, SYS_DVBT2); 2642 cxd2841er_set_ts_clock_mode(priv, SYS_DVBT2);
@@ -1974,12 +2649,21 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
1974 /* Enable demod clock */ 2649 /* Enable demod clock */
1975 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); 2650 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
1976 /* Disable RF level monitor */ 2651 /* Disable RF level monitor */
2652 cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00);
1977 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 2653 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
1978 /* Enable ADC clock */ 2654 /* Enable ADC clock */
1979 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 2655 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
1980 /* Enable ADC 1 */ 2656 /* Enable ADC 1 */
1981 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); 2657 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
1982 /* xtal freq 20.5MHz */ 2658
2659 if (priv->xtal == SONY_XTAL_41000) {
2660 data[0] = 0x0A;
2661 data[1] = 0xD4;
2662 } else {
2663 data[0] = 0x09;
2664 data[1] = 0x54;
2665 }
2666
1983 cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); 2667 cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
1984 /* Enable ADC 4 */ 2668 /* Enable ADC 4 */
1985 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 2669 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
@@ -2002,6 +2686,10 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
2002 /* Set SLV-T Bank : 0x2b */ 2686 /* Set SLV-T Bank : 0x2b */
2003 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); 2687 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
2004 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x76, 0x20, 0x70); 2688 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x76, 0x20, 0x70);
2689 /* Set SLV-T Bank : 0x23 */
2690 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23);
2691 /* L1 Control setting */
2692 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE6, 0x00, 0x03);
2005 /* Set SLV-T Bank : 0x00 */ 2693 /* Set SLV-T Bank : 0x00 */
2006 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2694 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2007 /* TSIF setting */ 2695 /* TSIF setting */
@@ -2020,6 +2708,72 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
2020 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); 2708 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
2021 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x20, 0x3f); 2709 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x20, 0x3f);
2022 2710
2711 /* 24MHz Xtal setting */
2712 if (priv->xtal == SONY_XTAL_24000) {
2713 /* Set SLV-T Bank : 0x11 */
2714 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
2715 data[0] = 0xEB;
2716 data[1] = 0x03;
2717 data[2] = 0x3B;
2718 cxd2841er_write_regs(priv, I2C_SLVT, 0x33, data, 3);
2719
2720 /* Set SLV-T Bank : 0x20 */
2721 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
2722 data[0] = 0x5E;
2723 data[1] = 0x5E;
2724 data[2] = 0x47;
2725 cxd2841er_write_regs(priv, I2C_SLVT, 0x95, data, 3);
2726
2727 cxd2841er_write_reg(priv, I2C_SLVT, 0x99, 0x18);
2728
2729 data[0] = 0x3F;
2730 data[1] = 0xFF;
2731 cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2732
2733 /* Set SLV-T Bank : 0x24 */
2734 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24);
2735 data[0] = 0x0B;
2736 data[1] = 0x72;
2737 cxd2841er_write_regs(priv, I2C_SLVT, 0x34, data, 2);
2738
2739 data[0] = 0x93;
2740 data[1] = 0xF3;
2741 data[2] = 0x00;
2742 cxd2841er_write_regs(priv, I2C_SLVT, 0xD2, data, 3);
2743
2744 data[0] = 0x05;
2745 data[1] = 0xB8;
2746 data[2] = 0xD8;
2747 cxd2841er_write_regs(priv, I2C_SLVT, 0xDD, data, 3);
2748
2749 cxd2841er_write_reg(priv, I2C_SLVT, 0xE0, 0x00);
2750
2751 /* Set SLV-T Bank : 0x25 */
2752 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x25);
2753 cxd2841er_write_reg(priv, I2C_SLVT, 0xED, 0x60);
2754
2755 /* Set SLV-T Bank : 0x27 */
2756 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
2757 cxd2841er_write_reg(priv, I2C_SLVT, 0xFA, 0x34);
2758
2759 /* Set SLV-T Bank : 0x2B */
2760 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2B);
2761 cxd2841er_write_reg(priv, I2C_SLVT, 0x4B, 0x2F);
2762 cxd2841er_write_reg(priv, I2C_SLVT, 0x9E, 0x0E);
2763
2764 /* Set SLV-T Bank : 0x2D */
2765 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2D);
2766 data[0] = 0x89;
2767 data[1] = 0x89;
2768 cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data, 2);
2769
2770 /* Set SLV-T Bank : 0x5E */
2771 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x5E);
2772 data[0] = 0x24;
2773 data[1] = 0x95;
2774 cxd2841er_write_regs(priv, I2C_SLVT, 0x8C, data, 2);
2775 }
2776
2023 cxd2841er_sleep_tc_to_active_t2_band(priv, bandwidth); 2777 cxd2841er_sleep_tc_to_active_t2_band(priv, bandwidth);
2024 2778
2025 /* Set SLV-T Bank : 0x00 */ 2779 /* Set SLV-T Bank : 0x00 */
@@ -2032,6 +2786,84 @@ static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
2032 return 0; 2786 return 0;
2033} 2787}
2034 2788
2789/* ISDB-Tb part */
2790static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
2791 u32 bandwidth)
2792{
2793 u8 data[2] = { 0x09, 0x54 };
2794 u8 data24m[2] = {0x60, 0x00};
2795 u8 data24m2[3] = {0xB7, 0x1B, 0x00};
2796
2797 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2798 cxd2841er_set_ts_clock_mode(priv, SYS_DVBT);
2799 /* Set SLV-X Bank : 0x00 */
2800 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
2801 /* Set demod mode */
2802 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x06);
2803 /* Set SLV-T Bank : 0x00 */
2804 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2805 /* Enable demod clock */
2806 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
2807 /* Enable RF level monitor */
2808 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x01);
2809 cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x01);
2810 /* Enable ADC clock */
2811 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
2812 /* Enable ADC 1 */
2813 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
2814 /* xtal freq 20.5MHz or 24M */
2815 cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
2816 /* Enable ADC 4 */
2817 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
2818 /* ASCOT setting ON */
2819 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01);
2820 /* FEC Auto Recovery setting */
2821 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01);
2822 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01);
2823 /* ISDB-T initial setting */
2824 /* Set SLV-T Bank : 0x00 */
2825 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2826 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x00, 0x01);
2827 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x00, 0x01);
2828 /* Set SLV-T Bank : 0x10 */
2829 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2830 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x69, 0x04, 0x07);
2831 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x6B, 0x03, 0x07);
2832 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9D, 0x50, 0xFF);
2833 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xD3, 0x06, 0x1F);
2834 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xED, 0x00, 0x01);
2835 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE2, 0xCE, 0x80);
2836 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xF2, 0x13, 0x10);
2837 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x2E, 0x3F);
2838 /* Set SLV-T Bank : 0x15 */
2839 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2840 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x02, 0x03);
2841 /* Set SLV-T Bank : 0x1E */
2842 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x1E);
2843 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x73, 0x68, 0xFF);
2844 /* Set SLV-T Bank : 0x63 */
2845 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x63);
2846 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x81, 0x00, 0x01);
2847
2848 /* for xtal 24MHz */
2849 /* Set SLV-T Bank : 0x10 */
2850 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2851 cxd2841er_write_regs(priv, I2C_SLVT, 0xBF, data24m, 2);
2852 /* Set SLV-T Bank : 0x60 */
2853 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
2854 cxd2841er_write_regs(priv, I2C_SLVT, 0xA8, data24m2, 3);
2855
2856 cxd2841er_sleep_tc_to_active_i_band(priv, bandwidth);
2857 /* Set SLV-T Bank : 0x00 */
2858 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2859 /* Disable HiZ Setting 1 */
2860 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28);
2861 /* Disable HiZ Setting 2 */
2862 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
2863 priv->state = STATE_ACTIVE_TC;
2864 return 0;
2865}
2866
2035static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv, 2867static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
2036 u32 bandwidth) 2868 u32 bandwidth)
2037{ 2869{
@@ -2079,7 +2911,7 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
2079 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); 2911 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01);
2080 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); 2912 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01);
2081 2913
2082 cxd2841er_sleep_tc_to_active_c_band(priv, 8000000); 2914 cxd2841er_sleep_tc_to_active_c_band(priv, bandwidth);
2083 /* Set SLV-T Bank : 0x00 */ 2915 /* Set SLV-T Bank : 0x00 */
2084 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2916 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2085 /* Disable HiZ Setting 1 */ 2917 /* Disable HiZ Setting 1 */
@@ -2142,10 +2974,10 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
2142 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 2974 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
2143 u32 symbol_rate = p->symbol_rate/1000; 2975 u32 symbol_rate = p->symbol_rate/1000;
2144 2976
2145 dev_dbg(&priv->i2c->dev, "%s(): %s frequency=%d symbol_rate=%d\n", 2977 dev_dbg(&priv->i2c->dev, "%s(): %s frequency=%d symbol_rate=%d xtal=%d\n",
2146 __func__, 2978 __func__,
2147 (p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"), 2979 (p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"),
2148 p->frequency, symbol_rate); 2980 p->frequency, symbol_rate, priv->xtal);
2149 switch (priv->state) { 2981 switch (priv->state) {
2150 case STATE_SLEEP_S: 2982 case STATE_SLEEP_S:
2151 ret = cxd2841er_sleep_s_to_active_s( 2983 ret = cxd2841er_sleep_s_to_active_s(
@@ -2199,7 +3031,8 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
2199 struct cxd2841er_priv *priv = fe->demodulator_priv; 3031 struct cxd2841er_priv *priv = fe->demodulator_priv;
2200 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3032 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
2201 3033
2202 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3034 dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n",
3035 __func__, p->delivery_system, p->bandwidth_hz);
2203 if (p->delivery_system == SYS_DVBT) { 3036 if (p->delivery_system == SYS_DVBT) {
2204 priv->system = SYS_DVBT; 3037 priv->system = SYS_DVBT;
2205 switch (priv->state) { 3038 switch (priv->state) {
@@ -2233,9 +3066,33 @@ static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
2233 __func__, priv->state); 3066 __func__, priv->state);
2234 ret = -EINVAL; 3067 ret = -EINVAL;
2235 } 3068 }
3069 } else if (p->delivery_system == SYS_ISDBT) {
3070 priv->system = SYS_ISDBT;
3071 switch (priv->state) {
3072 case STATE_SLEEP_TC:
3073 ret = cxd2841er_sleep_tc_to_active_i(
3074 priv, p->bandwidth_hz);
3075 break;
3076 case STATE_ACTIVE_TC:
3077 ret = cxd2841er_retune_active(priv, p);
3078 break;
3079 default:
3080 dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
3081 __func__, priv->state);
3082 ret = -EINVAL;
3083 }
2236 } else if (p->delivery_system == SYS_DVBC_ANNEX_A || 3084 } else if (p->delivery_system == SYS_DVBC_ANNEX_A ||
2237 p->delivery_system == SYS_DVBC_ANNEX_C) { 3085 p->delivery_system == SYS_DVBC_ANNEX_C) {
2238 priv->system = SYS_DVBC_ANNEX_A; 3086 priv->system = SYS_DVBC_ANNEX_A;
3087 /* correct bandwidth */
3088 if (p->bandwidth_hz != 6000000 &&
3089 p->bandwidth_hz != 7000000 &&
3090 p->bandwidth_hz != 8000000) {
3091 p->bandwidth_hz = 8000000;
3092 dev_dbg(&priv->i2c->dev, "%s(): forcing bandwidth to %d\n",
3093 __func__, p->bandwidth_hz);
3094 }
3095
2239 switch (priv->state) { 3096 switch (priv->state) {
2240 case STATE_SLEEP_TC: 3097 case STATE_SLEEP_TC:
2241 ret = cxd2841er_sleep_tc_to_active_c( 3098 ret = cxd2841er_sleep_tc_to_active_c(
@@ -2321,7 +3178,8 @@ static int cxd2841er_tune_tc(struct dvb_frontend *fe,
2321 struct cxd2841er_priv *priv = fe->demodulator_priv; 3178 struct cxd2841er_priv *priv = fe->demodulator_priv;
2322 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3179 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
2323 3180
2324 dev_dbg(&priv->i2c->dev, "%s(): re_tune %d\n", __func__, re_tune); 3181 dev_dbg(&priv->i2c->dev, "%s(): re_tune %d bandwidth=%d\n", __func__,
3182 re_tune, p->bandwidth_hz);
2325 if (re_tune) { 3183 if (re_tune) {
2326 ret = cxd2841er_set_frontend_tc(fe); 3184 ret = cxd2841er_set_frontend_tc(fe);
2327 if (ret) 3185 if (ret)
@@ -2329,7 +3187,16 @@ static int cxd2841er_tune_tc(struct dvb_frontend *fe,
2329 cxd2841er_read_status_tc(fe, status); 3187 cxd2841er_read_status_tc(fe, status);
2330 if (*status & FE_HAS_LOCK) { 3188 if (*status & FE_HAS_LOCK) {
2331 switch (priv->system) { 3189 switch (priv->system) {
3190 case SYS_ISDBT:
3191 ret = cxd2841er_get_carrier_offset_i(
3192 priv, p->bandwidth_hz,
3193 &carrier_offset);
3194 break;
2332 case SYS_DVBT: 3195 case SYS_DVBT:
3196 ret = cxd2841er_get_carrier_offset_t(
3197 priv, p->bandwidth_hz,
3198 &carrier_offset);
3199 break;
2333 case SYS_DVBT2: 3200 case SYS_DVBT2:
2334 ret = cxd2841er_get_carrier_offset_t2( 3201 ret = cxd2841er_get_carrier_offset_t2(
2335 priv, p->bandwidth_hz, 3202 priv, p->bandwidth_hz,
@@ -2382,6 +3249,9 @@ static int cxd2841er_sleep_tc(struct dvb_frontend *fe)
2382 case SYS_DVBT2: 3249 case SYS_DVBT2:
2383 cxd2841er_active_t2_to_sleep_tc(priv); 3250 cxd2841er_active_t2_to_sleep_tc(priv);
2384 break; 3251 break;
3252 case SYS_ISDBT:
3253 cxd2841er_active_i_to_sleep_tc(priv);
3254 break;
2385 case SYS_DVBC_ANNEX_A: 3255 case SYS_DVBC_ANNEX_A:
2386 cxd2841er_active_c_to_sleep_tc(priv); 3256 cxd2841er_active_c_to_sleep_tc(priv);
2387 break; 3257 break;
@@ -2516,6 +3386,18 @@ static int cxd2841er_init_s(struct dvb_frontend *fe)
2516{ 3386{
2517 struct cxd2841er_priv *priv = fe->demodulator_priv; 3387 struct cxd2841er_priv *priv = fe->demodulator_priv;
2518 3388
3389 /* sanity. force demod to SHUTDOWN state */
3390 if (priv->state == STATE_SLEEP_S) {
3391 dev_dbg(&priv->i2c->dev, "%s() forcing sleep->shutdown\n",
3392 __func__);
3393 cxd2841er_sleep_s_to_shutdown(priv);
3394 } else if (priv->state == STATE_ACTIVE_S) {
3395 dev_dbg(&priv->i2c->dev, "%s() forcing active->sleep->shutdown\n",
3396 __func__);
3397 cxd2841er_active_s_to_sleep_s(priv);
3398 cxd2841er_sleep_s_to_shutdown(priv);
3399 }
3400
2519 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3401 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2520 cxd2841er_shutdown_to_sleep_s(priv); 3402 cxd2841er_shutdown_to_sleep_s(priv);
2521 /* SONY_DEMOD_CONFIG_SAT_IFAGCNEG set to 1 */ 3403 /* SONY_DEMOD_CONFIG_SAT_IFAGCNEG set to 1 */
@@ -2527,8 +3409,10 @@ static int cxd2841er_init_s(struct dvb_frontend *fe)
2527static int cxd2841er_init_tc(struct dvb_frontend *fe) 3409static int cxd2841er_init_tc(struct dvb_frontend *fe)
2528{ 3410{
2529 struct cxd2841er_priv *priv = fe->demodulator_priv; 3411 struct cxd2841er_priv *priv = fe->demodulator_priv;
3412 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
2530 3413
2531 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3414 dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n",
3415 __func__, p->bandwidth_hz);
2532 cxd2841er_shutdown_to_sleep_tc(priv); 3416 cxd2841er_shutdown_to_sleep_tc(priv);
2533 /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */ 3417 /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */
2534 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 3418 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
@@ -2542,8 +3426,7 @@ static int cxd2841er_init_tc(struct dvb_frontend *fe)
2542} 3426}
2543 3427
2544static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops; 3428static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops;
2545static struct dvb_frontend_ops cxd2841er_dvbt_t2_ops; 3429static struct dvb_frontend_ops cxd2841er_t_c_ops;
2546static struct dvb_frontend_ops cxd2841er_dvbc_ops;
2547 3430
2548static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg, 3431static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
2549 struct i2c_adapter *i2c, 3432 struct i2c_adapter *i2c,
@@ -2551,6 +3434,7 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
2551{ 3434{
2552 u8 chip_id = 0; 3435 u8 chip_id = 0;
2553 const char *type; 3436 const char *type;
3437 const char *name;
2554 struct cxd2841er_priv *priv = NULL; 3438 struct cxd2841er_priv *priv = NULL;
2555 3439
2556 /* allocate memory for the internal state */ 3440 /* allocate memory for the internal state */
@@ -2561,46 +3445,49 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
2561 priv->config = cfg; 3445 priv->config = cfg;
2562 priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1; 3446 priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1;
2563 priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1; 3447 priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1;
2564 /* create dvb_frontend */ 3448 priv->xtal = cfg->xtal;
2565 switch (system) {
2566 case SYS_DVBS:
2567 memcpy(&priv->frontend.ops,
2568 &cxd2841er_dvbs_s2_ops,
2569 sizeof(struct dvb_frontend_ops));
2570 type = "S/S2";
2571 break;
2572 case SYS_DVBT:
2573 memcpy(&priv->frontend.ops,
2574 &cxd2841er_dvbt_t2_ops,
2575 sizeof(struct dvb_frontend_ops));
2576 type = "T/T2";
2577 break;
2578 case SYS_DVBC_ANNEX_A:
2579 memcpy(&priv->frontend.ops,
2580 &cxd2841er_dvbc_ops,
2581 sizeof(struct dvb_frontend_ops));
2582 type = "C/C2";
2583 break;
2584 default:
2585 kfree(priv);
2586 return NULL;
2587 }
2588 priv->frontend.demodulator_priv = priv; 3449 priv->frontend.demodulator_priv = priv;
2589 dev_info(&priv->i2c->dev, 3450 dev_info(&priv->i2c->dev,
2590 "%s(): attaching CXD2841ER DVB-%s frontend\n",
2591 __func__, type);
2592 dev_info(&priv->i2c->dev,
2593 "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n", 3451 "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n",
2594 __func__, priv->i2c, 3452 __func__, priv->i2c,
2595 priv->i2c_addr_slvx, priv->i2c_addr_slvt); 3453 priv->i2c_addr_slvx, priv->i2c_addr_slvt);
2596 chip_id = cxd2841er_chip_id(priv); 3454 chip_id = cxd2841er_chip_id(priv);
2597 if (chip_id != CXD2841ER_CHIP_ID) { 3455 switch (chip_id) {
3456 case CXD2841ER_CHIP_ID:
3457 snprintf(cxd2841er_t_c_ops.info.name, 128,
3458 "Sony CXD2841ER DVB-T/T2/C demodulator");
3459 name = "CXD2841ER";
3460 break;
3461 case CXD2854ER_CHIP_ID:
3462 snprintf(cxd2841er_t_c_ops.info.name, 128,
3463 "Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator");
3464 cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT;
3465 name = "CXD2854ER";
3466 break;
3467 default:
2598 dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n", 3468 dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n",
2599 __func__, chip_id); 3469 __func__, chip_id);
2600 priv->frontend.demodulator_priv = NULL; 3470 priv->frontend.demodulator_priv = NULL;
2601 kfree(priv); 3471 kfree(priv);
2602 return NULL; 3472 return NULL;
2603 } 3473 }
3474
3475 /* create dvb_frontend */
3476 if (system == SYS_DVBS) {
3477 memcpy(&priv->frontend.ops,
3478 &cxd2841er_dvbs_s2_ops,
3479 sizeof(struct dvb_frontend_ops));
3480 type = "S/S2";
3481 } else {
3482 memcpy(&priv->frontend.ops,
3483 &cxd2841er_t_c_ops,
3484 sizeof(struct dvb_frontend_ops));
3485 type = "T/T2/C/ISDB-T";
3486 }
3487
3488 dev_info(&priv->i2c->dev,
3489 "%s(): attaching %s DVB-%s frontend\n",
3490 __func__, name, type);
2604 dev_info(&priv->i2c->dev, "%s(): chip ID 0x%02x OK.\n", 3491 dev_info(&priv->i2c->dev, "%s(): chip ID 0x%02x OK.\n",
2605 __func__, chip_id); 3492 __func__, chip_id);
2606 return &priv->frontend; 3493 return &priv->frontend;
@@ -2613,19 +3500,12 @@ struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
2613} 3500}
2614EXPORT_SYMBOL(cxd2841er_attach_s); 3501EXPORT_SYMBOL(cxd2841er_attach_s);
2615 3502
2616struct dvb_frontend *cxd2841er_attach_t(struct cxd2841er_config *cfg, 3503struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
2617 struct i2c_adapter *i2c) 3504 struct i2c_adapter *i2c)
2618{ 3505{
2619 return cxd2841er_attach(cfg, i2c, SYS_DVBT); 3506 return cxd2841er_attach(cfg, i2c, 0);
2620} 3507}
2621EXPORT_SYMBOL(cxd2841er_attach_t); 3508EXPORT_SYMBOL(cxd2841er_attach_t_c);
2622
2623struct dvb_frontend *cxd2841er_attach_c(struct cxd2841er_config *cfg,
2624 struct i2c_adapter *i2c)
2625{
2626 return cxd2841er_attach(cfg, i2c, SYS_DVBC_ANNEX_A);
2627}
2628EXPORT_SYMBOL(cxd2841er_attach_c);
2629 3509
2630static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { 3510static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
2631 .delsys = { SYS_DVBS, SYS_DVBS2 }, 3511 .delsys = { SYS_DVBS, SYS_DVBS2 },
@@ -2655,10 +3535,10 @@ static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
2655 .tune = cxd2841er_tune_s 3535 .tune = cxd2841er_tune_s
2656}; 3536};
2657 3537
2658static struct dvb_frontend_ops cxd2841er_dvbt_t2_ops = { 3538static struct dvb_frontend_ops cxd2841er_t_c_ops = {
2659 .delsys = { SYS_DVBT, SYS_DVBT2 }, 3539 .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
2660 .info = { 3540 .info = {
2661 .name = "Sony CXD2841ER DVB-T/T2 demodulator", 3541 .name = "", /* will set in attach function */
2662 .caps = FE_CAN_FEC_1_2 | 3542 .caps = FE_CAN_FEC_1_2 |
2663 FE_CAN_FEC_2_3 | 3543 FE_CAN_FEC_2_3 |
2664 FE_CAN_FEC_3_4 | 3544 FE_CAN_FEC_3_4 |
@@ -2691,37 +3571,6 @@ static struct dvb_frontend_ops cxd2841er_dvbt_t2_ops = {
2691 .get_frontend_algo = cxd2841er_get_algo 3571 .get_frontend_algo = cxd2841er_get_algo
2692}; 3572};
2693 3573
2694static struct dvb_frontend_ops cxd2841er_dvbc_ops = { 3574MODULE_DESCRIPTION("Sony CXD2841ER/CXD2854ER DVB-C/C2/T/T2/S/S2 demodulator driver");
2695 .delsys = { SYS_DVBC_ANNEX_A }, 3575MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>, Abylay Ospan <aospan@netup.ru>");
2696 .info = {
2697 .name = "Sony CXD2841ER DVB-C demodulator",
2698 .caps = FE_CAN_FEC_1_2 |
2699 FE_CAN_FEC_2_3 |
2700 FE_CAN_FEC_3_4 |
2701 FE_CAN_FEC_5_6 |
2702 FE_CAN_FEC_7_8 |
2703 FE_CAN_FEC_AUTO |
2704 FE_CAN_QAM_16 |
2705 FE_CAN_QAM_32 |
2706 FE_CAN_QAM_64 |
2707 FE_CAN_QAM_128 |
2708 FE_CAN_QAM_256 |
2709 FE_CAN_QAM_AUTO |
2710 FE_CAN_INVERSION_AUTO,
2711 .frequency_min = 42000000,
2712 .frequency_max = 1002000000
2713 },
2714 .init = cxd2841er_init_tc,
2715 .sleep = cxd2841er_sleep_tc,
2716 .release = cxd2841er_release,
2717 .set_frontend = cxd2841er_set_frontend_tc,
2718 .get_frontend = cxd2841er_get_frontend,
2719 .read_status = cxd2841er_read_status_tc,
2720 .tune = cxd2841er_tune_tc,
2721 .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl,
2722 .get_frontend_algo = cxd2841er_get_algo,
2723};
2724
2725MODULE_DESCRIPTION("Sony CXD2841ER DVB-C/C2/T/T2/S/S2 demodulator driver");
2726MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>");
2727MODULE_LICENSE("GPL"); 3576MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/cxd2841er.h b/drivers/media/dvb-frontends/cxd2841er.h
index 3472bdd58949..62ad5f07390b 100644
--- a/drivers/media/dvb-frontends/cxd2841er.h
+++ b/drivers/media/dvb-frontends/cxd2841er.h
@@ -25,41 +25,39 @@
25#include <linux/kconfig.h> 25#include <linux/kconfig.h>
26#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
27 27
28enum cxd2841er_xtal {
29 SONY_XTAL_20500, /* 20.5 MHz */
30 SONY_XTAL_24000, /* 24 MHz */
31 SONY_XTAL_41000 /* 41 MHz */
32};
33
28struct cxd2841er_config { 34struct cxd2841er_config {
29 u8 i2c_addr; 35 u8 i2c_addr;
36 enum cxd2841er_xtal xtal;
30}; 37};
31 38
32#if IS_REACHABLE(CONFIG_DVB_CXD2841ER) 39#if IS_REACHABLE(CONFIG_DVB_CXD2841ER)
33extern struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg, 40extern struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
34 struct i2c_adapter *i2c); 41 struct i2c_adapter *i2c);
35 42
36extern struct dvb_frontend *cxd2841er_attach_t(struct cxd2841er_config *cfg, 43extern struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
37 struct i2c_adapter *i2c);
38
39extern struct dvb_frontend *cxd2841er_attach_c(struct cxd2841er_config *cfg,
40 struct i2c_adapter *i2c); 44 struct i2c_adapter *i2c);
41#else 45#else
42static inline struct dvb_frontend *cxd2841er_attach_s( 46static inline struct dvb_frontend *cxd2841er_attach_s(
43 struct cxd2841er_config *cfg, 47 struct cxd2841er_config *cfg,
44 struct i2c_adapter *i2c) 48 struct i2c_adapter *i2c)
45{ 49{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 50 pr_warn("%s: driver disabled by Kconfig\n", __func__);
47 return NULL; 51 return NULL;
48} 52}
49 53
50static inline struct dvb_frontend *cxd2841er_attach_t( 54static inline struct dvb_frontend *cxd2841er_attach_t_c(
51 struct cxd2841er_config *cfg, struct i2c_adapter *i2c) 55 struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
52{ 56{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 57 pr_warn("%s: driver disabled by Kconfig\n", __func__);
54 return NULL; 58 return NULL;
55} 59}
56 60
57static inline struct dvb_frontend *cxd2841er_attach_c(
58 struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
59{
60 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
61 return NULL;
62}
63#endif 61#endif
64 62
65#endif 63#endif
diff --git a/drivers/media/dvb-frontends/cxd2841er_priv.h b/drivers/media/dvb-frontends/cxd2841er_priv.h
index 33e2f495277b..0bbce451149f 100644
--- a/drivers/media/dvb-frontends/cxd2841er_priv.h
+++ b/drivers/media/dvb-frontends/cxd2841er_priv.h
@@ -26,6 +26,7 @@
26#define I2C_SLVT 1 26#define I2C_SLVT 1
27 27
28#define CXD2841ER_CHIP_ID 0xa7 28#define CXD2841ER_CHIP_ID 0xa7
29#define CXD2854ER_CHIP_ID 0xc1
29 30
30#define CXD2841ER_DVBS_POLLING_INVL 10 31#define CXD2841ER_DVBS_POLLING_INVL 10
31 32
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
index addffc33993a..447b518e287a 100644
--- a/drivers/media/dvb-frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -959,6 +959,15 @@ static int ds3000_set_frontend(struct dvb_frontend *fe)
959 /* enable ac coupling */ 959 /* enable ac coupling */
960 ds3000_writereg(state, 0x25, 0x8a); 960 ds3000_writereg(state, 0x25, 0x8a);
961 961
962 if ((c->symbol_rate < ds3000_ops.info.symbol_rate_min) ||
963 (c->symbol_rate > ds3000_ops.info.symbol_rate_max)) {
964 dprintk("%s() symbol_rate %u out of range (%u ... %u)\n",
965 __func__, c->symbol_rate,
966 ds3000_ops.info.symbol_rate_min,
967 ds3000_ops.info.symbol_rate_max);
968 return -EINVAL;
969 }
970
962 /* enhance symbol rate performance */ 971 /* enhance symbol rate performance */
963 if ((c->symbol_rate / 1000) <= 5000) { 972 if ((c->symbol_rate / 1000) <= 5000) {
964 value = 29777 / (c->symbol_rate / 1000) + 1; 973 value = 29777 / (c->symbol_rate / 1000) + 1;
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
new file mode 100644
index 000000000000..97a8982740a6
--- /dev/null
+++ b/drivers/media/dvb-frontends/helene.c
@@ -0,0 +1,1042 @@
1/*
2 * helene.c
3 *
4 * Sony HELENE DVB-S/S2 DVB-T/T2 DVB-C/C2 ISDB-T/S tuner driver (CXD2858ER)
5 *
6 * Copyright 2012 Sony Corporation
7 * Copyright (C) 2014 NetUP Inc.
8 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * 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 */
20
21#include <linux/slab.h>
22#include <linux/module.h>
23#include <linux/dvb/frontend.h>
24#include <linux/types.h>
25#include "helene.h"
26#include "dvb_frontend.h"
27
28#define MAX_WRITE_REGSIZE 20
29
30enum helene_state {
31 STATE_UNKNOWN,
32 STATE_SLEEP,
33 STATE_ACTIVE
34};
35
36struct helene_priv {
37 u32 frequency;
38 u8 i2c_address;
39 struct i2c_adapter *i2c;
40 enum helene_state state;
41 void *set_tuner_data;
42 int (*set_tuner)(void *, int);
43 enum helene_xtal xtal;
44};
45
46#define TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system) \
47 (((tv_system) != SONY_HELENE_DTV_DVBC_6) && \
48 ((tv_system) != SONY_HELENE_DTV_DVBC_8)\
49 && ((tv_system) != SONY_HELENE_DTV_DVBC2_6) && \
50 ((tv_system) != SONY_HELENE_DTV_DVBC2_8))
51
52#define HELENE_AUTO 0xff
53#define HELENE_OFFSET(ofs) ((u8)(ofs) & 0x1F)
54#define HELENE_BW_6 0x00
55#define HELENE_BW_7 0x01
56#define HELENE_BW_8 0x02
57#define HELENE_BW_1_7 0x03
58
59enum helene_tv_system_t {
60 SONY_HELENE_TV_SYSTEM_UNKNOWN,
61 /* Terrestrial Analog */
62 SONY_HELENE_ATV_MN_EIAJ,
63 /**< System-M (Japan) (IF: Fp=5.75MHz in default) */
64 SONY_HELENE_ATV_MN_SAP,
65 /**< System-M (US) (IF: Fp=5.75MHz in default) */
66 SONY_HELENE_ATV_MN_A2,
67 /**< System-M (Korea) (IF: Fp=5.9MHz in default) */
68 SONY_HELENE_ATV_BG,
69 /**< System-B/G (IF: Fp=7.3MHz in default) */
70 SONY_HELENE_ATV_I,
71 /**< System-I (IF: Fp=7.85MHz in default) */
72 SONY_HELENE_ATV_DK,
73 /**< System-D/K (IF: Fp=7.85MHz in default) */
74 SONY_HELENE_ATV_L,
75 /**< System-L (IF: Fp=7.85MHz in default) */
76 SONY_HELENE_ATV_L_DASH,
77 /**< System-L DASH (IF: Fp=2.2MHz in default) */
78 /* Terrestrial/Cable Digital */
79 SONY_HELENE_DTV_8VSB,
80 /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */
81 SONY_HELENE_DTV_QAM,
82 /**< US QAM (IF: Fc=3.7MHz in default) */
83 SONY_HELENE_DTV_ISDBT_6,
84 /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */
85 SONY_HELENE_DTV_ISDBT_7,
86 /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */
87 SONY_HELENE_DTV_ISDBT_8,
88 /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */
89 SONY_HELENE_DTV_DVBT_5,
90 /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */
91 SONY_HELENE_DTV_DVBT_6,
92 /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */
93 SONY_HELENE_DTV_DVBT_7,
94 /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */
95 SONY_HELENE_DTV_DVBT_8,
96 /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */
97 SONY_HELENE_DTV_DVBT2_1_7,
98 /**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */
99 SONY_HELENE_DTV_DVBT2_5,
100 /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */
101 SONY_HELENE_DTV_DVBT2_6,
102 /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */
103 SONY_HELENE_DTV_DVBT2_7,
104 /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */
105 SONY_HELENE_DTV_DVBT2_8,
106 /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */
107 SONY_HELENE_DTV_DVBC_6,
108 /**< DVB-C 6MHzBW (IF: Fc=3.7MHz in default) */
109 SONY_HELENE_DTV_DVBC_8,
110 /**< DVB-C 8MHzBW (IF: Fc=4.9MHz in default) */
111 SONY_HELENE_DTV_DVBC2_6,
112 /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */
113 SONY_HELENE_DTV_DVBC2_8,
114 /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */
115 SONY_HELENE_DTV_DTMB,
116 /**< DTMB (IF: Fc=5.1MHz in default) */
117 /* Satellite */
118 SONY_HELENE_STV_ISDBS,
119 /**< ISDB-S */
120 SONY_HELENE_STV_DVBS,
121 /**< DVB-S */
122 SONY_HELENE_STV_DVBS2,
123 /**< DVB-S2 */
124
125 SONY_HELENE_ATV_MIN = SONY_HELENE_ATV_MN_EIAJ,
126 /**< Minimum analog terrestrial system */
127 SONY_HELENE_ATV_MAX = SONY_HELENE_ATV_L_DASH,
128 /**< Maximum analog terrestrial system */
129 SONY_HELENE_DTV_MIN = SONY_HELENE_DTV_8VSB,
130 /**< Minimum digital terrestrial system */
131 SONY_HELENE_DTV_MAX = SONY_HELENE_DTV_DTMB,
132 /**< Maximum digital terrestrial system */
133 SONY_HELENE_TERR_TV_SYSTEM_NUM,
134 /**< Number of supported terrestrial broadcasting system */
135 SONY_HELENE_STV_MIN = SONY_HELENE_STV_ISDBS,
136 /**< Minimum satellite system */
137 SONY_HELENE_STV_MAX = SONY_HELENE_STV_DVBS2
138 /**< Maximum satellite system */
139};
140
141struct helene_terr_adjust_param_t {
142 /* < Addr:0x69 Bit[6:4] : RFVGA gain.
143 * 0xFF means Auto. (RF_GAIN_SEL = 1)
144 */
145 uint8_t RF_GAIN;
146 /* < Addr:0x69 Bit[3:0] : IF_BPF gain.
147 */
148 uint8_t IF_BPF_GC;
149 /* < Addr:0x6B Bit[3:0] : RF overload
150 * RF input detect level. (FRF <= 172MHz)
151 */
152 uint8_t RFOVLD_DET_LV1_VL;
153 /* < Addr:0x6B Bit[3:0] : RF overload
154 * RF input detect level. (172MHz < FRF <= 464MHz)
155 */
156 uint8_t RFOVLD_DET_LV1_VH;
157 /* < Addr:0x6B Bit[3:0] : RF overload
158 * RF input detect level. (FRF > 464MHz)
159 */
160 uint8_t RFOVLD_DET_LV1_U;
161 /* < Addr:0x6C Bit[2:0] :
162 * Internal RFAGC detect level. (FRF <= 172MHz)
163 */
164 uint8_t IFOVLD_DET_LV_VL;
165 /* < Addr:0x6C Bit[2:0] :
166 * Internal RFAGC detect level. (172MHz < FRF <= 464MHz)
167 */
168 uint8_t IFOVLD_DET_LV_VH;
169 /* < Addr:0x6C Bit[2:0] :
170 * Internal RFAGC detect level. (FRF > 464MHz)
171 */
172 uint8_t IFOVLD_DET_LV_U;
173 /* < Addr:0x6D Bit[5:4] :
174 * IF filter center offset.
175 */
176 uint8_t IF_BPF_F0;
177 /* < Addr:0x6D Bit[1:0] :
178 * 6MHzBW(0x00) or 7MHzBW(0x01)
179 * or 8MHzBW(0x02) or 1.7MHzBW(0x03)
180 */
181 uint8_t BW;
182 /* < Addr:0x6E Bit[4:0] :
183 * 5bit signed. IF offset (kHz) = FIF_OFFSET x 50
184 */
185 uint8_t FIF_OFFSET;
186 /* < Addr:0x6F Bit[4:0] :
187 * 5bit signed. BW offset (kHz) =
188 * BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW)
189 */
190 uint8_t BW_OFFSET;
191 /* < Addr:0x9C Bit[0] :
192 * Local polarity. (0: Upper Local, 1: Lower Local)
193 */
194 uint8_t IS_LOWERLOCAL;
195};
196
197static const struct helene_terr_adjust_param_t
198terr_params[SONY_HELENE_TERR_TV_SYSTEM_NUM] = {
199 /*< SONY_HELENE_TV_SYSTEM_UNKNOWN */
200 {HELENE_AUTO, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(0), 0x00},
202 /* Analog */
203 /**< SONY_HELENE_ATV_MN_EIAJ (System-M (Japan)) */
204 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
205 HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(1), 0x00},
206 /**< SONY_HELENE_ATV_MN_SAP (System-M (US)) */
207 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
208 HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(1), 0x00},
209 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
210 HELENE_BW_6, HELENE_OFFSET(3), HELENE_OFFSET(1), 0x00},
211 /**< SONY_HELENE_ATV_MN_A2 (System-M (Korea)) */
212 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
213 HELENE_BW_7, HELENE_OFFSET(11), HELENE_OFFSET(5), 0x00},
214 /**< SONY_HELENE_ATV_BG (System-B/G) */
215 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
216 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00},
217 /**< SONY_HELENE_ATV_I (System-I) */
218 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
219 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00},
220 /**< SONY_HELENE_ATV_DK (System-D/K) */
221 {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00,
222 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00},
223 /**< SONY_HELENE_ATV_L (System-L) */
224 {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00,
225 HELENE_BW_8, HELENE_OFFSET(-1), HELENE_OFFSET(4), 0x00},
226 /**< SONY_HELENE_ATV_L_DASH (System-L DASH) */
227 /* Digital */
228 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x03, 0x03, 0x03, 0x00,
229 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00},
230 /**< SONY_HELENE_DTV_8VSB (ATSC 8VSB) */
231 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
232 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00},
233 /**< SONY_HELENE_DTV_QAM (US QAM) */
234 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
235 HELENE_BW_6, HELENE_OFFSET(-9), HELENE_OFFSET(-5), 0x00},
236 /**< SONY_HELENE_DTV_ISDBT_6 (ISDB-T 6MHzBW) */
237 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
238 HELENE_BW_7, HELENE_OFFSET(-7), HELENE_OFFSET(-6), 0x00},
239 /**< SONY_HELENE_DTV_ISDBT_7 (ISDB-T 7MHzBW) */
240 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
241 HELENE_BW_8, HELENE_OFFSET(-5), HELENE_OFFSET(-7), 0x00},
242 /**< SONY_HELENE_DTV_ISDBT_8 (ISDB-T 8MHzBW) */
243 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
244 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
245 /**< SONY_HELENE_DTV_DVBT_5 (DVB-T 5MHzBW) */
246 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
247 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
248 /**< SONY_HELENE_DTV_DVBT_6 (DVB-T 6MHzBW) */
249 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
250 HELENE_BW_7, HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00},
251 /**< SONY_HELENE_DTV_DVBT_7 (DVB-T 7MHzBW) */
252 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
253 HELENE_BW_8, HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00},
254 /**< SONY_HELENE_DTV_DVBT_8 (DVB-T 8MHzBW) */
255 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
256 HELENE_BW_1_7, HELENE_OFFSET(-10), HELENE_OFFSET(-10), 0x00},
257 /**< SONY_HELENE_DTV_DVBT2_1_7 (DVB-T2 1.7MHzBW) */
258 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
259 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
260 /**< SONY_HELENE_DTV_DVBT2_5 (DVB-T2 5MHzBW) */
261 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
262 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
263 /**< SONY_HELENE_DTV_DVBT2_6 (DVB-T2 6MHzBW) */
264 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
265 HELENE_BW_7, HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00},
266 /**< SONY_HELENE_DTV_DVBT2_7 (DVB-T2 7MHzBW) */
267 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
268 HELENE_BW_8, HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00},
269 /**< SONY_HELENE_DTV_DVBT2_8 (DVB-T2 8MHzBW) */
270 {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00,
271 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-4), 0x00},
272 /**< SONY_HELENE_DTV_DVBC_6 (DVB-C 6MHzBW) */
273 {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00,
274 HELENE_BW_8, HELENE_OFFSET(-2), HELENE_OFFSET(-3), 0x00},
275 /**< SONY_HELENE_DTV_DVBC_8 (DVB-C 8MHzBW) */
276 {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00,
277 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-2), 0x00},
278 /**< SONY_HELENE_DTV_DVBC2_6 (DVB-C2 6MHzBW) */
279 {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00,
280 HELENE_BW_8, HELENE_OFFSET(-2), HELENE_OFFSET(0), 0x00},
281 /**< SONY_HELENE_DTV_DVBC2_8 (DVB-C2 8MHzBW) */
282 {HELENE_AUTO, 0x04, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
283 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(1), 0x00}
284 /**< SONY_HELENE_DTV_DTMB (DTMB) */
285};
286
287static void helene_i2c_debug(struct helene_priv *priv,
288 u8 reg, u8 write, const u8 *data, u32 len)
289{
290 dev_dbg(&priv->i2c->dev, "helene: I2C %s reg 0x%02x size %d\n",
291 (write == 0 ? "read" : "write"), reg, len);
292 print_hex_dump_bytes("helene: I2C data: ",
293 DUMP_PREFIX_OFFSET, data, len);
294}
295
296static int helene_write_regs(struct helene_priv *priv,
297 u8 reg, const u8 *data, u32 len)
298{
299 int ret;
300 u8 buf[MAX_WRITE_REGSIZE + 1];
301 struct i2c_msg msg[1] = {
302 {
303 .addr = priv->i2c_address,
304 .flags = 0,
305 .len = len + 1,
306 .buf = buf,
307 }
308 };
309
310 if (len + 1 > sizeof(buf)) {
311 dev_warn(&priv->i2c->dev,
312 "wr reg=%04x: len=%d vs %Zu is too big!\n",
313 reg, len + 1, sizeof(buf));
314 return -E2BIG;
315 }
316
317 helene_i2c_debug(priv, reg, 1, data, len);
318 buf[0] = reg;
319 memcpy(&buf[1], data, len);
320 ret = i2c_transfer(priv->i2c, msg, 1);
321 if (ret >= 0 && ret != 1)
322 ret = -EREMOTEIO;
323 if (ret < 0) {
324 dev_warn(&priv->i2c->dev,
325 "%s: i2c wr failed=%d reg=%02x len=%d\n",
326 KBUILD_MODNAME, ret, reg, len);
327 return ret;
328 }
329 return 0;
330}
331
332static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
333{
334 return helene_write_regs(priv, reg, &val, 1);
335}
336
337static int helene_read_regs(struct helene_priv *priv,
338 u8 reg, u8 *val, u32 len)
339{
340 int ret;
341 struct i2c_msg msg[2] = {
342 {
343 .addr = priv->i2c_address,
344 .flags = 0,
345 .len = 1,
346 .buf = &reg,
347 }, {
348 .addr = priv->i2c_address,
349 .flags = I2C_M_RD,
350 .len = len,
351 .buf = val,
352 }
353 };
354
355 ret = i2c_transfer(priv->i2c, &msg[0], 1);
356 if (ret >= 0 && ret != 1)
357 ret = -EREMOTEIO;
358 if (ret < 0) {
359 dev_warn(&priv->i2c->dev,
360 "%s: I2C rw failed=%d addr=%02x reg=%02x\n",
361 KBUILD_MODNAME, ret, priv->i2c_address, reg);
362 return ret;
363 }
364 ret = i2c_transfer(priv->i2c, &msg[1], 1);
365 if (ret >= 0 && ret != 1)
366 ret = -EREMOTEIO;
367 if (ret < 0) {
368 dev_warn(&priv->i2c->dev,
369 "%s: i2c rd failed=%d addr=%02x reg=%02x\n",
370 KBUILD_MODNAME, ret, priv->i2c_address, reg);
371 return ret;
372 }
373 helene_i2c_debug(priv, reg, 0, val, len);
374 return 0;
375}
376
377static int helene_read_reg(struct helene_priv *priv, u8 reg, u8 *val)
378{
379 return helene_read_regs(priv, reg, val, 1);
380}
381
382static int helene_set_reg_bits(struct helene_priv *priv,
383 u8 reg, u8 data, u8 mask)
384{
385 int res;
386 u8 rdata;
387
388 if (mask != 0xff) {
389 res = helene_read_reg(priv, reg, &rdata);
390 if (res != 0)
391 return res;
392 data = ((data & mask) | (rdata & (mask ^ 0xFF)));
393 }
394 return helene_write_reg(priv, reg, data);
395}
396
397static int helene_enter_power_save(struct helene_priv *priv)
398{
399 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
400 if (priv->state == STATE_SLEEP)
401 return 0;
402
403 /* Standby setting for CPU */
404 helene_write_reg(priv, 0x88, 0x0);
405
406 /* Standby setting for internal logic block */
407 helene_write_reg(priv, 0x87, 0xC0);
408
409 priv->state = STATE_SLEEP;
410 return 0;
411}
412
413static int helene_leave_power_save(struct helene_priv *priv)
414{
415 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
416 if (priv->state == STATE_ACTIVE)
417 return 0;
418
419 /* Standby setting for internal logic block */
420 helene_write_reg(priv, 0x87, 0xC4);
421
422 /* Standby setting for CPU */
423 helene_write_reg(priv, 0x88, 0x40);
424
425 priv->state = STATE_ACTIVE;
426 return 0;
427}
428
429static int helene_init(struct dvb_frontend *fe)
430{
431 struct helene_priv *priv = fe->tuner_priv;
432
433 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
434 return helene_leave_power_save(priv);
435}
436
437static int helene_release(struct dvb_frontend *fe)
438{
439 struct helene_priv *priv = fe->tuner_priv;
440
441 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
442 kfree(fe->tuner_priv);
443 fe->tuner_priv = NULL;
444 return 0;
445}
446
447static int helene_sleep(struct dvb_frontend *fe)
448{
449 struct helene_priv *priv = fe->tuner_priv;
450
451 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
452 helene_enter_power_save(priv);
453 return 0;
454}
455
456static enum helene_tv_system_t helene_get_tv_system(struct dvb_frontend *fe)
457{
458 enum helene_tv_system_t system = SONY_HELENE_TV_SYSTEM_UNKNOWN;
459 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
460 struct helene_priv *priv = fe->tuner_priv;
461
462 if (p->delivery_system == SYS_DVBT) {
463 if (p->bandwidth_hz <= 5000000)
464 system = SONY_HELENE_DTV_DVBT_5;
465 else if (p->bandwidth_hz <= 6000000)
466 system = SONY_HELENE_DTV_DVBT_6;
467 else if (p->bandwidth_hz <= 7000000)
468 system = SONY_HELENE_DTV_DVBT_7;
469 else if (p->bandwidth_hz <= 8000000)
470 system = SONY_HELENE_DTV_DVBT_8;
471 else {
472 system = SONY_HELENE_DTV_DVBT_8;
473 p->bandwidth_hz = 8000000;
474 }
475 } else if (p->delivery_system == SYS_DVBT2) {
476 if (p->bandwidth_hz <= 5000000)
477 system = SONY_HELENE_DTV_DVBT2_5;
478 else if (p->bandwidth_hz <= 6000000)
479 system = SONY_HELENE_DTV_DVBT2_6;
480 else if (p->bandwidth_hz <= 7000000)
481 system = SONY_HELENE_DTV_DVBT2_7;
482 else if (p->bandwidth_hz <= 8000000)
483 system = SONY_HELENE_DTV_DVBT2_8;
484 else {
485 system = SONY_HELENE_DTV_DVBT2_8;
486 p->bandwidth_hz = 8000000;
487 }
488 } else if (p->delivery_system == SYS_DVBS) {
489 system = SONY_HELENE_STV_DVBS;
490 } else if (p->delivery_system == SYS_DVBS2) {
491 system = SONY_HELENE_STV_DVBS2;
492 } else if (p->delivery_system == SYS_ISDBS) {
493 system = SONY_HELENE_STV_ISDBS;
494 } else if (p->delivery_system == SYS_ISDBT) {
495 if (p->bandwidth_hz <= 6000000)
496 system = SONY_HELENE_DTV_ISDBT_6;
497 else if (p->bandwidth_hz <= 7000000)
498 system = SONY_HELENE_DTV_ISDBT_7;
499 else if (p->bandwidth_hz <= 8000000)
500 system = SONY_HELENE_DTV_ISDBT_8;
501 else {
502 system = SONY_HELENE_DTV_ISDBT_8;
503 p->bandwidth_hz = 8000000;
504 }
505 } else if (p->delivery_system == SYS_DVBC_ANNEX_A) {
506 if (p->bandwidth_hz <= 6000000)
507 system = SONY_HELENE_DTV_DVBC_6;
508 else if (p->bandwidth_hz <= 8000000)
509 system = SONY_HELENE_DTV_DVBC_8;
510 }
511 dev_dbg(&priv->i2c->dev,
512 "%s(): HELENE DTV system %d (delsys %d, bandwidth %d)\n",
513 __func__, (int)system, p->delivery_system,
514 p->bandwidth_hz);
515 return system;
516}
517
518static int helene_set_params_s(struct dvb_frontend *fe)
519{
520 u8 data[MAX_WRITE_REGSIZE];
521 u32 frequency;
522 enum helene_tv_system_t tv_system;
523 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
524 struct helene_priv *priv = fe->tuner_priv;
525 int frequencykHz = p->frequency;
526 uint32_t frequency4kHz = 0;
527 u32 symbol_rate = p->symbol_rate/1000;
528
529 dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz sr=%uKsps\n",
530 __func__, frequencykHz, symbol_rate);
531 tv_system = helene_get_tv_system(fe);
532
533 if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) {
534 dev_err(&priv->i2c->dev, "%s(): unknown DTV system\n",
535 __func__);
536 return -EINVAL;
537 }
538 /* RF switch turn to satellite */
539 if (priv->set_tuner)
540 priv->set_tuner(priv->set_tuner_data, 0);
541 frequency = roundup(p->frequency / 1000, 1);
542
543 /* Disable IF signal output */
544 helene_write_reg(priv, 0x15, 0x02);
545
546 /* RFIN matching in power save (Sat) reset */
547 helene_write_reg(priv, 0x43, 0x06);
548
549 /* Analog block setting (0x6A, 0x6B) */
550 data[0] = 0x00;
551 data[1] = 0x00;
552 helene_write_regs(priv, 0x6A, data, 2);
553 helene_write_reg(priv, 0x75, 0x99);
554 helene_write_reg(priv, 0x9D, 0x00);
555
556 /* Tuning setting for CPU (0x61) */
557 helene_write_reg(priv, 0x61, 0x07);
558
559 /* Satellite mode select (0x01) */
560 helene_write_reg(priv, 0x01, 0x01);
561
562 /* Clock enable for internal logic block, CPU wake-up (0x04, 0x05) */
563 data[0] = 0xC4;
564 data[1] = 0x40;
565
566 switch (priv->xtal) {
567 case SONY_HELENE_XTAL_16000:
568 data[2] = 0x02;
569 break;
570 case SONY_HELENE_XTAL_20500:
571 data[2] = 0x02;
572 break;
573 case SONY_HELENE_XTAL_24000:
574 data[2] = 0x03;
575 break;
576 case SONY_HELENE_XTAL_41000:
577 data[2] = 0x05;
578 break;
579 default:
580 dev_err(&priv->i2c->dev, "%s(): unknown xtal %d\n",
581 __func__, priv->xtal);
582 return -EINVAL;
583 }
584
585 /* Setting for analog block (0x07). LOOPFILTER INTERNAL */
586 data[3] = 0x80;
587
588 /* Tuning setting for analog block
589 * (0x08, 0x09, 0x0A, 0x0B). LOOPFILTER INTERNAL
590 */
591 if (priv->xtal == SONY_HELENE_XTAL_20500)
592 data[4] = 0x58;
593 else
594 data[4] = 0x70;
595
596 data[5] = 0x1E;
597 data[6] = 0x02;
598 data[7] = 0x24;
599
600 /* Enable for analog block (0x0C, 0x0D, 0x0E). SAT LNA ON */
601 data[8] = 0x0F;
602 data[8] |= 0xE0; /* POWERSAVE_TERR_RF_ACTIVE */
603 data[9] = 0x02;
604 data[10] = 0x1E;
605
606 /* Setting for LPF cutoff frequency (0x0F) */
607 switch (tv_system) {
608 case SONY_HELENE_STV_ISDBS:
609 data[11] = 0x22; /* 22MHz */
610 break;
611 case SONY_HELENE_STV_DVBS:
612 if (symbol_rate <= 4000)
613 data[11] = 0x05;
614 else if (symbol_rate <= 10000)
615 data[11] = (uint8_t)((symbol_rate * 47
616 + (40000-1)) / 40000);
617 else
618 data[11] = (uint8_t)((symbol_rate * 27
619 + (40000-1)) / 40000 + 5);
620
621 if (data[11] > 36)
622 data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */
623 break;
624 case SONY_HELENE_STV_DVBS2:
625 if (symbol_rate <= 4000)
626 data[11] = 0x05;
627 else if (symbol_rate <= 10000)
628 data[11] = (uint8_t)((symbol_rate * 11
629 + (10000-1)) / 10000);
630 else
631 data[11] = (uint8_t)((symbol_rate * 3
632 + (5000-1)) / 5000 + 5);
633
634 if (data[11] > 36)
635 data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */
636 break;
637 default:
638 dev_err(&priv->i2c->dev, "%s(): unknown standard %d\n",
639 __func__, tv_system);
640 return -EINVAL;
641 }
642
643 /* RF tuning frequency setting (0x10, 0x11, 0x12) */
644 frequency4kHz = (frequencykHz + 2) / 4;
645 data[12] = (uint8_t)(frequency4kHz & 0xFF); /* FRF_L */
646 data[13] = (uint8_t)((frequency4kHz >> 8) & 0xFF); /* FRF_M */
647 /* FRF_H (bit[3:0]) */
648 data[14] = (uint8_t)((frequency4kHz >> 16) & 0x0F);
649
650 /* Tuning command (0x13) */
651 data[15] = 0xFF;
652
653 /* Setting for IQOUT_LIMIT (0x14) 0.75Vpp */
654 data[16] = 0x00;
655
656 /* Enable IQ output (0x15) */
657 data[17] = 0x01;
658
659 helene_write_regs(priv, 0x04, data, 18);
660
661 dev_dbg(&priv->i2c->dev, "%s(): tune done\n",
662 __func__);
663
664 priv->frequency = frequency;
665 return 0;
666}
667
668static int helene_set_params(struct dvb_frontend *fe)
669{
670 u8 data[MAX_WRITE_REGSIZE];
671 u32 frequency;
672 enum helene_tv_system_t tv_system;
673 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
674 struct helene_priv *priv = fe->tuner_priv;
675 int frequencykHz = p->frequency / 1000;
676
677 dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n",
678 __func__, frequencykHz);
679 tv_system = helene_get_tv_system(fe);
680
681 if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) {
682 dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n",
683 __func__);
684 return -EINVAL;
685 }
686 if (priv->set_tuner)
687 priv->set_tuner(priv->set_tuner_data, 1);
688 frequency = roundup(p->frequency / 1000, 25);
689
690 /* mode select */
691 helene_write_reg(priv, 0x01, 0x00);
692
693 /* Disable IF signal output */
694 helene_write_reg(priv, 0x74, 0x02);
695
696 if (priv->state == STATE_SLEEP)
697 helene_leave_power_save(priv);
698
699 /* Initial setting for internal analog block (0x91, 0x92) */
700 if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
701 (tv_system == SONY_HELENE_DTV_DVBC_8)) {
702 data[0] = 0x16;
703 data[1] = 0x26;
704 } else {
705 data[0] = 0x10;
706 data[1] = 0x20;
707 }
708 helene_write_regs(priv, 0x91, data, 2);
709
710 /* Setting for analog block */
711 if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system))
712 data[0] = 0x90;
713 else
714 data[0] = 0x00;
715
716 /* Setting for local polarity (0x9D) */
717 data[1] = (uint8_t)(terr_params[tv_system].IS_LOWERLOCAL & 0x01);
718 helene_write_regs(priv, 0x9C, data, 2);
719
720 /* Enable for analog block */
721 data[0] = 0xEE;
722 data[1] = 0x02;
723 data[2] = 0x1E;
724 data[3] = 0x67; /* Tuning setting for CPU */
725
726 /* Setting for PLL reference divider for xtal=24MHz */
727 if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
728 (tv_system == SONY_HELENE_DTV_DVBC_8))
729 data[4] = 0x18;
730 else
731 data[4] = 0x03;
732
733 /* Tuning setting for analog block */
734 if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system)) {
735 data[5] = 0x38;
736 data[6] = 0x1E;
737 data[7] = 0x02;
738 data[8] = 0x24;
739 } else if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
740 (tv_system == SONY_HELENE_DTV_DVBC_8)) {
741 data[5] = 0x1C;
742 data[6] = 0x78;
743 data[7] = 0x08;
744 data[8] = 0x1C;
745 } else {
746 data[5] = 0xB4;
747 data[6] = 0x78;
748 data[7] = 0x08;
749 data[8] = 0x30;
750 }
751 helene_write_regs(priv, 0x5E, data, 9);
752
753 /* LT_AMP_EN should be 0 */
754 helene_set_reg_bits(priv, 0x67, 0x0, 0x02);
755
756 /* Setting for IFOUT_LIMIT */
757 data[0] = 0x00; /* 1.5Vpp */
758
759 /* RF_GAIN setting */
760 if (terr_params[tv_system].RF_GAIN == HELENE_AUTO)
761 data[1] = 0x80; /* RF_GAIN_SEL = 1 */
762 else
763 data[1] = (uint8_t)((terr_params[tv_system].RF_GAIN
764 << 4) & 0x70);
765
766 /* IF_BPF_GC setting */
767 data[1] |= (uint8_t)(terr_params[tv_system].IF_BPF_GC & 0x0F);
768
769 /* Setting for internal RFAGC (0x6A, 0x6B, 0x6C) */
770 data[2] = 0x00;
771 if (frequencykHz <= 172000) {
772 data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VL
773 & 0x0F);
774 data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VL
775 & 0x07);
776 } else if (frequencykHz <= 464000) {
777 data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VH
778 & 0x0F);
779 data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VH
780 & 0x07);
781 } else {
782 data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_U
783 & 0x0F);
784 data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_U
785 & 0x07);
786 }
787 data[4] |= 0x20;
788
789 /* Setting for IF frequency and bandwidth */
790
791 /* IF filter center frequency offset (IF_BPF_F0) (0x6D) */
792 data[5] = (uint8_t)((terr_params[tv_system].IF_BPF_F0 << 4) & 0x30);
793
794 /* IF filter band width (BW) (0x6D) */
795 data[5] |= (uint8_t)(terr_params[tv_system].BW & 0x03);
796
797 /* IF frequency offset value (FIF_OFFSET) (0x6E) */
798 data[6] = (uint8_t)(terr_params[tv_system].FIF_OFFSET & 0x1F);
799
800 /* IF band width offset value (BW_OFFSET) (0x6F) */
801 data[7] = (uint8_t)(terr_params[tv_system].BW_OFFSET & 0x1F);
802
803 /* RF tuning frequency setting (0x70, 0x71, 0x72) */
804 data[8] = (uint8_t)(frequencykHz & 0xFF); /* FRF_L */
805 data[9] = (uint8_t)((frequencykHz >> 8) & 0xFF); /* FRF_M */
806 data[10] = (uint8_t)((frequencykHz >> 16)
807 & 0x0F); /* FRF_H (bit[3:0]) */
808
809 /* Tuning command */
810 data[11] = 0xFF;
811
812 /* Enable IF output, AGC and IFOUT pin selection (0x74) */
813 data[12] = 0x01;
814
815 if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
816 (tv_system == SONY_HELENE_DTV_DVBC_8)) {
817 data[13] = 0xD9;
818 data[14] = 0x0F;
819 data[15] = 0x24;
820 data[16] = 0x87;
821 } else {
822 data[13] = 0x99;
823 data[14] = 0x00;
824 data[15] = 0x24;
825 data[16] = 0x87;
826 }
827
828 helene_write_regs(priv, 0x68, data, 17);
829
830 dev_dbg(&priv->i2c->dev, "%s(): tune done\n",
831 __func__);
832
833 priv->frequency = frequency;
834 return 0;
835}
836
837static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency)
838{
839 struct helene_priv *priv = fe->tuner_priv;
840
841 *frequency = priv->frequency * 1000;
842 return 0;
843}
844
845static struct dvb_tuner_ops helene_tuner_ops = {
846 .info = {
847 .name = "Sony HELENE Ter tuner",
848 .frequency_min = 1000000,
849 .frequency_max = 1200000000,
850 .frequency_step = 25000,
851 },
852 .init = helene_init,
853 .release = helene_release,
854 .sleep = helene_sleep,
855 .set_params = helene_set_params,
856 .get_frequency = helene_get_frequency,
857};
858
859static struct dvb_tuner_ops helene_tuner_ops_s = {
860 .info = {
861 .name = "Sony HELENE Sat tuner",
862 .frequency_min = 500000,
863 .frequency_max = 2500000,
864 .frequency_step = 1000,
865 },
866 .init = helene_init,
867 .release = helene_release,
868 .sleep = helene_sleep,
869 .set_params = helene_set_params_s,
870 .get_frequency = helene_get_frequency,
871};
872
873/* power-on tuner
874 * call once after reset
875 */
876static int helene_x_pon(struct helene_priv *priv)
877{
878 /* RFIN matching in power save (terrestrial) = ACTIVE */
879 /* RFIN matching in power save (satellite) = ACTIVE */
880 u8 dataT[] = { 0x06, 0x00, 0x02, 0x00 };
881 /* SAT_RF_ACTIVE = true, lnaOff = false, terrRfActive = true */
882 u8 dataS[] = { 0x05, 0x06 };
883 u8 cdata[] = {0x7A, 0x01};
884 u8 data[20];
885 u8 rdata[2];
886
887 /* mode select */
888 helene_write_reg(priv, 0x01, 0x00);
889
890 helene_write_reg(priv, 0x67, dataT[3]);
891 helene_write_reg(priv, 0x43, dataS[1]);
892 helene_write_regs(priv, 0x5E, dataT, 3);
893 helene_write_reg(priv, 0x0C, dataS[0]);
894
895 /* Initial setting for internal logic block */
896 helene_write_regs(priv, 0x99, cdata, sizeof(cdata));
897
898 /* 0x81 - 0x94 */
899 data[0] = 0x18; /* xtal 24 MHz */
900 data[1] = (uint8_t)(0x80 | (0x04 & 0x1F)); /* 4 x 25 = 100uA */
901 data[2] = (uint8_t)(0x80 | (0x26 & 0x7F)); /* 38 x 0.25 = 9.5pF */
902 data[3] = 0x80; /* REFOUT signal output 500mVpp */
903 data[4] = 0x00; /* GPIO settings */
904 data[5] = 0x00; /* GPIO settings */
905 data[6] = 0xC4; /* Clock enable for internal logic block */
906 data[7] = 0x40; /* Start CPU boot-up */
907 data[8] = 0x10; /* For burst-write */
908
909 /* Setting for internal RFAGC */
910 data[9] = 0x00;
911 data[10] = 0x45;
912 data[11] = 0x75;
913
914 data[12] = 0x07; /* Setting for analog block */
915
916 /* Initial setting for internal analog block */
917 data[13] = 0x1C;
918 data[14] = 0x3F;
919 data[15] = 0x02;
920 data[16] = 0x10;
921 data[17] = 0x20;
922 data[18] = 0x0A;
923 data[19] = 0x00;
924
925 helene_write_regs(priv, 0x81, data, sizeof(data));
926
927 /* Setting for internal RFAGC */
928 helene_write_reg(priv, 0x9B, 0x00);
929
930 msleep(20);
931
932 /* Check CPU_STT/CPU_ERR */
933 helene_read_regs(priv, 0x1A, rdata, sizeof(rdata));
934
935 if (rdata[0] != 0x00) {
936 dev_err(&priv->i2c->dev,
937 "HELENE tuner CPU error 0x%x\n", rdata[0]);
938 return -EIO;
939 }
940
941 /* VCO current setting */
942 cdata[0] = 0x90;
943 cdata[1] = 0x06;
944 helene_write_regs(priv, 0x17, cdata, sizeof(cdata));
945 msleep(20);
946 helene_read_reg(priv, 0x19, data);
947 helene_write_reg(priv, 0x95, (uint8_t)((data[0] >> 4) & 0x0F));
948
949 /* Disable IF signal output */
950 helene_write_reg(priv, 0x74, 0x02);
951
952 /* Standby setting for CPU */
953 helene_write_reg(priv, 0x88, 0x00);
954
955 /* Standby setting for internal logic block */
956 helene_write_reg(priv, 0x87, 0xC0);
957
958 /* Load capacitance control setting for crystal oscillator */
959 helene_write_reg(priv, 0x80, 0x01);
960
961 /* Satellite initial setting */
962 cdata[0] = 0x07;
963 cdata[1] = 0x00;
964 helene_write_regs(priv, 0x41, cdata, sizeof(cdata));
965
966 dev_info(&priv->i2c->dev,
967 "HELENE tuner x_pon done\n");
968
969 return 0;
970}
971
972struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
973 const struct helene_config *config,
974 struct i2c_adapter *i2c)
975{
976 struct helene_priv *priv = NULL;
977
978 priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL);
979 if (priv == NULL)
980 return NULL;
981 priv->i2c_address = (config->i2c_address >> 1);
982 priv->i2c = i2c;
983 priv->set_tuner_data = config->set_tuner_priv;
984 priv->set_tuner = config->set_tuner_callback;
985 priv->xtal = config->xtal;
986
987 if (fe->ops.i2c_gate_ctrl)
988 fe->ops.i2c_gate_ctrl(fe, 1);
989
990 if (helene_x_pon(priv) != 0)
991 return NULL;
992
993 if (fe->ops.i2c_gate_ctrl)
994 fe->ops.i2c_gate_ctrl(fe, 0);
995
996 memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_s,
997 sizeof(struct dvb_tuner_ops));
998 fe->tuner_priv = priv;
999 dev_info(&priv->i2c->dev,
1000 "Sony HELENE Sat attached on addr=%x at I2C adapter %p\n",
1001 priv->i2c_address, priv->i2c);
1002 return fe;
1003}
1004EXPORT_SYMBOL(helene_attach_s);
1005
1006struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
1007 const struct helene_config *config,
1008 struct i2c_adapter *i2c)
1009{
1010 struct helene_priv *priv = NULL;
1011
1012 priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL);
1013 if (priv == NULL)
1014 return NULL;
1015 priv->i2c_address = (config->i2c_address >> 1);
1016 priv->i2c = i2c;
1017 priv->set_tuner_data = config->set_tuner_priv;
1018 priv->set_tuner = config->set_tuner_callback;
1019 priv->xtal = config->xtal;
1020
1021 if (fe->ops.i2c_gate_ctrl)
1022 fe->ops.i2c_gate_ctrl(fe, 1);
1023
1024 if (helene_x_pon(priv) != 0)
1025 return NULL;
1026
1027 if (fe->ops.i2c_gate_ctrl)
1028 fe->ops.i2c_gate_ctrl(fe, 0);
1029
1030 memcpy(&fe->ops.tuner_ops, &helene_tuner_ops,
1031 sizeof(struct dvb_tuner_ops));
1032 fe->tuner_priv = priv;
1033 dev_info(&priv->i2c->dev,
1034 "Sony HELENE Ter attached on addr=%x at I2C adapter %p\n",
1035 priv->i2c_address, priv->i2c);
1036 return fe;
1037}
1038EXPORT_SYMBOL(helene_attach);
1039
1040MODULE_DESCRIPTION("Sony HELENE Sat/Ter tuner driver");
1041MODULE_AUTHOR("Abylay Ospan <aospan@netup.ru>");
1042MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/helene.h b/drivers/media/dvb-frontends/helene.h
new file mode 100644
index 000000000000..e1b9224cfc55
--- /dev/null
+++ b/drivers/media/dvb-frontends/helene.h
@@ -0,0 +1,79 @@
1/*
2 * helene.h
3 *
4 * Sony HELENE DVB-S/S2/T/T2/C/C2/ISDB-T/S tuner driver (CXD2858ER)
5 *
6 * Copyright 2012 Sony Corporation
7 * Copyright (C) 2014 NetUP Inc.
8 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * 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 */
20
21#ifndef __DVB_HELENE_H__
22#define __DVB_HELENE_H__
23
24#include <linux/kconfig.h>
25#include <linux/dvb/frontend.h>
26#include <linux/i2c.h>
27
28enum helene_xtal {
29 SONY_HELENE_XTAL_16000, /* 16 MHz */
30 SONY_HELENE_XTAL_20500, /* 20.5 MHz */
31 SONY_HELENE_XTAL_24000, /* 24 MHz */
32 SONY_HELENE_XTAL_41000 /* 41 MHz */
33};
34
35/**
36 * struct helene_config - the configuration of 'Helene' tuner driver
37 * @i2c_address: I2C address of the tuner
38 * @xtal_freq_mhz: Oscillator frequency, MHz
39 * @set_tuner_priv: Callback function private context
40 * @set_tuner_callback: Callback function that notifies the parent driver
41 * which tuner is active now
42 */
43struct helene_config {
44 u8 i2c_address;
45 u8 xtal_freq_mhz;
46 void *set_tuner_priv;
47 int (*set_tuner_callback)(void *, int);
48 enum helene_xtal xtal;
49};
50
51#if IS_REACHABLE(CONFIG_DVB_HELENE)
52extern struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
53 const struct helene_config *config,
54 struct i2c_adapter *i2c);
55#else
56static inline struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
57 const struct helene_config *config,
58 struct i2c_adapter *i2c)
59{
60 pr_warn("%s: driver disabled by Kconfig\n", __func__);
61 return NULL;
62}
63#endif
64
65#if IS_REACHABLE(CONFIG_DVB_HELENE)
66extern struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
67 const struct helene_config *config,
68 struct i2c_adapter *i2c);
69#else
70static inline struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
71 const struct helene_config *config,
72 struct i2c_adapter *i2c)
73{
74 pr_warn("%s: driver disabled by Kconfig\n", __func__);
75 return NULL;
76}
77#endif
78
79#endif
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
index 000606af70f7..a98bca5270d9 100644
--- a/drivers/media/dvb-frontends/horus3a.c
+++ b/drivers/media/dvb-frontends/horus3a.c
@@ -66,7 +66,7 @@ static int horus3a_write_regs(struct horus3a_priv *priv,
66 } 66 }
67 }; 67 };
68 68
69 if (len + 1 >= sizeof(buf)) { 69 if (len + 1 > sizeof(buf)) {
70 dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n", 70 dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
71 reg, len + 1); 71 reg, len + 1);
72 return -E2BIG; 72 return -E2BIG;
@@ -272,24 +272,6 @@ static int horus3a_set_params(struct dvb_frontend *fe)
272 if (fc_lpf > 36) 272 if (fc_lpf > 36)
273 fc_lpf = 36; 273 fc_lpf = 36;
274 } else if (p->delivery_system == SYS_DVBS2) { 274 } else if (p->delivery_system == SYS_DVBS2) {
275 int rolloff;
276
277 switch (p->rolloff) {
278 case ROLLOFF_35:
279 rolloff = 35;
280 break;
281 case ROLLOFF_25:
282 rolloff = 25;
283 break;
284 case ROLLOFF_20:
285 rolloff = 20;
286 break;
287 case ROLLOFF_AUTO:
288 default:
289 dev_err(&priv->i2c->dev,
290 "horus3a: auto roll-off is not supported\n");
291 return -EINVAL;
292 }
293 /* 275 /*
294 * SR <= 4.5: 276 * SR <= 4.5:
295 * fc_lpf = 5 277 * fc_lpf = 5
@@ -302,11 +284,9 @@ static int horus3a_set_params(struct dvb_frontend *fe)
302 if (symbol_rate <= 4500) 284 if (symbol_rate <= 4500)
303 fc_lpf = 5; 285 fc_lpf = 5;
304 else if (symbol_rate <= 10000) 286 else if (symbol_rate <= 10000)
305 fc_lpf = (u8)DIV_ROUND_UP( 287 fc_lpf = (u8)((symbol_rate * 11 + (10000-1)) / 10000);
306 symbol_rate * (200 + rolloff), 200000);
307 else 288 else
308 fc_lpf = (u8)DIV_ROUND_UP( 289 fc_lpf = (u8)((symbol_rate * 3 + (5000-1)) / 5000 + 5);
309 symbol_rate * (100 + rolloff), 200000) + 5;
310 /* 5 <= fc_lpf <= 36 is valid */ 290 /* 5 <= fc_lpf <= 36 is valid */
311 if (fc_lpf > 36) 291 if (fc_lpf > 36)
312 fc_lpf = 36; 292 fc_lpf = 36;
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index a09b12313a73..ef79a4ec31e2 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -609,7 +609,7 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
609{ 609{
610 struct m88rs2000_state *state = fe->demodulator_priv; 610 struct m88rs2000_state *state = fe->demodulator_priv;
611 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 611 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
612 enum fe_status status; 612 enum fe_status status = 0;
613 int i, ret = 0; 613 int i, ret = 0;
614 u32 tuner_freq; 614 u32 tuner_freq;
615 s16 offset = 0; 615 s16 offset = 0;
diff --git a/drivers/staging/media/mn88472/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index 7ea749cf19f9..18fb2df1e2bd 100644
--- a/drivers/staging/media/mn88472/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -17,28 +17,90 @@
17#include "mn88472_priv.h" 17#include "mn88472_priv.h"
18 18
19static int mn88472_get_tune_settings(struct dvb_frontend *fe, 19static int mn88472_get_tune_settings(struct dvb_frontend *fe,
20 struct dvb_frontend_tune_settings *s) 20 struct dvb_frontend_tune_settings *s)
21{ 21{
22 s->min_delay_ms = 800; 22 s->min_delay_ms = 1000;
23 return 0; 23 return 0;
24} 24}
25 25
26static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
27{
28 struct i2c_client *client = fe->demodulator_priv;
29 struct mn88472_dev *dev = i2c_get_clientdata(client);
30 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
31 int ret;
32 unsigned int utmp;
33
34 if (!dev->active) {
35 ret = -EAGAIN;
36 goto err;
37 }
38
39 switch (c->delivery_system) {
40 case SYS_DVBT:
41 ret = regmap_read(dev->regmap[0], 0x7f, &utmp);
42 if (ret)
43 goto err;
44 if ((utmp & 0x0f) >= 0x09)
45 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
46 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
47 else
48 *status = 0;
49 break;
50 case SYS_DVBT2:
51 ret = regmap_read(dev->regmap[2], 0x92, &utmp);
52 if (ret)
53 goto err;
54 if ((utmp & 0x0f) >= 0x0d)
55 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
56 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
57 else if ((utmp & 0x0f) >= 0x0a)
58 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
59 FE_HAS_VITERBI;
60 else if ((utmp & 0x0f) >= 0x07)
61 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
62 else
63 *status = 0;
64 break;
65 case SYS_DVBC_ANNEX_A:
66 ret = regmap_read(dev->regmap[1], 0x84, &utmp);
67 if (ret)
68 goto err;
69 if ((utmp & 0x0f) >= 0x08)
70 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
71 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
72 else
73 *status = 0;
74 break;
75 default:
76 ret = -EINVAL;
77 goto err;
78 }
79
80 return 0;
81err:
82 dev_dbg(&client->dev, "failed=%d\n", ret);
83 return ret;
84}
85
26static int mn88472_set_frontend(struct dvb_frontend *fe) 86static int mn88472_set_frontend(struct dvb_frontend *fe)
27{ 87{
28 struct i2c_client *client = fe->demodulator_priv; 88 struct i2c_client *client = fe->demodulator_priv;
29 struct mn88472_dev *dev = i2c_get_clientdata(client); 89 struct mn88472_dev *dev = i2c_get_clientdata(client);
30 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 90 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
31 int ret, i; 91 int ret, i;
32 u32 if_frequency = 0; 92 unsigned int utmp;
33 u64 tmp; 93 u32 if_frequency;
34 u8 delivery_system_val, if_val[3], bw_val[7], bw_val2; 94 u8 buf[3], delivery_system_val, bandwidth_val, *bandwidth_vals_ptr;
95 u8 reg_bank0_b4_val, reg_bank0_cd_val, reg_bank0_d4_val;
96 u8 reg_bank0_d6_val;
35 97
36 dev_dbg(&client->dev, 98 dev_dbg(&client->dev,
37 "delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n", 99 "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n",
38 c->delivery_system, c->modulation, 100 c->delivery_system, c->modulation, c->frequency,
39 c->frequency, c->symbol_rate, c->inversion); 101 c->bandwidth_hz, c->symbol_rate, c->inversion, c->stream_id);
40 102
41 if (!dev->warm) { 103 if (!dev->active) {
42 ret = -EAGAIN; 104 ret = -EAGAIN;
43 goto err; 105 goto err;
44 } 106 }
@@ -46,39 +108,64 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
46 switch (c->delivery_system) { 108 switch (c->delivery_system) {
47 case SYS_DVBT: 109 case SYS_DVBT:
48 delivery_system_val = 0x02; 110 delivery_system_val = 0x02;
111 reg_bank0_b4_val = 0x00;
112 reg_bank0_cd_val = 0x1f;
113 reg_bank0_d4_val = 0x0a;
114 reg_bank0_d6_val = 0x48;
49 break; 115 break;
50 case SYS_DVBT2: 116 case SYS_DVBT2:
51 delivery_system_val = 0x03; 117 delivery_system_val = 0x03;
118 reg_bank0_b4_val = 0xf6;
119 reg_bank0_cd_val = 0x01;
120 reg_bank0_d4_val = 0x09;
121 reg_bank0_d6_val = 0x46;
52 break; 122 break;
53 case SYS_DVBC_ANNEX_A: 123 case SYS_DVBC_ANNEX_A:
54 delivery_system_val = 0x04; 124 delivery_system_val = 0x04;
125 reg_bank0_b4_val = 0x00;
126 reg_bank0_cd_val = 0x17;
127 reg_bank0_d4_val = 0x09;
128 reg_bank0_d6_val = 0x48;
55 break; 129 break;
56 default: 130 default:
57 ret = -EINVAL; 131 ret = -EINVAL;
58 goto err; 132 goto err;
59 } 133 }
60 134
61 if (c->bandwidth_hz <= 5000000) { 135 switch (c->delivery_system) {
62 memcpy(bw_val, "\xe5\x99\x9a\x1b\xa9\x1b\xa9", 7); 136 case SYS_DVBT:
63 bw_val2 = 0x03; 137 case SYS_DVBT2:
64 } else if (c->bandwidth_hz <= 6000000) { 138 switch (c->bandwidth_hz) {
65 /* IF 3570000 Hz, BW 6000000 Hz */ 139 case 5000000:
66 memcpy(bw_val, "\xbf\x55\x55\x15\x6b\x15\x6b", 7); 140 bandwidth_vals_ptr = "\xe5\x99\x9a\x1b\xa9\x1b\xa9";
67 bw_val2 = 0x02; 141 bandwidth_val = 0x03;
68 } else if (c->bandwidth_hz <= 7000000) { 142 break;
69 /* IF 4570000 Hz, BW 7000000 Hz */ 143 case 6000000:
70 memcpy(bw_val, "\xa4\x00\x00\x0f\x2c\x0f\x2c", 7); 144 bandwidth_vals_ptr = "\xbf\x55\x55\x15\x6b\x15\x6b";
71 bw_val2 = 0x01; 145 bandwidth_val = 0x02;
72 } else if (c->bandwidth_hz <= 8000000) { 146 break;
73 /* IF 4570000 Hz, BW 8000000 Hz */ 147 case 7000000:
74 memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7); 148 bandwidth_vals_ptr = "\xa4\x00\x00\x0f\x2c\x0f\x2c";
75 bw_val2 = 0x00; 149 bandwidth_val = 0x01;
76 } else { 150 break;
77 ret = -EINVAL; 151 case 8000000:
78 goto err; 152 bandwidth_vals_ptr = "\x8f\x80\x00\x08\xee\x08\xee";
153 bandwidth_val = 0x00;
154 break;
155 default:
156 ret = -EINVAL;
157 goto err;
158 }
159 break;
160 case SYS_DVBC_ANNEX_A:
161 bandwidth_vals_ptr = NULL;
162 bandwidth_val = 0x00;
163 break;
164 default:
165 break;
79 } 166 }
80 167
81 /* program tuner */ 168 /* Program tuner */
82 if (fe->ops.tuner_ops.set_params) { 169 if (fe->ops.tuner_ops.set_params) {
83 ret = fe->ops.tuner_ops.set_params(fe); 170 ret = fe->ops.tuner_ops.set_params(fe);
84 if (ret) 171 if (ret)
@@ -91,20 +178,10 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
91 goto err; 178 goto err;
92 179
93 dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency); 180 dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
94 } 181 } else {
95 182 ret = -EINVAL;
96 /* Calculate IF registers ( (1<<24)*IF / Xtal ) */
97 tmp = div_u64(if_frequency * (u64)(1<<24) + (dev->xtal / 2),
98 dev->xtal);
99 if_val[0] = (tmp >> 16) & 0xff;
100 if_val[1] = (tmp >> 8) & 0xff;
101 if_val[2] = (tmp >> 0) & 0xff;
102
103 ret = regmap_write(dev->regmap[2], 0xfb, 0x13);
104 ret = regmap_write(dev->regmap[2], 0xef, 0x13);
105 ret = regmap_write(dev->regmap[2], 0xf9, 0x13);
106 if (ret)
107 goto err; 183 goto err;
184 }
108 185
109 ret = regmap_write(dev->regmap[2], 0x00, 0x66); 186 ret = regmap_write(dev->regmap[2], 0x00, 0x66);
110 if (ret) 187 if (ret)
@@ -118,157 +195,81 @@ static int mn88472_set_frontend(struct dvb_frontend *fe)
118 ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val); 195 ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
119 if (ret) 196 if (ret)
120 goto err; 197 goto err;
121 ret = regmap_write(dev->regmap[2], 0x04, bw_val2); 198 ret = regmap_write(dev->regmap[2], 0x04, bandwidth_val);
122 if (ret) 199 if (ret)
123 goto err; 200 goto err;
124 201
125 for (i = 0; i < sizeof(if_val); i++) { 202 /* IF */
126 ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[i]); 203 utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, dev->clk);
204 buf[0] = (utmp >> 16) & 0xff;
205 buf[1] = (utmp >> 8) & 0xff;
206 buf[2] = (utmp >> 0) & 0xff;
207 for (i = 0; i < 3; i++) {
208 ret = regmap_write(dev->regmap[2], 0x10 + i, buf[i]);
127 if (ret) 209 if (ret)
128 goto err; 210 goto err;
129 } 211 }
130 212
131 for (i = 0; i < sizeof(bw_val); i++) { 213 /* Bandwidth */
132 ret = regmap_write(dev->regmap[2], 0x13 + i, bw_val[i]); 214 if (bandwidth_vals_ptr) {
133 if (ret) 215 for (i = 0; i < 7; i++) {
134 goto err; 216 ret = regmap_write(dev->regmap[2], 0x13 + i,
217 bandwidth_vals_ptr[i]);
218 if (ret)
219 goto err;
220 }
135 } 221 }
136 222
223 ret = regmap_write(dev->regmap[0], 0xb4, reg_bank0_b4_val);
224 if (ret)
225 goto err;
226 ret = regmap_write(dev->regmap[0], 0xcd, reg_bank0_cd_val);
227 if (ret)
228 goto err;
229 ret = regmap_write(dev->regmap[0], 0xd4, reg_bank0_d4_val);
230 if (ret)
231 goto err;
232 ret = regmap_write(dev->regmap[0], 0xd6, reg_bank0_d6_val);
233 if (ret)
234 goto err;
235
137 switch (c->delivery_system) { 236 switch (c->delivery_system) {
138 case SYS_DVBT: 237 case SYS_DVBT:
139 ret = regmap_write(dev->regmap[0], 0x07, 0x26); 238 ret = regmap_write(dev->regmap[0], 0x07, 0x26);
140 ret = regmap_write(dev->regmap[0], 0xb0, 0x0a); 239 if (ret)
141 ret = regmap_write(dev->regmap[0], 0xb4, 0x00); 240 goto err;
142 ret = regmap_write(dev->regmap[0], 0xcd, 0x1f);
143 ret = regmap_write(dev->regmap[0], 0xd4, 0x0a);
144 ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
145 ret = regmap_write(dev->regmap[0], 0x00, 0xba); 241 ret = regmap_write(dev->regmap[0], 0x00, 0xba);
242 if (ret)
243 goto err;
146 ret = regmap_write(dev->regmap[0], 0x01, 0x13); 244 ret = regmap_write(dev->regmap[0], 0x01, 0x13);
147 if (ret) 245 if (ret)
148 goto err; 246 goto err;
149 break; 247 break;
150 case SYS_DVBT2: 248 case SYS_DVBT2:
151 ret = regmap_write(dev->regmap[2], 0x2b, 0x13); 249 ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
250 if (ret)
251 goto err;
152 ret = regmap_write(dev->regmap[2], 0x4f, 0x05); 252 ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
253 if (ret)
254 goto err;
153 ret = regmap_write(dev->regmap[1], 0xf6, 0x05); 255 ret = regmap_write(dev->regmap[1], 0xf6, 0x05);
154 ret = regmap_write(dev->regmap[0], 0xb0, 0x0a);
155 ret = regmap_write(dev->regmap[0], 0xb4, 0xf6);
156 ret = regmap_write(dev->regmap[0], 0xcd, 0x01);
157 ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
158 ret = regmap_write(dev->regmap[0], 0xd6, 0x46);
159 ret = regmap_write(dev->regmap[2], 0x30, 0x80);
160 ret = regmap_write(dev->regmap[2], 0x32, 0x00);
161 if (ret) 256 if (ret)
162 goto err; 257 goto err;
163 break; 258 ret = regmap_write(dev->regmap[2], 0x32, c->stream_id);
164 case SYS_DVBC_ANNEX_A:
165 ret = regmap_write(dev->regmap[0], 0xb0, 0x0b);
166 ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
167 ret = regmap_write(dev->regmap[0], 0xcd, 0x17);
168 ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
169 ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
170 ret = regmap_write(dev->regmap[1], 0x00, 0xb0);
171 if (ret) 259 if (ret)
172 goto err; 260 goto err;
173 break; 261 break;
174 default: 262 case SYS_DVBC_ANNEX_A:
175 ret = -EINVAL;
176 goto err;
177 }
178
179 ret = regmap_write(dev->regmap[0], 0x46, 0x00);
180 ret = regmap_write(dev->regmap[0], 0xae, 0x00);
181
182 switch (dev->ts_mode) {
183 case SERIAL_TS_MODE:
184 ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
185 break;
186 case PARALLEL_TS_MODE:
187 ret = regmap_write(dev->regmap[2], 0x08, 0x00);
188 break; 263 break;
189 default: 264 default:
190 dev_dbg(&client->dev, "ts_mode error: %d\n", dev->ts_mode);
191 ret = -EINVAL;
192 goto err;
193 }
194
195 switch (dev->ts_clock) {
196 case VARIABLE_TS_CLOCK:
197 ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
198 break; 265 break;
199 case FIXED_TS_CLOCK:
200 ret = regmap_write(dev->regmap[0], 0xd9, 0xe1);
201 break;
202 default:
203 dev_dbg(&client->dev, "ts_clock error: %d\n", dev->ts_clock);
204 ret = -EINVAL;
205 goto err;
206 } 266 }
207 267
208 /* Reset demod */ 268 /* Reset FSM */
209 ret = regmap_write(dev->regmap[2], 0xf8, 0x9f); 269 ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
210 if (ret) 270 if (ret)
211 goto err; 271 goto err;
212 272
213 dev->delivery_system = c->delivery_system;
214
215 return 0;
216err:
217 dev_dbg(&client->dev, "failed=%d\n", ret);
218 return ret;
219}
220
221static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)
222{
223 struct i2c_client *client = fe->demodulator_priv;
224 struct mn88472_dev *dev = i2c_get_clientdata(client);
225 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
226 int ret;
227 unsigned int utmp;
228 int lock = 0;
229
230 *status = 0;
231
232 if (!dev->warm) {
233 ret = -EAGAIN;
234 goto err;
235 }
236
237 switch (c->delivery_system) {
238 case SYS_DVBT:
239 ret = regmap_read(dev->regmap[0], 0x7F, &utmp);
240 if (ret)
241 goto err;
242 if ((utmp & 0xF) >= 0x09)
243 lock = 1;
244 break;
245 case SYS_DVBT2:
246 ret = regmap_read(dev->regmap[2], 0x92, &utmp);
247 if (ret)
248 goto err;
249 if ((utmp & 0xF) >= 0x07)
250 *status |= FE_HAS_SIGNAL;
251 if ((utmp & 0xF) >= 0x0a)
252 *status |= FE_HAS_CARRIER;
253 if ((utmp & 0xF) >= 0x0d)
254 *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
255 break;
256 case SYS_DVBC_ANNEX_A:
257 ret = regmap_read(dev->regmap[1], 0x84, &utmp);
258 if (ret)
259 goto err;
260 if ((utmp & 0xF) >= 0x08)
261 lock = 1;
262 break;
263 default:
264 ret = -EINVAL;
265 goto err;
266 }
267
268 if (lock)
269 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
270 FE_HAS_SYNC | FE_HAS_LOCK;
271
272 return 0; 273 return 0;
273err: 274err:
274 dev_dbg(&client->dev, "failed=%d\n", ret); 275 dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -279,93 +280,107 @@ static int mn88472_init(struct dvb_frontend *fe)
279{ 280{
280 struct i2c_client *client = fe->demodulator_priv; 281 struct i2c_client *client = fe->demodulator_priv;
281 struct mn88472_dev *dev = i2c_get_clientdata(client); 282 struct mn88472_dev *dev = i2c_get_clientdata(client);
282 int ret, len, remaining; 283 int ret, len, rem;
283 const struct firmware *fw = NULL; 284 unsigned int utmp;
284 u8 *fw_file = MN88472_FIRMWARE; 285 const struct firmware *firmware;
285 unsigned int tmp; 286 const char *name = MN88472_FIRMWARE;
286 287
287 dev_dbg(&client->dev, "\n"); 288 dev_dbg(&client->dev, "\n");
288 289
289 /* set cold state by default */ 290 /* Power up */
290 dev->warm = false;
291
292 /* power on */
293 ret = regmap_write(dev->regmap[2], 0x05, 0x00); 291 ret = regmap_write(dev->regmap[2], 0x05, 0x00);
294 if (ret) 292 if (ret)
295 goto err; 293 goto err;
296 294 ret = regmap_write(dev->regmap[2], 0x0b, 0x00);
297 ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2);
298 if (ret) 295 if (ret)
299 goto err; 296 goto err;
300 297 ret = regmap_write(dev->regmap[2], 0x0c, 0x00);
301 /* check if firmware is already running */
302 ret = regmap_read(dev->regmap[0], 0xf5, &tmp);
303 if (ret) 298 if (ret)
304 goto err; 299 goto err;
305 300
306 if (!(tmp & 0x1)) { 301 /* Check if firmware is already running */
307 dev_info(&client->dev, "firmware already running\n"); 302 ret = regmap_read(dev->regmap[0], 0xf5, &utmp);
308 dev->warm = true; 303 if (ret)
309 return 0; 304 goto err;
310 } 305 if (!(utmp & 0x01))
306 goto warm;
311 307
312 /* request the firmware, this will block and timeout */ 308 ret = request_firmware(&firmware, name, &client->dev);
313 ret = request_firmware(&fw, fw_file, &client->dev);
314 if (ret) { 309 if (ret) {
315 dev_err(&client->dev, "firmare file '%s' not found\n", 310 dev_err(&client->dev, "firmware file '%s' not found\n", name);
316 fw_file);
317 goto err; 311 goto err;
318 } 312 }
319 313
320 dev_info(&client->dev, "downloading firmware from file '%s'\n", 314 dev_info(&client->dev, "downloading firmware from file '%s'\n", name);
321 fw_file);
322 315
323 ret = regmap_write(dev->regmap[0], 0xf5, 0x03); 316 ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
324 if (ret) 317 if (ret)
325 goto firmware_release; 318 goto err_release_firmware;
326
327 for (remaining = fw->size; remaining > 0;
328 remaining -= (dev->i2c_wr_max - 1)) {
329 len = remaining;
330 if (len > (dev->i2c_wr_max - 1))
331 len = dev->i2c_wr_max - 1;
332 319
320 for (rem = firmware->size; rem > 0; rem -= (dev->i2c_write_max - 1)) {
321 len = min(dev->i2c_write_max - 1, rem);
333 ret = regmap_bulk_write(dev->regmap[0], 0xf6, 322 ret = regmap_bulk_write(dev->regmap[0], 0xf6,
334 &fw->data[fw->size - remaining], len); 323 &firmware->data[firmware->size - rem],
324 len);
335 if (ret) { 325 if (ret) {
336 dev_err(&client->dev, 326 dev_err(&client->dev, "firmware download failed %d\n",
337 "firmware download failed=%d\n", ret); 327 ret);
338 goto firmware_release; 328 goto err_release_firmware;
339 } 329 }
340 } 330 }
341 331
342 /* parity check of firmware */ 332 /* Parity check of firmware */
343 ret = regmap_read(dev->regmap[0], 0xf8, &tmp); 333 ret = regmap_read(dev->regmap[0], 0xf8, &utmp);
344 if (ret) { 334 if (ret)
345 dev_err(&client->dev, 335 goto err_release_firmware;
346 "parity reg read failed=%d\n", ret); 336 if (utmp & 0x10) {
347 goto firmware_release; 337 ret = -EINVAL;
348 } 338 dev_err(&client->dev, "firmware did not run\n");
349 if (tmp & 0x10) { 339 goto err_release_firmware;
350 dev_err(&client->dev,
351 "firmware parity check failed=0x%x\n", tmp);
352 goto firmware_release;
353 } 340 }
354 dev_err(&client->dev, "firmware parity check succeeded=0x%x\n", tmp);
355 341
356 ret = regmap_write(dev->regmap[0], 0xf5, 0x00); 342 ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
357 if (ret) 343 if (ret)
358 goto firmware_release; 344 goto err_release_firmware;
345
346 release_firmware(firmware);
347warm:
348 /* TS config */
349 switch (dev->ts_mode) {
350 case SERIAL_TS_MODE:
351 utmp = 0x1d;
352 break;
353 case PARALLEL_TS_MODE:
354 utmp = 0x00;
355 break;
356 default:
357 ret = -EINVAL;
358 goto err;
359 }
360 ret = regmap_write(dev->regmap[2], 0x08, utmp);
361 if (ret)
362 goto err;
359 363
360 release_firmware(fw); 364 switch (dev->ts_clk) {
361 fw = NULL; 365 case VARIABLE_TS_CLOCK:
366 utmp = 0xe3;
367 break;
368 case FIXED_TS_CLOCK:
369 utmp = 0xe1;
370 break;
371 default:
372 ret = -EINVAL;
373 goto err;
374 }
375 ret = regmap_write(dev->regmap[0], 0xd9, utmp);
376 if (ret)
377 goto err;
362 378
363 /* warm state */ 379 dev->active = true;
364 dev->warm = true;
365 380
366 return 0; 381 return 0;
367firmware_release: 382err_release_firmware:
368 release_firmware(fw); 383 release_firmware(firmware);
369err: 384err:
370 dev_dbg(&client->dev, "failed=%d\n", ret); 385 dev_dbg(&client->dev, "failed=%d\n", ret);
371 return ret; 386 return ret;
@@ -379,18 +394,17 @@ static int mn88472_sleep(struct dvb_frontend *fe)
379 394
380 dev_dbg(&client->dev, "\n"); 395 dev_dbg(&client->dev, "\n");
381 396
382 /* power off */ 397 /* Power down */
398 ret = regmap_write(dev->regmap[2], 0x0c, 0x30);
399 if (ret)
400 goto err;
383 ret = regmap_write(dev->regmap[2], 0x0b, 0x30); 401 ret = regmap_write(dev->regmap[2], 0x0b, 0x30);
384
385 if (ret) 402 if (ret)
386 goto err; 403 goto err;
387
388 ret = regmap_write(dev->regmap[2], 0x05, 0x3e); 404 ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
389 if (ret) 405 if (ret)
390 goto err; 406 goto err;
391 407
392 dev->delivery_system = SYS_UNDEFINED;
393
394 return 0; 408 return 0;
395err: 409err:
396 dev_dbg(&client->dev, "failed=%d\n", ret); 410 dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -434,10 +448,19 @@ static struct dvb_frontend_ops mn88472_ops = {
434 .read_status = mn88472_read_status, 448 .read_status = mn88472_read_status,
435}; 449};
436 450
451static struct dvb_frontend *mn88472_get_dvb_frontend(struct i2c_client *client)
452{
453 struct mn88472_dev *dev = i2c_get_clientdata(client);
454
455 dev_dbg(&client->dev, "\n");
456
457 return &dev->fe;
458}
459
437static int mn88472_probe(struct i2c_client *client, 460static int mn88472_probe(struct i2c_client *client,
438 const struct i2c_device_id *id) 461 const struct i2c_device_id *id)
439{ 462{
440 struct mn88472_config *config = client->dev.platform_data; 463 struct mn88472_config *pdata = client->dev.platform_data;
441 struct mn88472_dev *dev; 464 struct mn88472_dev *dev;
442 int ret; 465 int ret;
443 unsigned int utmp; 466 unsigned int utmp;
@@ -448,23 +471,16 @@ static int mn88472_probe(struct i2c_client *client,
448 471
449 dev_dbg(&client->dev, "\n"); 472 dev_dbg(&client->dev, "\n");
450 473
451 /* Caller really need to provide pointer for frontend we create. */
452 if (config->fe == NULL) {
453 dev_err(&client->dev, "frontend pointer not defined\n");
454 ret = -EINVAL;
455 goto err;
456 }
457
458 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 474 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
459 if (!dev) { 475 if (!dev) {
460 ret = -ENOMEM; 476 ret = -ENOMEM;
461 goto err; 477 goto err;
462 } 478 }
463 479
464 dev->i2c_wr_max = config->i2c_wr_max; 480 dev->i2c_write_max = pdata->i2c_wr_max ? pdata->i2c_wr_max : ~0;
465 dev->xtal = config->xtal; 481 dev->clk = pdata->xtal;
466 dev->ts_mode = config->ts_mode; 482 dev->ts_mode = pdata->ts_mode;
467 dev->ts_clock = config->ts_clock; 483 dev->ts_clk = pdata->ts_clock;
468 dev->client[0] = client; 484 dev->client[0] = client;
469 dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config); 485 dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);
470 if (IS_ERR(dev->regmap[0])) { 486 if (IS_ERR(dev->regmap[0])) {
@@ -472,15 +488,25 @@ static int mn88472_probe(struct i2c_client *client,
472 goto err_kfree; 488 goto err_kfree;
473 } 489 }
474 490
475 /* check demod answers to I2C */ 491 /* Check demod answers with correct chip id */
476 ret = regmap_read(dev->regmap[0], 0x00, &utmp); 492 ret = regmap_read(dev->regmap[0], 0xff, &utmp);
477 if (ret) 493 if (ret)
478 goto err_regmap_0_regmap_exit; 494 goto err_regmap_0_regmap_exit;
479 495
496 dev_dbg(&client->dev, "chip id=%02x\n", utmp);
497
498 if (utmp != 0x02) {
499 ret = -ENODEV;
500 goto err_regmap_0_regmap_exit;
501 }
502
480 /* 503 /*
481 * Chip has three I2C addresses for different register pages. Used 504 * Chip has three I2C addresses for different register banks. Used
482 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients, 505 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
483 * 0x1a and 0x1c, in order to get own I2C client for each register page. 506 * 0x1a and 0x1c, in order to get own I2C client for each register bank.
507 *
508 * Also, register bank 2 do not support sequential I/O. Only single
509 * register write or read is allowed to that bank.
484 */ 510 */
485 dev->client[1] = i2c_new_dummy(client->adapter, 0x1a); 511 dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
486 if (!dev->client[1]) { 512 if (!dev->client[1]) {
@@ -510,15 +536,25 @@ static int mn88472_probe(struct i2c_client *client,
510 } 536 }
511 i2c_set_clientdata(dev->client[2], dev); 537 i2c_set_clientdata(dev->client[2], dev);
512 538
513 /* create dvb_frontend */ 539 /* Sleep because chip is active by default */
540 ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
541 if (ret)
542 goto err_regmap_2_regmap_exit;
543
544 /* Create dvb frontend */
514 memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops)); 545 memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
515 dev->fe.demodulator_priv = client; 546 dev->fe.demodulator_priv = client;
516 *config->fe = &dev->fe; 547 *pdata->fe = &dev->fe;
517 i2c_set_clientdata(client, dev); 548 i2c_set_clientdata(client, dev);
518 549
519 dev_info(&client->dev, "Panasonic MN88472 successfully attached\n"); 550 /* Setup callbacks */
520 return 0; 551 pdata->get_dvb_frontend = mn88472_get_dvb_frontend;
521 552
553 dev_info(&client->dev, "Panasonic MN88472 successfully identified\n");
554
555 return 0;
556err_regmap_2_regmap_exit:
557 regmap_exit(dev->regmap[2]);
522err_client_2_i2c_unregister_device: 558err_client_2_i2c_unregister_device:
523 i2c_unregister_device(dev->client[2]); 559 i2c_unregister_device(dev->client[2]);
524err_regmap_1_regmap_exit: 560err_regmap_1_regmap_exit:
@@ -561,11 +597,12 @@ MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
561 597
562static struct i2c_driver mn88472_driver = { 598static struct i2c_driver mn88472_driver = {
563 .driver = { 599 .driver = {
564 .name = "mn88472", 600 .name = "mn88472",
601 .suppress_bind_attrs = true,
565 }, 602 },
566 .probe = mn88472_probe, 603 .probe = mn88472_probe,
567 .remove = mn88472_remove, 604 .remove = mn88472_remove,
568 .id_table = mn88472_id_table, 605 .id_table = mn88472_id_table,
569}; 606};
570 607
571module_i2c_driver(mn88472_driver); 608module_i2c_driver(mn88472_driver);
diff --git a/drivers/media/dvb-frontends/mn88472.h b/drivers/media/dvb-frontends/mn88472.h
index 095294d292f3..323632523876 100644
--- a/drivers/media/dvb-frontends/mn88472.h
+++ b/drivers/media/dvb-frontends/mn88472.h
@@ -19,23 +19,33 @@
19 19
20#include <linux/dvb/frontend.h> 20#include <linux/dvb/frontend.h>
21 21
22enum ts_clock { 22/**
23 VARIABLE_TS_CLOCK, 23 * struct mn88472_config - Platform data for the mn88472 driver
24 FIXED_TS_CLOCK, 24 * @xtal: Clock frequency.
25}; 25 * @ts_mode: TS mode.
26 * @ts_clock: TS clock config.
27 * @i2c_wr_max: Max number of bytes driver writes to I2C at once.
28 * @get_dvb_frontend: Get DVB frontend.
29 */
26 30
27enum ts_mode { 31/* Define old names for backward compatibility */
28 SERIAL_TS_MODE, 32#define VARIABLE_TS_CLOCK MN88472_TS_CLK_VARIABLE
29 PARALLEL_TS_MODE, 33#define FIXED_TS_CLOCK MN88472_TS_CLK_FIXED
30}; 34#define SERIAL_TS_MODE MN88472_TS_MODE_SERIAL
35#define PARALLEL_TS_MODE MN88472_TS_MODE_PARALLEL
31 36
32struct mn88472_config { 37struct mn88472_config {
33 /* 38 unsigned int xtal;
34 * Max num of bytes given I2C adapter could write at once. 39
35 * Default: none 40#define MN88472_TS_MODE_SERIAL 0
36 */ 41#define MN88472_TS_MODE_PARALLEL 1
37 u16 i2c_wr_max; 42 int ts_mode;
38 43
44#define MN88472_TS_CLK_FIXED 0
45#define MN88472_TS_CLK_VARIABLE 1
46 int ts_clock;
47
48 u16 i2c_wr_max;
39 49
40 /* Everything after that is returned by the driver. */ 50 /* Everything after that is returned by the driver. */
41 51
@@ -43,14 +53,7 @@ struct mn88472_config {
43 * DVB frontend. 53 * DVB frontend.
44 */ 54 */
45 struct dvb_frontend **fe; 55 struct dvb_frontend **fe;
46 56 struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
47 /*
48 * Xtal frequency.
49 * Hz
50 */
51 u32 xtal;
52 int ts_mode;
53 int ts_clock;
54}; 57};
55 58
56#endif 59#endif
diff --git a/drivers/staging/media/mn88472/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index 1a0de9e46b66..cdf2597a25d1 100644
--- a/drivers/staging/media/mn88472/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -28,12 +28,11 @@ struct mn88472_dev {
28 struct i2c_client *client[3]; 28 struct i2c_client *client[3];
29 struct regmap *regmap[3]; 29 struct regmap *regmap[3];
30 struct dvb_frontend fe; 30 struct dvb_frontend fe;
31 u16 i2c_wr_max; 31 u16 i2c_write_max;
32 enum fe_delivery_system delivery_system; 32 unsigned int clk;
33 bool warm; /* FW running */ 33 unsigned int active:1;
34 u32 xtal; 34 unsigned int ts_mode:1;
35 int ts_mode; 35 unsigned int ts_clk:1;
36 int ts_clock;
37}; 36};
38 37
39#endif 38#endif
diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c
index 6c5d592161d4..451974a1d7ed 100644
--- a/drivers/media/dvb-frontends/mn88473.c
+++ b/drivers/media/dvb-frontends/mn88473.c
@@ -330,7 +330,7 @@ static int mn88473_init(struct dvb_frontend *fe)
330 /* Request the firmware, this will block and timeout */ 330 /* Request the firmware, this will block and timeout */
331 ret = request_firmware(&fw, name, &client->dev); 331 ret = request_firmware(&fw, name, &client->dev);
332 if (ret) { 332 if (ret) {
333 dev_err(&client->dev, "firmare file '%s' not found\n", name); 333 dev_err(&client->dev, "firmware file '%s' not found\n", name);
334 goto err; 334 goto err;
335 } 335 }
336 336
@@ -536,7 +536,7 @@ static int mn88473_probe(struct i2c_client *client,
536 /* Sleep because chip is active by default */ 536 /* Sleep because chip is active by default */
537 ret = regmap_write(dev->regmap[2], 0x05, 0x3e); 537 ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
538 if (ret) 538 if (ret)
539 goto err_client_2_i2c_unregister_device; 539 goto err_regmap_2_regmap_exit;
540 540
541 /* Create dvb frontend */ 541 /* Create dvb frontend */
542 memcpy(&dev->frontend.ops, &mn88473_ops, sizeof(dev->frontend.ops)); 542 memcpy(&dev->frontend.ops, &mn88473_ops, sizeof(dev->frontend.ops));
@@ -547,7 +547,8 @@ static int mn88473_probe(struct i2c_client *client,
547 dev_info(&client->dev, "Panasonic MN88473 successfully identified\n"); 547 dev_info(&client->dev, "Panasonic MN88473 successfully identified\n");
548 548
549 return 0; 549 return 0;
550 550err_regmap_2_regmap_exit:
551 regmap_exit(dev->regmap[2]);
551err_client_2_i2c_unregister_device: 552err_client_2_i2c_unregister_device:
552 i2c_unregister_device(dev->client[2]); 553 i2c_unregister_device(dev->client[2]);
553err_regmap_1_regmap_exit: 554err_regmap_1_regmap_exit:
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index bfb6beedd40b..c16c69e9d26c 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -947,6 +947,8 @@ static int rtl2832_slave_ts_ctrl(struct i2c_client *client, bool enable)
947 goto err; 947 goto err;
948 } 948 }
949 949
950 dev->slave_ts = enable;
951
950 return 0; 952 return 0;
951err: 953err:
952 dev_dbg(&client->dev, "failed=%d\n", ret); 954 dev_dbg(&client->dev, "failed=%d\n", ret);
@@ -960,7 +962,7 @@ static int rtl2832_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
960 int ret; 962 int ret;
961 u8 u8tmp; 963 u8 u8tmp;
962 964
963 dev_dbg(&client->dev, "onoff=%d\n", onoff); 965 dev_dbg(&client->dev, "onoff=%d, slave_ts=%d\n", onoff, dev->slave_ts);
964 966
965 /* enable / disable PID filter */ 967 /* enable / disable PID filter */
966 if (onoff) 968 if (onoff)
@@ -968,7 +970,10 @@ static int rtl2832_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
968 else 970 else
969 u8tmp = 0x00; 971 u8tmp = 0x00;
970 972
971 ret = regmap_update_bits(dev->regmap, 0x061, 0xc0, u8tmp); 973 if (dev->slave_ts)
974 ret = regmap_update_bits(dev->regmap, 0x021, 0xc0, u8tmp);
975 else
976 ret = regmap_update_bits(dev->regmap, 0x061, 0xc0, u8tmp);
972 if (ret) 977 if (ret)
973 goto err; 978 goto err;
974 979
@@ -986,8 +991,8 @@ static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid,
986 int ret; 991 int ret;
987 u8 buf[4]; 992 u8 buf[4];
988 993
989 dev_dbg(&client->dev, "index=%d pid=%04x onoff=%d\n", 994 dev_dbg(&client->dev, "index=%d pid=%04x onoff=%d slave_ts=%d\n",
990 index, pid, onoff); 995 index, pid, onoff, dev->slave_ts);
991 996
992 /* skip invalid PIDs (0x2000) */ 997 /* skip invalid PIDs (0x2000) */
993 if (pid > 0x1fff || index > 32) 998 if (pid > 0x1fff || index > 32)
@@ -1003,14 +1008,22 @@ static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid,
1003 buf[1] = (dev->filters >> 8) & 0xff; 1008 buf[1] = (dev->filters >> 8) & 0xff;
1004 buf[2] = (dev->filters >> 16) & 0xff; 1009 buf[2] = (dev->filters >> 16) & 0xff;
1005 buf[3] = (dev->filters >> 24) & 0xff; 1010 buf[3] = (dev->filters >> 24) & 0xff;
1006 ret = regmap_bulk_write(dev->regmap, 0x062, buf, 4); 1011
1012 if (dev->slave_ts)
1013 ret = regmap_bulk_write(dev->regmap, 0x022, buf, 4);
1014 else
1015 ret = regmap_bulk_write(dev->regmap, 0x062, buf, 4);
1007 if (ret) 1016 if (ret)
1008 goto err; 1017 goto err;
1009 1018
1010 /* add PID */ 1019 /* add PID */
1011 buf[0] = (pid >> 8) & 0xff; 1020 buf[0] = (pid >> 8) & 0xff;
1012 buf[1] = (pid >> 0) & 0xff; 1021 buf[1] = (pid >> 0) & 0xff;
1013 ret = regmap_bulk_write(dev->regmap, 0x066 + 2 * index, buf, 2); 1022
1023 if (dev->slave_ts)
1024 ret = regmap_bulk_write(dev->regmap, 0x026 + 2 * index, buf, 2);
1025 else
1026 ret = regmap_bulk_write(dev->regmap, 0x066 + 2 * index, buf, 2);
1014 if (ret) 1027 if (ret)
1015 goto err; 1028 goto err;
1016 1029
diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h
index c1a8a69e9015..9a6d01a9c690 100644
--- a/drivers/media/dvb-frontends/rtl2832_priv.h
+++ b/drivers/media/dvb-frontends/rtl2832_priv.h
@@ -44,6 +44,7 @@ struct rtl2832_dev {
44 bool sleeping; 44 bool sleeping;
45 struct delayed_work i2c_gate_work; 45 struct delayed_work i2c_gate_work;
46 unsigned long filters; /* PID filter */ 46 unsigned long filters; /* PID filter */
47 bool slave_ts;
47}; 48};
48 49
49struct rtl2832_reg_entry { 50struct rtl2832_reg_entry {
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index a1cd50f331f1..1795abeda658 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -423,7 +423,7 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
423 unsigned long arg) 423 unsigned long arg)
424{ 424{
425 struct media_devnode *devnode = media_devnode_data(filp); 425 struct media_devnode *devnode = media_devnode_data(filp);
426 struct media_device *dev = to_media_device(devnode); 426 struct media_device *dev = devnode->media_dev;
427 long ret; 427 long ret;
428 428
429 mutex_lock(&dev->graph_mutex); 429 mutex_lock(&dev->graph_mutex);
@@ -495,7 +495,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
495 unsigned long arg) 495 unsigned long arg)
496{ 496{
497 struct media_devnode *devnode = media_devnode_data(filp); 497 struct media_devnode *devnode = media_devnode_data(filp);
498 struct media_device *dev = to_media_device(devnode); 498 struct media_device *dev = devnode->media_dev;
499 long ret; 499 long ret;
500 500
501 switch (cmd) { 501 switch (cmd) {
@@ -531,7 +531,8 @@ static const struct media_file_operations media_device_fops = {
531static ssize_t show_model(struct device *cd, 531static ssize_t show_model(struct device *cd,
532 struct device_attribute *attr, char *buf) 532 struct device_attribute *attr, char *buf)
533{ 533{
534 struct media_device *mdev = to_media_device(to_media_devnode(cd)); 534 struct media_devnode *devnode = to_media_devnode(cd);
535 struct media_device *mdev = devnode->media_dev;
535 536
536 return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model); 537 return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
537} 538}
@@ -704,23 +705,35 @@ EXPORT_SYMBOL_GPL(media_device_cleanup);
704int __must_check __media_device_register(struct media_device *mdev, 705int __must_check __media_device_register(struct media_device *mdev,
705 struct module *owner) 706 struct module *owner)
706{ 707{
708 struct media_devnode *devnode;
707 int ret; 709 int ret;
708 710
711 devnode = kzalloc(sizeof(*devnode), GFP_KERNEL);
712 if (!devnode)
713 return -ENOMEM;
714
709 /* Register the device node. */ 715 /* Register the device node. */
710 mdev->devnode.fops = &media_device_fops; 716 mdev->devnode = devnode;
711 mdev->devnode.parent = mdev->dev; 717 devnode->fops = &media_device_fops;
712 mdev->devnode.release = media_device_release; 718 devnode->parent = mdev->dev;
719 devnode->release = media_device_release;
713 720
714 /* Set version 0 to indicate user-space that the graph is static */ 721 /* Set version 0 to indicate user-space that the graph is static */
715 mdev->topology_version = 0; 722 mdev->topology_version = 0;
716 723
717 ret = media_devnode_register(&mdev->devnode, owner); 724 ret = media_devnode_register(mdev, devnode, owner);
718 if (ret < 0) 725 if (ret < 0) {
726 /* devnode free is handled in media_devnode_*() */
727 mdev->devnode = NULL;
719 return ret; 728 return ret;
729 }
720 730
721 ret = device_create_file(&mdev->devnode.dev, &dev_attr_model); 731 ret = device_create_file(&devnode->dev, &dev_attr_model);
722 if (ret < 0) { 732 if (ret < 0) {
723 media_devnode_unregister(&mdev->devnode); 733 /* devnode free is handled in media_devnode_*() */
734 mdev->devnode = NULL;
735 media_devnode_unregister_prepare(devnode);
736 media_devnode_unregister(devnode);
724 return ret; 737 return ret;
725 } 738 }
726 739
@@ -771,11 +784,14 @@ void media_device_unregister(struct media_device *mdev)
771 mutex_lock(&mdev->graph_mutex); 784 mutex_lock(&mdev->graph_mutex);
772 785
773 /* Check if mdev was ever registered at all */ 786 /* Check if mdev was ever registered at all */
774 if (!media_devnode_is_registered(&mdev->devnode)) { 787 if (!media_devnode_is_registered(mdev->devnode)) {
775 mutex_unlock(&mdev->graph_mutex); 788 mutex_unlock(&mdev->graph_mutex);
776 return; 789 return;
777 } 790 }
778 791
792 /* Clear the devnode register bit to avoid races with media dev open */
793 media_devnode_unregister_prepare(mdev->devnode);
794
779 /* Remove all entities from the media device */ 795 /* Remove all entities from the media device */
780 list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) 796 list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
781 __media_device_unregister_entity(entity); 797 __media_device_unregister_entity(entity);
@@ -794,9 +810,12 @@ void media_device_unregister(struct media_device *mdev)
794 810
795 mutex_unlock(&mdev->graph_mutex); 811 mutex_unlock(&mdev->graph_mutex);
796 812
797 device_remove_file(&mdev->devnode.dev, &dev_attr_model); 813 dev_dbg(mdev->dev, "Media device unregistered\n");
798 dev_dbg(mdev->dev, "Media device unregistering\n"); 814
799 media_devnode_unregister(&mdev->devnode); 815 device_remove_file(&mdev->devnode->dev, &dev_attr_model);
816 media_devnode_unregister(mdev->devnode);
817 /* devnode free is handled in media_devnode_*() */
818 mdev->devnode = NULL;
800} 819}
801EXPORT_SYMBOL_GPL(media_device_unregister); 820EXPORT_SYMBOL_GPL(media_device_unregister);
802 821
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
index b66dc9d0766b..f2772ba6f611 100644
--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -44,6 +44,7 @@
44#include <linux/uaccess.h> 44#include <linux/uaccess.h>
45 45
46#include <media/media-devnode.h> 46#include <media/media-devnode.h>
47#include <media/media-device.h>
47 48
48#define MEDIA_NUM_DEVICES 256 49#define MEDIA_NUM_DEVICES 256
49#define MEDIA_NAME "media" 50#define MEDIA_NAME "media"
@@ -59,21 +60,19 @@ static DECLARE_BITMAP(media_devnode_nums, MEDIA_NUM_DEVICES);
59/* Called when the last user of the media device exits. */ 60/* Called when the last user of the media device exits. */
60static void media_devnode_release(struct device *cd) 61static void media_devnode_release(struct device *cd)
61{ 62{
62 struct media_devnode *mdev = to_media_devnode(cd); 63 struct media_devnode *devnode = to_media_devnode(cd);
63 64
64 mutex_lock(&media_devnode_lock); 65 mutex_lock(&media_devnode_lock);
65
66 /* Delete the cdev on this minor as well */
67 cdev_del(&mdev->cdev);
68
69 /* Mark device node number as free */ 66 /* Mark device node number as free */
70 clear_bit(mdev->minor, media_devnode_nums); 67 clear_bit(devnode->minor, media_devnode_nums);
71
72 mutex_unlock(&media_devnode_lock); 68 mutex_unlock(&media_devnode_lock);
73 69
74 /* Release media_devnode and perform other cleanups as needed. */ 70 /* Release media_devnode and perform other cleanups as needed. */
75 if (mdev->release) 71 if (devnode->release)
76 mdev->release(mdev); 72 devnode->release(devnode);
73
74 kfree(devnode);
75 pr_debug("%s: Media Devnode Deallocated\n", __func__);
77} 76}
78 77
79static struct bus_type media_bus_type = { 78static struct bus_type media_bus_type = {
@@ -83,37 +82,37 @@ static struct bus_type media_bus_type = {
83static ssize_t media_read(struct file *filp, char __user *buf, 82static ssize_t media_read(struct file *filp, char __user *buf,
84 size_t sz, loff_t *off) 83 size_t sz, loff_t *off)
85{ 84{
86 struct media_devnode *mdev = media_devnode_data(filp); 85 struct media_devnode *devnode = media_devnode_data(filp);
87 86
88 if (!mdev->fops->read) 87 if (!devnode->fops->read)
89 return -EINVAL; 88 return -EINVAL;
90 if (!media_devnode_is_registered(mdev)) 89 if (!media_devnode_is_registered(devnode))
91 return -EIO; 90 return -EIO;
92 return mdev->fops->read(filp, buf, sz, off); 91 return devnode->fops->read(filp, buf, sz, off);
93} 92}
94 93
95static ssize_t media_write(struct file *filp, const char __user *buf, 94static ssize_t media_write(struct file *filp, const char __user *buf,
96 size_t sz, loff_t *off) 95 size_t sz, loff_t *off)
97{ 96{
98 struct media_devnode *mdev = media_devnode_data(filp); 97 struct media_devnode *devnode = media_devnode_data(filp);
99 98
100 if (!mdev->fops->write) 99 if (!devnode->fops->write)
101 return -EINVAL; 100 return -EINVAL;
102 if (!media_devnode_is_registered(mdev)) 101 if (!media_devnode_is_registered(devnode))
103 return -EIO; 102 return -EIO;
104 return mdev->fops->write(filp, buf, sz, off); 103 return devnode->fops->write(filp, buf, sz, off);
105} 104}
106 105
107static unsigned int media_poll(struct file *filp, 106static unsigned int media_poll(struct file *filp,
108 struct poll_table_struct *poll) 107 struct poll_table_struct *poll)
109{ 108{
110 struct media_devnode *mdev = media_devnode_data(filp); 109 struct media_devnode *devnode = media_devnode_data(filp);
111 110
112 if (!media_devnode_is_registered(mdev)) 111 if (!media_devnode_is_registered(devnode))
113 return POLLERR | POLLHUP; 112 return POLLERR | POLLHUP;
114 if (!mdev->fops->poll) 113 if (!devnode->fops->poll)
115 return DEFAULT_POLLMASK; 114 return DEFAULT_POLLMASK;
116 return mdev->fops->poll(filp, poll); 115 return devnode->fops->poll(filp, poll);
117} 116}
118 117
119static long 118static long
@@ -121,12 +120,12 @@ __media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg,
121 long (*ioctl_func)(struct file *filp, unsigned int cmd, 120 long (*ioctl_func)(struct file *filp, unsigned int cmd,
122 unsigned long arg)) 121 unsigned long arg))
123{ 122{
124 struct media_devnode *mdev = media_devnode_data(filp); 123 struct media_devnode *devnode = media_devnode_data(filp);
125 124
126 if (!ioctl_func) 125 if (!ioctl_func)
127 return -ENOTTY; 126 return -ENOTTY;
128 127
129 if (!media_devnode_is_registered(mdev)) 128 if (!media_devnode_is_registered(devnode))
130 return -EIO; 129 return -EIO;
131 130
132 return ioctl_func(filp, cmd, arg); 131 return ioctl_func(filp, cmd, arg);
@@ -134,9 +133,9 @@ __media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg,
134 133
135static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 134static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
136{ 135{
137 struct media_devnode *mdev = media_devnode_data(filp); 136 struct media_devnode *devnode = media_devnode_data(filp);
138 137
139 return __media_ioctl(filp, cmd, arg, mdev->fops->ioctl); 138 return __media_ioctl(filp, cmd, arg, devnode->fops->ioctl);
140} 139}
141 140
142#ifdef CONFIG_COMPAT 141#ifdef CONFIG_COMPAT
@@ -144,9 +143,9 @@ static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
144static long media_compat_ioctl(struct file *filp, unsigned int cmd, 143static long media_compat_ioctl(struct file *filp, unsigned int cmd,
145 unsigned long arg) 144 unsigned long arg)
146{ 145{
147 struct media_devnode *mdev = media_devnode_data(filp); 146 struct media_devnode *devnode = media_devnode_data(filp);
148 147
149 return __media_ioctl(filp, cmd, arg, mdev->fops->compat_ioctl); 148 return __media_ioctl(filp, cmd, arg, devnode->fops->compat_ioctl);
150} 149}
151 150
152#endif /* CONFIG_COMPAT */ 151#endif /* CONFIG_COMPAT */
@@ -154,7 +153,7 @@ static long media_compat_ioctl(struct file *filp, unsigned int cmd,
154/* Override for the open function */ 153/* Override for the open function */
155static int media_open(struct inode *inode, struct file *filp) 154static int media_open(struct inode *inode, struct file *filp)
156{ 155{
157 struct media_devnode *mdev; 156 struct media_devnode *devnode;
158 int ret; 157 int ret;
159 158
160 /* Check if the media device is available. This needs to be done with 159 /* Check if the media device is available. This needs to be done with
@@ -164,23 +163,23 @@ static int media_open(struct inode *inode, struct file *filp)
164 * a crash. 163 * a crash.
165 */ 164 */
166 mutex_lock(&media_devnode_lock); 165 mutex_lock(&media_devnode_lock);
167 mdev = container_of(inode->i_cdev, struct media_devnode, cdev); 166 devnode = container_of(inode->i_cdev, struct media_devnode, cdev);
168 /* return ENXIO if the media device has been removed 167 /* return ENXIO if the media device has been removed
169 already or if it is not registered anymore. */ 168 already or if it is not registered anymore. */
170 if (!media_devnode_is_registered(mdev)) { 169 if (!media_devnode_is_registered(devnode)) {
171 mutex_unlock(&media_devnode_lock); 170 mutex_unlock(&media_devnode_lock);
172 return -ENXIO; 171 return -ENXIO;
173 } 172 }
174 /* and increase the device refcount */ 173 /* and increase the device refcount */
175 get_device(&mdev->dev); 174 get_device(&devnode->dev);
176 mutex_unlock(&media_devnode_lock); 175 mutex_unlock(&media_devnode_lock);
177 176
178 filp->private_data = mdev; 177 filp->private_data = devnode;
179 178
180 if (mdev->fops->open) { 179 if (devnode->fops->open) {
181 ret = mdev->fops->open(filp); 180 ret = devnode->fops->open(filp);
182 if (ret) { 181 if (ret) {
183 put_device(&mdev->dev); 182 put_device(&devnode->dev);
184 filp->private_data = NULL; 183 filp->private_data = NULL;
185 return ret; 184 return ret;
186 } 185 }
@@ -192,16 +191,18 @@ static int media_open(struct inode *inode, struct file *filp)
192/* Override for the release function */ 191/* Override for the release function */
193static int media_release(struct inode *inode, struct file *filp) 192static int media_release(struct inode *inode, struct file *filp)
194{ 193{
195 struct media_devnode *mdev = media_devnode_data(filp); 194 struct media_devnode *devnode = media_devnode_data(filp);
196 195
197 if (mdev->fops->release) 196 if (devnode->fops->release)
198 mdev->fops->release(filp); 197 devnode->fops->release(filp);
199 198
200 filp->private_data = NULL; 199 filp->private_data = NULL;
201 200
202 /* decrease the refcount unconditionally since the release() 201 /* decrease the refcount unconditionally since the release()
203 return value is ignored. */ 202 return value is ignored. */
204 put_device(&mdev->dev); 203 put_device(&devnode->dev);
204
205 pr_debug("%s: Media Release\n", __func__);
205 return 0; 206 return 0;
206} 207}
207 208
@@ -219,7 +220,8 @@ static const struct file_operations media_devnode_fops = {
219 .llseek = no_llseek, 220 .llseek = no_llseek,
220}; 221};
221 222
222int __must_check media_devnode_register(struct media_devnode *mdev, 223int __must_check media_devnode_register(struct media_device *mdev,
224 struct media_devnode *devnode,
223 struct module *owner) 225 struct module *owner)
224{ 226{
225 int minor; 227 int minor;
@@ -231,61 +233,80 @@ int __must_check media_devnode_register(struct media_devnode *mdev,
231 if (minor == MEDIA_NUM_DEVICES) { 233 if (minor == MEDIA_NUM_DEVICES) {
232 mutex_unlock(&media_devnode_lock); 234 mutex_unlock(&media_devnode_lock);
233 pr_err("could not get a free minor\n"); 235 pr_err("could not get a free minor\n");
236 kfree(devnode);
234 return -ENFILE; 237 return -ENFILE;
235 } 238 }
236 239
237 set_bit(minor, media_devnode_nums); 240 set_bit(minor, media_devnode_nums);
238 mutex_unlock(&media_devnode_lock); 241 mutex_unlock(&media_devnode_lock);
239 242
240 mdev->minor = minor; 243 devnode->minor = minor;
244 devnode->media_dev = mdev;
245
246 /* Part 1: Initialize dev now to use dev.kobj for cdev.kobj.parent */
247 devnode->dev.bus = &media_bus_type;
248 devnode->dev.devt = MKDEV(MAJOR(media_dev_t), devnode->minor);
249 devnode->dev.release = media_devnode_release;
250 if (devnode->parent)
251 devnode->dev.parent = devnode->parent;
252 dev_set_name(&devnode->dev, "media%d", devnode->minor);
253 device_initialize(&devnode->dev);
241 254
242 /* Part 2: Initialize and register the character device */ 255 /* Part 2: Initialize and register the character device */
243 cdev_init(&mdev->cdev, &media_devnode_fops); 256 cdev_init(&devnode->cdev, &media_devnode_fops);
244 mdev->cdev.owner = owner; 257 devnode->cdev.owner = owner;
258 devnode->cdev.kobj.parent = &devnode->dev.kobj;
245 259
246 ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1); 260 ret = cdev_add(&devnode->cdev, MKDEV(MAJOR(media_dev_t), devnode->minor), 1);
247 if (ret < 0) { 261 if (ret < 0) {
248 pr_err("%s: cdev_add failed\n", __func__); 262 pr_err("%s: cdev_add failed\n", __func__);
249 goto error; 263 goto cdev_add_error;
250 } 264 }
251 265
252 /* Part 3: Register the media device */ 266 /* Part 3: Add the media device */
253 mdev->dev.bus = &media_bus_type; 267 ret = device_add(&devnode->dev);
254 mdev->dev.devt = MKDEV(MAJOR(media_dev_t), mdev->minor);
255 mdev->dev.release = media_devnode_release;
256 if (mdev->parent)
257 mdev->dev.parent = mdev->parent;
258 dev_set_name(&mdev->dev, "media%d", mdev->minor);
259 ret = device_register(&mdev->dev);
260 if (ret < 0) { 268 if (ret < 0) {
261 pr_err("%s: device_register failed\n", __func__); 269 pr_err("%s: device_add failed\n", __func__);
262 goto error; 270 goto device_add_error;
263 } 271 }
264 272
265 /* Part 4: Activate this minor. The char device can now be used. */ 273 /* Part 4: Activate this minor. The char device can now be used. */
266 set_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); 274 set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
267 275
268 return 0; 276 return 0;
269 277
270error: 278device_add_error:
279 cdev_del(&devnode->cdev);
280cdev_add_error:
271 mutex_lock(&media_devnode_lock); 281 mutex_lock(&media_devnode_lock);
272 cdev_del(&mdev->cdev); 282 clear_bit(devnode->minor, media_devnode_nums);
273 clear_bit(mdev->minor, media_devnode_nums); 283 devnode->media_dev = NULL;
274 mutex_unlock(&media_devnode_lock); 284 mutex_unlock(&media_devnode_lock);
275 285
286 put_device(&devnode->dev);
276 return ret; 287 return ret;
277} 288}
278 289
279void media_devnode_unregister(struct media_devnode *mdev) 290void media_devnode_unregister_prepare(struct media_devnode *devnode)
280{ 291{
281 /* Check if mdev was ever registered at all */ 292 /* Check if devnode was ever registered at all */
282 if (!media_devnode_is_registered(mdev)) 293 if (!media_devnode_is_registered(devnode))
283 return; 294 return;
284 295
285 mutex_lock(&media_devnode_lock); 296 mutex_lock(&media_devnode_lock);
286 clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); 297 clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
298 mutex_unlock(&media_devnode_lock);
299}
300
301void media_devnode_unregister(struct media_devnode *devnode)
302{
303 mutex_lock(&media_devnode_lock);
304 /* Delete the cdev on this minor as well */
305 cdev_del(&devnode->cdev);
287 mutex_unlock(&media_devnode_lock); 306 mutex_unlock(&media_devnode_lock);
288 device_unregister(&mdev->dev); 307 device_del(&devnode->dev);
308 devnode->media_dev = NULL;
309 put_device(&devnode->dev);
289} 310}
290 311
291/* 312/*
diff --git a/drivers/media/pci/netup_unidvb/Kconfig b/drivers/media/pci/netup_unidvb/Kconfig
index f277b0b10c2d..0ad37714c7fd 100644
--- a/drivers/media/pci/netup_unidvb/Kconfig
+++ b/drivers/media/pci/netup_unidvb/Kconfig
@@ -5,8 +5,13 @@ config DVB_NETUP_UNIDVB
5 select VIDEOBUF2_VMALLOC 5 select VIDEOBUF2_VMALLOC
6 select DVB_HORUS3A if MEDIA_SUBDRV_AUTOSELECT 6 select DVB_HORUS3A if MEDIA_SUBDRV_AUTOSELECT
7 select DVB_ASCOT2E if MEDIA_SUBDRV_AUTOSELECT 7 select DVB_ASCOT2E if MEDIA_SUBDRV_AUTOSELECT
8 select DVB_HELENE if MEDIA_SUBDRV_AUTOSELECT
8 select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT 9 select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT
9 select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT 10 select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT
10 ---help--- 11 ---help---
11 Support for NetUP PCI express Universal DVB card. 12 Support for NetUP PCI express Universal DVB card.
12 13 help
14 Say Y when you want to support NetUP Dual Universal DVB card
15 Card can receive two independent streams in following standards:
16 DVB-S/S2, T/T2, C/C2
17 Two CI slots available for CAM modules.
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb.h b/drivers/media/pci/netup_unidvb/netup_unidvb.h
index a67b28111905..39b08ecda1fc 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb.h
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb.h
@@ -50,6 +50,15 @@
50#define NETUP_UNIDVB_IRQ_CAM0 (1 << 11) 50#define NETUP_UNIDVB_IRQ_CAM0 (1 << 11)
51#define NETUP_UNIDVB_IRQ_CAM1 (1 << 12) 51#define NETUP_UNIDVB_IRQ_CAM1 (1 << 12)
52 52
53/* NetUP Universal DVB card hardware revisions and it's PCI device id's:
54 * 1.3 - CXD2841ER demod, ASCOT2E and HORUS3A tuners
55 * 1.4 - CXD2854ER demod, HELENE tuner
56*/
57enum netup_hw_rev {
58 NETUP_HW_REV_1_3 = 0x18F6,
59 NETUP_HW_REV_1_4 = 0x18F7
60};
61
53struct netup_dma { 62struct netup_dma {
54 u8 num; 63 u8 num;
55 spinlock_t lock; 64 spinlock_t lock;
@@ -119,6 +128,7 @@ struct netup_unidvb_dev {
119 struct netup_dma dma[2]; 128 struct netup_dma dma[2];
120 struct netup_ci_state ci[2]; 129 struct netup_ci_state ci[2];
121 struct netup_spi *spi; 130 struct netup_spi *spi;
131 enum netup_hw_rev rev;
122}; 132};
123 133
124int netup_i2c_register(struct netup_unidvb_dev *ndev); 134int netup_i2c_register(struct netup_unidvb_dev *ndev);
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c b/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c
index f46ffac66ee9..f535270c2116 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_ci.c
@@ -147,7 +147,7 @@ static int netup_unidvb_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
147{ 147{
148 struct netup_ci_state *state = en50221->data; 148 struct netup_ci_state *state = en50221->data;
149 struct netup_unidvb_dev *dev = state->dev; 149 struct netup_unidvb_dev *dev = state->dev;
150 u8 val = *((u8 __force *)state->membase8_io + addr); 150 u8 val = *((u8 __force *)state->membase8_config + addr);
151 151
152 dev_dbg(&dev->pci_dev->dev, 152 dev_dbg(&dev->pci_dev->dev,
153 "%s(): addr=0x%x val=0x%x\n", __func__, addr, val); 153 "%s(): addr=0x%x val=0x%x\n", __func__, addr, val);
@@ -162,7 +162,7 @@ static int netup_unidvb_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
162 162
163 dev_dbg(&dev->pci_dev->dev, 163 dev_dbg(&dev->pci_dev->dev,
164 "%s(): addr=0x%x data=0x%x\n", __func__, addr, data); 164 "%s(): addr=0x%x data=0x%x\n", __func__, addr, data);
165 *((u8 __force *)state->membase8_io + addr) = data; 165 *((u8 __force *)state->membase8_config + addr) = data;
166 return 0; 166 return 0;
167} 167}
168 168
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 2b667b315913..d278d4e151a0 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -34,6 +34,7 @@
34#include "cxd2841er.h" 34#include "cxd2841er.h"
35#include "horus3a.h" 35#include "horus3a.h"
36#include "ascot2e.h" 36#include "ascot2e.h"
37#include "helene.h"
37#include "lnbh25.h" 38#include "lnbh25.h"
38 39
39static int spi_enable; 40static int spi_enable;
@@ -120,7 +121,8 @@ static int netup_unidvb_tuner_ctrl(void *priv, int is_dvb_tc);
120static void netup_unidvb_queue_cleanup(struct netup_dma *dma); 121static void netup_unidvb_queue_cleanup(struct netup_dma *dma);
121 122
122static struct cxd2841er_config demod_config = { 123static struct cxd2841er_config demod_config = {
123 .i2c_addr = 0xc8 124 .i2c_addr = 0xc8,
125 .xtal = SONY_XTAL_24000
124}; 126};
125 127
126static struct horus3a_config horus3a_conf = { 128static struct horus3a_config horus3a_conf = {
@@ -134,6 +136,12 @@ static struct ascot2e_config ascot2e_conf = {
134 .set_tuner_callback = netup_unidvb_tuner_ctrl 136 .set_tuner_callback = netup_unidvb_tuner_ctrl
135}; 137};
136 138
139static struct helene_config helene_conf = {
140 .i2c_address = 0xc0,
141 .xtal = SONY_HELENE_XTAL_24000,
142 .set_tuner_callback = netup_unidvb_tuner_ctrl
143};
144
137static struct lnbh25_config lnbh25_conf = { 145static struct lnbh25_config lnbh25_conf = {
138 .i2c_address = 0x10, 146 .i2c_address = 0x10,
139 .data2_config = LNBH25_TEN | LNBH25_EXTM 147 .data2_config = LNBH25_TEN | LNBH25_EXTM
@@ -152,6 +160,11 @@ static int netup_unidvb_tuner_ctrl(void *priv, int is_dvb_tc)
152 __func__, dma->num, is_dvb_tc); 160 __func__, dma->num, is_dvb_tc);
153 reg = readb(ndev->bmmio0 + GPIO_REG_IO); 161 reg = readb(ndev->bmmio0 + GPIO_REG_IO);
154 mask = (dma->num == 0) ? GPIO_RFA_CTL : GPIO_RFB_CTL; 162 mask = (dma->num == 0) ? GPIO_RFA_CTL : GPIO_RFB_CTL;
163
164 /* inverted tuner control in hw rev. 1.4 */
165 if (ndev->rev == NETUP_HW_REV_1_4)
166 is_dvb_tc = !is_dvb_tc;
167
155 if (!is_dvb_tc) 168 if (!is_dvb_tc)
156 reg |= mask; 169 reg |= mask;
157 else 170 else
@@ -372,7 +385,15 @@ static int netup_unidvb_queue_init(struct netup_dma *dma,
372static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev, 385static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
373 int num) 386 int num)
374{ 387{
375 struct vb2_dvb_frontend *fe0, *fe1, *fe2; 388 int fe_count = 2;
389 int i = 0;
390 struct vb2_dvb_frontend *fes[2];
391 u8 fe_name[32];
392
393 if (ndev->rev == NETUP_HW_REV_1_3)
394 demod_config.xtal = SONY_XTAL_20500;
395 else
396 demod_config.xtal = SONY_XTAL_24000;
376 397
377 if (num < 0 || num > 1) { 398 if (num < 0 || num > 1) {
378 dev_dbg(&ndev->pci_dev->dev, 399 dev_dbg(&ndev->pci_dev->dev,
@@ -381,84 +402,96 @@ static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
381 } 402 }
382 mutex_init(&ndev->frontends[num].lock); 403 mutex_init(&ndev->frontends[num].lock);
383 INIT_LIST_HEAD(&ndev->frontends[num].felist); 404 INIT_LIST_HEAD(&ndev->frontends[num].felist);
384 if (vb2_dvb_alloc_frontend(&ndev->frontends[num], 1) == NULL || 405
385 vb2_dvb_alloc_frontend( 406 for (i = 0; i < fe_count; i++) {
386 &ndev->frontends[num], 2) == NULL || 407 if (vb2_dvb_alloc_frontend(&ndev->frontends[num], i+1)
387 vb2_dvb_alloc_frontend( 408 == NULL) {
388 &ndev->frontends[num], 3) == NULL) { 409 dev_err(&ndev->pci_dev->dev,
389 dev_dbg(&ndev->pci_dev->dev, 410 "%s(): unable to allocate vb2_dvb_frontend\n",
390 "%s(): unable to allocate vb2_dvb_frontend\n", 411 __func__);
391 __func__); 412 return -ENOMEM;
392 return -ENOMEM; 413 }
393 } 414 }
394 fe0 = vb2_dvb_get_frontend(&ndev->frontends[num], 1); 415
395 fe1 = vb2_dvb_get_frontend(&ndev->frontends[num], 2); 416 for (i = 0; i < fe_count; i++) {
396 fe2 = vb2_dvb_get_frontend(&ndev->frontends[num], 3); 417 fes[i] = vb2_dvb_get_frontend(&ndev->frontends[num], i+1);
397 if (fe0 == NULL || fe1 == NULL || fe2 == NULL) { 418 if (fes[i] == NULL) {
398 dev_dbg(&ndev->pci_dev->dev, 419 dev_err(&ndev->pci_dev->dev,
399 "%s(): frontends has not been allocated\n", __func__); 420 "%s(): frontends has not been allocated\n",
400 return -EINVAL; 421 __func__);
422 return -EINVAL;
423 }
424 }
425
426 for (i = 0; i < fe_count; i++) {
427 netup_unidvb_queue_init(&ndev->dma[num], &fes[i]->dvb.dvbq);
428 snprintf(fe_name, sizeof(fe_name), "netup_fe%d", i);
429 fes[i]->dvb.name = fe_name;
401 } 430 }
402 netup_unidvb_queue_init(&ndev->dma[num], &fe0->dvb.dvbq); 431
403 netup_unidvb_queue_init(&ndev->dma[num], &fe1->dvb.dvbq); 432 fes[0]->dvb.frontend = dvb_attach(cxd2841er_attach_s,
404 netup_unidvb_queue_init(&ndev->dma[num], &fe2->dvb.dvbq);
405 fe0->dvb.name = "netup_fe0";
406 fe1->dvb.name = "netup_fe1";
407 fe2->dvb.name = "netup_fe2";
408 fe0->dvb.frontend = dvb_attach(cxd2841er_attach_s,
409 &demod_config, &ndev->i2c[num].adap); 433 &demod_config, &ndev->i2c[num].adap);
410 if (fe0->dvb.frontend == NULL) { 434 if (fes[0]->dvb.frontend == NULL) {
411 dev_dbg(&ndev->pci_dev->dev, 435 dev_dbg(&ndev->pci_dev->dev,
412 "%s(): unable to attach DVB-S/S2 frontend\n", 436 "%s(): unable to attach DVB-S/S2 frontend\n",
413 __func__); 437 __func__);
414 goto frontend_detach; 438 goto frontend_detach;
415 } 439 }
416 horus3a_conf.set_tuner_priv = &ndev->dma[num]; 440
417 if (!dvb_attach(horus3a_attach, fe0->dvb.frontend, 441 if (ndev->rev == NETUP_HW_REV_1_3) {
418 &horus3a_conf, &ndev->i2c[num].adap)) { 442 horus3a_conf.set_tuner_priv = &ndev->dma[num];
419 dev_dbg(&ndev->pci_dev->dev, 443 if (!dvb_attach(horus3a_attach, fes[0]->dvb.frontend,
420 "%s(): unable to attach DVB-S/S2 tuner frontend\n", 444 &horus3a_conf, &ndev->i2c[num].adap)) {
421 __func__); 445 dev_dbg(&ndev->pci_dev->dev,
422 goto frontend_detach; 446 "%s(): unable to attach HORUS3A DVB-S/S2 tuner frontend\n",
447 __func__);
448 goto frontend_detach;
449 }
450 } else {
451 helene_conf.set_tuner_priv = &ndev->dma[num];
452 if (!dvb_attach(helene_attach_s, fes[0]->dvb.frontend,
453 &helene_conf, &ndev->i2c[num].adap)) {
454 dev_err(&ndev->pci_dev->dev,
455 "%s(): unable to attach HELENE DVB-S/S2 tuner frontend\n",
456 __func__);
457 goto frontend_detach;
458 }
423 } 459 }
424 if (!dvb_attach(lnbh25_attach, fe0->dvb.frontend, 460
461 if (!dvb_attach(lnbh25_attach, fes[0]->dvb.frontend,
425 &lnbh25_conf, &ndev->i2c[num].adap)) { 462 &lnbh25_conf, &ndev->i2c[num].adap)) {
426 dev_dbg(&ndev->pci_dev->dev, 463 dev_dbg(&ndev->pci_dev->dev,
427 "%s(): unable to attach SEC frontend\n", __func__); 464 "%s(): unable to attach SEC frontend\n", __func__);
428 goto frontend_detach; 465 goto frontend_detach;
429 } 466 }
467
430 /* DVB-T/T2 frontend */ 468 /* DVB-T/T2 frontend */
431 fe1->dvb.frontend = dvb_attach(cxd2841er_attach_t, 469 fes[1]->dvb.frontend = dvb_attach(cxd2841er_attach_t_c,
432 &demod_config, &ndev->i2c[num].adap); 470 &demod_config, &ndev->i2c[num].adap);
433 if (fe1->dvb.frontend == NULL) { 471 if (fes[1]->dvb.frontend == NULL) {
434 dev_dbg(&ndev->pci_dev->dev,
435 "%s(): unable to attach DVB-T frontend\n", __func__);
436 goto frontend_detach;
437 }
438 fe1->dvb.frontend->id = 1;
439 ascot2e_conf.set_tuner_priv = &ndev->dma[num];
440 if (!dvb_attach(ascot2e_attach, fe1->dvb.frontend,
441 &ascot2e_conf, &ndev->i2c[num].adap)) {
442 dev_dbg(&ndev->pci_dev->dev,
443 "%s(): unable to attach DVB-T tuner frontend\n",
444 __func__);
445 goto frontend_detach;
446 }
447 /* DVB-C/C2 frontend */
448 fe2->dvb.frontend = dvb_attach(cxd2841er_attach_c,
449 &demod_config, &ndev->i2c[num].adap);
450 if (fe2->dvb.frontend == NULL) {
451 dev_dbg(&ndev->pci_dev->dev, 472 dev_dbg(&ndev->pci_dev->dev,
452 "%s(): unable to attach DVB-C frontend\n", __func__); 473 "%s(): unable to attach Ter frontend\n", __func__);
453 goto frontend_detach; 474 goto frontend_detach;
454 } 475 }
455 fe2->dvb.frontend->id = 2; 476 fes[1]->dvb.frontend->id = 1;
456 if (!dvb_attach(ascot2e_attach, fe2->dvb.frontend, 477 if (ndev->rev == NETUP_HW_REV_1_3) {
457 &ascot2e_conf, &ndev->i2c[num].adap)) { 478 ascot2e_conf.set_tuner_priv = &ndev->dma[num];
458 dev_dbg(&ndev->pci_dev->dev, 479 if (!dvb_attach(ascot2e_attach, fes[1]->dvb.frontend,
459 "%s(): unable to attach DVB-T/C tuner frontend\n", 480 &ascot2e_conf, &ndev->i2c[num].adap)) {
460 __func__); 481 dev_dbg(&ndev->pci_dev->dev,
461 goto frontend_detach; 482 "%s(): unable to attach Ter tuner frontend\n",
483 __func__);
484 goto frontend_detach;
485 }
486 } else {
487 helene_conf.set_tuner_priv = &ndev->dma[num];
488 if (!dvb_attach(helene_attach, fes[1]->dvb.frontend,
489 &helene_conf, &ndev->i2c[num].adap)) {
490 dev_err(&ndev->pci_dev->dev,
491 "%s(): unable to attach HELENE Ter tuner frontend\n",
492 __func__);
493 goto frontend_detach;
494 }
462 } 495 }
463 496
464 if (vb2_dvb_register_bus(&ndev->frontends[num], 497 if (vb2_dvb_register_bus(&ndev->frontends[num],
@@ -730,7 +763,7 @@ static int netup_unidvb_request_mmio(struct pci_dev *pci_dev)
730static int netup_unidvb_request_modules(struct device *dev) 763static int netup_unidvb_request_modules(struct device *dev)
731{ 764{
732 static const char * const modules[] = { 765 static const char * const modules[] = {
733 "lnbh25", "ascot2e", "horus3a", "cxd2841er", NULL 766 "lnbh25", "ascot2e", "horus3a", "cxd2841er", "helene", NULL
734 }; 767 };
735 const char * const *curr_mod = modules; 768 const char * const *curr_mod = modules;
736 int err; 769 int err;
@@ -774,6 +807,16 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
774 if (!ndev) 807 if (!ndev)
775 goto dev_alloc_err; 808 goto dev_alloc_err;
776 809
810 /* detect hardware revision */
811 if (pci_dev->device == NETUP_HW_REV_1_3)
812 ndev->rev = NETUP_HW_REV_1_3;
813 else
814 ndev->rev = NETUP_HW_REV_1_4;
815
816 dev_info(&pci_dev->dev,
817 "%s(): board (0x%x) hardware revision 0x%x\n",
818 __func__, pci_dev->device, ndev->rev);
819
777 ndev->old_fw = old_firmware; 820 ndev->old_fw = old_firmware;
778 ndev->wq = create_singlethread_workqueue(NETUP_UNIDVB_NAME); 821 ndev->wq = create_singlethread_workqueue(NETUP_UNIDVB_NAME);
779 if (!ndev->wq) { 822 if (!ndev->wq) {
@@ -972,7 +1015,8 @@ static void netup_unidvb_finidev(struct pci_dev *pci_dev)
972 1015
973 1016
974static struct pci_device_id netup_unidvb_pci_tbl[] = { 1017static struct pci_device_id netup_unidvb_pci_tbl[] = {
975 { PCI_DEVICE(0x1b55, 0x18f6) }, 1018 { PCI_DEVICE(0x1b55, 0x18f6) }, /* hw rev. 1.3 */
1019 { PCI_DEVICE(0x1b55, 0x18f7) }, /* hw rev. 1.4 */
976 { 0, } 1020 { 0, }
977}; 1021};
978MODULE_DEVICE_TABLE(pci, netup_unidvb_pci_tbl); 1022MODULE_DEVICE_TABLE(pci, netup_unidvb_pci_tbl);
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 84e041c0a70e..9d0a3ffe36d2 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -110,6 +110,7 @@ source "drivers/media/platform/exynos4-is/Kconfig"
110source "drivers/media/platform/s5p-tv/Kconfig" 110source "drivers/media/platform/s5p-tv/Kconfig"
111source "drivers/media/platform/am437x/Kconfig" 111source "drivers/media/platform/am437x/Kconfig"
112source "drivers/media/platform/xilinx/Kconfig" 112source "drivers/media/platform/xilinx/Kconfig"
113source "drivers/media/platform/rcar-vin/Kconfig"
113 114
114config VIDEO_TI_CAL 115config VIDEO_TI_CAL
115 tristate "TI CAL (Camera Adaptation Layer) driver" 116 tristate "TI CAL (Camera Adaptation Layer) driver"
@@ -247,10 +248,24 @@ config VIDEO_RENESAS_JPU
247 To compile this driver as a module, choose M here: the module 248 To compile this driver as a module, choose M here: the module
248 will be called rcar_jpu. 249 will be called rcar_jpu.
249 250
251config VIDEO_RENESAS_FCP
252 tristate "Renesas Frame Compression Processor"
253 depends on ARCH_RENESAS || COMPILE_TEST
254 depends on OF
255 ---help---
256 This is a driver for the Renesas Frame Compression Processor (FCP).
257 The FCP is a companion module of video processing modules in the
258 Renesas R-Car Gen3 SoCs. It handles memory access for the codec,
259 VSP and FDP modules.
260
261 To compile this driver as a module, choose M here: the module
262 will be called rcar-fcp.
263
250config VIDEO_RENESAS_VSP1 264config VIDEO_RENESAS_VSP1
251 tristate "Renesas VSP1 Video Processing Engine" 265 tristate "Renesas VSP1 Video Processing Engine"
252 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA 266 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
253 depends on (ARCH_RENESAS && OF) || COMPILE_TEST 267 depends on (ARCH_RENESAS && OF) || COMPILE_TEST
268 depends on !ARM64 || VIDEO_RENESAS_FCP
254 select VIDEOBUF2_DMA_CONTIG 269 select VIDEOBUF2_DMA_CONTIG
255 ---help--- 270 ---help---
256 This is a V4L2 driver for the Renesas VSP1 video processing engine. 271 This is a V4L2 driver for the Renesas VSP1 video processing engine.
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index bbb7bd1eb268..c83800a74a2d 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
46 46
47obj-$(CONFIG_SOC_CAMERA) += soc_camera/ 47obj-$(CONFIG_SOC_CAMERA) += soc_camera/
48 48
49obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o
49obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o 50obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
50obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ 51obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
51 52
@@ -55,4 +56,6 @@ obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/
55 56
56obj-$(CONFIG_VIDEO_XILINX) += xilinx/ 57obj-$(CONFIG_VIDEO_XILINX) += xilinx/
57 58
59obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/
60
58ccflags-y += -I$(srctree)/drivers/media/i2c 61ccflags-y += -I$(srctree)/drivers/media/i2c
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index c04973669a47..c9d2009c2476 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1124,6 +1124,7 @@ static int gsc_probe(struct platform_device *pdev)
1124 goto err_m2m; 1124 goto err_m2m;
1125 1125
1126 /* Initialize continious memory allocator */ 1126 /* Initialize continious memory allocator */
1127 vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
1127 gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev); 1128 gsc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
1128 if (IS_ERR(gsc->alloc_ctx)) { 1129 if (IS_ERR(gsc->alloc_ctx)) {
1129 ret = PTR_ERR(gsc->alloc_ctx); 1130 ret = PTR_ERR(gsc->alloc_ctx);
@@ -1153,6 +1154,7 @@ static int gsc_remove(struct platform_device *pdev)
1153 v4l2_device_unregister(&gsc->v4l2_dev); 1154 v4l2_device_unregister(&gsc->v4l2_dev);
1154 1155
1155 vb2_dma_contig_cleanup_ctx(gsc->alloc_ctx); 1156 vb2_dma_contig_cleanup_ctx(gsc->alloc_ctx);
1157 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
1156 pm_runtime_disable(&pdev->dev); 1158 pm_runtime_disable(&pdev->dev);
1157 gsc_clk_put(gsc); 1159 gsc_clk_put(gsc);
1158 1160
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index b1c1cea82a27..368f44f24d4c 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1019,6 +1019,7 @@ static int fimc_probe(struct platform_device *pdev)
1019 } 1019 }
1020 1020
1021 /* Initialize contiguous memory allocator */ 1021 /* Initialize contiguous memory allocator */
1022 vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
1022 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); 1023 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
1023 if (IS_ERR(fimc->alloc_ctx)) { 1024 if (IS_ERR(fimc->alloc_ctx)) {
1024 ret = PTR_ERR(fimc->alloc_ctx); 1025 ret = PTR_ERR(fimc->alloc_ctx);
@@ -1124,6 +1125,7 @@ static int fimc_remove(struct platform_device *pdev)
1124 1125
1125 fimc_unregister_capture_subdev(fimc); 1126 fimc_unregister_capture_subdev(fimc);
1126 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); 1127 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1128 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
1127 1129
1128 clk_disable(fimc->clock[CLK_BUS]); 1130 clk_disable(fimc->clock[CLK_BUS]);
1129 fimc_clk_put(fimc); 1131 fimc_clk_put(fimc);
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 979c388ebf60..bd98b56318b7 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -847,6 +847,7 @@ static int fimc_is_probe(struct platform_device *pdev)
847 if (ret < 0) 847 if (ret < 0)
848 goto err_pm; 848 goto err_pm;
849 849
850 vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
850 is->alloc_ctx = vb2_dma_contig_init_ctx(dev); 851 is->alloc_ctx = vb2_dma_contig_init_ctx(dev);
851 if (IS_ERR(is->alloc_ctx)) { 852 if (IS_ERR(is->alloc_ctx)) {
852 ret = PTR_ERR(is->alloc_ctx); 853 ret = PTR_ERR(is->alloc_ctx);
@@ -940,6 +941,7 @@ static int fimc_is_remove(struct platform_device *pdev)
940 free_irq(is->irq, is); 941 free_irq(is->irq, is);
941 fimc_is_unregister_subdevs(is); 942 fimc_is_unregister_subdevs(is);
942 vb2_dma_contig_cleanup_ctx(is->alloc_ctx); 943 vb2_dma_contig_cleanup_ctx(is->alloc_ctx);
944 vb2_dma_contig_clear_max_seg_size(dev);
943 fimc_is_put_clocks(is); 945 fimc_is_put_clocks(is);
944 fimc_is_debugfs_remove(is); 946 fimc_is_debugfs_remove(is);
945 release_firmware(is->fw.f_w); 947 release_firmware(is->fw.f_w);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index dc1b929f7a33..27cb620cb714 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1551,6 +1551,7 @@ static int fimc_lite_probe(struct platform_device *pdev)
1551 goto err_sd; 1551 goto err_sd;
1552 } 1552 }
1553 1553
1554 vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
1554 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); 1555 fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev);
1555 if (IS_ERR(fimc->alloc_ctx)) { 1556 if (IS_ERR(fimc->alloc_ctx)) {
1556 ret = PTR_ERR(fimc->alloc_ctx); 1557 ret = PTR_ERR(fimc->alloc_ctx);
@@ -1652,6 +1653,7 @@ static int fimc_lite_remove(struct platform_device *pdev)
1652 pm_runtime_set_suspended(dev); 1653 pm_runtime_set_suspended(dev);
1653 fimc_lite_unregister_capture_subdev(fimc); 1654 fimc_lite_unregister_capture_subdev(fimc);
1654 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); 1655 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1656 vb2_dma_contig_clear_max_seg_size(dev);
1655 fimc_lite_clk_put(fimc); 1657 fimc_lite_clk_put(fimc);
1656 1658
1657 dev_info(dev, "Driver unloaded\n"); 1659 dev_info(dev, "Driver unloaded\n");
diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
new file mode 100644
index 000000000000..6a7bcc3028b1
--- /dev/null
+++ b/drivers/media/platform/rcar-fcp.c
@@ -0,0 +1,181 @@
1/*
2 * rcar-fcp.c -- R-Car Frame Compression Processor Driver
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include <linux/mutex.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/slab.h>
21
22#include <media/rcar-fcp.h>
23
24struct rcar_fcp_device {
25 struct list_head list;
26 struct device *dev;
27};
28
29static LIST_HEAD(fcp_devices);
30static DEFINE_MUTEX(fcp_lock);
31
32/* -----------------------------------------------------------------------------
33 * Public API
34 */
35
36/**
37 * rcar_fcp_get - Find and acquire a reference to an FCP instance
38 * @np: Device node of the FCP instance
39 *
40 * Search the list of registered FCP instances for the instance corresponding to
41 * the given device node.
42 *
43 * Return a pointer to the FCP instance, or an ERR_PTR if the instance can't be
44 * found.
45 */
46struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
47{
48 struct rcar_fcp_device *fcp;
49
50 mutex_lock(&fcp_lock);
51
52 list_for_each_entry(fcp, &fcp_devices, list) {
53 if (fcp->dev->of_node != np)
54 continue;
55
56 /*
57 * Make sure the module won't be unloaded behind our back. This
58 * is a poor man's safety net, the module should really not be
59 * unloaded while FCP users can be active.
60 */
61 if (!try_module_get(fcp->dev->driver->owner))
62 fcp = NULL;
63
64 goto done;
65 }
66
67 fcp = ERR_PTR(-EPROBE_DEFER);
68
69done:
70 mutex_unlock(&fcp_lock);
71 return fcp;
72}
73EXPORT_SYMBOL_GPL(rcar_fcp_get);
74
75/**
76 * rcar_fcp_put - Release a reference to an FCP instance
77 * @fcp: The FCP instance
78 *
79 * Release the FCP instance acquired by a call to rcar_fcp_get().
80 */
81void rcar_fcp_put(struct rcar_fcp_device *fcp)
82{
83 if (fcp)
84 module_put(fcp->dev->driver->owner);
85}
86EXPORT_SYMBOL_GPL(rcar_fcp_put);
87
88/**
89 * rcar_fcp_enable - Enable an FCP
90 * @fcp: The FCP instance
91 *
92 * Before any memory access through an FCP is performed by a module, the FCP
93 * must be enabled by a call to this function. The enable calls are reference
94 * counted, each successful call must be followed by one rcar_fcp_disable()
95 * call when no more memory transfer can occur through the FCP.
96 *
97 * Return 0 on success or a negative error code if an error occurs. The enable
98 * reference count isn't increased when this function returns an error.
99 */
100int rcar_fcp_enable(struct rcar_fcp_device *fcp)
101{
102 if (!fcp)
103 return 0;
104
105 return pm_runtime_get_sync(fcp->dev);
106}
107EXPORT_SYMBOL_GPL(rcar_fcp_enable);
108
109/**
110 * rcar_fcp_disable - Disable an FCP
111 * @fcp: The FCP instance
112 *
113 * This function is the counterpart of rcar_fcp_enable(). As enable calls are
114 * reference counted a disable call may not disable the FCP synchronously.
115 */
116void rcar_fcp_disable(struct rcar_fcp_device *fcp)
117{
118 if (fcp)
119 pm_runtime_put(fcp->dev);
120}
121EXPORT_SYMBOL_GPL(rcar_fcp_disable);
122
123/* -----------------------------------------------------------------------------
124 * Platform Driver
125 */
126
127static int rcar_fcp_probe(struct platform_device *pdev)
128{
129 struct rcar_fcp_device *fcp;
130
131 fcp = devm_kzalloc(&pdev->dev, sizeof(*fcp), GFP_KERNEL);
132 if (fcp == NULL)
133 return -ENOMEM;
134
135 fcp->dev = &pdev->dev;
136
137 pm_runtime_enable(&pdev->dev);
138
139 mutex_lock(&fcp_lock);
140 list_add_tail(&fcp->list, &fcp_devices);
141 mutex_unlock(&fcp_lock);
142
143 platform_set_drvdata(pdev, fcp);
144
145 return 0;
146}
147
148static int rcar_fcp_remove(struct platform_device *pdev)
149{
150 struct rcar_fcp_device *fcp = platform_get_drvdata(pdev);
151
152 mutex_lock(&fcp_lock);
153 list_del(&fcp->list);
154 mutex_unlock(&fcp_lock);
155
156 pm_runtime_disable(&pdev->dev);
157
158 return 0;
159}
160
161static const struct of_device_id rcar_fcp_of_match[] = {
162 { .compatible = "renesas,fcpv" },
163 { },
164};
165
166static struct platform_driver rcar_fcp_platform_driver = {
167 .probe = rcar_fcp_probe,
168 .remove = rcar_fcp_remove,
169 .driver = {
170 .name = "rcar-fcp",
171 .of_match_table = rcar_fcp_of_match,
172 .suppress_bind_attrs = true,
173 },
174};
175
176module_platform_driver(rcar_fcp_platform_driver);
177
178MODULE_ALIAS("rcar-fcp");
179MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
180MODULE_DESCRIPTION("Renesas FCP Driver");
181MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig
new file mode 100644
index 000000000000..b2ff2d4e8bb1
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/Kconfig
@@ -0,0 +1,11 @@
1config VIDEO_RCAR_VIN
2 tristate "R-Car Video Input (VIN) Driver"
3 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA
4 depends on ARCH_RENESAS || COMPILE_TEST
5 select VIDEOBUF2_DMA_CONTIG
6 ---help---
7 Support for Renesas R-Car Video Input (VIN) driver.
8 Supports R-Car Gen2 SoCs.
9
10 To compile this driver as a module, choose M here: the
11 module will be called rcar-vin.
diff --git a/drivers/media/platform/rcar-vin/Makefile b/drivers/media/platform/rcar-vin/Makefile
new file mode 100644
index 000000000000..48c5632c21dc
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/Makefile
@@ -0,0 +1,3 @@
1rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o
2
3obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
new file mode 100644
index 000000000000..4b2007b73463
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -0,0 +1,334 @@
1/*
2 * Driver for Renesas R-Car VIN
3 *
4 * Copyright (C) 2016 Renesas Electronics Corp.
5 * Copyright (C) 2011-2013 Renesas Solutions Corp.
6 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7 * Copyright (C) 2008 Magnus Damm
8 *
9 * Based on the soc-camera rcar_vin driver
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_device.h>
20#include <linux/of_graph.h>
21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
23
24#include <media/v4l2-of.h>
25
26#include "rcar-vin.h"
27
28/* -----------------------------------------------------------------------------
29 * Async notifier
30 */
31
32#define notifier_to_vin(n) container_of(n, struct rvin_dev, notifier)
33
34static int rvin_mbus_supported(struct rvin_dev *vin)
35{
36 struct v4l2_subdev *sd;
37 struct v4l2_subdev_mbus_code_enum code = {
38 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
39 };
40
41 sd = vin_to_source(vin);
42
43 code.index = 0;
44 while (!v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code)) {
45 code.index++;
46 switch (code.code) {
47 case MEDIA_BUS_FMT_YUYV8_1X16:
48 case MEDIA_BUS_FMT_YUYV8_2X8:
49 case MEDIA_BUS_FMT_YUYV10_2X10:
50 case MEDIA_BUS_FMT_RGB888_1X24:
51 vin->source.code = code.code;
52 vin_dbg(vin, "Found supported media bus format: %d\n",
53 vin->source.code);
54 return true;
55 default:
56 break;
57 }
58 }
59
60 return false;
61}
62
63static int rvin_graph_notify_complete(struct v4l2_async_notifier *notifier)
64{
65 struct rvin_dev *vin = notifier_to_vin(notifier);
66 int ret;
67
68 ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
69 if (ret < 0) {
70 vin_err(vin, "Failed to register subdev nodes\n");
71 return ret;
72 }
73
74 if (!rvin_mbus_supported(vin)) {
75 vin_err(vin, "No supported mediabus format found\n");
76 return -EINVAL;
77 }
78
79 return rvin_v4l2_probe(vin);
80}
81
82static void rvin_graph_notify_unbind(struct v4l2_async_notifier *notifier,
83 struct v4l2_subdev *sd,
84 struct v4l2_async_subdev *asd)
85{
86 struct rvin_dev *vin = notifier_to_vin(notifier);
87
88 rvin_v4l2_remove(vin);
89}
90
91static int rvin_graph_notify_bound(struct v4l2_async_notifier *notifier,
92 struct v4l2_subdev *subdev,
93 struct v4l2_async_subdev *asd)
94{
95 struct rvin_dev *vin = notifier_to_vin(notifier);
96
97 vin_dbg(vin, "subdev %s bound\n", subdev->name);
98
99 vin->entity.entity = &subdev->entity;
100 vin->entity.subdev = subdev;
101
102 return 0;
103}
104
105static int rvin_graph_parse(struct rvin_dev *vin,
106 struct device_node *node)
107{
108 struct device_node *remote;
109 struct device_node *ep = NULL;
110 struct device_node *next;
111 int ret = 0;
112
113 while (1) {
114 next = of_graph_get_next_endpoint(node, ep);
115 if (!next)
116 break;
117
118 of_node_put(ep);
119 ep = next;
120
121 remote = of_graph_get_remote_port_parent(ep);
122 if (!remote) {
123 ret = -EINVAL;
124 break;
125 }
126
127 /* Skip entities that we have already processed. */
128 if (remote == vin->dev->of_node) {
129 of_node_put(remote);
130 continue;
131 }
132
133 /* Remote node to connect */
134 if (!vin->entity.node) {
135 vin->entity.node = remote;
136 vin->entity.asd.match_type = V4L2_ASYNC_MATCH_OF;
137 vin->entity.asd.match.of.node = remote;
138 ret++;
139 }
140 }
141
142 of_node_put(ep);
143
144 return ret;
145}
146
147static int rvin_graph_init(struct rvin_dev *vin)
148{
149 struct v4l2_async_subdev **subdevs = NULL;
150 int ret;
151
152 /* Parse the graph to extract a list of subdevice DT nodes. */
153 ret = rvin_graph_parse(vin, vin->dev->of_node);
154 if (ret < 0) {
155 vin_err(vin, "Graph parsing failed\n");
156 goto done;
157 }
158
159 if (!ret) {
160 vin_err(vin, "No subdev found in graph\n");
161 goto done;
162 }
163
164 if (ret != 1) {
165 vin_err(vin, "More then one subdev found in graph\n");
166 goto done;
167 }
168
169 /* Register the subdevices notifier. */
170 subdevs = devm_kzalloc(vin->dev, sizeof(*subdevs), GFP_KERNEL);
171 if (subdevs == NULL) {
172 ret = -ENOMEM;
173 goto done;
174 }
175
176 subdevs[0] = &vin->entity.asd;
177
178 vin->notifier.subdevs = subdevs;
179 vin->notifier.num_subdevs = 1;
180 vin->notifier.bound = rvin_graph_notify_bound;
181 vin->notifier.unbind = rvin_graph_notify_unbind;
182 vin->notifier.complete = rvin_graph_notify_complete;
183
184 ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
185 if (ret < 0) {
186 vin_err(vin, "Notifier registration failed\n");
187 goto done;
188 }
189
190 ret = 0;
191
192done:
193 if (ret < 0) {
194 v4l2_async_notifier_unregister(&vin->notifier);
195 of_node_put(vin->entity.node);
196 }
197
198 return ret;
199}
200
201/* -----------------------------------------------------------------------------
202 * Platform Device Driver
203 */
204
205static const struct of_device_id rvin_of_id_table[] = {
206 { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
207 { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
208 { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
209 { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
210 { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
211 { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
212 { },
213};
214MODULE_DEVICE_TABLE(of, rvin_of_id_table);
215
216static int rvin_parse_dt(struct rvin_dev *vin)
217{
218 const struct of_device_id *match;
219 struct v4l2_of_endpoint ep;
220 struct device_node *np;
221 int ret;
222
223 match = of_match_device(of_match_ptr(rvin_of_id_table), vin->dev);
224 if (!match)
225 return -ENODEV;
226
227 vin->chip = (enum chip_id)match->data;
228
229 np = of_graph_get_next_endpoint(vin->dev->of_node, NULL);
230 if (!np) {
231 vin_err(vin, "Could not find endpoint\n");
232 return -EINVAL;
233 }
234
235 ret = v4l2_of_parse_endpoint(np, &ep);
236 if (ret) {
237 vin_err(vin, "Could not parse endpoint\n");
238 return ret;
239 }
240
241 of_node_put(np);
242
243 vin->mbus_cfg.type = ep.bus_type;
244
245 switch (vin->mbus_cfg.type) {
246 case V4L2_MBUS_PARALLEL:
247 vin->mbus_cfg.flags = ep.bus.parallel.flags;
248 break;
249 case V4L2_MBUS_BT656:
250 vin->mbus_cfg.flags = 0;
251 break;
252 default:
253 vin_err(vin, "Unknown media bus type\n");
254 return -EINVAL;
255 }
256
257 return 0;
258}
259
260static int rcar_vin_probe(struct platform_device *pdev)
261{
262 struct rvin_dev *vin;
263 struct resource *mem;
264 int irq, ret;
265
266 vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
267 if (!vin)
268 return -ENOMEM;
269
270 vin->dev = &pdev->dev;
271
272 ret = rvin_parse_dt(vin);
273 if (ret)
274 return ret;
275
276 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
277 if (mem == NULL)
278 return -EINVAL;
279
280 vin->base = devm_ioremap_resource(vin->dev, mem);
281 if (IS_ERR(vin->base))
282 return PTR_ERR(vin->base);
283
284 irq = platform_get_irq(pdev, 0);
285 if (irq <= 0)
286 return ret;
287
288 ret = rvin_dma_probe(vin, irq);
289 if (ret)
290 return ret;
291
292 ret = rvin_graph_init(vin);
293 if (ret < 0)
294 goto error;
295
296 pm_suspend_ignore_children(&pdev->dev, true);
297 pm_runtime_enable(&pdev->dev);
298
299 platform_set_drvdata(pdev, vin);
300
301 return 0;
302error:
303 rvin_dma_remove(vin);
304
305 return ret;
306}
307
308static int rcar_vin_remove(struct platform_device *pdev)
309{
310 struct rvin_dev *vin = platform_get_drvdata(pdev);
311
312 pm_runtime_disable(&pdev->dev);
313
314 v4l2_async_notifier_unregister(&vin->notifier);
315
316 rvin_dma_remove(vin);
317
318 return 0;
319}
320
321static struct platform_driver rcar_vin_driver = {
322 .driver = {
323 .name = "rcar-vin",
324 .of_match_table = rvin_of_id_table,
325 },
326 .probe = rcar_vin_probe,
327 .remove = rcar_vin_remove,
328};
329
330module_platform_driver(rcar_vin_driver);
331
332MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
333MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
334MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
new file mode 100644
index 000000000000..dad3b031f778
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -0,0 +1,1196 @@
1/*
2 * Driver for Renesas R-Car VIN
3 *
4 * Copyright (C) 2016 Renesas Electronics Corp.
5 * Copyright (C) 2011-2013 Renesas Solutions Corp.
6 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7 * Copyright (C) 2008 Magnus Damm
8 *
9 * Based on the soc-camera rcar_vin driver
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19
20#include <media/videobuf2-dma-contig.h>
21
22#include "rcar-vin.h"
23
24/* -----------------------------------------------------------------------------
25 * HW Functions
26 */
27
28/* Register offsets for R-Car VIN */
29#define VNMC_REG 0x00 /* Video n Main Control Register */
30#define VNMS_REG 0x04 /* Video n Module Status Register */
31#define VNFC_REG 0x08 /* Video n Frame Capture Register */
32#define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */
33#define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */
34#define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */
35#define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */
36#define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */
37#define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */
38#define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */
39#define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */
40#define VNIS_REG 0x2C /* Video n Image Stride Register */
41#define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
42#define VNIE_REG 0x40 /* Video n Interrupt Enable Register */
43#define VNINTS_REG 0x44 /* Video n Interrupt Status Register */
44#define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */
45#define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */
46#define VNYS_REG 0x50 /* Video n Y Scale Register */
47#define VNXS_REG 0x54 /* Video n X Scale Register */
48#define VNDMR_REG 0x58 /* Video n Data Mode Register */
49#define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */
50#define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */
51#define VNC1A_REG 0x80 /* Video n Coefficient Set C1A Register */
52#define VNC1B_REG 0x84 /* Video n Coefficient Set C1B Register */
53#define VNC1C_REG 0x88 /* Video n Coefficient Set C1C Register */
54#define VNC2A_REG 0x90 /* Video n Coefficient Set C2A Register */
55#define VNC2B_REG 0x94 /* Video n Coefficient Set C2B Register */
56#define VNC2C_REG 0x98 /* Video n Coefficient Set C2C Register */
57#define VNC3A_REG 0xA0 /* Video n Coefficient Set C3A Register */
58#define VNC3B_REG 0xA4 /* Video n Coefficient Set C3B Register */
59#define VNC3C_REG 0xA8 /* Video n Coefficient Set C3C Register */
60#define VNC4A_REG 0xB0 /* Video n Coefficient Set C4A Register */
61#define VNC4B_REG 0xB4 /* Video n Coefficient Set C4B Register */
62#define VNC4C_REG 0xB8 /* Video n Coefficient Set C4C Register */
63#define VNC5A_REG 0xC0 /* Video n Coefficient Set C5A Register */
64#define VNC5B_REG 0xC4 /* Video n Coefficient Set C5B Register */
65#define VNC5C_REG 0xC8 /* Video n Coefficient Set C5C Register */
66#define VNC6A_REG 0xD0 /* Video n Coefficient Set C6A Register */
67#define VNC6B_REG 0xD4 /* Video n Coefficient Set C6B Register */
68#define VNC6C_REG 0xD8 /* Video n Coefficient Set C6C Register */
69#define VNC7A_REG 0xE0 /* Video n Coefficient Set C7A Register */
70#define VNC7B_REG 0xE4 /* Video n Coefficient Set C7B Register */
71#define VNC7C_REG 0xE8 /* Video n Coefficient Set C7C Register */
72#define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */
73#define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */
74#define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */
75
76
77/* Register bit fields for R-Car VIN */
78/* Video n Main Control Register bits */
79#define VNMC_FOC (1 << 21)
80#define VNMC_YCAL (1 << 19)
81#define VNMC_INF_YUV8_BT656 (0 << 16)
82#define VNMC_INF_YUV8_BT601 (1 << 16)
83#define VNMC_INF_YUV10_BT656 (2 << 16)
84#define VNMC_INF_YUV10_BT601 (3 << 16)
85#define VNMC_INF_YUV16 (5 << 16)
86#define VNMC_INF_RGB888 (6 << 16)
87#define VNMC_VUP (1 << 10)
88#define VNMC_IM_ODD (0 << 3)
89#define VNMC_IM_ODD_EVEN (1 << 3)
90#define VNMC_IM_EVEN (2 << 3)
91#define VNMC_IM_FULL (3 << 3)
92#define VNMC_BPS (1 << 1)
93#define VNMC_ME (1 << 0)
94
95/* Video n Module Status Register bits */
96#define VNMS_FBS_MASK (3 << 3)
97#define VNMS_FBS_SHIFT 3
98#define VNMS_AV (1 << 1)
99#define VNMS_CA (1 << 0)
100
101/* Video n Frame Capture Register bits */
102#define VNFC_C_FRAME (1 << 1)
103#define VNFC_S_FRAME (1 << 0)
104
105/* Video n Interrupt Enable Register bits */
106#define VNIE_FIE (1 << 4)
107#define VNIE_EFE (1 << 1)
108
109/* Video n Data Mode Register bits */
110#define VNDMR_EXRGB (1 << 8)
111#define VNDMR_BPSM (1 << 4)
112#define VNDMR_DTMD_YCSEP (1 << 1)
113#define VNDMR_DTMD_ARGB1555 (1 << 0)
114
115/* Video n Data Mode Register 2 bits */
116#define VNDMR2_VPS (1 << 30)
117#define VNDMR2_HPS (1 << 29)
118#define VNDMR2_FTEV (1 << 17)
119#define VNDMR2_VLV(n) ((n & 0xf) << 12)
120
121static void rvin_write(struct rvin_dev *vin, u32 value, u32 offset)
122{
123 iowrite32(value, vin->base + offset);
124}
125
126static u32 rvin_read(struct rvin_dev *vin, u32 offset)
127{
128 return ioread32(vin->base + offset);
129}
130
131static int rvin_setup(struct rvin_dev *vin)
132{
133 u32 vnmc, dmr, dmr2, interrupts;
134 bool progressive = false, output_is_yuv = false, input_is_yuv = false;
135
136 switch (vin->format.field) {
137 case V4L2_FIELD_TOP:
138 vnmc = VNMC_IM_ODD;
139 break;
140 case V4L2_FIELD_BOTTOM:
141 vnmc = VNMC_IM_EVEN;
142 break;
143 case V4L2_FIELD_INTERLACED:
144 case V4L2_FIELD_INTERLACED_TB:
145 vnmc = VNMC_IM_FULL;
146 break;
147 case V4L2_FIELD_INTERLACED_BT:
148 vnmc = VNMC_IM_FULL | VNMC_FOC;
149 break;
150 case V4L2_FIELD_NONE:
151 if (vin->continuous) {
152 vnmc = VNMC_IM_ODD_EVEN;
153 progressive = true;
154 } else {
155 vnmc = VNMC_IM_ODD;
156 }
157 break;
158 default:
159 vnmc = VNMC_IM_ODD;
160 break;
161 }
162
163 /*
164 * Input interface
165 */
166 switch (vin->source.code) {
167 case MEDIA_BUS_FMT_YUYV8_1X16:
168 /* BT.601/BT.1358 16bit YCbCr422 */
169 vnmc |= VNMC_INF_YUV16;
170 input_is_yuv = true;
171 break;
172 case MEDIA_BUS_FMT_YUYV8_2X8:
173 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
174 vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ?
175 VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
176 input_is_yuv = true;
177 break;
178 case MEDIA_BUS_FMT_RGB888_1X24:
179 vnmc |= VNMC_INF_RGB888;
180 break;
181 case MEDIA_BUS_FMT_YUYV10_2X10:
182 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
183 vnmc |= vin->mbus_cfg.type == V4L2_MBUS_BT656 ?
184 VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
185 input_is_yuv = true;
186 break;
187 default:
188 break;
189 }
190
191 /* Enable VSYNC Field Toogle mode after one VSYNC input */
192 dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1);
193
194 /* Hsync Signal Polarity Select */
195 if (!(vin->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
196 dmr2 |= VNDMR2_HPS;
197
198 /* Vsync Signal Polarity Select */
199 if (!(vin->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
200 dmr2 |= VNDMR2_VPS;
201
202 /*
203 * Output format
204 */
205 switch (vin->format.pixelformat) {
206 case V4L2_PIX_FMT_NV16:
207 rvin_write(vin,
208 ALIGN(vin->format.width * vin->format.height, 0x80),
209 VNUVAOF_REG);
210 dmr = VNDMR_DTMD_YCSEP;
211 output_is_yuv = true;
212 break;
213 case V4L2_PIX_FMT_YUYV:
214 dmr = VNDMR_BPSM;
215 output_is_yuv = true;
216 break;
217 case V4L2_PIX_FMT_UYVY:
218 dmr = 0;
219 output_is_yuv = true;
220 break;
221 case V4L2_PIX_FMT_XRGB555:
222 dmr = VNDMR_DTMD_ARGB1555;
223 break;
224 case V4L2_PIX_FMT_RGB565:
225 dmr = 0;
226 break;
227 case V4L2_PIX_FMT_XBGR32:
228 if (vin->chip == RCAR_GEN2 || vin->chip == RCAR_H1) {
229 dmr = VNDMR_EXRGB;
230 break;
231 }
232 /* fall through */
233 default:
234 vin_err(vin, "Invalid pixelformat (0x%x)\n",
235 vin->format.pixelformat);
236 return -EINVAL;
237 }
238
239 /* Always update on field change */
240 vnmc |= VNMC_VUP;
241
242 /* If input and output use the same colorspace, use bypass mode */
243 if (input_is_yuv == output_is_yuv)
244 vnmc |= VNMC_BPS;
245
246 /* Progressive or interlaced mode */
247 interrupts = progressive ? VNIE_FIE : VNIE_EFE;
248
249 /* Ack interrupts */
250 rvin_write(vin, interrupts, VNINTS_REG);
251 /* Enable interrupts */
252 rvin_write(vin, interrupts, VNIE_REG);
253 /* Start capturing */
254 rvin_write(vin, dmr, VNDMR_REG);
255 rvin_write(vin, dmr2, VNDMR2_REG);
256
257 /* Enable module */
258 rvin_write(vin, vnmc | VNMC_ME, VNMC_REG);
259
260 return 0;
261}
262
263static void rvin_capture_on(struct rvin_dev *vin)
264{
265 vin_dbg(vin, "Capture on in %s mode\n",
266 vin->continuous ? "continuous" : "single");
267
268 if (vin->continuous)
269 /* Continuous Frame Capture Mode */
270 rvin_write(vin, VNFC_C_FRAME, VNFC_REG);
271 else
272 /* Single Frame Capture Mode */
273 rvin_write(vin, VNFC_S_FRAME, VNFC_REG);
274}
275
276static void rvin_capture_off(struct rvin_dev *vin)
277{
278 /* Set continuous & single transfer off */
279 rvin_write(vin, 0, VNFC_REG);
280}
281
282static int rvin_capture_start(struct rvin_dev *vin)
283{
284 int ret;
285
286 rvin_crop_scale_comp(vin);
287
288 ret = rvin_setup(vin);
289 if (ret)
290 return ret;
291
292 rvin_capture_on(vin);
293
294 return 0;
295}
296
297static void rvin_capture_stop(struct rvin_dev *vin)
298{
299 rvin_capture_off(vin);
300
301 /* Disable module */
302 rvin_write(vin, rvin_read(vin, VNMC_REG) & ~VNMC_ME, VNMC_REG);
303}
304
305static void rvin_disable_interrupts(struct rvin_dev *vin)
306{
307 rvin_write(vin, 0, VNIE_REG);
308}
309
310static u32 rvin_get_interrupt_status(struct rvin_dev *vin)
311{
312 return rvin_read(vin, VNINTS_REG);
313}
314
315static void rvin_ack_interrupt(struct rvin_dev *vin)
316{
317 rvin_write(vin, rvin_read(vin, VNINTS_REG), VNINTS_REG);
318}
319
320static bool rvin_capture_active(struct rvin_dev *vin)
321{
322 return rvin_read(vin, VNMS_REG) & VNMS_CA;
323}
324
325static int rvin_get_active_slot(struct rvin_dev *vin)
326{
327 if (vin->continuous)
328 return (rvin_read(vin, VNMS_REG) & VNMS_FBS_MASK)
329 >> VNMS_FBS_SHIFT;
330
331 return 0;
332}
333
334static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
335{
336 const struct rvin_video_format *fmt;
337 int offsetx, offsety;
338 dma_addr_t offset;
339
340 fmt = rvin_format_from_pixel(vin->format.pixelformat);
341
342 /*
343 * There is no HW support for composition do the beast we can
344 * by modifying the buffer offset
345 */
346 offsetx = vin->compose.left * fmt->bpp;
347 offsety = vin->compose.top * vin->format.bytesperline;
348 offset = addr + offsetx + offsety;
349
350 /*
351 * The address needs to be 128 bytes aligned. Driver should never accept
352 * settings that do not satisfy this in the first place...
353 */
354 if (WARN_ON((offsetx | offsety | offset) & HW_BUFFER_MASK))
355 return;
356
357 rvin_write(vin, offset, VNMB_REG(slot));
358}
359
360/* -----------------------------------------------------------------------------
361 * Crop and Scaling Gen2
362 */
363
364struct vin_coeff {
365 unsigned short xs_value;
366 u32 coeff_set[24];
367};
368
369static const struct vin_coeff vin_coeff_set[] = {
370 { 0x0000, {
371 0x00000000, 0x00000000, 0x00000000,
372 0x00000000, 0x00000000, 0x00000000,
373 0x00000000, 0x00000000, 0x00000000,
374 0x00000000, 0x00000000, 0x00000000,
375 0x00000000, 0x00000000, 0x00000000,
376 0x00000000, 0x00000000, 0x00000000,
377 0x00000000, 0x00000000, 0x00000000,
378 0x00000000, 0x00000000, 0x00000000 },
379 },
380 { 0x1000, {
381 0x000fa400, 0x000fa400, 0x09625902,
382 0x000003f8, 0x00000403, 0x3de0d9f0,
383 0x001fffed, 0x00000804, 0x3cc1f9c3,
384 0x001003de, 0x00000c01, 0x3cb34d7f,
385 0x002003d2, 0x00000c00, 0x3d24a92d,
386 0x00200bca, 0x00000bff, 0x3df600d2,
387 0x002013cc, 0x000007ff, 0x3ed70c7e,
388 0x00100fde, 0x00000000, 0x3f87c036 },
389 },
390 { 0x1200, {
391 0x002ffff1, 0x002ffff1, 0x02a0a9c8,
392 0x002003e7, 0x001ffffa, 0x000185bc,
393 0x002007dc, 0x000003ff, 0x3e52859c,
394 0x00200bd4, 0x00000002, 0x3d53996b,
395 0x00100fd0, 0x00000403, 0x3d04ad2d,
396 0x00000bd5, 0x00000403, 0x3d35ace7,
397 0x3ff003e4, 0x00000801, 0x3dc674a1,
398 0x3fffe800, 0x00000800, 0x3e76f461 },
399 },
400 { 0x1400, {
401 0x00100be3, 0x00100be3, 0x04d1359a,
402 0x00000fdb, 0x002003ed, 0x0211fd93,
403 0x00000fd6, 0x002003f4, 0x0002d97b,
404 0x000007d6, 0x002ffffb, 0x3e93b956,
405 0x3ff003da, 0x001003ff, 0x3db49926,
406 0x3fffefe9, 0x00100001, 0x3d655cee,
407 0x3fffd400, 0x00000003, 0x3d65f4b6,
408 0x000fb421, 0x00000402, 0x3dc6547e },
409 },
410 { 0x1600, {
411 0x00000bdd, 0x00000bdd, 0x06519578,
412 0x3ff007da, 0x00000be3, 0x03c24973,
413 0x3ff003d9, 0x00000be9, 0x01b30d5f,
414 0x3ffff7df, 0x001003f1, 0x0003c542,
415 0x000fdfec, 0x001003f7, 0x3ec4711d,
416 0x000fc400, 0x002ffffd, 0x3df504f1,
417 0x001fa81a, 0x002ffc00, 0x3d957cc2,
418 0x002f8c3c, 0x00100000, 0x3db5c891 },
419 },
420 { 0x1800, {
421 0x3ff003dc, 0x3ff003dc, 0x0791e558,
422 0x000ff7dd, 0x3ff007de, 0x05328554,
423 0x000fe7e3, 0x3ff00be2, 0x03232546,
424 0x000fd7ee, 0x000007e9, 0x0143bd30,
425 0x001fb800, 0x000007ee, 0x00044511,
426 0x002fa015, 0x000007f4, 0x3ef4bcee,
427 0x002f8832, 0x001003f9, 0x3e4514c7,
428 0x001f7853, 0x001003fd, 0x3de54c9f },
429 },
430 { 0x1a00, {
431 0x000fefe0, 0x000fefe0, 0x08721d3c,
432 0x001fdbe7, 0x000ffbde, 0x0652a139,
433 0x001fcbf0, 0x000003df, 0x0463292e,
434 0x002fb3ff, 0x3ff007e3, 0x0293a91d,
435 0x002f9c12, 0x3ff00be7, 0x01241905,
436 0x001f8c29, 0x000007ed, 0x3fe470eb,
437 0x000f7c46, 0x000007f2, 0x3f04b8ca,
438 0x3fef7865, 0x000007f6, 0x3e74e4a8 },
439 },
440 { 0x1c00, {
441 0x001fd3e9, 0x001fd3e9, 0x08f23d26,
442 0x002fbff3, 0x001fe3e4, 0x0712ad23,
443 0x002fa800, 0x000ff3e0, 0x05631d1b,
444 0x001f9810, 0x000ffbe1, 0x03b3890d,
445 0x000f8c23, 0x000003e3, 0x0233e8fa,
446 0x3fef843b, 0x000003e7, 0x00f430e4,
447 0x3fbf8456, 0x3ff00bea, 0x00046cc8,
448 0x3f8f8c72, 0x3ff00bef, 0x3f3490ac },
449 },
450 { 0x1e00, {
451 0x001fbbf4, 0x001fbbf4, 0x09425112,
452 0x001fa800, 0x002fc7ed, 0x0792b110,
453 0x000f980e, 0x001fdbe6, 0x0613110a,
454 0x3fff8c20, 0x001fe7e3, 0x04a368fd,
455 0x3fcf8c33, 0x000ff7e2, 0x0343b8ed,
456 0x3f9f8c4a, 0x000fffe3, 0x0203f8da,
457 0x3f5f9c61, 0x000003e6, 0x00e428c5,
458 0x3f1fb07b, 0x000003eb, 0x3fe440af },
459 },
460 { 0x2000, {
461 0x000fa400, 0x000fa400, 0x09625902,
462 0x3fff980c, 0x001fb7f5, 0x0812b0ff,
463 0x3fdf901c, 0x001fc7ed, 0x06b2fcfa,
464 0x3faf902d, 0x001fd3e8, 0x055348f1,
465 0x3f7f983f, 0x001fe3e5, 0x04038ce3,
466 0x3f3fa454, 0x001fefe3, 0x02e3c8d1,
467 0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0,
468 0x3ecfd880, 0x000fffe6, 0x00c404ac },
469 },
470 { 0x2200, {
471 0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4,
472 0x3fbf9818, 0x3fffa400, 0x0842a8f1,
473 0x3f8f9827, 0x000fb3f7, 0x0702f0ec,
474 0x3f5fa037, 0x000fc3ef, 0x05d330e4,
475 0x3f2fac49, 0x001fcfea, 0x04a364d9,
476 0x3effc05c, 0x001fdbe7, 0x038394ca,
477 0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb,
478 0x3ea00083, 0x001fefe6, 0x0183c0a9 },
479 },
480 { 0x2400, {
481 0x3f9fa014, 0x3f9fa014, 0x098260e6,
482 0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5,
483 0x3f4fa431, 0x3fefa400, 0x0742d8e1,
484 0x3f1fb440, 0x3fffb3f8, 0x062310d9,
485 0x3eefc850, 0x000fbbf2, 0x050340d0,
486 0x3ecfe062, 0x000fcbec, 0x041364c2,
487 0x3ea00073, 0x001fd3ea, 0x03037cb5,
488 0x3e902086, 0x001fdfe8, 0x022388a5 },
489 },
490 { 0x2600, {
491 0x3f5fa81e, 0x3f5fa81e, 0x096258da,
492 0x3f3fac2b, 0x3f8fa412, 0x088290d8,
493 0x3f0fbc38, 0x3fafa408, 0x0772c8d5,
494 0x3eefcc47, 0x3fcfa800, 0x0672f4ce,
495 0x3ecfe456, 0x3fefaffa, 0x05531cc6,
496 0x3eb00066, 0x3fffbbf3, 0x047334bb,
497 0x3ea01c77, 0x000fc7ee, 0x039348ae,
498 0x3ea04486, 0x000fd3eb, 0x02b350a1 },
499 },
500 { 0x2800, {
501 0x3f2fb426, 0x3f2fb426, 0x094250ce,
502 0x3f0fc032, 0x3f4fac1b, 0x086284cd,
503 0x3eefd040, 0x3f7fa811, 0x0782acc9,
504 0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4,
505 0x3eb0005b, 0x3fbfac00, 0x05b2f4bc,
506 0x3eb0186a, 0x3fdfb3fa, 0x04c308b4,
507 0x3eb04077, 0x3fefbbf4, 0x03f31ca8,
508 0x3ec06884, 0x000fbff2, 0x03031c9e },
509 },
510 { 0x2a00, {
511 0x3f0fc42d, 0x3f0fc42d, 0x090240c4,
512 0x3eefd439, 0x3f2fb822, 0x08526cc2,
513 0x3edfe845, 0x3f4fb018, 0x078294bf,
514 0x3ec00051, 0x3f6fac0f, 0x06b2b4bb,
515 0x3ec0185f, 0x3f8fac07, 0x05e2ccb4,
516 0x3ec0386b, 0x3fafac00, 0x0502e8ac,
517 0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3,
518 0x3ef08482, 0x3fdfbbf6, 0x0372f898 },
519 },
520 { 0x2c00, {
521 0x3eefdc31, 0x3eefdc31, 0x08e238b8,
522 0x3edfec3d, 0x3f0fc828, 0x082258b9,
523 0x3ed00049, 0x3f1fc01e, 0x077278b6,
524 0x3ed01455, 0x3f3fb815, 0x06c294b2,
525 0x3ed03460, 0x3f5fb40d, 0x0602acac,
526 0x3ef0506c, 0x3f7fb006, 0x0542c0a4,
527 0x3f107476, 0x3f9fb400, 0x0472c89d,
528 0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 },
529 },
530 { 0x2e00, {
531 0x3eefec37, 0x3eefec37, 0x088220b0,
532 0x3ee00041, 0x3effdc2d, 0x07f244ae,
533 0x3ee0144c, 0x3f0fd023, 0x07625cad,
534 0x3ef02c57, 0x3f1fc81a, 0x06c274a9,
535 0x3f004861, 0x3f3fbc13, 0x060288a6,
536 0x3f20686b, 0x3f5fb80c, 0x05529c9e,
537 0x3f408c74, 0x3f6fb805, 0x04b2ac96,
538 0x3f80ac7e, 0x3f8fb800, 0x0402ac8e },
539 },
540 { 0x3000, {
541 0x3ef0003a, 0x3ef0003a, 0x084210a6,
542 0x3ef01045, 0x3effec32, 0x07b228a7,
543 0x3f00284e, 0x3f0fdc29, 0x073244a4,
544 0x3f104058, 0x3f0fd420, 0x06a258a2,
545 0x3f305c62, 0x3f2fc818, 0x0612689d,
546 0x3f508069, 0x3f3fc011, 0x05728496,
547 0x3f80a072, 0x3f4fc00a, 0x04d28c90,
548 0x3fc0c07b, 0x3f6fbc04, 0x04429088 },
549 },
550 { 0x3200, {
551 0x3f00103e, 0x3f00103e, 0x07f1fc9e,
552 0x3f102447, 0x3f000035, 0x0782149d,
553 0x3f203c4f, 0x3f0ff02c, 0x07122c9c,
554 0x3f405458, 0x3f0fe424, 0x06924099,
555 0x3f607061, 0x3f1fd41d, 0x06024c97,
556 0x3f909068, 0x3f2fcc16, 0x05726490,
557 0x3fc0b070, 0x3f3fc80f, 0x04f26c8a,
558 0x0000d077, 0x3f4fc409, 0x04627484 },
559 },
560 { 0x3400, {
561 0x3f202040, 0x3f202040, 0x07a1e898,
562 0x3f303449, 0x3f100c38, 0x0741fc98,
563 0x3f504c50, 0x3f10002f, 0x06e21495,
564 0x3f706459, 0x3f1ff028, 0x06722492,
565 0x3fa08060, 0x3f1fe421, 0x05f2348f,
566 0x3fd09c67, 0x3f1fdc19, 0x05824c89,
567 0x0000bc6e, 0x3f2fd014, 0x04f25086,
568 0x0040dc74, 0x3f3fcc0d, 0x04825c7f },
569 },
570 { 0x3600, {
571 0x3f403042, 0x3f403042, 0x0761d890,
572 0x3f504848, 0x3f301c3b, 0x0701f090,
573 0x3f805c50, 0x3f200c33, 0x06a2008f,
574 0x3fa07458, 0x3f10002b, 0x06520c8d,
575 0x3fd0905e, 0x3f1ff424, 0x05e22089,
576 0x0000ac65, 0x3f1fe81d, 0x05823483,
577 0x0030cc6a, 0x3f2fdc18, 0x04f23c81,
578 0x0080e871, 0x3f2fd412, 0x0482407c },
579 },
580 { 0x3800, {
581 0x3f604043, 0x3f604043, 0x0721c88a,
582 0x3f80544a, 0x3f502c3c, 0x06d1d88a,
583 0x3fb06851, 0x3f301c35, 0x0681e889,
584 0x3fd08456, 0x3f30082f, 0x0611fc88,
585 0x00009c5d, 0x3f200027, 0x05d20884,
586 0x0030b863, 0x3f2ff421, 0x05621880,
587 0x0070d468, 0x3f2fe81b, 0x0502247c,
588 0x00c0ec6f, 0x3f2fe015, 0x04a22877 },
589 },
590 { 0x3a00, {
591 0x3f904c44, 0x3f904c44, 0x06e1b884,
592 0x3fb0604a, 0x3f70383e, 0x0691c885,
593 0x3fe07451, 0x3f502c36, 0x0661d483,
594 0x00009055, 0x3f401831, 0x0601ec81,
595 0x0030a85b, 0x3f300c2a, 0x05b1f480,
596 0x0070c061, 0x3f300024, 0x0562047a,
597 0x00b0d867, 0x3f3ff41e, 0x05020c77,
598 0x00f0f46b, 0x3f2fec19, 0x04a21474 },
599 },
600 { 0x3c00, {
601 0x3fb05c43, 0x3fb05c43, 0x06c1b07e,
602 0x3fe06c4b, 0x3f902c3f, 0x0681c081,
603 0x0000844f, 0x3f703838, 0x0631cc7d,
604 0x00309855, 0x3f602433, 0x05d1d47e,
605 0x0060b459, 0x3f50142e, 0x0581e47b,
606 0x00a0c85f, 0x3f400828, 0x0531f078,
607 0x00e0e064, 0x3f300021, 0x0501fc73,
608 0x00b0fc6a, 0x3f3ff41d, 0x04a20873 },
609 },
610 { 0x3e00, {
611 0x3fe06444, 0x3fe06444, 0x0681a07a,
612 0x00007849, 0x3fc0503f, 0x0641b07a,
613 0x0020904d, 0x3fa0403a, 0x05f1c07a,
614 0x0060a453, 0x3f803034, 0x05c1c878,
615 0x0090b858, 0x3f70202f, 0x0571d477,
616 0x00d0d05d, 0x3f501829, 0x0531e073,
617 0x0110e462, 0x3f500825, 0x04e1e471,
618 0x01510065, 0x3f40001f, 0x04a1f06d },
619 },
620 { 0x4000, {
621 0x00007044, 0x00007044, 0x06519476,
622 0x00208448, 0x3fe05c3f, 0x0621a476,
623 0x0050984d, 0x3fc04c3a, 0x05e1b075,
624 0x0080ac52, 0x3fa03c35, 0x05a1b875,
625 0x00c0c056, 0x3f803030, 0x0561c473,
626 0x0100d45b, 0x3f70202b, 0x0521d46f,
627 0x0140e860, 0x3f601427, 0x04d1d46e,
628 0x01810064, 0x3f500822, 0x0491dc6b },
629 },
630 { 0x5000, {
631 0x0110a442, 0x0110a442, 0x0551545e,
632 0x0140b045, 0x00e0983f, 0x0531585f,
633 0x0160c047, 0x00c08c3c, 0x0511645e,
634 0x0190cc4a, 0x00908039, 0x04f1685f,
635 0x01c0dc4c, 0x00707436, 0x04d1705e,
636 0x0200e850, 0x00506833, 0x04b1785b,
637 0x0230f453, 0x00305c30, 0x0491805a,
638 0x02710056, 0x0010542d, 0x04718059 },
639 },
640 { 0x6000, {
641 0x01c0bc40, 0x01c0bc40, 0x04c13052,
642 0x01e0c841, 0x01a0b43d, 0x04c13851,
643 0x0210cc44, 0x0180a83c, 0x04a13453,
644 0x0230d845, 0x0160a03a, 0x04913c52,
645 0x0260e047, 0x01409838, 0x04714052,
646 0x0280ec49, 0x01208c37, 0x04514c50,
647 0x02b0f44b, 0x01008435, 0x04414c50,
648 0x02d1004c, 0x00e07c33, 0x0431544f },
649 },
650 { 0x7000, {
651 0x0230c83e, 0x0230c83e, 0x04711c4c,
652 0x0250d03f, 0x0210c43c, 0x0471204b,
653 0x0270d840, 0x0200b83c, 0x0451244b,
654 0x0290dc42, 0x01e0b43a, 0x0441244c,
655 0x02b0e443, 0x01c0b038, 0x0441284b,
656 0x02d0ec44, 0x01b0a438, 0x0421304a,
657 0x02f0f445, 0x0190a036, 0x04213449,
658 0x0310f847, 0x01709c34, 0x04213848 },
659 },
660 { 0x8000, {
661 0x0280d03d, 0x0280d03d, 0x04310c48,
662 0x02a0d43e, 0x0270c83c, 0x04311047,
663 0x02b0dc3e, 0x0250c83a, 0x04311447,
664 0x02d0e040, 0x0240c03a, 0x04211446,
665 0x02e0e840, 0x0220bc39, 0x04111847,
666 0x0300e842, 0x0210b438, 0x04012445,
667 0x0310f043, 0x0200b037, 0x04012045,
668 0x0330f444, 0x01e0ac36, 0x03f12445 },
669 },
670 { 0xefff, {
671 0x0340dc3a, 0x0340dc3a, 0x03b0ec40,
672 0x0340e03a, 0x0330e039, 0x03c0f03e,
673 0x0350e03b, 0x0330dc39, 0x03c0ec3e,
674 0x0350e43a, 0x0320dc38, 0x03c0f43e,
675 0x0360e43b, 0x0320d839, 0x03b0f03e,
676 0x0360e83b, 0x0310d838, 0x03c0fc3b,
677 0x0370e83b, 0x0310d439, 0x03a0f83d,
678 0x0370e83c, 0x0300d438, 0x03b0fc3c },
679 }
680};
681
682static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs)
683{
684 int i;
685 const struct vin_coeff *p_prev_set = NULL;
686 const struct vin_coeff *p_set = NULL;
687
688 /* Look for suitable coefficient values */
689 for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
690 p_prev_set = p_set;
691 p_set = &vin_coeff_set[i];
692
693 if (xs < p_set->xs_value)
694 break;
695 }
696
697 /* Use previous value if its XS value is closer */
698 if (p_prev_set && p_set &&
699 xs - p_prev_set->xs_value < p_set->xs_value - xs)
700 p_set = p_prev_set;
701
702 /* Set coefficient registers */
703 rvin_write(vin, p_set->coeff_set[0], VNC1A_REG);
704 rvin_write(vin, p_set->coeff_set[1], VNC1B_REG);
705 rvin_write(vin, p_set->coeff_set[2], VNC1C_REG);
706
707 rvin_write(vin, p_set->coeff_set[3], VNC2A_REG);
708 rvin_write(vin, p_set->coeff_set[4], VNC2B_REG);
709 rvin_write(vin, p_set->coeff_set[5], VNC2C_REG);
710
711 rvin_write(vin, p_set->coeff_set[6], VNC3A_REG);
712 rvin_write(vin, p_set->coeff_set[7], VNC3B_REG);
713 rvin_write(vin, p_set->coeff_set[8], VNC3C_REG);
714
715 rvin_write(vin, p_set->coeff_set[9], VNC4A_REG);
716 rvin_write(vin, p_set->coeff_set[10], VNC4B_REG);
717 rvin_write(vin, p_set->coeff_set[11], VNC4C_REG);
718
719 rvin_write(vin, p_set->coeff_set[12], VNC5A_REG);
720 rvin_write(vin, p_set->coeff_set[13], VNC5B_REG);
721 rvin_write(vin, p_set->coeff_set[14], VNC5C_REG);
722
723 rvin_write(vin, p_set->coeff_set[15], VNC6A_REG);
724 rvin_write(vin, p_set->coeff_set[16], VNC6B_REG);
725 rvin_write(vin, p_set->coeff_set[17], VNC6C_REG);
726
727 rvin_write(vin, p_set->coeff_set[18], VNC7A_REG);
728 rvin_write(vin, p_set->coeff_set[19], VNC7B_REG);
729 rvin_write(vin, p_set->coeff_set[20], VNC7C_REG);
730
731 rvin_write(vin, p_set->coeff_set[21], VNC8A_REG);
732 rvin_write(vin, p_set->coeff_set[22], VNC8B_REG);
733 rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
734}
735
736void rvin_crop_scale_comp(struct rvin_dev *vin)
737{
738 u32 xs, ys;
739
740 /* Set Start/End Pixel/Line Pre-Clip */
741 rvin_write(vin, vin->crop.left, VNSPPRC_REG);
742 rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
743 switch (vin->format.field) {
744 case V4L2_FIELD_INTERLACED:
745 case V4L2_FIELD_INTERLACED_TB:
746 case V4L2_FIELD_INTERLACED_BT:
747 rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG);
748 rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1,
749 VNELPRC_REG);
750 break;
751 default:
752 rvin_write(vin, vin->crop.top, VNSLPRC_REG);
753 rvin_write(vin, vin->crop.top + vin->crop.height - 1,
754 VNELPRC_REG);
755 break;
756 }
757
758 /* Set scaling coefficient */
759 ys = 0;
760 if (vin->crop.height != vin->compose.height)
761 ys = (4096 * vin->crop.height) / vin->compose.height;
762 rvin_write(vin, ys, VNYS_REG);
763
764 xs = 0;
765 if (vin->crop.width != vin->compose.width)
766 xs = (4096 * vin->crop.width) / vin->compose.width;
767
768 /* Horizontal upscaling is up to double size */
769 if (xs > 0 && xs < 2048)
770 xs = 2048;
771
772 rvin_write(vin, xs, VNXS_REG);
773
774 /* Horizontal upscaling is done out by scaling down from double size */
775 if (xs < 4096)
776 xs *= 2;
777
778 rvin_set_coeff(vin, xs);
779
780 /* Set Start/End Pixel/Line Post-Clip */
781 rvin_write(vin, 0, VNSPPOC_REG);
782 rvin_write(vin, 0, VNSLPOC_REG);
783 rvin_write(vin, vin->format.width - 1, VNEPPOC_REG);
784 switch (vin->format.field) {
785 case V4L2_FIELD_INTERLACED:
786 case V4L2_FIELD_INTERLACED_TB:
787 case V4L2_FIELD_INTERLACED_BT:
788 rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG);
789 break;
790 default:
791 rvin_write(vin, vin->format.height - 1, VNELPOC_REG);
792 break;
793 }
794
795 if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
796 rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
797 else
798 rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
799
800 vin_dbg(vin,
801 "Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n",
802 vin->crop.width, vin->crop.height, vin->crop.left,
803 vin->crop.top, ys, xs, vin->format.width, vin->format.height,
804 0, 0);
805}
806
807void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
808 u32 width, u32 height)
809{
810 /* All VIN channels on Gen2 have scalers */
811 pix->width = width;
812 pix->height = height;
813}
814
815/* -----------------------------------------------------------------------------
816 * DMA Functions
817 */
818
819#define RVIN_TIMEOUT_MS 100
820#define RVIN_RETRIES 10
821
822struct rvin_buffer {
823 struct vb2_v4l2_buffer vb;
824 struct list_head list;
825};
826
827#define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
828 struct rvin_buffer, \
829 vb)->list)
830
831/* Moves a buffer from the queue to the HW slots */
832static bool rvin_fill_hw_slot(struct rvin_dev *vin, int slot)
833{
834 struct rvin_buffer *buf;
835 struct vb2_v4l2_buffer *vbuf;
836 dma_addr_t phys_addr_top;
837
838 if (vin->queue_buf[slot] != NULL)
839 return true;
840
841 if (list_empty(&vin->buf_list))
842 return false;
843
844 vin_dbg(vin, "Filling HW slot: %d\n", slot);
845
846 /* Keep track of buffer we give to HW */
847 buf = list_entry(vin->buf_list.next, struct rvin_buffer, list);
848 vbuf = &buf->vb;
849 list_del_init(to_buf_list(vbuf));
850 vin->queue_buf[slot] = vbuf;
851
852 /* Setup DMA */
853 phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
854 rvin_set_slot_addr(vin, slot, phys_addr_top);
855
856 return true;
857}
858
859static bool rvin_fill_hw(struct rvin_dev *vin)
860{
861 int slot, limit;
862
863 limit = vin->continuous ? HW_BUFFER_NUM : 1;
864
865 for (slot = 0; slot < limit; slot++)
866 if (!rvin_fill_hw_slot(vin, slot))
867 return false;
868 return true;
869}
870
871static irqreturn_t rvin_irq(int irq, void *data)
872{
873 struct rvin_dev *vin = data;
874 u32 int_status;
875 int slot;
876 unsigned int sequence, handled = 0;
877 unsigned long flags;
878
879 spin_lock_irqsave(&vin->qlock, flags);
880
881 int_status = rvin_get_interrupt_status(vin);
882 if (!int_status)
883 goto done;
884
885 rvin_ack_interrupt(vin);
886 handled = 1;
887
888 /* Nothing to do if capture status is 'STOPPED' */
889 if (vin->state == STOPPED) {
890 vin_dbg(vin, "IRQ while state stopped\n");
891 goto done;
892 }
893
894 /* Nothing to do if capture status is 'STOPPING' */
895 if (vin->state == STOPPING) {
896 vin_dbg(vin, "IRQ while state stopping\n");
897 goto done;
898 }
899
900 /* Prepare for capture and update state */
901 slot = rvin_get_active_slot(vin);
902 sequence = vin->sequence++;
903
904 vin_dbg(vin, "IRQ %02d: %d\tbuf0: %c buf1: %c buf2: %c\tmore: %d\n",
905 sequence, slot,
906 slot == 0 ? 'x' : vin->queue_buf[0] != NULL ? '1' : '0',
907 slot == 1 ? 'x' : vin->queue_buf[1] != NULL ? '1' : '0',
908 slot == 2 ? 'x' : vin->queue_buf[2] != NULL ? '1' : '0',
909 !list_empty(&vin->buf_list));
910
911 /* HW have written to a slot that is not prepared we are in trouble */
912 if (WARN_ON((vin->queue_buf[slot] == NULL)))
913 goto done;
914
915 /* Capture frame */
916 vin->queue_buf[slot]->field = vin->format.field;
917 vin->queue_buf[slot]->sequence = sequence;
918 vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
919 vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE);
920 vin->queue_buf[slot] = NULL;
921
922 /* Prepare for next frame */
923 if (!rvin_fill_hw(vin)) {
924
925 /*
926 * Can't supply HW with new buffers fast enough. Halt
927 * capture until more buffers are available.
928 */
929 vin->state = STALLED;
930
931 /*
932 * The continuous capturing requires an explicit stop
933 * operation when there is no buffer to be set into
934 * the VnMBm registers.
935 */
936 if (vin->continuous) {
937 rvin_capture_off(vin);
938 vin_dbg(vin, "IRQ %02d: hw not ready stop\n", sequence);
939 }
940 } else {
941 /*
942 * The single capturing requires an explicit capture
943 * operation to fetch the next frame.
944 */
945 if (!vin->continuous)
946 rvin_capture_on(vin);
947 }
948done:
949 spin_unlock_irqrestore(&vin->qlock, flags);
950
951 return IRQ_RETVAL(handled);
952}
953
954/* Need to hold qlock before calling */
955static void return_all_buffers(struct rvin_dev *vin,
956 enum vb2_buffer_state state)
957{
958 struct rvin_buffer *buf, *node;
959 int i;
960
961 for (i = 0; i < HW_BUFFER_NUM; i++) {
962 if (vin->queue_buf[i]) {
963 vb2_buffer_done(&vin->queue_buf[i]->vb2_buf,
964 state);
965 vin->queue_buf[i] = NULL;
966 }
967 }
968
969 list_for_each_entry_safe(buf, node, &vin->buf_list, list) {
970 vb2_buffer_done(&buf->vb.vb2_buf, state);
971 list_del(&buf->list);
972 }
973}
974
975static int rvin_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
976 unsigned int *nplanes, unsigned int sizes[],
977 void *alloc_ctxs[])
978
979{
980 struct rvin_dev *vin = vb2_get_drv_priv(vq);
981
982 alloc_ctxs[0] = vin->alloc_ctx;
983 /* Make sure the image size is large enough. */
984 if (*nplanes)
985 return sizes[0] < vin->format.sizeimage ? -EINVAL : 0;
986
987 *nplanes = 1;
988 sizes[0] = vin->format.sizeimage;
989
990 return 0;
991};
992
993static int rvin_buffer_prepare(struct vb2_buffer *vb)
994{
995 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
996 unsigned long size = vin->format.sizeimage;
997
998 if (vb2_plane_size(vb, 0) < size) {
999 vin_err(vin, "buffer too small (%lu < %lu)\n",
1000 vb2_plane_size(vb, 0), size);
1001 return -EINVAL;
1002 }
1003
1004 vb2_set_plane_payload(vb, 0, size);
1005
1006 return 0;
1007}
1008
1009static void rvin_buffer_queue(struct vb2_buffer *vb)
1010{
1011 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1012 struct rvin_dev *vin = vb2_get_drv_priv(vb->vb2_queue);
1013 unsigned long flags;
1014
1015 spin_lock_irqsave(&vin->qlock, flags);
1016
1017 list_add_tail(to_buf_list(vbuf), &vin->buf_list);
1018
1019 /*
1020 * If capture is stalled add buffer to HW and restart
1021 * capturing if HW is ready to continue.
1022 */
1023 if (vin->state == STALLED)
1024 if (rvin_fill_hw(vin))
1025 rvin_capture_on(vin);
1026
1027 spin_unlock_irqrestore(&vin->qlock, flags);
1028}
1029
1030static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count)
1031{
1032 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1033 struct v4l2_subdev *sd;
1034 unsigned long flags;
1035 int ret;
1036
1037 sd = vin_to_source(vin);
1038 v4l2_subdev_call(sd, video, s_stream, 1);
1039
1040 spin_lock_irqsave(&vin->qlock, flags);
1041
1042 vin->state = RUNNING;
1043 vin->sequence = 0;
1044
1045 /* Continuous capture requires more buffers then there are HW slots */
1046 vin->continuous = count > HW_BUFFER_NUM;
1047
1048 /*
1049 * This should never happen but if we don't have enough
1050 * buffers for HW bail out
1051 */
1052 if (!rvin_fill_hw(vin)) {
1053 vin_err(vin, "HW not ready to start, not enough buffers available\n");
1054 ret = -EINVAL;
1055 goto out;
1056 }
1057
1058 ret = rvin_capture_start(vin);
1059out:
1060 /* Return all buffers if something went wrong */
1061 if (ret) {
1062 return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
1063 v4l2_subdev_call(sd, video, s_stream, 0);
1064 }
1065
1066 spin_unlock_irqrestore(&vin->qlock, flags);
1067
1068 return ret;
1069}
1070
1071static void rvin_stop_streaming(struct vb2_queue *vq)
1072{
1073 struct rvin_dev *vin = vb2_get_drv_priv(vq);
1074 struct v4l2_subdev *sd;
1075 unsigned long flags;
1076 int retries = 0;
1077
1078 spin_lock_irqsave(&vin->qlock, flags);
1079
1080 vin->state = STOPPING;
1081
1082 /* Wait for streaming to stop */
1083 while (retries++ < RVIN_RETRIES) {
1084
1085 rvin_capture_stop(vin);
1086
1087 /* Check if HW is stopped */
1088 if (!rvin_capture_active(vin)) {
1089 vin->state = STOPPED;
1090 break;
1091 }
1092
1093 spin_unlock_irqrestore(&vin->qlock, flags);
1094 msleep(RVIN_TIMEOUT_MS);
1095 spin_lock_irqsave(&vin->qlock, flags);
1096 }
1097
1098 if (vin->state != STOPPED) {
1099 /*
1100 * If this happens something have gone horribly wrong.
1101 * Set state to stopped to prevent the interrupt handler
1102 * to make things worse...
1103 */
1104 vin_err(vin, "Failed stop HW, something is seriously broken\n");
1105 vin->state = STOPPED;
1106 }
1107
1108 /* Release all active buffers */
1109 return_all_buffers(vin, VB2_BUF_STATE_ERROR);
1110
1111 spin_unlock_irqrestore(&vin->qlock, flags);
1112
1113 sd = vin_to_source(vin);
1114 v4l2_subdev_call(sd, video, s_stream, 0);
1115
1116 /* disable interrupts */
1117 rvin_disable_interrupts(vin);
1118}
1119
1120static struct vb2_ops rvin_qops = {
1121 .queue_setup = rvin_queue_setup,
1122 .buf_prepare = rvin_buffer_prepare,
1123 .buf_queue = rvin_buffer_queue,
1124 .start_streaming = rvin_start_streaming,
1125 .stop_streaming = rvin_stop_streaming,
1126 .wait_prepare = vb2_ops_wait_prepare,
1127 .wait_finish = vb2_ops_wait_finish,
1128};
1129
1130void rvin_dma_remove(struct rvin_dev *vin)
1131{
1132 if (!IS_ERR_OR_NULL(vin->alloc_ctx))
1133 vb2_dma_contig_cleanup_ctx(vin->alloc_ctx);
1134
1135 mutex_destroy(&vin->lock);
1136
1137 v4l2_device_unregister(&vin->v4l2_dev);
1138}
1139
1140int rvin_dma_probe(struct rvin_dev *vin, int irq)
1141{
1142 struct vb2_queue *q = &vin->queue;
1143 int i, ret;
1144
1145 /* Initialize the top-level structure */
1146 ret = v4l2_device_register(vin->dev, &vin->v4l2_dev);
1147 if (ret)
1148 return ret;
1149
1150 mutex_init(&vin->lock);
1151 INIT_LIST_HEAD(&vin->buf_list);
1152
1153 spin_lock_init(&vin->qlock);
1154
1155 vin->state = STOPPED;
1156
1157 for (i = 0; i < HW_BUFFER_NUM; i++)
1158 vin->queue_buf[i] = NULL;
1159
1160 /* buffer queue */
1161 vin->alloc_ctx = vb2_dma_contig_init_ctx(vin->dev);
1162 if (IS_ERR(vin->alloc_ctx)) {
1163 ret = PTR_ERR(vin->alloc_ctx);
1164 goto error;
1165 }
1166
1167 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1168 q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
1169 q->lock = &vin->lock;
1170 q->drv_priv = vin;
1171 q->buf_struct_size = sizeof(struct rvin_buffer);
1172 q->ops = &rvin_qops;
1173 q->mem_ops = &vb2_dma_contig_memops;
1174 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1175 q->min_buffers_needed = 2;
1176
1177 ret = vb2_queue_init(q);
1178 if (ret < 0) {
1179 vin_err(vin, "failed to initialize VB2 queue\n");
1180 goto error;
1181 }
1182
1183 /* irq */
1184 ret = devm_request_irq(vin->dev, irq, rvin_irq, IRQF_SHARED,
1185 KBUILD_MODNAME, vin);
1186 if (ret) {
1187 vin_err(vin, "failed to request irq\n");
1188 goto error;
1189 }
1190
1191 return 0;
1192error:
1193 rvin_dma_remove(vin);
1194
1195 return ret;
1196}
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
new file mode 100644
index 000000000000..0bc4487e2482
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -0,0 +1,768 @@
1/*
2 * Driver for Renesas R-Car VIN
3 *
4 * Copyright (C) 2016 Renesas Electronics Corp.
5 * Copyright (C) 2011-2013 Renesas Solutions Corp.
6 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7 * Copyright (C) 2008 Magnus Damm
8 *
9 * Based on the soc-camera rcar_vin driver
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/pm_runtime.h>
18
19#include <media/v4l2-event.h>
20#include <media/v4l2-ioctl.h>
21#include <media/v4l2-rect.h>
22
23#include "rcar-vin.h"
24
25#define RVIN_DEFAULT_FORMAT V4L2_PIX_FMT_YUYV
26#define RVIN_MAX_WIDTH 2048
27#define RVIN_MAX_HEIGHT 2048
28
29/* -----------------------------------------------------------------------------
30 * Format Conversions
31 */
32
33static const struct rvin_video_format rvin_formats[] = {
34 {
35 .fourcc = V4L2_PIX_FMT_NV16,
36 .bpp = 1,
37 },
38 {
39 .fourcc = V4L2_PIX_FMT_YUYV,
40 .bpp = 2,
41 },
42 {
43 .fourcc = V4L2_PIX_FMT_UYVY,
44 .bpp = 2,
45 },
46 {
47 .fourcc = V4L2_PIX_FMT_RGB565,
48 .bpp = 2,
49 },
50 {
51 .fourcc = V4L2_PIX_FMT_XRGB555,
52 .bpp = 2,
53 },
54 {
55 .fourcc = V4L2_PIX_FMT_XBGR32,
56 .bpp = 4,
57 },
58};
59
60const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat)
61{
62 int i;
63
64 for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)
65 if (rvin_formats[i].fourcc == pixelformat)
66 return rvin_formats + i;
67
68 return NULL;
69}
70
71static u32 rvin_format_bytesperline(struct v4l2_pix_format *pix)
72{
73 const struct rvin_video_format *fmt;
74
75 fmt = rvin_format_from_pixel(pix->pixelformat);
76
77 if (WARN_ON(!fmt))
78 return -EINVAL;
79
80 return pix->width * fmt->bpp;
81}
82
83static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
84{
85 if (pix->pixelformat == V4L2_PIX_FMT_NV16)
86 return pix->bytesperline * pix->height * 2;
87
88 return pix->bytesperline * pix->height;
89}
90
91/* -----------------------------------------------------------------------------
92 * V4L2
93 */
94
95static int __rvin_try_format_source(struct rvin_dev *vin,
96 u32 which,
97 struct v4l2_pix_format *pix,
98 struct rvin_source_fmt *source)
99{
100 struct v4l2_subdev *sd;
101 struct v4l2_subdev_pad_config pad_cfg;
102 struct v4l2_subdev_format format = {
103 .which = which,
104 };
105 int ret;
106
107 sd = vin_to_source(vin);
108
109 v4l2_fill_mbus_format(&format.format, pix, vin->source.code);
110
111 ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, pad, set_fmt,
112 &pad_cfg, &format);
113 if (ret < 0)
114 return ret;
115
116 v4l2_fill_pix_format(pix, &format.format);
117
118 source->width = pix->width;
119 source->height = pix->height;
120
121 vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
122 source->height);
123
124 return 0;
125}
126
127static int __rvin_try_format(struct rvin_dev *vin,
128 u32 which,
129 struct v4l2_pix_format *pix,
130 struct rvin_source_fmt *source)
131{
132 const struct rvin_video_format *info;
133 u32 rwidth, rheight, walign;
134
135 /* Requested */
136 rwidth = pix->width;
137 rheight = pix->height;
138
139 /*
140 * Retrieve format information and select the current format if the
141 * requested format isn't supported.
142 */
143 info = rvin_format_from_pixel(pix->pixelformat);
144 if (!info) {
145 vin_dbg(vin, "Format %x not found, keeping %x\n",
146 pix->pixelformat, vin->format.pixelformat);
147 *pix = vin->format;
148 pix->width = rwidth;
149 pix->height = rheight;
150 }
151
152 /* Always recalculate */
153 pix->bytesperline = 0;
154 pix->sizeimage = 0;
155
156 /* Limit to source capabilities */
157 __rvin_try_format_source(vin, which, pix, source);
158
159 /* If source can't match format try if VIN can scale */
160 if (source->width != rwidth || source->height != rheight)
161 rvin_scale_try(vin, pix, rwidth, rheight);
162
163 /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
164 walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
165
166 /* Limit to VIN capabilities */
167 v4l_bound_align_image(&pix->width, 2, RVIN_MAX_WIDTH, walign,
168 &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0);
169
170 switch (pix->field) {
171 case V4L2_FIELD_NONE:
172 case V4L2_FIELD_TOP:
173 case V4L2_FIELD_BOTTOM:
174 case V4L2_FIELD_INTERLACED_TB:
175 case V4L2_FIELD_INTERLACED_BT:
176 case V4L2_FIELD_INTERLACED:
177 break;
178 default:
179 pix->field = V4L2_FIELD_NONE;
180 break;
181 }
182
183 pix->bytesperline = max_t(u32, pix->bytesperline,
184 rvin_format_bytesperline(pix));
185 pix->sizeimage = max_t(u32, pix->sizeimage,
186 rvin_format_sizeimage(pix));
187
188 vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n",
189 rwidth, rheight, pix->width, pix->height,
190 pix->bytesperline, pix->sizeimage);
191
192 return 0;
193}
194
195static int rvin_querycap(struct file *file, void *priv,
196 struct v4l2_capability *cap)
197{
198 struct rvin_dev *vin = video_drvdata(file);
199
200 strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
201 strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
202 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
203 dev_name(vin->dev));
204 return 0;
205}
206
207static int rvin_try_fmt_vid_cap(struct file *file, void *priv,
208 struct v4l2_format *f)
209{
210 struct rvin_dev *vin = video_drvdata(file);
211 struct rvin_source_fmt source;
212
213 return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix,
214 &source);
215}
216
217static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
218 struct v4l2_format *f)
219{
220 struct rvin_dev *vin = video_drvdata(file);
221 struct rvin_source_fmt source;
222 int ret;
223
224 if (vb2_is_busy(&vin->queue))
225 return -EBUSY;
226
227 ret = __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix,
228 &source);
229 if (ret)
230 return ret;
231
232 vin->source.width = source.width;
233 vin->source.height = source.height;
234
235 vin->format = f->fmt.pix;
236
237 return 0;
238}
239
240static int rvin_g_fmt_vid_cap(struct file *file, void *priv,
241 struct v4l2_format *f)
242{
243 struct rvin_dev *vin = video_drvdata(file);
244
245 f->fmt.pix = vin->format;
246
247 return 0;
248}
249
250static int rvin_enum_fmt_vid_cap(struct file *file, void *priv,
251 struct v4l2_fmtdesc *f)
252{
253 if (f->index >= ARRAY_SIZE(rvin_formats))
254 return -EINVAL;
255
256 f->pixelformat = rvin_formats[f->index].fourcc;
257
258 return 0;
259}
260
261static int rvin_g_selection(struct file *file, void *fh,
262 struct v4l2_selection *s)
263{
264 struct rvin_dev *vin = video_drvdata(file);
265
266 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
267 return -EINVAL;
268
269 switch (s->target) {
270 case V4L2_SEL_TGT_CROP_BOUNDS:
271 case V4L2_SEL_TGT_CROP_DEFAULT:
272 s->r.left = s->r.top = 0;
273 s->r.width = vin->source.width;
274 s->r.height = vin->source.height;
275 break;
276 case V4L2_SEL_TGT_CROP:
277 s->r = vin->crop;
278 break;
279 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
280 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
281 s->r.left = s->r.top = 0;
282 s->r.width = vin->format.width;
283 s->r.height = vin->format.height;
284 break;
285 case V4L2_SEL_TGT_COMPOSE:
286 s->r = vin->compose;
287 break;
288 default:
289 return -EINVAL;
290 }
291
292 return 0;
293}
294
295static int rvin_s_selection(struct file *file, void *fh,
296 struct v4l2_selection *s)
297{
298 struct rvin_dev *vin = video_drvdata(file);
299 const struct rvin_video_format *fmt;
300 struct v4l2_rect r = s->r;
301 struct v4l2_rect max_rect;
302 struct v4l2_rect min_rect = {
303 .width = 6,
304 .height = 2,
305 };
306
307 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
308 return -EINVAL;
309
310 v4l2_rect_set_min_size(&r, &min_rect);
311
312 switch (s->target) {
313 case V4L2_SEL_TGT_CROP:
314 /* Can't crop outside of source input */
315 max_rect.top = max_rect.left = 0;
316 max_rect.width = vin->source.width;
317 max_rect.height = vin->source.height;
318 v4l2_rect_map_inside(&r, &max_rect);
319
320 v4l_bound_align_image(&r.width, 2, vin->source.width, 1,
321 &r.height, 4, vin->source.height, 2, 0);
322
323 r.top = clamp_t(s32, r.top, 0, vin->source.height - r.height);
324 r.left = clamp_t(s32, r.left, 0, vin->source.width - r.width);
325
326 vin->crop = s->r = r;
327
328 vin_dbg(vin, "Cropped %dx%d@%d:%d of %dx%d\n",
329 r.width, r.height, r.left, r.top,
330 vin->source.width, vin->source.height);
331 break;
332 case V4L2_SEL_TGT_COMPOSE:
333 /* Make sure compose rect fits inside output format */
334 max_rect.top = max_rect.left = 0;
335 max_rect.width = vin->format.width;
336 max_rect.height = vin->format.height;
337 v4l2_rect_map_inside(&r, &max_rect);
338
339 /*
340 * Composing is done by adding a offset to the buffer address,
341 * the HW wants this address to be aligned to HW_BUFFER_MASK.
342 * Make sure the top and left values meets this requirement.
343 */
344 while ((r.top * vin->format.bytesperline) & HW_BUFFER_MASK)
345 r.top--;
346
347 fmt = rvin_format_from_pixel(vin->format.pixelformat);
348 while ((r.left * fmt->bpp) & HW_BUFFER_MASK)
349 r.left--;
350
351 vin->compose = s->r = r;
352
353 vin_dbg(vin, "Compose %dx%d@%d:%d in %dx%d\n",
354 r.width, r.height, r.left, r.top,
355 vin->format.width, vin->format.height);
356 break;
357 default:
358 return -EINVAL;
359 }
360
361 /* HW supports modifying configuration while running */
362 rvin_crop_scale_comp(vin);
363
364 return 0;
365}
366
367static int rvin_cropcap(struct file *file, void *priv,
368 struct v4l2_cropcap *crop)
369{
370 struct rvin_dev *vin = video_drvdata(file);
371 struct v4l2_subdev *sd = vin_to_source(vin);
372
373 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
374 return -EINVAL;
375
376 return v4l2_subdev_call(sd, video, cropcap, crop);
377}
378
379static int rvin_enum_input(struct file *file, void *priv,
380 struct v4l2_input *i)
381{
382 struct rvin_dev *vin = video_drvdata(file);
383 struct v4l2_subdev *sd = vin_to_source(vin);
384 int ret;
385
386 if (i->index != 0)
387 return -EINVAL;
388
389 ret = v4l2_subdev_call(sd, video, g_input_status, &i->status);
390 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
391 return ret;
392
393 i->type = V4L2_INPUT_TYPE_CAMERA;
394 i->std = vin->vdev.tvnorms;
395 strlcpy(i->name, "Camera", sizeof(i->name));
396
397 return 0;
398}
399
400static int rvin_g_input(struct file *file, void *priv, unsigned int *i)
401{
402 *i = 0;
403 return 0;
404}
405
406static int rvin_s_input(struct file *file, void *priv, unsigned int i)
407{
408 if (i > 0)
409 return -EINVAL;
410 return 0;
411}
412
413static int rvin_querystd(struct file *file, void *priv, v4l2_std_id *a)
414{
415 struct rvin_dev *vin = video_drvdata(file);
416 struct v4l2_subdev *sd = vin_to_source(vin);
417
418 return v4l2_subdev_call(sd, video, querystd, a);
419}
420
421static int rvin_s_std(struct file *file, void *priv, v4l2_std_id a)
422{
423 struct rvin_dev *vin = video_drvdata(file);
424 struct v4l2_subdev *sd = vin_to_source(vin);
425 struct v4l2_subdev_format fmt = {
426 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
427 };
428 struct v4l2_mbus_framefmt *mf = &fmt.format;
429 int ret = v4l2_subdev_call(sd, video, s_std, a);
430
431 if (ret < 0)
432 return ret;
433
434 /* Changing the standard will change the width/height */
435 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
436 if (ret) {
437 vin_err(vin, "Failed to get initial format\n");
438 return ret;
439 }
440
441 vin->format.width = mf->width;
442 vin->format.height = mf->height;
443
444 vin->crop.top = vin->crop.left = 0;
445 vin->crop.width = mf->width;
446 vin->crop.height = mf->height;
447
448 vin->compose.top = vin->compose.left = 0;
449 vin->compose.width = mf->width;
450 vin->compose.height = mf->height;
451
452 return 0;
453}
454
455static int rvin_g_std(struct file *file, void *priv, v4l2_std_id *a)
456{
457 struct rvin_dev *vin = video_drvdata(file);
458 struct v4l2_subdev *sd = vin_to_source(vin);
459
460 return v4l2_subdev_call(sd, video, g_std, a);
461}
462
463static int rvin_subscribe_event(struct v4l2_fh *fh,
464 const struct v4l2_event_subscription *sub)
465{
466 switch (sub->type) {
467 case V4L2_EVENT_SOURCE_CHANGE:
468 return v4l2_event_subscribe(fh, sub, 4, NULL);
469 }
470 return v4l2_ctrl_subscribe_event(fh, sub);
471}
472
473static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
474 .vidioc_querycap = rvin_querycap,
475 .vidioc_try_fmt_vid_cap = rvin_try_fmt_vid_cap,
476 .vidioc_g_fmt_vid_cap = rvin_g_fmt_vid_cap,
477 .vidioc_s_fmt_vid_cap = rvin_s_fmt_vid_cap,
478 .vidioc_enum_fmt_vid_cap = rvin_enum_fmt_vid_cap,
479
480 .vidioc_g_selection = rvin_g_selection,
481 .vidioc_s_selection = rvin_s_selection,
482
483 .vidioc_cropcap = rvin_cropcap,
484
485 .vidioc_enum_input = rvin_enum_input,
486 .vidioc_g_input = rvin_g_input,
487 .vidioc_s_input = rvin_s_input,
488
489 .vidioc_querystd = rvin_querystd,
490 .vidioc_g_std = rvin_g_std,
491 .vidioc_s_std = rvin_s_std,
492
493 .vidioc_reqbufs = vb2_ioctl_reqbufs,
494 .vidioc_create_bufs = vb2_ioctl_create_bufs,
495 .vidioc_querybuf = vb2_ioctl_querybuf,
496 .vidioc_qbuf = vb2_ioctl_qbuf,
497 .vidioc_dqbuf = vb2_ioctl_dqbuf,
498 .vidioc_expbuf = vb2_ioctl_expbuf,
499 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
500 .vidioc_streamon = vb2_ioctl_streamon,
501 .vidioc_streamoff = vb2_ioctl_streamoff,
502
503 .vidioc_log_status = v4l2_ctrl_log_status,
504 .vidioc_subscribe_event = rvin_subscribe_event,
505 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
506};
507
508/* -----------------------------------------------------------------------------
509 * File Operations
510 */
511
512static int rvin_power_on(struct rvin_dev *vin)
513{
514 int ret;
515 struct v4l2_subdev *sd = vin_to_source(vin);
516
517 pm_runtime_get_sync(vin->v4l2_dev.dev);
518
519 ret = v4l2_subdev_call(sd, core, s_power, 1);
520 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
521 return ret;
522 return 0;
523}
524
525static int rvin_power_off(struct rvin_dev *vin)
526{
527 int ret;
528 struct v4l2_subdev *sd = vin_to_source(vin);
529
530 ret = v4l2_subdev_call(sd, core, s_power, 0);
531
532 pm_runtime_put(vin->v4l2_dev.dev);
533
534 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
535 return ret;
536
537 return 0;
538}
539
540static int rvin_initialize_device(struct file *file)
541{
542 struct rvin_dev *vin = video_drvdata(file);
543 int ret;
544
545 struct v4l2_format f = {
546 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
547 .fmt.pix = {
548 .width = vin->format.width,
549 .height = vin->format.height,
550 .field = vin->format.field,
551 .colorspace = vin->format.colorspace,
552 .pixelformat = vin->format.pixelformat,
553 },
554 };
555
556 ret = rvin_power_on(vin);
557 if (ret < 0)
558 return ret;
559
560 pm_runtime_enable(&vin->vdev.dev);
561 ret = pm_runtime_resume(&vin->vdev.dev);
562 if (ret < 0 && ret != -ENOSYS)
563 goto eresume;
564
565 /*
566 * Try to configure with default parameters. Notice: this is the
567 * very first open, so, we cannot race against other calls,
568 * apart from someone else calling open() simultaneously, but
569 * .host_lock is protecting us against it.
570 */
571 ret = rvin_s_fmt_vid_cap(file, NULL, &f);
572 if (ret < 0)
573 goto esfmt;
574
575 v4l2_ctrl_handler_setup(&vin->ctrl_handler);
576
577 return 0;
578esfmt:
579 pm_runtime_disable(&vin->vdev.dev);
580eresume:
581 rvin_power_off(vin);
582
583 return ret;
584}
585
586static int rvin_open(struct file *file)
587{
588 struct rvin_dev *vin = video_drvdata(file);
589 int ret;
590
591 mutex_lock(&vin->lock);
592
593 file->private_data = vin;
594
595 ret = v4l2_fh_open(file);
596 if (ret)
597 goto unlock;
598
599 if (!v4l2_fh_is_singular_file(file))
600 goto unlock;
601
602 if (rvin_initialize_device(file)) {
603 v4l2_fh_release(file);
604 ret = -ENODEV;
605 }
606
607unlock:
608 mutex_unlock(&vin->lock);
609 return ret;
610}
611
612static int rvin_release(struct file *file)
613{
614 struct rvin_dev *vin = video_drvdata(file);
615 bool fh_singular;
616 int ret;
617
618 mutex_lock(&vin->lock);
619
620 /* Save the singular status before we call the clean-up helper */
621 fh_singular = v4l2_fh_is_singular_file(file);
622
623 /* the release helper will cleanup any on-going streaming */
624 ret = _vb2_fop_release(file, NULL);
625
626 /*
627 * If this was the last open file.
628 * Then de-initialize hw module.
629 */
630 if (fh_singular) {
631 pm_runtime_suspend(&vin->vdev.dev);
632 pm_runtime_disable(&vin->vdev.dev);
633 rvin_power_off(vin);
634 }
635
636 mutex_unlock(&vin->lock);
637
638 return ret;
639}
640
641static const struct v4l2_file_operations rvin_fops = {
642 .owner = THIS_MODULE,
643 .unlocked_ioctl = video_ioctl2,
644 .open = rvin_open,
645 .release = rvin_release,
646 .poll = vb2_fop_poll,
647 .mmap = vb2_fop_mmap,
648 .read = vb2_fop_read,
649};
650
651void rvin_v4l2_remove(struct rvin_dev *vin)
652{
653 v4l2_info(&vin->v4l2_dev, "Removing %s\n",
654 video_device_node_name(&vin->vdev));
655
656 /* Checks internaly if handlers have been init or not */
657 v4l2_ctrl_handler_free(&vin->ctrl_handler);
658
659 /* Checks internaly if vdev have been init or not */
660 video_unregister_device(&vin->vdev);
661}
662
663static void rvin_notify(struct v4l2_subdev *sd,
664 unsigned int notification, void *arg)
665{
666 struct rvin_dev *vin =
667 container_of(sd->v4l2_dev, struct rvin_dev, v4l2_dev);
668
669 switch (notification) {
670 case V4L2_DEVICE_NOTIFY_EVENT:
671 v4l2_event_queue(&vin->vdev, arg);
672 break;
673 default:
674 break;
675 }
676}
677
678int rvin_v4l2_probe(struct rvin_dev *vin)
679{
680 struct v4l2_subdev_format fmt = {
681 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
682 };
683 struct v4l2_mbus_framefmt *mf = &fmt.format;
684 struct video_device *vdev = &vin->vdev;
685 struct v4l2_subdev *sd = vin_to_source(vin);
686 int ret;
687
688 v4l2_set_subdev_hostdata(sd, vin);
689
690 vin->v4l2_dev.notify = rvin_notify;
691
692 ret = v4l2_subdev_call(sd, video, g_tvnorms, &vin->vdev.tvnorms);
693 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
694 return ret;
695
696 if (vin->vdev.tvnorms == 0) {
697 /* Disable the STD API if there are no tvnorms defined */
698 v4l2_disable_ioctl(&vin->vdev, VIDIOC_G_STD);
699 v4l2_disable_ioctl(&vin->vdev, VIDIOC_S_STD);
700 v4l2_disable_ioctl(&vin->vdev, VIDIOC_QUERYSTD);
701 v4l2_disable_ioctl(&vin->vdev, VIDIOC_ENUMSTD);
702 }
703
704 /* Add the controls */
705 /*
706 * Currently the subdev with the largest number of controls (13) is
707 * ov6550. So let's pick 16 as a hint for the control handler. Note
708 * that this is a hint only: too large and you waste some memory, too
709 * small and there is a (very) small performance hit when looking up
710 * controls in the internal hash.
711 */
712 ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
713 if (ret < 0)
714 return ret;
715
716 ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, sd->ctrl_handler, NULL);
717 if (ret < 0)
718 return ret;
719
720 /* video node */
721 vdev->fops = &rvin_fops;
722 vdev->v4l2_dev = &vin->v4l2_dev;
723 vdev->queue = &vin->queue;
724 strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
725 vdev->release = video_device_release_empty;
726 vdev->ioctl_ops = &rvin_ioctl_ops;
727 vdev->lock = &vin->lock;
728 vdev->ctrl_handler = &vin->ctrl_handler;
729 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
730 V4L2_CAP_READWRITE;
731
732 /* Try to improve our guess of a reasonable window format */
733 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
734 if (ret) {
735 vin_err(vin, "Failed to get initial format\n");
736 return ret;
737 }
738
739 /* Set default format */
740 vin->format.width = mf->width;
741 vin->format.height = mf->height;
742 vin->format.colorspace = mf->colorspace;
743 vin->format.field = mf->field;
744 vin->format.pixelformat = RVIN_DEFAULT_FORMAT;
745
746
747 /* Set initial crop and compose */
748 vin->crop.top = vin->crop.left = 0;
749 vin->crop.width = mf->width;
750 vin->crop.height = mf->height;
751
752 vin->compose.top = vin->compose.left = 0;
753 vin->compose.width = mf->width;
754 vin->compose.height = mf->height;
755
756 ret = video_register_device(&vin->vdev, VFL_TYPE_GRABBER, -1);
757 if (ret) {
758 vin_err(vin, "Failed to register video device\n");
759 return ret;
760 }
761
762 video_set_drvdata(&vin->vdev, vin);
763
764 v4l2_info(&vin->v4l2_dev, "Device registered as %s\n",
765 video_device_node_name(&vin->vdev));
766
767 return ret;
768}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
new file mode 100644
index 000000000000..544a3b362808
--- /dev/null
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -0,0 +1,163 @@
1/*
2 * Driver for Renesas R-Car VIN
3 *
4 * Copyright (C) 2016 Renesas Electronics Corp.
5 * Copyright (C) 2011-2013 Renesas Solutions Corp.
6 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7 * Copyright (C) 2008 Magnus Damm
8 *
9 * Based on the soc-camera rcar_vin driver
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#ifndef __RCAR_VIN__
18#define __RCAR_VIN__
19
20#include <media/v4l2-async.h>
21#include <media/v4l2-ctrls.h>
22#include <media/v4l2-dev.h>
23#include <media/v4l2-device.h>
24#include <media/videobuf2-v4l2.h>
25
26/* Number of HW buffers */
27#define HW_BUFFER_NUM 3
28
29/* Address alignment mask for HW buffers */
30#define HW_BUFFER_MASK 0x7f
31
32enum chip_id {
33 RCAR_GEN2,
34 RCAR_H1,
35 RCAR_M1,
36};
37
38/**
39 * STOPPED - No operation in progress
40 * RUNNING - Operation in progress have buffers
41 * STALLED - No operation in progress have no buffers
42 * STOPPING - Stopping operation
43 */
44enum rvin_dma_state {
45 STOPPED = 0,
46 RUNNING,
47 STALLED,
48 STOPPING,
49};
50
51/**
52 * struct rvin_source_fmt - Source information
53 * @code: Media bus format from source
54 * @width: Width from source
55 * @height: Height from source
56 */
57struct rvin_source_fmt {
58 u32 code;
59 u32 width;
60 u32 height;
61};
62
63/**
64 * struct rvin_video_format - Data format stored in memory
65 * @fourcc: Pixelformat
66 * @bpp: Bytes per pixel
67 */
68struct rvin_video_format {
69 u32 fourcc;
70 u8 bpp;
71};
72
73struct rvin_graph_entity {
74 struct device_node *node;
75 struct media_entity *entity;
76
77 struct v4l2_async_subdev asd;
78 struct v4l2_subdev *subdev;
79};
80
81/**
82 * struct rvin_dev - Renesas VIN device structure
83 * @dev: (OF) device
84 * @base: device I/O register space remapped to virtual memory
85 * @chip: type of VIN chip
86 * @mbus_cfg media bus configuration
87 *
88 * @vdev: V4L2 video device associated with VIN
89 * @v4l2_dev: V4L2 device
90 * @ctrl_handler: V4L2 control handler
91 * @notifier: V4L2 asynchronous subdevs notifier
92 * @entity: entity in the DT for subdevice
93 *
94 * @lock: protects @queue
95 * @queue: vb2 buffers queue
96 * @alloc_ctx: allocation context for the vb2 @queue
97 *
98 * @qlock: protects @queue_buf, @buf_list, @continuous, @sequence
99 * @state
100 * @queue_buf: Keeps track of buffers given to HW slot
101 * @buf_list: list of queued buffers
102 * @continuous: tracks if active operation is continuous or single mode
103 * @sequence: V4L2 buffers sequence number
104 * @state: keeps track of operation state
105 *
106 * @source: active format from the video source
107 * @format: active V4L2 pixel format
108 *
109 * @crop: active cropping
110 * @compose: active composing
111 */
112struct rvin_dev {
113 struct device *dev;
114 void __iomem *base;
115 enum chip_id chip;
116 struct v4l2_mbus_config mbus_cfg;
117
118 struct video_device vdev;
119 struct v4l2_device v4l2_dev;
120 struct v4l2_ctrl_handler ctrl_handler;
121 struct v4l2_async_notifier notifier;
122 struct rvin_graph_entity entity;
123
124 struct mutex lock;
125 struct vb2_queue queue;
126 struct vb2_alloc_ctx *alloc_ctx;
127
128 spinlock_t qlock;
129 struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];
130 struct list_head buf_list;
131 bool continuous;
132 unsigned int sequence;
133 enum rvin_dma_state state;
134
135 struct rvin_source_fmt source;
136 struct v4l2_pix_format format;
137
138 struct v4l2_rect crop;
139 struct v4l2_rect compose;
140};
141
142#define vin_to_source(vin) vin->entity.subdev
143
144/* Debug */
145#define vin_dbg(d, fmt, arg...) dev_dbg(d->dev, fmt, ##arg)
146#define vin_info(d, fmt, arg...) dev_info(d->dev, fmt, ##arg)
147#define vin_warn(d, fmt, arg...) dev_warn(d->dev, fmt, ##arg)
148#define vin_err(d, fmt, arg...) dev_err(d->dev, fmt, ##arg)
149
150int rvin_dma_probe(struct rvin_dev *vin, int irq);
151void rvin_dma_remove(struct rvin_dev *vin);
152
153int rvin_v4l2_probe(struct rvin_dev *vin);
154void rvin_v4l2_remove(struct rvin_dev *vin);
155
156const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
157
158/* Cropping, composing and scaling */
159void rvin_scale_try(struct rvin_dev *vin, struct v4l2_pix_format *pix,
160 u32 width, u32 height);
161void rvin_crop_scale_comp(struct rvin_dev *vin);
162
163#endif
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 612d1ea514f1..d3e3469db8de 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -681,6 +681,7 @@ static int g2d_probe(struct platform_device *pdev)
681 goto put_clk_gate; 681 goto put_clk_gate;
682 } 682 }
683 683
684 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
684 dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 685 dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
685 if (IS_ERR(dev->alloc_ctx)) { 686 if (IS_ERR(dev->alloc_ctx)) {
686 ret = PTR_ERR(dev->alloc_ctx); 687 ret = PTR_ERR(dev->alloc_ctx);
@@ -757,6 +758,7 @@ static int g2d_remove(struct platform_device *pdev)
757 video_unregister_device(dev->vfd); 758 video_unregister_device(dev->vfd);
758 v4l2_device_unregister(&dev->v4l2_dev); 759 v4l2_device_unregister(&dev->v4l2_dev);
759 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 760 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
761 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
760 clk_unprepare(dev->gate); 762 clk_unprepare(dev->gate);
761 clk_put(dev->gate); 763 clk_put(dev->gate);
762 clk_unprepare(dev->clk); 764 clk_unprepare(dev->clk);
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index caa19b408551..17bc94092864 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -2843,6 +2843,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev)
2843 goto device_register_rollback; 2843 goto device_register_rollback;
2844 } 2844 }
2845 2845
2846 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
2846 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 2847 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2847 if (IS_ERR(jpeg->alloc_ctx)) { 2848 if (IS_ERR(jpeg->alloc_ctx)) {
2848 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n"); 2849 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
@@ -2942,6 +2943,7 @@ static int s5p_jpeg_remove(struct platform_device *pdev)
2942 video_unregister_device(jpeg->vfd_decoder); 2943 video_unregister_device(jpeg->vfd_decoder);
2943 video_unregister_device(jpeg->vfd_encoder); 2944 video_unregister_device(jpeg->vfd_encoder);
2944 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx); 2945 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2946 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
2945 v4l2_m2m_release(jpeg->m2m_dev); 2947 v4l2_m2m_release(jpeg->m2m_dev);
2946 v4l2_device_unregister(&jpeg->v4l2_dev); 2948 v4l2_device_unregister(&jpeg->v4l2_dev);
2947 2949
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index b16466fe35ee..6ee620ee8cd5 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -22,6 +22,7 @@
22#include <media/v4l2-event.h> 22#include <media/v4l2-event.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_reserved_mem.h>
25#include <media/videobuf2-v4l2.h> 26#include <media/videobuf2-v4l2.h>
26#include "s5p_mfc_common.h" 27#include "s5p_mfc_common.h"
27#include "s5p_mfc_ctrl.h" 28#include "s5p_mfc_ctrl.h"
@@ -29,6 +30,7 @@
29#include "s5p_mfc_dec.h" 30#include "s5p_mfc_dec.h"
30#include "s5p_mfc_enc.h" 31#include "s5p_mfc_enc.h"
31#include "s5p_mfc_intr.h" 32#include "s5p_mfc_intr.h"
33#include "s5p_mfc_iommu.h"
32#include "s5p_mfc_opr.h" 34#include "s5p_mfc_opr.h"
33#include "s5p_mfc_cmd.h" 35#include "s5p_mfc_cmd.h"
34#include "s5p_mfc_pm.h" 36#include "s5p_mfc_pm.h"
@@ -1043,55 +1045,94 @@ static const struct v4l2_file_operations s5p_mfc_fops = {
1043 .mmap = s5p_mfc_mmap, 1045 .mmap = s5p_mfc_mmap,
1044}; 1046};
1045 1047
1046static int match_child(struct device *dev, void *data) 1048/* DMA memory related helper functions */
1049static void s5p_mfc_memdev_release(struct device *dev)
1047{ 1050{
1048 if (!dev_name(dev)) 1051 of_reserved_mem_device_release(dev);
1049 return 0;
1050 return !strcmp(dev_name(dev), (char *)data);
1051} 1052}
1052 1053
1053static void *mfc_get_drv_data(struct platform_device *pdev); 1054static struct device *s5p_mfc_alloc_memdev(struct device *dev,
1054 1055 const char *name, unsigned int idx)
1055static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
1056{ 1056{
1057 unsigned int mem_info[2] = { }; 1057 struct device *child;
1058 int ret;
1058 1059
1059 dev->mem_dev_l = devm_kzalloc(&dev->plat_dev->dev, 1060 child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL);
1060 sizeof(struct device), GFP_KERNEL); 1061 if (!child)
1061 if (!dev->mem_dev_l) { 1062 return NULL;
1062 mfc_err("Not enough memory\n"); 1063
1063 return -ENOMEM; 1064 device_initialize(child);
1064 } 1065 dev_set_name(child, "%s:%s", dev_name(dev), name);
1065 device_initialize(dev->mem_dev_l); 1066 child->parent = dev;
1066 of_property_read_u32_array(dev->plat_dev->dev.of_node, 1067 child->bus = dev->bus;
1067 "samsung,mfc-l", mem_info, 2); 1068 child->coherent_dma_mask = dev->coherent_dma_mask;
1068 if (dma_declare_coherent_memory(dev->mem_dev_l, mem_info[0], 1069 child->dma_mask = dev->dma_mask;
1069 mem_info[0], mem_info[1], 1070 child->release = s5p_mfc_memdev_release;
1070 DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) { 1071
1071 mfc_err("Failed to declare coherent memory for\n" 1072 if (device_add(child) == 0) {
1072 "MFC device\n"); 1073 ret = of_reserved_mem_device_init_by_idx(child, dev->of_node,
1073 return -ENOMEM; 1074 idx);
1075 if (ret == 0)
1076 return child;
1074 } 1077 }
1075 1078
1076 dev->mem_dev_r = devm_kzalloc(&dev->plat_dev->dev, 1079 put_device(child);
1077 sizeof(struct device), GFP_KERNEL); 1080 return NULL;
1078 if (!dev->mem_dev_r) { 1081}
1079 mfc_err("Not enough memory\n"); 1082
1080 return -ENOMEM; 1083static int s5p_mfc_configure_dma_memory(struct s5p_mfc_dev *mfc_dev)
1084{
1085 struct device *dev = &mfc_dev->plat_dev->dev;
1086
1087 /*
1088 * When IOMMU is available, we cannot use the default configuration,
1089 * because of MFC firmware requirements: address space limited to
1090 * 256M and non-zero default start address.
1091 * This is still simplified, not optimal configuration, but for now
1092 * IOMMU core doesn't allow to configure device's IOMMUs channel
1093 * separately.
1094 */
1095 if (exynos_is_iommu_available(dev)) {
1096 int ret = exynos_configure_iommu(dev, S5P_MFC_IOMMU_DMA_BASE,
1097 S5P_MFC_IOMMU_DMA_SIZE);
1098 if (ret == 0)
1099 mfc_dev->mem_dev_l = mfc_dev->mem_dev_r = dev;
1100 return ret;
1081 } 1101 }
1082 device_initialize(dev->mem_dev_r); 1102
1083 of_property_read_u32_array(dev->plat_dev->dev.of_node, 1103 /*
1084 "samsung,mfc-r", mem_info, 2); 1104 * Create and initialize virtual devices for accessing
1085 if (dma_declare_coherent_memory(dev->mem_dev_r, mem_info[0], 1105 * reserved memory regions.
1086 mem_info[0], mem_info[1], 1106 */
1087 DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0) { 1107 mfc_dev->mem_dev_l = s5p_mfc_alloc_memdev(dev, "left",
1088 pr_err("Failed to declare coherent memory for\n" 1108 MFC_BANK1_ALLOC_CTX);
1089 "MFC device\n"); 1109 if (!mfc_dev->mem_dev_l)
1090 return -ENOMEM; 1110 return -ENODEV;
1111 mfc_dev->mem_dev_r = s5p_mfc_alloc_memdev(dev, "right",
1112 MFC_BANK2_ALLOC_CTX);
1113 if (!mfc_dev->mem_dev_r) {
1114 device_unregister(mfc_dev->mem_dev_l);
1115 return -ENODEV;
1091 } 1116 }
1117
1092 return 0; 1118 return 0;
1093} 1119}
1094 1120
1121static void s5p_mfc_unconfigure_dma_memory(struct s5p_mfc_dev *mfc_dev)
1122{
1123 struct device *dev = &mfc_dev->plat_dev->dev;
1124
1125 if (exynos_is_iommu_available(dev)) {
1126 exynos_unconfigure_iommu(dev);
1127 return;
1128 }
1129
1130 device_unregister(mfc_dev->mem_dev_l);
1131 device_unregister(mfc_dev->mem_dev_r);
1132}
1133
1134static void *mfc_get_drv_data(struct platform_device *pdev);
1135
1095/* MFC probe function */ 1136/* MFC probe function */
1096static int s5p_mfc_probe(struct platform_device *pdev) 1137static int s5p_mfc_probe(struct platform_device *pdev)
1097{ 1138{
@@ -1117,12 +1158,6 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1117 1158
1118 dev->variant = mfc_get_drv_data(pdev); 1159 dev->variant = mfc_get_drv_data(pdev);
1119 1160
1120 ret = s5p_mfc_init_pm(dev);
1121 if (ret < 0) {
1122 dev_err(&pdev->dev, "failed to get mfc clock source\n");
1123 return ret;
1124 }
1125
1126 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1161 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1127 1162
1128 dev->regs_base = devm_ioremap_resource(&pdev->dev, res); 1163 dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
@@ -1143,32 +1178,25 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1143 goto err_res; 1178 goto err_res;
1144 } 1179 }
1145 1180
1146 if (pdev->dev.of_node) { 1181 ret = s5p_mfc_configure_dma_memory(dev);
1147 ret = s5p_mfc_alloc_memdevs(dev); 1182 if (ret < 0) {
1148 if (ret < 0) 1183 dev_err(&pdev->dev, "failed to configure DMA memory\n");
1149 goto err_res; 1184 return ret;
1150 } else {
1151 dev->mem_dev_l = device_find_child(&dev->plat_dev->dev,
1152 "s5p-mfc-l", match_child);
1153 if (!dev->mem_dev_l) {
1154 mfc_err("Mem child (L) device get failed\n");
1155 ret = -ENODEV;
1156 goto err_res;
1157 }
1158 dev->mem_dev_r = device_find_child(&dev->plat_dev->dev,
1159 "s5p-mfc-r", match_child);
1160 if (!dev->mem_dev_r) {
1161 mfc_err("Mem child (R) device get failed\n");
1162 ret = -ENODEV;
1163 goto err_res;
1164 }
1165 } 1185 }
1166 1186
1187 ret = s5p_mfc_init_pm(dev);
1188 if (ret < 0) {
1189 dev_err(&pdev->dev, "failed to get mfc clock source\n");
1190 return ret;
1191 }
1192
1193 vb2_dma_contig_set_max_seg_size(dev->mem_dev_l, DMA_BIT_MASK(32));
1167 dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l); 1194 dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
1168 if (IS_ERR(dev->alloc_ctx[0])) { 1195 if (IS_ERR(dev->alloc_ctx[0])) {
1169 ret = PTR_ERR(dev->alloc_ctx[0]); 1196 ret = PTR_ERR(dev->alloc_ctx[0]);
1170 goto err_res; 1197 goto err_res;
1171 } 1198 }
1199 vb2_dma_contig_set_max_seg_size(dev->mem_dev_r, DMA_BIT_MASK(32));
1172 dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r); 1200 dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r);
1173 if (IS_ERR(dev->alloc_ctx[1])) { 1201 if (IS_ERR(dev->alloc_ctx[1])) {
1174 ret = PTR_ERR(dev->alloc_ctx[1]); 1202 ret = PTR_ERR(dev->alloc_ctx[1]);
@@ -1201,14 +1229,6 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1201 vfd->vfl_dir = VFL_DIR_M2M; 1229 vfd->vfl_dir = VFL_DIR_M2M;
1202 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME); 1230 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME);
1203 dev->vfd_dec = vfd; 1231 dev->vfd_dec = vfd;
1204 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1205 if (ret) {
1206 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1207 video_device_release(vfd);
1208 goto err_dec_reg;
1209 }
1210 v4l2_info(&dev->v4l2_dev,
1211 "decoder registered as /dev/video%d\n", vfd->num);
1212 video_set_drvdata(vfd, dev); 1232 video_set_drvdata(vfd, dev);
1213 1233
1214 /* encoder */ 1234 /* encoder */
@@ -1226,14 +1246,6 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1226 vfd->vfl_dir = VFL_DIR_M2M; 1246 vfd->vfl_dir = VFL_DIR_M2M;
1227 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME); 1247 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
1228 dev->vfd_enc = vfd; 1248 dev->vfd_enc = vfd;
1229 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1230 if (ret) {
1231 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1232 video_device_release(vfd);
1233 goto err_enc_reg;
1234 }
1235 v4l2_info(&dev->v4l2_dev,
1236 "encoder registered as /dev/video%d\n", vfd->num);
1237 video_set_drvdata(vfd, dev); 1249 video_set_drvdata(vfd, dev);
1238 platform_set_drvdata(pdev, dev); 1250 platform_set_drvdata(pdev, dev);
1239 1251
@@ -1250,15 +1262,34 @@ static int s5p_mfc_probe(struct platform_device *pdev)
1250 s5p_mfc_init_hw_cmds(dev); 1262 s5p_mfc_init_hw_cmds(dev);
1251 s5p_mfc_init_regs(dev); 1263 s5p_mfc_init_regs(dev);
1252 1264
1265 /* Register decoder and encoder */
1266 ret = video_register_device(dev->vfd_dec, VFL_TYPE_GRABBER, 0);
1267 if (ret) {
1268 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1269 video_device_release(dev->vfd_dec);
1270 goto err_dec_reg;
1271 }
1272 v4l2_info(&dev->v4l2_dev,
1273 "decoder registered as /dev/video%d\n", dev->vfd_dec->num);
1274
1275 ret = video_register_device(dev->vfd_enc, VFL_TYPE_GRABBER, 0);
1276 if (ret) {
1277 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1278 video_device_release(dev->vfd_enc);
1279 goto err_enc_reg;
1280 }
1281 v4l2_info(&dev->v4l2_dev,
1282 "encoder registered as /dev/video%d\n", dev->vfd_enc->num);
1283
1253 pr_debug("%s--\n", __func__); 1284 pr_debug("%s--\n", __func__);
1254 return 0; 1285 return 0;
1255 1286
1256/* Deinit MFC if probe had failed */ 1287/* Deinit MFC if probe had failed */
1257err_enc_reg: 1288err_enc_reg:
1258 video_device_release(dev->vfd_enc);
1259err_enc_alloc:
1260 video_unregister_device(dev->vfd_dec); 1289 video_unregister_device(dev->vfd_dec);
1261err_dec_reg: 1290err_dec_reg:
1291 video_device_release(dev->vfd_enc);
1292err_enc_alloc:
1262 video_device_release(dev->vfd_dec); 1293 video_device_release(dev->vfd_dec);
1263err_dec_alloc: 1294err_dec_alloc:
1264 v4l2_device_unregister(&dev->v4l2_dev); 1295 v4l2_device_unregister(&dev->v4l2_dev);
@@ -1293,10 +1324,9 @@ static int s5p_mfc_remove(struct platform_device *pdev)
1293 s5p_mfc_release_firmware(dev); 1324 s5p_mfc_release_firmware(dev);
1294 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]); 1325 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
1295 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]); 1326 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
1296 if (pdev->dev.of_node) { 1327 s5p_mfc_unconfigure_dma_memory(dev);
1297 put_device(dev->mem_dev_l); 1328 vb2_dma_contig_clear_max_seg_size(dev->mem_dev_l);
1298 put_device(dev->mem_dev_r); 1329 vb2_dma_contig_clear_max_seg_size(dev->mem_dev_r);
1299 }
1300 1330
1301 s5p_mfc_final_pm(dev); 1331 s5p_mfc_final_pm(dev);
1302 return 0; 1332 return 0;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index f2d6376ce618..a01a373a4c4f 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -474,7 +474,6 @@ static int reqbufs_output(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx,
474 ret = vb2_reqbufs(&ctx->vq_src, reqbufs); 474 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
475 if (ret) 475 if (ret)
476 goto out; 476 goto out;
477 s5p_mfc_close_mfc_inst(dev, ctx);
478 ctx->src_bufs_cnt = 0; 477 ctx->src_bufs_cnt = 0;
479 ctx->output_state = QUEUE_FREE; 478 ctx->output_state = QUEUE_FREE;
480 } else if (ctx->output_state == QUEUE_FREE) { 479 } else if (ctx->output_state == QUEUE_FREE) {
@@ -573,7 +572,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
573 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); 572 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
574 573
575 if (reqbufs->memory != V4L2_MEMORY_MMAP) { 574 if (reqbufs->memory != V4L2_MEMORY_MMAP) {
576 mfc_err("Only V4L2_MEMORY_MAP is supported\n"); 575 mfc_err("Only V4L2_MEMORY_MMAP is supported\n");
577 return -EINVAL; 576 return -EINVAL;
578 } 577 }
579 578
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 034b5c1d35a1..2f76aba4cc78 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -1043,10 +1043,6 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1043 mfc_err("failed to try output format\n"); 1043 mfc_err("failed to try output format\n");
1044 return -EINVAL; 1044 return -EINVAL;
1045 } 1045 }
1046 if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
1047 mfc_err("must be set encoding output size\n");
1048 return -EINVAL;
1049 }
1050 if ((dev->variant->version_bit & fmt->versions) == 0) { 1046 if ((dev->variant->version_bit & fmt->versions) == 0) {
1051 mfc_err("Unsupported format by this MFC version.\n"); 1047 mfc_err("Unsupported format by this MFC version.\n");
1052 return -EINVAL; 1048 return -EINVAL;
@@ -1060,11 +1056,6 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
1060 mfc_err("failed to try output format\n"); 1056 mfc_err("failed to try output format\n");
1061 return -EINVAL; 1057 return -EINVAL;
1062 } 1058 }
1063
1064 if (fmt->num_planes != pix_fmt_mp->num_planes) {
1065 mfc_err("failed to try output format\n");
1066 return -EINVAL;
1067 }
1068 if ((dev->variant->version_bit & fmt->versions) == 0) { 1059 if ((dev->variant->version_bit & fmt->versions) == 0) {
1069 mfc_err("Unsupported format by this MFC version.\n"); 1060 mfc_err("Unsupported format by this MFC version.\n");
1070 return -EINVAL; 1061 return -EINVAL;
@@ -1144,7 +1135,10 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1144 return -EINVAL; 1135 return -EINVAL;
1145 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1136 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1146 if (reqbufs->count == 0) { 1137 if (reqbufs->count == 0) {
1138 mfc_debug(2, "Freeing buffers\n");
1147 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); 1139 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
1140 s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers,
1141 ctx);
1148 ctx->capture_state = QUEUE_FREE; 1142 ctx->capture_state = QUEUE_FREE;
1149 return ret; 1143 return ret;
1150 } 1144 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
new file mode 100644
index 000000000000..6962132ae8fa
--- /dev/null
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_iommu.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2015 Samsung Electronics Co.Ltd
3 * Authors: Marek Szyprowski <m.szyprowski@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef S5P_MFC_IOMMU_H_
12#define S5P_MFC_IOMMU_H_
13
14#define S5P_MFC_IOMMU_DMA_BASE 0x20000000lu
15#define S5P_MFC_IOMMU_DMA_SIZE SZ_256M
16
17#if defined(CONFIG_EXYNOS_IOMMU) && defined(CONFIG_ARM_DMA_USE_IOMMU)
18
19#include <asm/dma-iommu.h>
20
21static inline bool exynos_is_iommu_available(struct device *dev)
22{
23 return dev->archdata.iommu != NULL;
24}
25
26static inline void exynos_unconfigure_iommu(struct device *dev)
27{
28 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
29
30 arm_iommu_detach_device(dev);
31 arm_iommu_release_mapping(mapping);
32}
33
34static inline int exynos_configure_iommu(struct device *dev,
35 unsigned int base, unsigned int size)
36{
37 struct dma_iommu_mapping *mapping = NULL;
38 int ret;
39
40 /* Disable the default mapping created by device core */
41 if (to_dma_iommu_mapping(dev))
42 exynos_unconfigure_iommu(dev);
43
44 mapping = arm_iommu_create_mapping(dev->bus, base, size);
45 if (IS_ERR(mapping)) {
46 pr_warn("Failed to create IOMMU mapping for device %s\n",
47 dev_name(dev));
48 return PTR_ERR(mapping);
49 }
50
51 ret = arm_iommu_attach_device(dev, mapping);
52 if (ret) {
53 pr_warn("Failed to attached device %s to IOMMU_mapping\n",
54 dev_name(dev));
55 arm_iommu_release_mapping(mapping);
56 return ret;
57 }
58
59 return 0;
60}
61
62#else
63
64static inline bool exynos_is_iommu_available(struct device *dev)
65{
66 return false;
67}
68
69static inline int exynos_configure_iommu(struct device *dev,
70 unsigned int base, unsigned int size)
71{
72 return -ENOSYS;
73}
74
75static inline void exynos_unconfigure_iommu(struct device *dev) { }
76
77#endif
78
79#endif /* S5P_MFC_IOMMU_H_ */
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
index 5f97a3398c11..9f7522104333 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
@@ -54,6 +54,7 @@ int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
54 pm->clock = clk_get(&dev->plat_dev->dev, MFC_SCLK_NAME); 54 pm->clock = clk_get(&dev->plat_dev->dev, MFC_SCLK_NAME);
55 if (IS_ERR(pm->clock)) { 55 if (IS_ERR(pm->clock)) {
56 mfc_info("Failed to get MFC special clock control\n"); 56 mfc_info("Failed to get MFC special clock control\n");
57 pm->clock = NULL;
57 } else { 58 } else {
58 clk_set_rate(pm->clock, MFC_SCLK_RATE); 59 clk_set_rate(pm->clock, MFC_SCLK_RATE);
59 ret = clk_prepare_enable(pm->clock); 60 ret = clk_prepare_enable(pm->clock);
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index 7ab5578a0405..123d27107f60 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -80,6 +80,7 @@ int mxr_acquire_video(struct mxr_device *mdev,
80 goto fail; 80 goto fail;
81 } 81 }
82 82
83 vb2_dma_contig_set_max_seg_size(mdev->dev, DMA_BIT_MASK(32));
83 mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev); 84 mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
84 if (IS_ERR(mdev->alloc_ctx)) { 85 if (IS_ERR(mdev->alloc_ctx)) {
85 mxr_err(mdev, "could not acquire vb2 allocator\n"); 86 mxr_err(mdev, "could not acquire vb2 allocator\n");
@@ -152,6 +153,7 @@ void mxr_release_video(struct mxr_device *mdev)
152 kfree(mdev->output[i]); 153 kfree(mdev->output[i]);
153 154
154 vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx); 155 vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
156 vb2_dma_contig_clear_max_seg_size(mdev->dev);
155 v4l2_device_unregister(&mdev->v4l2_dev); 157 v4l2_device_unregister(&mdev->v4l2_dev);
156} 158}
157 159
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index 83029a4854ae..39f66414f621 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -25,8 +25,8 @@ config VIDEO_PXA27x
25 ---help--- 25 ---help---
26 This is a v4l2 driver for the PXA27x Quick Capture Interface 26 This is a v4l2 driver for the PXA27x Quick Capture Interface
27 27
28config VIDEO_RCAR_VIN 28config VIDEO_RCAR_VIN_OLD
29 tristate "R-Car Video Input (VIN) support" 29 tristate "R-Car Video Input (VIN) support (DEPRECATED)"
30 depends on VIDEO_DEV && SOC_CAMERA 30 depends on VIDEO_DEV && SOC_CAMERA
31 depends on ARCH_RENESAS || COMPILE_TEST 31 depends on ARCH_RENESAS || COMPILE_TEST
32 depends on HAS_DMA 32 depends on HAS_DMA
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
index 7ee71ae231c7..7703cb7ce456 100644
--- a/drivers/media/platform/soc_camera/Makefile
+++ b/drivers/media/platform/soc_camera/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
10obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 10obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
11obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 11obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
12obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o 12obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
13obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar_vin.o 13obj-$(CONFIG_VIDEO_RCAR_VIN_OLD) += rcar_vin.o
diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 95b3ac2ea7ef..1328e1bd2143 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,7 +1,8 @@
1vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_pipe.o 1vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_pipe.o
2vsp1-y += vsp1_dl.o vsp1_drm.o vsp1_video.o 2vsp1-y += vsp1_dl.o vsp1_drm.o vsp1_video.o
3vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o 3vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
4vsp1-y += vsp1_hsit.o vsp1_lif.o vsp1_lut.o 4vsp1-y += vsp1_clu.o vsp1_hsit.o vsp1_lut.o
5vsp1-y += vsp1_bru.o vsp1_sru.o vsp1_uds.o 5vsp1-y += vsp1_bru.o vsp1_sru.o vsp1_uds.o
6vsp1-y += vsp1_lif.o
6 7
7obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o 8obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 46738b6c5f72..06a2ec7e5ad4 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -25,11 +25,13 @@
25 25
26struct clk; 26struct clk;
27struct device; 27struct device;
28struct rcar_fcp_device;
28 29
29struct vsp1_drm; 30struct vsp1_drm;
30struct vsp1_entity; 31struct vsp1_entity;
31struct vsp1_platform_data; 32struct vsp1_platform_data;
32struct vsp1_bru; 33struct vsp1_bru;
34struct vsp1_clu;
33struct vsp1_hsit; 35struct vsp1_hsit;
34struct vsp1_lif; 36struct vsp1_lif;
35struct vsp1_lut; 37struct vsp1_lut;
@@ -45,6 +47,9 @@ struct vsp1_uds;
45#define VSP1_HAS_LUT (1 << 1) 47#define VSP1_HAS_LUT (1 << 1)
46#define VSP1_HAS_SRU (1 << 2) 48#define VSP1_HAS_SRU (1 << 2)
47#define VSP1_HAS_BRU (1 << 3) 49#define VSP1_HAS_BRU (1 << 3)
50#define VSP1_HAS_CLU (1 << 4)
51#define VSP1_HAS_WPF_VFLIP (1 << 5)
52#define VSP1_HAS_WPF_HFLIP (1 << 6)
48 53
49struct vsp1_device_info { 54struct vsp1_device_info {
50 u32 version; 55 u32 version;
@@ -62,12 +67,10 @@ struct vsp1_device {
62 const struct vsp1_device_info *info; 67 const struct vsp1_device_info *info;
63 68
64 void __iomem *mmio; 69 void __iomem *mmio;
65 struct clk *clock; 70 struct rcar_fcp_device *fcp;
66
67 struct mutex lock;
68 int ref_count;
69 71
70 struct vsp1_bru *bru; 72 struct vsp1_bru *bru;
73 struct vsp1_clu *clu;
71 struct vsp1_hsit *hsi; 74 struct vsp1_hsit *hsi;
72 struct vsp1_hsit *hst; 75 struct vsp1_hsit *hst;
73 struct vsp1_lif *lif; 76 struct vsp1_lif *lif;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index b1068c018011..8268b87727a7 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -249,7 +249,7 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
249 return 0; 249 return 0;
250} 250}
251 251
252static struct v4l2_subdev_pad_ops bru_pad_ops = { 252static const struct v4l2_subdev_pad_ops bru_pad_ops = {
253 .init_cfg = vsp1_entity_init_cfg, 253 .init_cfg = vsp1_entity_init_cfg,
254 .enum_mbus_code = bru_enum_mbus_code, 254 .enum_mbus_code = bru_enum_mbus_code,
255 .enum_frame_size = bru_enum_frame_size, 255 .enum_frame_size = bru_enum_frame_size,
@@ -259,7 +259,7 @@ static struct v4l2_subdev_pad_ops bru_pad_ops = {
259 .set_selection = bru_set_selection, 259 .set_selection = bru_set_selection,
260}; 260};
261 261
262static struct v4l2_subdev_ops bru_ops = { 262static const struct v4l2_subdev_ops bru_ops = {
263 .pad = &bru_pad_ops, 263 .pad = &bru_pad_ops,
264}; 264};
265 265
@@ -269,13 +269,16 @@ static struct v4l2_subdev_ops bru_ops = {
269 269
270static void bru_configure(struct vsp1_entity *entity, 270static void bru_configure(struct vsp1_entity *entity,
271 struct vsp1_pipeline *pipe, 271 struct vsp1_pipeline *pipe,
272 struct vsp1_dl_list *dl) 272 struct vsp1_dl_list *dl, bool full)
273{ 273{
274 struct vsp1_bru *bru = to_bru(&entity->subdev); 274 struct vsp1_bru *bru = to_bru(&entity->subdev);
275 struct v4l2_mbus_framefmt *format; 275 struct v4l2_mbus_framefmt *format;
276 unsigned int flags; 276 unsigned int flags;
277 unsigned int i; 277 unsigned int i;
278 278
279 if (!full)
280 return;
281
279 format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config, 282 format = vsp1_entity_get_pad_format(&bru->entity, bru->entity.config,
280 bru->entity.source_pad); 283 bru->entity.source_pad);
281 284
@@ -390,7 +393,8 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
390 bru->entity.type = VSP1_ENTITY_BRU; 393 bru->entity.type = VSP1_ENTITY_BRU;
391 394
392 ret = vsp1_entity_init(vsp1, &bru->entity, "bru", 395 ret = vsp1_entity_init(vsp1, &bru->entity, "bru",
393 vsp1->info->num_bru_inputs + 1, &bru_ops); 396 vsp1->info->num_bru_inputs + 1, &bru_ops,
397 MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
394 if (ret < 0) 398 if (ret < 0)
395 return ERR_PTR(ret); 399 return ERR_PTR(ret);
396 400
diff --git a/drivers/media/platform/vsp1/vsp1_clu.c b/drivers/media/platform/vsp1/vsp1_clu.c
new file mode 100644
index 000000000000..b63d2dbe5ea3
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_clu.c
@@ -0,0 +1,292 @@
1/*
2 * vsp1_clu.c -- R-Car VSP1 Cubic Look-Up Table
3 *
4 * Copyright (C) 2015-2016 Renesas Electronics Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/slab.h>
16
17#include <media/v4l2-subdev.h>
18
19#include "vsp1.h"
20#include "vsp1_clu.h"
21#include "vsp1_dl.h"
22
23#define CLU_MIN_SIZE 4U
24#define CLU_MAX_SIZE 8190U
25
26/* -----------------------------------------------------------------------------
27 * Device Access
28 */
29
30static inline void vsp1_clu_write(struct vsp1_clu *clu, struct vsp1_dl_list *dl,
31 u32 reg, u32 data)
32{
33 vsp1_dl_list_write(dl, reg, data);
34}
35
36/* -----------------------------------------------------------------------------
37 * Controls
38 */
39
40#define V4L2_CID_VSP1_CLU_TABLE (V4L2_CID_USER_BASE | 0x1001)
41#define V4L2_CID_VSP1_CLU_MODE (V4L2_CID_USER_BASE | 0x1002)
42#define V4L2_CID_VSP1_CLU_MODE_2D 0
43#define V4L2_CID_VSP1_CLU_MODE_3D 1
44
45static int clu_set_table(struct vsp1_clu *clu, struct v4l2_ctrl *ctrl)
46{
47 struct vsp1_dl_body *dlb;
48 unsigned int i;
49
50 dlb = vsp1_dl_fragment_alloc(clu->entity.vsp1, 1 + 17 * 17 * 17);
51 if (!dlb)
52 return -ENOMEM;
53
54 vsp1_dl_fragment_write(dlb, VI6_CLU_ADDR, 0);
55 for (i = 0; i < 17 * 17 * 17; ++i)
56 vsp1_dl_fragment_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]);
57
58 spin_lock_irq(&clu->lock);
59 swap(clu->clu, dlb);
60 spin_unlock_irq(&clu->lock);
61
62 vsp1_dl_fragment_free(dlb);
63 return 0;
64}
65
66static int clu_s_ctrl(struct v4l2_ctrl *ctrl)
67{
68 struct vsp1_clu *clu =
69 container_of(ctrl->handler, struct vsp1_clu, ctrls);
70
71 switch (ctrl->id) {
72 case V4L2_CID_VSP1_CLU_TABLE:
73 clu_set_table(clu, ctrl);
74 break;
75
76 case V4L2_CID_VSP1_CLU_MODE:
77 clu->mode = ctrl->val;
78 break;
79 }
80
81 return 0;
82}
83
84static const struct v4l2_ctrl_ops clu_ctrl_ops = {
85 .s_ctrl = clu_s_ctrl,
86};
87
88static const struct v4l2_ctrl_config clu_table_control = {
89 .ops = &clu_ctrl_ops,
90 .id = V4L2_CID_VSP1_CLU_TABLE,
91 .name = "Look-Up Table",
92 .type = V4L2_CTRL_TYPE_U32,
93 .min = 0x00000000,
94 .max = 0x00ffffff,
95 .step = 1,
96 .def = 0,
97 .dims = { 17, 17, 17 },
98};
99
100static const char * const clu_mode_menu[] = {
101 "2D",
102 "3D",
103 NULL,
104};
105
106static const struct v4l2_ctrl_config clu_mode_control = {
107 .ops = &clu_ctrl_ops,
108 .id = V4L2_CID_VSP1_CLU_MODE,
109 .name = "Mode",
110 .type = V4L2_CTRL_TYPE_MENU,
111 .min = 0,
112 .max = 1,
113 .def = 1,
114 .qmenu = clu_mode_menu,
115};
116
117/* -----------------------------------------------------------------------------
118 * V4L2 Subdevice Pad Operations
119 */
120
121static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
122 struct v4l2_subdev_pad_config *cfg,
123 struct v4l2_subdev_mbus_code_enum *code)
124{
125 static const unsigned int codes[] = {
126 MEDIA_BUS_FMT_ARGB8888_1X32,
127 MEDIA_BUS_FMT_AHSV8888_1X32,
128 MEDIA_BUS_FMT_AYUV8_1X32,
129 };
130
131 return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
132 ARRAY_SIZE(codes));
133}
134
135static int clu_enum_frame_size(struct v4l2_subdev *subdev,
136 struct v4l2_subdev_pad_config *cfg,
137 struct v4l2_subdev_frame_size_enum *fse)
138{
139 return vsp1_subdev_enum_frame_size(subdev, cfg, fse, CLU_MIN_SIZE,
140 CLU_MIN_SIZE, CLU_MAX_SIZE,
141 CLU_MAX_SIZE);
142}
143
144static int clu_set_format(struct v4l2_subdev *subdev,
145 struct v4l2_subdev_pad_config *cfg,
146 struct v4l2_subdev_format *fmt)
147{
148 struct vsp1_clu *clu = to_clu(subdev);
149 struct v4l2_subdev_pad_config *config;
150 struct v4l2_mbus_framefmt *format;
151
152 config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
153 if (!config)
154 return -EINVAL;
155
156 /* Default to YUV if the requested format is not supported. */
157 if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
158 fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
159 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
160 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
161
162 format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);
163
164 if (fmt->pad == CLU_PAD_SOURCE) {
165 /* The CLU output format can't be modified. */
166 fmt->format = *format;
167 return 0;
168 }
169
170 format->code = fmt->format.code;
171 format->width = clamp_t(unsigned int, fmt->format.width,
172 CLU_MIN_SIZE, CLU_MAX_SIZE);
173 format->height = clamp_t(unsigned int, fmt->format.height,
174 CLU_MIN_SIZE, CLU_MAX_SIZE);
175 format->field = V4L2_FIELD_NONE;
176 format->colorspace = V4L2_COLORSPACE_SRGB;
177
178 fmt->format = *format;
179
180 /* Propagate the format to the source pad. */
181 format = vsp1_entity_get_pad_format(&clu->entity, config,
182 CLU_PAD_SOURCE);
183 *format = fmt->format;
184
185 return 0;
186}
187
188/* -----------------------------------------------------------------------------
189 * V4L2 Subdevice Operations
190 */
191
192static const struct v4l2_subdev_pad_ops clu_pad_ops = {
193 .init_cfg = vsp1_entity_init_cfg,
194 .enum_mbus_code = clu_enum_mbus_code,
195 .enum_frame_size = clu_enum_frame_size,
196 .get_fmt = vsp1_subdev_get_pad_format,
197 .set_fmt = clu_set_format,
198};
199
200static const struct v4l2_subdev_ops clu_ops = {
201 .pad = &clu_pad_ops,
202};
203
204/* -----------------------------------------------------------------------------
205 * VSP1 Entity Operations
206 */
207
208static void clu_configure(struct vsp1_entity *entity,
209 struct vsp1_pipeline *pipe,
210 struct vsp1_dl_list *dl, bool full)
211{
212 struct vsp1_clu *clu = to_clu(&entity->subdev);
213 struct vsp1_dl_body *dlb;
214 unsigned long flags;
215 u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN;
216
217 /* The format can't be changed during streaming, only verify it at
218 * stream start and store the information internally for future partial
219 * reconfiguration calls.
220 */
221 if (full) {
222 struct v4l2_mbus_framefmt *format;
223
224 format = vsp1_entity_get_pad_format(&clu->entity,
225 clu->entity.config,
226 CLU_PAD_SINK);
227 clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32;
228 return;
229 }
230
231 /* 2D mode can only be used with the YCbCr pixel encoding. */
232 if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode)
233 ctrl |= VI6_CLU_CTRL_AX1I_2D | VI6_CLU_CTRL_AX2I_2D
234 | VI6_CLU_CTRL_OS0_2D | VI6_CLU_CTRL_OS1_2D
235 | VI6_CLU_CTRL_OS2_2D | VI6_CLU_CTRL_M2D;
236
237 vsp1_clu_write(clu, dl, VI6_CLU_CTRL, ctrl);
238
239 spin_lock_irqsave(&clu->lock, flags);
240 dlb = clu->clu;
241 clu->clu = NULL;
242 spin_unlock_irqrestore(&clu->lock, flags);
243
244 if (dlb)
245 vsp1_dl_list_add_fragment(dl, dlb);
246}
247
248static const struct vsp1_entity_operations clu_entity_ops = {
249 .configure = clu_configure,
250};
251
252/* -----------------------------------------------------------------------------
253 * Initialization and Cleanup
254 */
255
256struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1)
257{
258 struct vsp1_clu *clu;
259 int ret;
260
261 clu = devm_kzalloc(vsp1->dev, sizeof(*clu), GFP_KERNEL);
262 if (clu == NULL)
263 return ERR_PTR(-ENOMEM);
264
265 spin_lock_init(&clu->lock);
266
267 clu->entity.ops = &clu_entity_ops;
268 clu->entity.type = VSP1_ENTITY_CLU;
269
270 ret = vsp1_entity_init(vsp1, &clu->entity, "clu", 2, &clu_ops,
271 MEDIA_ENT_F_PROC_VIDEO_LUT);
272 if (ret < 0)
273 return ERR_PTR(ret);
274
275 /* Initialize the control handler. */
276 v4l2_ctrl_handler_init(&clu->ctrls, 2);
277 v4l2_ctrl_new_custom(&clu->ctrls, &clu_table_control, NULL);
278 v4l2_ctrl_new_custom(&clu->ctrls, &clu_mode_control, NULL);
279
280 clu->entity.subdev.ctrl_handler = &clu->ctrls;
281
282 if (clu->ctrls.error) {
283 dev_err(vsp1->dev, "clu: failed to initialize controls\n");
284 ret = clu->ctrls.error;
285 vsp1_entity_destroy(&clu->entity);
286 return ERR_PTR(ret);
287 }
288
289 v4l2_ctrl_handler_setup(&clu->ctrls);
290
291 return clu;
292}
diff --git a/drivers/media/platform/vsp1/vsp1_clu.h b/drivers/media/platform/vsp1/vsp1_clu.h
new file mode 100644
index 000000000000..036e0a2f1a42
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_clu.h
@@ -0,0 +1,48 @@
1/*
2 * vsp1_clu.h -- R-Car VSP1 Cubic Look-Up Table
3 *
4 * Copyright (C) 2015 Renesas Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#ifndef __VSP1_CLU_H__
14#define __VSP1_CLU_H__
15
16#include <linux/spinlock.h>
17
18#include <media/media-entity.h>
19#include <media/v4l2-ctrls.h>
20#include <media/v4l2-subdev.h>
21
22#include "vsp1_entity.h"
23
24struct vsp1_device;
25struct vsp1_dl_body;
26
27#define CLU_PAD_SINK 0
28#define CLU_PAD_SOURCE 1
29
30struct vsp1_clu {
31 struct vsp1_entity entity;
32
33 struct v4l2_ctrl_handler ctrls;
34
35 bool yuv_mode;
36 spinlock_t lock;
37 unsigned int mode;
38 struct vsp1_dl_body *clu;
39};
40
41static inline struct vsp1_clu *to_clu(struct v4l2_subdev *subdev)
42{
43 return container_of(subdev, struct vsp1_clu, entity.subdev);
44}
45
46struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1);
47
48#endif /* __VSP1_CLU_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index e238d9b9376b..37c3518aa2a8 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -15,6 +15,7 @@
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/gfp.h> 16#include <linux/gfp.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/workqueue.h>
18 19
19#include "vsp1.h" 20#include "vsp1.h"
20#include "vsp1_dl.h" 21#include "vsp1_dl.h"
@@ -92,11 +93,13 @@ enum vsp1_dl_mode {
92 * @index: index of the related WPF 93 * @index: index of the related WPF
93 * @mode: display list operation mode (header or headerless) 94 * @mode: display list operation mode (header or headerless)
94 * @vsp1: the VSP1 device 95 * @vsp1: the VSP1 device
95 * @lock: protects the active, queued and pending lists 96 * @lock: protects the free, active, queued, pending and gc_fragments lists
96 * @free: array of all free display lists 97 * @free: array of all free display lists
97 * @active: list currently being processed (loaded) by hardware 98 * @active: list currently being processed (loaded) by hardware
98 * @queued: list queued to the hardware (written to the DL registers) 99 * @queued: list queued to the hardware (written to the DL registers)
99 * @pending: list waiting to be queued to the hardware 100 * @pending: list waiting to be queued to the hardware
101 * @gc_work: fragments garbage collector work struct
102 * @gc_fragments: array of display list fragments waiting to be freed
100 */ 103 */
101struct vsp1_dl_manager { 104struct vsp1_dl_manager {
102 unsigned int index; 105 unsigned int index;
@@ -108,6 +111,9 @@ struct vsp1_dl_manager {
108 struct vsp1_dl_list *active; 111 struct vsp1_dl_list *active;
109 struct vsp1_dl_list *queued; 112 struct vsp1_dl_list *queued;
110 struct vsp1_dl_list *pending; 113 struct vsp1_dl_list *pending;
114
115 struct work_struct gc_work;
116 struct list_head gc_fragments;
111}; 117};
112 118
113/* ----------------------------------------------------------------------------- 119/* -----------------------------------------------------------------------------
@@ -262,21 +268,10 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
262 return dl; 268 return dl;
263} 269}
264 270
265static void vsp1_dl_list_free_fragments(struct vsp1_dl_list *dl)
266{
267 struct vsp1_dl_body *dlb, *next;
268
269 list_for_each_entry_safe(dlb, next, &dl->fragments, list) {
270 list_del(&dlb->list);
271 vsp1_dl_body_cleanup(dlb);
272 kfree(dlb);
273 }
274}
275
276static void vsp1_dl_list_free(struct vsp1_dl_list *dl) 271static void vsp1_dl_list_free(struct vsp1_dl_list *dl)
277{ 272{
278 vsp1_dl_body_cleanup(&dl->body0); 273 vsp1_dl_body_cleanup(&dl->body0);
279 vsp1_dl_list_free_fragments(dl); 274 list_splice_init(&dl->fragments, &dl->dlm->gc_fragments);
280 kfree(dl); 275 kfree(dl);
281} 276}
282 277
@@ -311,7 +306,16 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl)
311 if (!dl) 306 if (!dl)
312 return; 307 return;
313 308
314 vsp1_dl_list_free_fragments(dl); 309 /* We can't free fragments here as DMA memory can only be freed in
310 * interruptible context. Move all fragments to the display list
311 * manager's list of fragments to be freed, they will be
312 * garbage-collected by the work queue.
313 */
314 if (!list_empty(&dl->fragments)) {
315 list_splice_init(&dl->fragments, &dl->dlm->gc_fragments);
316 schedule_work(&dl->dlm->gc_work);
317 }
318
315 dl->body0.num_entries = 0; 319 dl->body0.num_entries = 0;
316 320
317 list_add_tail(&dl->list, &dl->dlm->free); 321 list_add_tail(&dl->list, &dl->dlm->free);
@@ -550,6 +554,40 @@ void vsp1_dlm_reset(struct vsp1_dl_manager *dlm)
550 dlm->pending = NULL; 554 dlm->pending = NULL;
551} 555}
552 556
557/*
558 * Free all fragments awaiting to be garbage-collected.
559 *
560 * This function must be called without the display list manager lock held.
561 */
562static void vsp1_dlm_fragments_free(struct vsp1_dl_manager *dlm)
563{
564 unsigned long flags;
565
566 spin_lock_irqsave(&dlm->lock, flags);
567
568 while (!list_empty(&dlm->gc_fragments)) {
569 struct vsp1_dl_body *dlb;
570
571 dlb = list_first_entry(&dlm->gc_fragments, struct vsp1_dl_body,
572 list);
573 list_del(&dlb->list);
574
575 spin_unlock_irqrestore(&dlm->lock, flags);
576 vsp1_dl_fragment_free(dlb);
577 spin_lock_irqsave(&dlm->lock, flags);
578 }
579
580 spin_unlock_irqrestore(&dlm->lock, flags);
581}
582
583static void vsp1_dlm_garbage_collect(struct work_struct *work)
584{
585 struct vsp1_dl_manager *dlm =
586 container_of(work, struct vsp1_dl_manager, gc_work);
587
588 vsp1_dlm_fragments_free(dlm);
589}
590
553struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, 591struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
554 unsigned int index, 592 unsigned int index,
555 unsigned int prealloc) 593 unsigned int prealloc)
@@ -568,6 +606,8 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
568 606
569 spin_lock_init(&dlm->lock); 607 spin_lock_init(&dlm->lock);
570 INIT_LIST_HEAD(&dlm->free); 608 INIT_LIST_HEAD(&dlm->free);
609 INIT_LIST_HEAD(&dlm->gc_fragments);
610 INIT_WORK(&dlm->gc_work, vsp1_dlm_garbage_collect);
571 611
572 for (i = 0; i < prealloc; ++i) { 612 for (i = 0; i < prealloc; ++i) {
573 struct vsp1_dl_list *dl; 613 struct vsp1_dl_list *dl;
@@ -589,8 +629,12 @@ void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm)
589 if (!dlm) 629 if (!dlm)
590 return; 630 return;
591 631
632 cancel_work_sync(&dlm->gc_work);
633
592 list_for_each_entry_safe(dl, next, &dlm->free, list) { 634 list_for_each_entry_safe(dl, next, &dlm->free, list) {
593 list_del(&dl->list); 635 list_del(&dl->list);
594 vsp1_dl_list_free(dl); 636 vsp1_dl_list_free(dl);
595 } 637 }
638
639 vsp1_dlm_fragments_free(dlm);
596} 640}
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index fc4bbc401e67..fe9665e57b3b 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -230,42 +230,33 @@ EXPORT_SYMBOL_GPL(vsp1_du_atomic_begin);
230 * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline 230 * vsp1_du_atomic_update - Setup one RPF input of the VSP pipeline
231 * @dev: the VSP device 231 * @dev: the VSP device
232 * @rpf_index: index of the RPF to setup (0-based) 232 * @rpf_index: index of the RPF to setup (0-based)
233 * @pixelformat: V4L2 pixel format for the RPF memory input 233 * @cfg: the RPF configuration
234 * @pitch: number of bytes per line in the image stored in memory
235 * @mem: DMA addresses of the memory buffers (one per plane)
236 * @src: the source crop rectangle for the RPF
237 * @dst: the destination compose rectangle for the BRU input
238 * @alpha: global alpha value for the input
239 * @zpos: the Z-order position of the input
240 * 234 *
241 * Configure the VSP to perform composition of the image referenced by @mem 235 * Configure the VSP to perform image composition through RPF @rpf_index as
242 * through RPF @rpf_index, using the @src crop rectangle and the @dst 236 * described by the @cfg configuration. The image to compose is referenced by
237 * @cfg.mem and composed using the @cfg.src crop rectangle and the @cfg.dst
243 * composition rectangle. The Z-order is configurable with higher @zpos values 238 * composition rectangle. The Z-order is configurable with higher @zpos values
244 * displayed on top. 239 * displayed on top.
245 * 240 *
246 * Image format as stored in memory is expressed as a V4L2 @pixelformat value. 241 * If the @cfg configuration is NULL, the RPF will be disabled. Calling the
247 * As a special case, setting the pixel format to 0 will disable the RPF. The
248 * @pitch, @mem, @src and @dst parameters are ignored in that case. Calling the
249 * function on a disabled RPF is allowed. 242 * function on a disabled RPF is allowed.
250 * 243 *
251 * The memory pitch is configurable to allow for padding at end of lines, or 244 * Image format as stored in memory is expressed as a V4L2 @cfg.pixelformat
252 * simple for images that extend beyond the crop rectangle boundaries. The 245 * value. The memory pitch is configurable to allow for padding at end of lines,
253 * @pitch value is expressed in bytes and applies to all planes for multiplanar 246 * or simply for images that extend beyond the crop rectangle boundaries. The
254 * formats. 247 * @cfg.pitch value is expressed in bytes and applies to all planes for
248 * multiplanar formats.
255 * 249 *
256 * The source memory buffer is referenced by the DMA address of its planes in 250 * The source memory buffer is referenced by the DMA address of its planes in
257 * the @mem array. Up to two planes are supported. The second plane DMA address 251 * the @cfg.mem array. Up to two planes are supported. The second plane DMA
258 * is ignored for formats using a single plane. 252 * address is ignored for formats using a single plane.
259 * 253 *
260 * This function isn't reentrant, the caller needs to serialize calls. 254 * This function isn't reentrant, the caller needs to serialize calls.
261 * 255 *
262 * Return 0 on success or a negative error code on failure. 256 * Return 0 on success or a negative error code on failure.
263 */ 257 */
264int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf_index, 258int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
265 u32 pixelformat, unsigned int pitch, 259 const struct vsp1_du_atomic_config *cfg)
266 dma_addr_t mem[2], const struct v4l2_rect *src,
267 const struct v4l2_rect *dst, unsigned int alpha,
268 unsigned int zpos)
269{ 260{
270 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 261 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
271 const struct vsp1_format_info *fmtinfo; 262 const struct vsp1_format_info *fmtinfo;
@@ -276,7 +267,7 @@ int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf_index,
276 267
277 rpf = vsp1->rpf[rpf_index]; 268 rpf = vsp1->rpf[rpf_index];
278 269
279 if (pixelformat == 0) { 270 if (!cfg) {
280 dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__, 271 dev_dbg(vsp1->dev, "%s: RPF%u: disable requested\n", __func__,
281 rpf_index); 272 rpf_index);
282 273
@@ -287,38 +278,39 @@ int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf_index,
287 dev_dbg(vsp1->dev, 278 dev_dbg(vsp1->dev,
288 "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad } zpos %u\n", 279 "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad } zpos %u\n",
289 __func__, rpf_index, 280 __func__, rpf_index,
290 src->left, src->top, src->width, src->height, 281 cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
291 dst->left, dst->top, dst->width, dst->height, 282 cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
292 pixelformat, pitch, &mem[0], &mem[1], zpos); 283 cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
284 cfg->zpos);
293 285
294 /* Store the format, stride, memory buffer address, crop and compose 286 /* Store the format, stride, memory buffer address, crop and compose
295 * rectangles and Z-order position and for the input. 287 * rectangles and Z-order position and for the input.
296 */ 288 */
297 fmtinfo = vsp1_get_format_info(pixelformat); 289 fmtinfo = vsp1_get_format_info(cfg->pixelformat);
298 if (!fmtinfo) { 290 if (!fmtinfo) {
299 dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n", 291 dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n",
300 pixelformat); 292 cfg->pixelformat);
301 return -EINVAL; 293 return -EINVAL;
302 } 294 }
303 295
304 rpf->fmtinfo = fmtinfo; 296 rpf->fmtinfo = fmtinfo;
305 rpf->format.num_planes = fmtinfo->planes; 297 rpf->format.num_planes = fmtinfo->planes;
306 rpf->format.plane_fmt[0].bytesperline = pitch; 298 rpf->format.plane_fmt[0].bytesperline = cfg->pitch;
307 rpf->format.plane_fmt[1].bytesperline = pitch; 299 rpf->format.plane_fmt[1].bytesperline = cfg->pitch;
308 rpf->alpha = alpha; 300 rpf->alpha = cfg->alpha;
309 301
310 rpf->mem.addr[0] = mem[0]; 302 rpf->mem.addr[0] = cfg->mem[0];
311 rpf->mem.addr[1] = mem[1]; 303 rpf->mem.addr[1] = cfg->mem[1];
312 rpf->mem.addr[2] = 0; 304 rpf->mem.addr[2] = 0;
313 305
314 vsp1->drm->inputs[rpf_index].crop = *src; 306 vsp1->drm->inputs[rpf_index].crop = cfg->src;
315 vsp1->drm->inputs[rpf_index].compose = *dst; 307 vsp1->drm->inputs[rpf_index].compose = cfg->dst;
316 vsp1->drm->inputs[rpf_index].zpos = zpos; 308 vsp1->drm->inputs[rpf_index].zpos = cfg->zpos;
317 vsp1->drm->inputs[rpf_index].enabled = true; 309 vsp1->drm->inputs[rpf_index].enabled = true;
318 310
319 return 0; 311 return 0;
320} 312}
321EXPORT_SYMBOL_GPL(vsp1_du_atomic_update_ext); 313EXPORT_SYMBOL_GPL(vsp1_du_atomic_update);
322 314
323static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1, 315static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
324 struct vsp1_rwpf *rpf, unsigned int bru_input) 316 struct vsp1_rwpf *rpf, unsigned int bru_input)
@@ -499,8 +491,10 @@ void vsp1_du_atomic_flush(struct device *dev)
499 491
500 vsp1_entity_route_setup(entity, pipe->dl); 492 vsp1_entity_route_setup(entity, pipe->dl);
501 493
502 if (entity->ops->configure) 494 if (entity->ops->configure) {
503 entity->ops->configure(entity, pipe, pipe->dl); 495 entity->ops->configure(entity, pipe, pipe->dl, true);
496 entity->ops->configure(entity, pipe, pipe->dl, false);
497 }
504 498
505 /* The memory buffer address must be applied after configuring 499 /* The memory buffer address must be applied after configuring
506 * the RPF to make sure the crop offset are computed. 500 * the RPF to make sure the crop offset are computed.
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index e2d779fac0eb..e1377ffe3d68 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -19,12 +19,15 @@
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/of_device.h> 20#include <linux/of_device.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
22#include <linux/videodev2.h> 23#include <linux/videodev2.h>
23 24
25#include <media/rcar-fcp.h>
24#include <media/v4l2-subdev.h> 26#include <media/v4l2-subdev.h>
25 27
26#include "vsp1.h" 28#include "vsp1.h"
27#include "vsp1_bru.h" 29#include "vsp1_bru.h"
30#include "vsp1_clu.h"
28#include "vsp1_dl.h" 31#include "vsp1_dl.h"
29#include "vsp1_drm.h" 32#include "vsp1_drm.h"
30#include "vsp1_hsit.h" 33#include "vsp1_hsit.h"
@@ -145,7 +148,7 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
145 return ret; 148 return ret;
146 } 149 }
147 150
148 if (vsp1->info->features & VSP1_HAS_LIF) { 151 if (vsp1->lif) {
149 ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity, 152 ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
150 RWPF_PAD_SOURCE, 153 RWPF_PAD_SOURCE,
151 &vsp1->lif->entity.subdev.entity, 154 &vsp1->lif->entity.subdev.entity,
@@ -168,19 +171,15 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
168 171
169 for (i = 0; i < vsp1->info->wpf_count; ++i) { 172 for (i = 0; i < vsp1->info->wpf_count; ++i) {
170 /* Connect the video device to the WPF. All connections are 173 /* Connect the video device to the WPF. All connections are
171 * immutable except for the WPF0 source link if a LIF is 174 * immutable.
172 * present.
173 */ 175 */
174 struct vsp1_rwpf *wpf = vsp1->wpf[i]; 176 struct vsp1_rwpf *wpf = vsp1->wpf[i];
175 unsigned int flags = MEDIA_LNK_FL_ENABLED;
176
177 if (!(vsp1->info->features & VSP1_HAS_LIF) || i != 0)
178 flags |= MEDIA_LNK_FL_IMMUTABLE;
179 177
180 ret = media_create_pad_link(&wpf->entity.subdev.entity, 178 ret = media_create_pad_link(&wpf->entity.subdev.entity,
181 RWPF_PAD_SOURCE, 179 RWPF_PAD_SOURCE,
182 &wpf->video->video.entity, 0, 180 &wpf->video->video.entity, 0,
183 flags); 181 MEDIA_LNK_FL_IMMUTABLE |
182 MEDIA_LNK_FL_ENABLED);
184 if (ret < 0) 183 if (ret < 0)
185 return ret; 184 return ret;
186 } 185 }
@@ -204,7 +203,8 @@ static void vsp1_destroy_entities(struct vsp1_device *vsp1)
204 } 203 }
205 204
206 v4l2_device_unregister(&vsp1->v4l2_dev); 205 v4l2_device_unregister(&vsp1->v4l2_dev);
207 media_device_unregister(&vsp1->media_dev); 206 if (vsp1->info->uapi)
207 media_device_unregister(&vsp1->media_dev);
208 media_device_cleanup(&vsp1->media_dev); 208 media_device_cleanup(&vsp1->media_dev);
209 209
210 if (!vsp1->info->uapi) 210 if (!vsp1->info->uapi)
@@ -252,6 +252,16 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
252 list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities); 252 list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities);
253 } 253 }
254 254
255 if (vsp1->info->features & VSP1_HAS_CLU) {
256 vsp1->clu = vsp1_clu_create(vsp1);
257 if (IS_ERR(vsp1->clu)) {
258 ret = PTR_ERR(vsp1->clu);
259 goto done;
260 }
261
262 list_add_tail(&vsp1->clu->entity.list_dev, &vsp1->entities);
263 }
264
255 vsp1->hsi = vsp1_hsit_create(vsp1, true); 265 vsp1->hsi = vsp1_hsit_create(vsp1, true);
256 if (IS_ERR(vsp1->hsi)) { 266 if (IS_ERR(vsp1->hsi)) {
257 ret = PTR_ERR(vsp1->hsi); 267 ret = PTR_ERR(vsp1->hsi);
@@ -268,7 +278,11 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
268 278
269 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities); 279 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities);
270 280
271 if (vsp1->info->features & VSP1_HAS_LIF) { 281 /* The LIF is only supported when used in conjunction with the DU, in
282 * which case the userspace API is disabled. If the userspace API is
283 * enabled skip the LIF, even when present.
284 */
285 if (vsp1->info->features & VSP1_HAS_LIF && !vsp1->info->uapi) {
272 vsp1->lif = vsp1_lif_create(vsp1); 286 vsp1->lif = vsp1_lif_create(vsp1);
273 if (IS_ERR(vsp1->lif)) { 287 if (IS_ERR(vsp1->lif)) {
274 ret = PTR_ERR(vsp1->lif); 288 ret = PTR_ERR(vsp1->lif);
@@ -379,14 +393,15 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
379 /* Register subdev nodes if the userspace API is enabled or initialize 393 /* Register subdev nodes if the userspace API is enabled or initialize
380 * the DRM pipeline otherwise. 394 * the DRM pipeline otherwise.
381 */ 395 */
382 if (vsp1->info->uapi) 396 if (vsp1->info->uapi) {
383 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); 397 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
384 else 398 if (ret < 0)
385 ret = vsp1_drm_init(vsp1); 399 goto done;
386 if (ret < 0)
387 goto done;
388 400
389 ret = media_device_register(mdev); 401 ret = media_device_register(mdev);
402 } else {
403 ret = vsp1_drm_init(vsp1);
404 }
390 405
391done: 406done:
392 if (ret < 0) 407 if (ret < 0)
@@ -462,35 +477,16 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
462/* 477/*
463 * vsp1_device_get - Acquire the VSP1 device 478 * vsp1_device_get - Acquire the VSP1 device
464 * 479 *
465 * Increment the VSP1 reference count and initialize the device if the first 480 * Make sure the device is not suspended and initialize it if needed.
466 * reference is taken.
467 * 481 *
468 * Return 0 on success or a negative error code otherwise. 482 * Return 0 on success or a negative error code otherwise.
469 */ 483 */
470int vsp1_device_get(struct vsp1_device *vsp1) 484int vsp1_device_get(struct vsp1_device *vsp1)
471{ 485{
472 int ret = 0; 486 int ret;
473
474 mutex_lock(&vsp1->lock);
475 if (vsp1->ref_count > 0)
476 goto done;
477
478 ret = clk_prepare_enable(vsp1->clock);
479 if (ret < 0)
480 goto done;
481
482 ret = vsp1_device_init(vsp1);
483 if (ret < 0) {
484 clk_disable_unprepare(vsp1->clock);
485 goto done;
486 }
487
488done:
489 if (!ret)
490 vsp1->ref_count++;
491 487
492 mutex_unlock(&vsp1->lock); 488 ret = pm_runtime_get_sync(vsp1->dev);
493 return ret; 489 return ret < 0 ? ret : 0;
494} 490}
495 491
496/* 492/*
@@ -501,12 +497,7 @@ done:
501 */ 497 */
502void vsp1_device_put(struct vsp1_device *vsp1) 498void vsp1_device_put(struct vsp1_device *vsp1)
503{ 499{
504 mutex_lock(&vsp1->lock); 500 pm_runtime_put_sync(vsp1->dev);
505
506 if (--vsp1->ref_count == 0)
507 clk_disable_unprepare(vsp1->clock);
508
509 mutex_unlock(&vsp1->lock);
510} 501}
511 502
512/* ----------------------------------------------------------------------------- 503/* -----------------------------------------------------------------------------
@@ -518,14 +509,8 @@ static int vsp1_pm_suspend(struct device *dev)
518{ 509{
519 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 510 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
520 511
521 WARN_ON(mutex_is_locked(&vsp1->lock));
522
523 if (vsp1->ref_count == 0)
524 return 0;
525
526 vsp1_pipelines_suspend(vsp1); 512 vsp1_pipelines_suspend(vsp1);
527 513 pm_runtime_force_suspend(vsp1->dev);
528 clk_disable_unprepare(vsp1->clock);
529 514
530 return 0; 515 return 0;
531} 516}
@@ -534,21 +519,39 @@ static int vsp1_pm_resume(struct device *dev)
534{ 519{
535 struct vsp1_device *vsp1 = dev_get_drvdata(dev); 520 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
536 521
537 WARN_ON(mutex_is_locked(&vsp1->lock)); 522 pm_runtime_force_resume(vsp1->dev);
523 vsp1_pipelines_resume(vsp1);
538 524
539 if (vsp1->ref_count == 0) 525 return 0;
540 return 0; 526}
527#endif
541 528
542 clk_prepare_enable(vsp1->clock); 529static int vsp1_pm_runtime_suspend(struct device *dev)
530{
531 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
543 532
544 vsp1_pipelines_resume(vsp1); 533 rcar_fcp_disable(vsp1->fcp);
545 534
546 return 0; 535 return 0;
547} 536}
548#endif 537
538static int vsp1_pm_runtime_resume(struct device *dev)
539{
540 struct vsp1_device *vsp1 = dev_get_drvdata(dev);
541 int ret;
542
543 if (vsp1->info) {
544 ret = vsp1_device_init(vsp1);
545 if (ret < 0)
546 return ret;
547 }
548
549 return rcar_fcp_enable(vsp1->fcp);
550}
549 551
550static const struct dev_pm_ops vsp1_pm_ops = { 552static const struct dev_pm_ops vsp1_pm_ops = {
551 SET_SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume) 553 SET_SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume)
554 SET_RUNTIME_PM_OPS(vsp1_pm_runtime_suspend, vsp1_pm_runtime_resume, NULL)
552}; 555};
553 556
554/* ----------------------------------------------------------------------------- 557/* -----------------------------------------------------------------------------
@@ -559,7 +562,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
559 { 562 {
560 .version = VI6_IP_VERSION_MODEL_VSPS_H2, 563 .version = VI6_IP_VERSION_MODEL_VSPS_H2,
561 .gen = 2, 564 .gen = 2,
562 .features = VSP1_HAS_BRU | VSP1_HAS_LUT | VSP1_HAS_SRU, 565 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
566 | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP,
563 .rpf_count = 5, 567 .rpf_count = 5,
564 .uds_count = 3, 568 .uds_count = 3,
565 .wpf_count = 4, 569 .wpf_count = 4,
@@ -568,9 +572,9 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
568 }, { 572 }, {
569 .version = VI6_IP_VERSION_MODEL_VSPR_H2, 573 .version = VI6_IP_VERSION_MODEL_VSPR_H2,
570 .gen = 2, 574 .gen = 2,
571 .features = VSP1_HAS_BRU | VSP1_HAS_SRU, 575 .features = VSP1_HAS_BRU | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP,
572 .rpf_count = 5, 576 .rpf_count = 5,
573 .uds_count = 1, 577 .uds_count = 3,
574 .wpf_count = 4, 578 .wpf_count = 4,
575 .num_bru_inputs = 4, 579 .num_bru_inputs = 4,
576 .uapi = true, 580 .uapi = true,
@@ -580,22 +584,24 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
580 .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_LUT, 584 .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_LUT,
581 .rpf_count = 4, 585 .rpf_count = 4,
582 .uds_count = 1, 586 .uds_count = 1,
583 .wpf_count = 4, 587 .wpf_count = 1,
584 .num_bru_inputs = 4, 588 .num_bru_inputs = 4,
585 .uapi = true, 589 .uapi = true,
586 }, { 590 }, {
587 .version = VI6_IP_VERSION_MODEL_VSPS_M2, 591 .version = VI6_IP_VERSION_MODEL_VSPS_M2,
588 .gen = 2, 592 .gen = 2,
589 .features = VSP1_HAS_BRU | VSP1_HAS_LUT | VSP1_HAS_SRU, 593 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
594 | VSP1_HAS_SRU | VSP1_HAS_WPF_VFLIP,
590 .rpf_count = 5, 595 .rpf_count = 5,
591 .uds_count = 3, 596 .uds_count = 1,
592 .wpf_count = 4, 597 .wpf_count = 4,
593 .num_bru_inputs = 4, 598 .num_bru_inputs = 4,
594 .uapi = true, 599 .uapi = true,
595 }, { 600 }, {
596 .version = VI6_IP_VERSION_MODEL_VSPI_GEN3, 601 .version = VI6_IP_VERSION_MODEL_VSPI_GEN3,
597 .gen = 3, 602 .gen = 3,
598 .features = VSP1_HAS_LUT | VSP1_HAS_SRU, 603 .features = VSP1_HAS_CLU | VSP1_HAS_LUT | VSP1_HAS_SRU
604 | VSP1_HAS_WPF_HFLIP | VSP1_HAS_WPF_VFLIP,
599 .rpf_count = 1, 605 .rpf_count = 1,
600 .uds_count = 1, 606 .uds_count = 1,
601 .wpf_count = 1, 607 .wpf_count = 1,
@@ -603,7 +609,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
603 }, { 609 }, {
604 .version = VI6_IP_VERSION_MODEL_VSPBD_GEN3, 610 .version = VI6_IP_VERSION_MODEL_VSPBD_GEN3,
605 .gen = 3, 611 .gen = 3,
606 .features = VSP1_HAS_BRU, 612 .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
607 .rpf_count = 5, 613 .rpf_count = 5,
608 .wpf_count = 1, 614 .wpf_count = 1,
609 .num_bru_inputs = 5, 615 .num_bru_inputs = 5,
@@ -611,7 +617,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
611 }, { 617 }, {
612 .version = VI6_IP_VERSION_MODEL_VSPBC_GEN3, 618 .version = VI6_IP_VERSION_MODEL_VSPBC_GEN3,
613 .gen = 3, 619 .gen = 3,
614 .features = VSP1_HAS_BRU | VSP1_HAS_LUT, 620 .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
621 | VSP1_HAS_WPF_VFLIP,
615 .rpf_count = 5, 622 .rpf_count = 5,
616 .wpf_count = 1, 623 .wpf_count = 1,
617 .num_bru_inputs = 5, 624 .num_bru_inputs = 5,
@@ -619,7 +626,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
619 }, { 626 }, {
620 .version = VI6_IP_VERSION_MODEL_VSPD_GEN3, 627 .version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
621 .gen = 3, 628 .gen = 3,
622 .features = VSP1_HAS_BRU | VSP1_HAS_LIF, 629 .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_WPF_VFLIP,
623 .rpf_count = 5, 630 .rpf_count = 5,
624 .wpf_count = 2, 631 .wpf_count = 2,
625 .num_bru_inputs = 5, 632 .num_bru_inputs = 5,
@@ -629,6 +636,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
629static int vsp1_probe(struct platform_device *pdev) 636static int vsp1_probe(struct platform_device *pdev)
630{ 637{
631 struct vsp1_device *vsp1; 638 struct vsp1_device *vsp1;
639 struct device_node *fcp_node;
632 struct resource *irq; 640 struct resource *irq;
633 struct resource *io; 641 struct resource *io;
634 unsigned int i; 642 unsigned int i;
@@ -640,22 +648,17 @@ static int vsp1_probe(struct platform_device *pdev)
640 return -ENOMEM; 648 return -ENOMEM;
641 649
642 vsp1->dev = &pdev->dev; 650 vsp1->dev = &pdev->dev;
643 mutex_init(&vsp1->lock);
644 INIT_LIST_HEAD(&vsp1->entities); 651 INIT_LIST_HEAD(&vsp1->entities);
645 INIT_LIST_HEAD(&vsp1->videos); 652 INIT_LIST_HEAD(&vsp1->videos);
646 653
647 /* I/O, IRQ and clock resources */ 654 platform_set_drvdata(pdev, vsp1);
655
656 /* I/O and IRQ resources (clock managed by the clock PM domain) */
648 io = platform_get_resource(pdev, IORESOURCE_MEM, 0); 657 io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
649 vsp1->mmio = devm_ioremap_resource(&pdev->dev, io); 658 vsp1->mmio = devm_ioremap_resource(&pdev->dev, io);
650 if (IS_ERR(vsp1->mmio)) 659 if (IS_ERR(vsp1->mmio))
651 return PTR_ERR(vsp1->mmio); 660 return PTR_ERR(vsp1->mmio);
652 661
653 vsp1->clock = devm_clk_get(&pdev->dev, NULL);
654 if (IS_ERR(vsp1->clock)) {
655 dev_err(&pdev->dev, "failed to get clock\n");
656 return PTR_ERR(vsp1->clock);
657 }
658
659 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 662 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
660 if (!irq) { 663 if (!irq) {
661 dev_err(&pdev->dev, "missing IRQ\n"); 664 dev_err(&pdev->dev, "missing IRQ\n");
@@ -669,13 +672,27 @@ static int vsp1_probe(struct platform_device *pdev)
669 return ret; 672 return ret;
670 } 673 }
671 674
675 /* FCP (optional) */
676 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
677 if (fcp_node) {
678 vsp1->fcp = rcar_fcp_get(fcp_node);
679 of_node_put(fcp_node);
680 if (IS_ERR(vsp1->fcp)) {
681 dev_dbg(&pdev->dev, "FCP not found (%ld)\n",
682 PTR_ERR(vsp1->fcp));
683 return PTR_ERR(vsp1->fcp);
684 }
685 }
686
672 /* Configure device parameters based on the version register. */ 687 /* Configure device parameters based on the version register. */
673 ret = clk_prepare_enable(vsp1->clock); 688 pm_runtime_enable(&pdev->dev);
689
690 ret = pm_runtime_get_sync(&pdev->dev);
674 if (ret < 0) 691 if (ret < 0)
675 return ret; 692 goto done;
676 693
677 version = vsp1_read(vsp1, VI6_IP_VERSION); 694 version = vsp1_read(vsp1, VI6_IP_VERSION);
678 clk_disable_unprepare(vsp1->clock); 695 pm_runtime_put_sync(&pdev->dev);
679 696
680 for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) { 697 for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) {
681 if ((version & VI6_IP_VERSION_MODEL_MASK) == 698 if ((version & VI6_IP_VERSION_MODEL_MASK) ==
@@ -687,7 +704,8 @@ static int vsp1_probe(struct platform_device *pdev)
687 704
688 if (!vsp1->info) { 705 if (!vsp1->info) {
689 dev_err(&pdev->dev, "unsupported IP version 0x%08x\n", version); 706 dev_err(&pdev->dev, "unsupported IP version 0x%08x\n", version);
690 return -ENXIO; 707 ret = -ENXIO;
708 goto done;
691 } 709 }
692 710
693 dev_dbg(&pdev->dev, "IP version 0x%08x\n", version); 711 dev_dbg(&pdev->dev, "IP version 0x%08x\n", version);
@@ -696,12 +714,14 @@ static int vsp1_probe(struct platform_device *pdev)
696 ret = vsp1_create_entities(vsp1); 714 ret = vsp1_create_entities(vsp1);
697 if (ret < 0) { 715 if (ret < 0) {
698 dev_err(&pdev->dev, "failed to create entities\n"); 716 dev_err(&pdev->dev, "failed to create entities\n");
699 return ret; 717 goto done;
700 } 718 }
701 719
702 platform_set_drvdata(pdev, vsp1); 720done:
721 if (ret)
722 pm_runtime_disable(&pdev->dev);
703 723
704 return 0; 724 return ret;
705} 725}
706 726
707static int vsp1_remove(struct platform_device *pdev) 727static int vsp1_remove(struct platform_device *pdev)
@@ -709,6 +729,9 @@ static int vsp1_remove(struct platform_device *pdev)
709 struct vsp1_device *vsp1 = platform_get_drvdata(pdev); 729 struct vsp1_device *vsp1 = platform_get_drvdata(pdev);
710 730
711 vsp1_destroy_entities(vsp1); 731 vsp1_destroy_entities(vsp1);
732 rcar_fcp_put(vsp1->fcp);
733
734 pm_runtime_disable(&pdev->dev);
712 735
713 return 0; 736 return 0;
714} 737}
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 3d070bcc6053..4cf6cc719c00 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -22,6 +22,12 @@
22#include "vsp1_dl.h" 22#include "vsp1_dl.h"
23#include "vsp1_entity.h" 23#include "vsp1_entity.h"
24 24
25static inline struct vsp1_entity *
26media_entity_to_vsp1_entity(struct media_entity *entity)
27{
28 return container_of(entity, struct vsp1_entity, subdev.entity);
29}
30
25void vsp1_entity_route_setup(struct vsp1_entity *source, 31void vsp1_entity_route_setup(struct vsp1_entity *source,
26 struct vsp1_dl_list *dl) 32 struct vsp1_dl_list *dl)
27{ 33{
@@ -30,7 +36,7 @@ void vsp1_entity_route_setup(struct vsp1_entity *source,
30 if (source->route->reg == 0) 36 if (source->route->reg == 0)
31 return; 37 return;
32 38
33 sink = container_of(source->sink, struct vsp1_entity, subdev.entity); 39 sink = media_entity_to_vsp1_entity(source->sink);
34 vsp1_dl_list_write(dl, source->route->reg, 40 vsp1_dl_list_write(dl, source->route->reg,
35 sink->route->inputs[source->sink_pad]); 41 sink->route->inputs[source->sink_pad]);
36} 42}
@@ -81,12 +87,30 @@ vsp1_entity_get_pad_format(struct vsp1_entity *entity,
81 return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad); 87 return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
82} 88}
83 89
90/**
91 * vsp1_entity_get_pad_selection - Get a pad selection from storage for entity
92 * @entity: the entity
93 * @cfg: the configuration storage
94 * @pad: the pad number
95 * @target: the selection target
96 *
97 * Return the selection rectangle stored in the given configuration for an
98 * entity's pad. The configuration can be an ACTIVE or TRY configuration. The
99 * selection target can be COMPOSE or CROP.
100 */
84struct v4l2_rect * 101struct v4l2_rect *
85vsp1_entity_get_pad_compose(struct vsp1_entity *entity, 102vsp1_entity_get_pad_selection(struct vsp1_entity *entity,
86 struct v4l2_subdev_pad_config *cfg, 103 struct v4l2_subdev_pad_config *cfg,
87 unsigned int pad) 104 unsigned int pad, unsigned int target)
88{ 105{
89 return v4l2_subdev_get_try_compose(&entity->subdev, cfg, pad); 106 switch (target) {
107 case V4L2_SEL_TGT_COMPOSE:
108 return v4l2_subdev_get_try_compose(&entity->subdev, cfg, pad);
109 case V4L2_SEL_TGT_CROP:
110 return v4l2_subdev_get_try_crop(&entity->subdev, cfg, pad);
111 default:
112 return NULL;
113 }
90} 114}
91 115
92/* 116/*
@@ -252,7 +276,7 @@ int vsp1_entity_link_setup(struct media_entity *entity,
252 if (!(local->flags & MEDIA_PAD_FL_SOURCE)) 276 if (!(local->flags & MEDIA_PAD_FL_SOURCE))
253 return 0; 277 return 0;
254 278
255 source = container_of(local->entity, struct vsp1_entity, subdev.entity); 279 source = media_entity_to_vsp1_entity(local->entity);
256 280
257 if (!source->route) 281 if (!source->route)
258 return 0; 282 return 0;
@@ -274,33 +298,50 @@ int vsp1_entity_link_setup(struct media_entity *entity,
274 * Initialization 298 * Initialization
275 */ 299 */
276 300
301#define VSP1_ENTITY_ROUTE(ent) \
302 { VSP1_ENTITY_##ent, 0, VI6_DPR_##ent##_ROUTE, \
303 { VI6_DPR_NODE_##ent }, VI6_DPR_NODE_##ent }
304
305#define VSP1_ENTITY_ROUTE_RPF(idx) \
306 { VSP1_ENTITY_RPF, idx, VI6_DPR_RPF_ROUTE(idx), \
307 { 0, }, VI6_DPR_NODE_RPF(idx) }
308
309#define VSP1_ENTITY_ROUTE_UDS(idx) \
310 { VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx), \
311 { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
312
313#define VSP1_ENTITY_ROUTE_WPF(idx) \
314 { VSP1_ENTITY_WPF, idx, 0, \
315 { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
316
277static const struct vsp1_route vsp1_routes[] = { 317static const struct vsp1_route vsp1_routes[] = {
278 { VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE, 318 { VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
279 { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1), 319 { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
280 VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), 320 VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
281 VI6_DPR_NODE_BRU_IN(4) } }, 321 VI6_DPR_NODE_BRU_IN(4) }, VI6_DPR_NODE_BRU_OUT },
282 { VSP1_ENTITY_HSI, 0, VI6_DPR_HSI_ROUTE, { VI6_DPR_NODE_HSI, } }, 322 VSP1_ENTITY_ROUTE(CLU),
283 { VSP1_ENTITY_HST, 0, VI6_DPR_HST_ROUTE, { VI6_DPR_NODE_HST, } }, 323 VSP1_ENTITY_ROUTE(HSI),
284 { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, } }, 324 VSP1_ENTITY_ROUTE(HST),
285 { VSP1_ENTITY_LUT, 0, VI6_DPR_LUT_ROUTE, { VI6_DPR_NODE_LUT, } }, 325 { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, }, VI6_DPR_NODE_LIF },
286 { VSP1_ENTITY_RPF, 0, VI6_DPR_RPF_ROUTE(0), { 0, } }, 326 VSP1_ENTITY_ROUTE(LUT),
287 { VSP1_ENTITY_RPF, 1, VI6_DPR_RPF_ROUTE(1), { 0, } }, 327 VSP1_ENTITY_ROUTE_RPF(0),
288 { VSP1_ENTITY_RPF, 2, VI6_DPR_RPF_ROUTE(2), { 0, } }, 328 VSP1_ENTITY_ROUTE_RPF(1),
289 { VSP1_ENTITY_RPF, 3, VI6_DPR_RPF_ROUTE(3), { 0, } }, 329 VSP1_ENTITY_ROUTE_RPF(2),
290 { VSP1_ENTITY_RPF, 4, VI6_DPR_RPF_ROUTE(4), { 0, } }, 330 VSP1_ENTITY_ROUTE_RPF(3),
291 { VSP1_ENTITY_SRU, 0, VI6_DPR_SRU_ROUTE, { VI6_DPR_NODE_SRU, } }, 331 VSP1_ENTITY_ROUTE_RPF(4),
292 { VSP1_ENTITY_UDS, 0, VI6_DPR_UDS_ROUTE(0), { VI6_DPR_NODE_UDS(0), } }, 332 VSP1_ENTITY_ROUTE(SRU),
293 { VSP1_ENTITY_UDS, 1, VI6_DPR_UDS_ROUTE(1), { VI6_DPR_NODE_UDS(1), } }, 333 VSP1_ENTITY_ROUTE_UDS(0),
294 { VSP1_ENTITY_UDS, 2, VI6_DPR_UDS_ROUTE(2), { VI6_DPR_NODE_UDS(2), } }, 334 VSP1_ENTITY_ROUTE_UDS(1),
295 { VSP1_ENTITY_WPF, 0, 0, { VI6_DPR_NODE_WPF(0), } }, 335 VSP1_ENTITY_ROUTE_UDS(2),
296 { VSP1_ENTITY_WPF, 1, 0, { VI6_DPR_NODE_WPF(1), } }, 336 VSP1_ENTITY_ROUTE_WPF(0),
297 { VSP1_ENTITY_WPF, 2, 0, { VI6_DPR_NODE_WPF(2), } }, 337 VSP1_ENTITY_ROUTE_WPF(1),
298 { VSP1_ENTITY_WPF, 3, 0, { VI6_DPR_NODE_WPF(3), } }, 338 VSP1_ENTITY_ROUTE_WPF(2),
339 VSP1_ENTITY_ROUTE_WPF(3),
299}; 340};
300 341
301int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, 342int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
302 const char *name, unsigned int num_pads, 343 const char *name, unsigned int num_pads,
303 const struct v4l2_subdev_ops *ops) 344 const struct v4l2_subdev_ops *ops, u32 function)
304{ 345{
305 struct v4l2_subdev *subdev; 346 struct v4l2_subdev *subdev;
306 unsigned int i; 347 unsigned int i;
@@ -341,6 +382,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
341 subdev = &entity->subdev; 382 subdev = &entity->subdev;
342 v4l2_subdev_init(subdev, ops); 383 v4l2_subdev_init(subdev, ops);
343 384
385 subdev->entity.function = function;
344 subdev->entity.ops = &vsp1->media_ops; 386 subdev->entity.ops = &vsp1->media_ops;
345 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 387 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
346 388
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 69eff4e17350..b43457fd2c43 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -24,6 +24,7 @@ struct vsp1_pipeline;
24 24
25enum vsp1_entity_type { 25enum vsp1_entity_type {
26 VSP1_ENTITY_BRU, 26 VSP1_ENTITY_BRU,
27 VSP1_ENTITY_CLU,
27 VSP1_ENTITY_HSI, 28 VSP1_ENTITY_HSI,
28 VSP1_ENTITY_HST, 29 VSP1_ENTITY_HST,
29 VSP1_ENTITY_LIF, 30 VSP1_ENTITY_LIF,
@@ -42,17 +43,21 @@ enum vsp1_entity_type {
42 * @index: Entity index this routing entry is associated with 43 * @index: Entity index this routing entry is associated with
43 * @reg: Output routing configuration register 44 * @reg: Output routing configuration register
44 * @inputs: Target node value for each input 45 * @inputs: Target node value for each input
46 * @output: Target node value for entity output
45 * 47 *
46 * Each $vsp1_route entry describes routing configuration for the entity 48 * Each $vsp1_route entry describes routing configuration for the entity
47 * specified by the entry's @type and @index. @reg indicates the register that 49 * specified by the entry's @type and @index. @reg indicates the register that
48 * holds output routing configuration for the entity, and the @inputs array 50 * holds output routing configuration for the entity, and the @inputs array
49 * store the target node value for each input of the entity. 51 * store the target node value for each input of the entity. The @output field
52 * stores the target node value of the entity output when used as a source for
53 * histogram generation.
50 */ 54 */
51struct vsp1_route { 55struct vsp1_route {
52 enum vsp1_entity_type type; 56 enum vsp1_entity_type type;
53 unsigned int index; 57 unsigned int index;
54 unsigned int reg; 58 unsigned int reg;
55 unsigned int inputs[VSP1_ENTITY_MAX_INPUTS]; 59 unsigned int inputs[VSP1_ENTITY_MAX_INPUTS];
60 unsigned int output;
56}; 61};
57 62
58/** 63/**
@@ -68,7 +73,7 @@ struct vsp1_entity_operations {
68 void (*destroy)(struct vsp1_entity *); 73 void (*destroy)(struct vsp1_entity *);
69 void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl); 74 void (*set_memory)(struct vsp1_entity *, struct vsp1_dl_list *dl);
70 void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *, 75 void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *,
71 struct vsp1_dl_list *); 76 struct vsp1_dl_list *, bool);
72}; 77};
73 78
74struct vsp1_entity { 79struct vsp1_entity {
@@ -100,7 +105,7 @@ static inline struct vsp1_entity *to_vsp1_entity(struct v4l2_subdev *subdev)
100 105
101int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, 106int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
102 const char *name, unsigned int num_pads, 107 const char *name, unsigned int num_pads,
103 const struct v4l2_subdev_ops *ops); 108 const struct v4l2_subdev_ops *ops, u32 function);
104void vsp1_entity_destroy(struct vsp1_entity *entity); 109void vsp1_entity_destroy(struct vsp1_entity *entity);
105 110
106extern const struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops; 111extern const struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops;
@@ -118,9 +123,9 @@ vsp1_entity_get_pad_format(struct vsp1_entity *entity,
118 struct v4l2_subdev_pad_config *cfg, 123 struct v4l2_subdev_pad_config *cfg,
119 unsigned int pad); 124 unsigned int pad);
120struct v4l2_rect * 125struct v4l2_rect *
121vsp1_entity_get_pad_compose(struct vsp1_entity *entity, 126vsp1_entity_get_pad_selection(struct vsp1_entity *entity,
122 struct v4l2_subdev_pad_config *cfg, 127 struct v4l2_subdev_pad_config *cfg,
123 unsigned int pad); 128 unsigned int pad, unsigned int target);
124int vsp1_entity_init_cfg(struct v4l2_subdev *subdev, 129int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
125 struct v4l2_subdev_pad_config *cfg); 130 struct v4l2_subdev_pad_config *cfg);
126 131
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 68b8567b374d..6e5077beb38c 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -107,7 +107,7 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
107 return 0; 107 return 0;
108} 108}
109 109
110static struct v4l2_subdev_pad_ops hsit_pad_ops = { 110static const struct v4l2_subdev_pad_ops hsit_pad_ops = {
111 .init_cfg = vsp1_entity_init_cfg, 111 .init_cfg = vsp1_entity_init_cfg,
112 .enum_mbus_code = hsit_enum_mbus_code, 112 .enum_mbus_code = hsit_enum_mbus_code,
113 .enum_frame_size = hsit_enum_frame_size, 113 .enum_frame_size = hsit_enum_frame_size,
@@ -115,7 +115,7 @@ static struct v4l2_subdev_pad_ops hsit_pad_ops = {
115 .set_fmt = hsit_set_format, 115 .set_fmt = hsit_set_format,
116}; 116};
117 117
118static struct v4l2_subdev_ops hsit_ops = { 118static const struct v4l2_subdev_ops hsit_ops = {
119 .pad = &hsit_pad_ops, 119 .pad = &hsit_pad_ops,
120}; 120};
121 121
@@ -125,10 +125,13 @@ static struct v4l2_subdev_ops hsit_ops = {
125 125
126static void hsit_configure(struct vsp1_entity *entity, 126static void hsit_configure(struct vsp1_entity *entity,
127 struct vsp1_pipeline *pipe, 127 struct vsp1_pipeline *pipe,
128 struct vsp1_dl_list *dl) 128 struct vsp1_dl_list *dl, bool full)
129{ 129{
130 struct vsp1_hsit *hsit = to_hsit(&entity->subdev); 130 struct vsp1_hsit *hsit = to_hsit(&entity->subdev);
131 131
132 if (!full)
133 return;
134
132 if (hsit->inverse) 135 if (hsit->inverse)
133 vsp1_hsit_write(hsit, dl, VI6_HSI_CTRL, VI6_HSI_CTRL_EN); 136 vsp1_hsit_write(hsit, dl, VI6_HSI_CTRL, VI6_HSI_CTRL_EN);
134 else 137 else
@@ -161,8 +164,9 @@ struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse)
161 else 164 else
162 hsit->entity.type = VSP1_ENTITY_HST; 165 hsit->entity.type = VSP1_ENTITY_HST;
163 166
164 ret = vsp1_entity_init(vsp1, &hsit->entity, inverse ? "hsi" : "hst", 2, 167 ret = vsp1_entity_init(vsp1, &hsit->entity, inverse ? "hsi" : "hst",
165 &hsit_ops); 168 2, &hsit_ops,
169 MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV);
166 if (ret < 0) 170 if (ret < 0)
167 return ERR_PTR(ret); 171 return ERR_PTR(ret);
168 172
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 0217393f22df..a720063f38c5 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -104,7 +104,7 @@ static int lif_set_format(struct v4l2_subdev *subdev,
104 return 0; 104 return 0;
105} 105}
106 106
107static struct v4l2_subdev_pad_ops lif_pad_ops = { 107static const struct v4l2_subdev_pad_ops lif_pad_ops = {
108 .init_cfg = vsp1_entity_init_cfg, 108 .init_cfg = vsp1_entity_init_cfg,
109 .enum_mbus_code = lif_enum_mbus_code, 109 .enum_mbus_code = lif_enum_mbus_code,
110 .enum_frame_size = lif_enum_frame_size, 110 .enum_frame_size = lif_enum_frame_size,
@@ -112,7 +112,7 @@ static struct v4l2_subdev_pad_ops lif_pad_ops = {
112 .set_fmt = lif_set_format, 112 .set_fmt = lif_set_format,
113}; 113};
114 114
115static struct v4l2_subdev_ops lif_ops = { 115static const struct v4l2_subdev_ops lif_ops = {
116 .pad = &lif_pad_ops, 116 .pad = &lif_pad_ops,
117}; 117};
118 118
@@ -122,7 +122,7 @@ static struct v4l2_subdev_ops lif_ops = {
122 122
123static void lif_configure(struct vsp1_entity *entity, 123static void lif_configure(struct vsp1_entity *entity,
124 struct vsp1_pipeline *pipe, 124 struct vsp1_pipeline *pipe,
125 struct vsp1_dl_list *dl) 125 struct vsp1_dl_list *dl, bool full)
126{ 126{
127 const struct v4l2_mbus_framefmt *format; 127 const struct v4l2_mbus_framefmt *format;
128 struct vsp1_lif *lif = to_lif(&entity->subdev); 128 struct vsp1_lif *lif = to_lif(&entity->subdev);
@@ -130,6 +130,9 @@ static void lif_configure(struct vsp1_entity *entity,
130 unsigned int obth = 400; 130 unsigned int obth = 400;
131 unsigned int lbth = 200; 131 unsigned int lbth = 200;
132 132
133 if (!full)
134 return;
135
133 format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, 136 format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
134 LIF_PAD_SOURCE); 137 LIF_PAD_SOURCE);
135 138
@@ -165,7 +168,12 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
165 lif->entity.ops = &lif_entity_ops; 168 lif->entity.ops = &lif_entity_ops;
166 lif->entity.type = VSP1_ENTITY_LIF; 169 lif->entity.type = VSP1_ENTITY_LIF;
167 170
168 ret = vsp1_entity_init(vsp1, &lif->entity, "lif", 2, &lif_ops); 171 /* The LIF is never exposed to userspace, but media entity registration
172 * requires a function to be set. Use PROC_VIDEO_PIXEL_FORMATTER just to
173 * avoid triggering a WARN_ON(), the value won't be seen anywhere.
174 */
175 ret = vsp1_entity_init(vsp1, &lif->entity, "lif", 2, &lif_ops,
176 MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER);
169 if (ret < 0) 177 if (ret < 0)
170 return ERR_PTR(ret); 178 return ERR_PTR(ret);
171 179
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index aa09e59f0ab8..dc31de9602ba 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/gfp.h> 15#include <linux/gfp.h>
16#include <linux/vsp1.h>
17 16
18#include <media/v4l2-subdev.h> 17#include <media/v4l2-subdev.h>
19 18
@@ -35,43 +34,62 @@ static inline void vsp1_lut_write(struct vsp1_lut *lut, struct vsp1_dl_list *dl,
35} 34}
36 35
37/* ----------------------------------------------------------------------------- 36/* -----------------------------------------------------------------------------
38 * V4L2 Subdevice Core Operations 37 * Controls
39 */ 38 */
40 39
41static int lut_set_table(struct vsp1_lut *lut, struct vsp1_lut_config *config) 40#define V4L2_CID_VSP1_LUT_TABLE (V4L2_CID_USER_BASE | 0x1001)
41
42static int lut_set_table(struct vsp1_lut *lut, struct v4l2_ctrl *ctrl)
42{ 43{
43 struct vsp1_dl_body *dlb; 44 struct vsp1_dl_body *dlb;
44 unsigned int i; 45 unsigned int i;
45 46
46 dlb = vsp1_dl_fragment_alloc(lut->entity.vsp1, ARRAY_SIZE(config->lut)); 47 dlb = vsp1_dl_fragment_alloc(lut->entity.vsp1, 256);
47 if (!dlb) 48 if (!dlb)
48 return -ENOMEM; 49 return -ENOMEM;
49 50
50 for (i = 0; i < ARRAY_SIZE(config->lut); ++i) 51 for (i = 0; i < 256; ++i)
51 vsp1_dl_fragment_write(dlb, VI6_LUT_TABLE + 4 * i, 52 vsp1_dl_fragment_write(dlb, VI6_LUT_TABLE + 4 * i,
52 config->lut[i]); 53 ctrl->p_new.p_u32[i]);
53 54
54 mutex_lock(&lut->lock); 55 spin_lock_irq(&lut->lock);
55 swap(lut->lut, dlb); 56 swap(lut->lut, dlb);
56 mutex_unlock(&lut->lock); 57 spin_unlock_irq(&lut->lock);
57 58
58 vsp1_dl_fragment_free(dlb); 59 vsp1_dl_fragment_free(dlb);
59 return 0; 60 return 0;
60} 61}
61 62
62static long lut_ioctl(struct v4l2_subdev *subdev, unsigned int cmd, void *arg) 63static int lut_s_ctrl(struct v4l2_ctrl *ctrl)
63{ 64{
64 struct vsp1_lut *lut = to_lut(subdev); 65 struct vsp1_lut *lut =
65 66 container_of(ctrl->handler, struct vsp1_lut, ctrls);
66 switch (cmd) {
67 case VIDIOC_VSP1_LUT_CONFIG:
68 return lut_set_table(lut, arg);
69 67
70 default: 68 switch (ctrl->id) {
71 return -ENOIOCTLCMD; 69 case V4L2_CID_VSP1_LUT_TABLE:
70 lut_set_table(lut, ctrl);
71 break;
72 } 72 }
73
74 return 0;
73} 75}
74 76
77static const struct v4l2_ctrl_ops lut_ctrl_ops = {
78 .s_ctrl = lut_s_ctrl,
79};
80
81static const struct v4l2_ctrl_config lut_table_control = {
82 .ops = &lut_ctrl_ops,
83 .id = V4L2_CID_VSP1_LUT_TABLE,
84 .name = "Look-Up Table",
85 .type = V4L2_CTRL_TYPE_U32,
86 .min = 0x00000000,
87 .max = 0x00ffffff,
88 .step = 1,
89 .def = 0,
90 .dims = { 256},
91};
92
75/* ----------------------------------------------------------------------------- 93/* -----------------------------------------------------------------------------
76 * V4L2 Subdevice Pad Operations 94 * V4L2 Subdevice Pad Operations
77 */ 95 */
@@ -147,11 +165,7 @@ static int lut_set_format(struct v4l2_subdev *subdev,
147 * V4L2 Subdevice Operations 165 * V4L2 Subdevice Operations
148 */ 166 */
149 167
150static struct v4l2_subdev_core_ops lut_core_ops = { 168static const struct v4l2_subdev_pad_ops lut_pad_ops = {
151 .ioctl = lut_ioctl,
152};
153
154static struct v4l2_subdev_pad_ops lut_pad_ops = {
155 .init_cfg = vsp1_entity_init_cfg, 169 .init_cfg = vsp1_entity_init_cfg,
156 .enum_mbus_code = lut_enum_mbus_code, 170 .enum_mbus_code = lut_enum_mbus_code,
157 .enum_frame_size = lut_enum_frame_size, 171 .enum_frame_size = lut_enum_frame_size,
@@ -159,8 +173,7 @@ static struct v4l2_subdev_pad_ops lut_pad_ops = {
159 .set_fmt = lut_set_format, 173 .set_fmt = lut_set_format,
160}; 174};
161 175
162static struct v4l2_subdev_ops lut_ops = { 176static const struct v4l2_subdev_ops lut_ops = {
163 .core = &lut_core_ops,
164 .pad = &lut_pad_ops, 177 .pad = &lut_pad_ops,
165}; 178};
166 179
@@ -170,18 +183,24 @@ static struct v4l2_subdev_ops lut_ops = {
170 183
171static void lut_configure(struct vsp1_entity *entity, 184static void lut_configure(struct vsp1_entity *entity,
172 struct vsp1_pipeline *pipe, 185 struct vsp1_pipeline *pipe,
173 struct vsp1_dl_list *dl) 186 struct vsp1_dl_list *dl, bool full)
174{ 187{
175 struct vsp1_lut *lut = to_lut(&entity->subdev); 188 struct vsp1_lut *lut = to_lut(&entity->subdev);
189 struct vsp1_dl_body *dlb;
190 unsigned long flags;
176 191
177 vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN); 192 if (full) {
178 193 vsp1_lut_write(lut, dl, VI6_LUT_CTRL, VI6_LUT_CTRL_EN);
179 mutex_lock(&lut->lock); 194 return;
180 if (lut->lut) {
181 vsp1_dl_list_add_fragment(dl, lut->lut);
182 lut->lut = NULL;
183 } 195 }
184 mutex_unlock(&lut->lock); 196
197 spin_lock_irqsave(&lut->lock, flags);
198 dlb = lut->lut;
199 lut->lut = NULL;
200 spin_unlock_irqrestore(&lut->lock, flags);
201
202 if (dlb)
203 vsp1_dl_list_add_fragment(dl, dlb);
185} 204}
186 205
187static const struct vsp1_entity_operations lut_entity_ops = { 206static const struct vsp1_entity_operations lut_entity_ops = {
@@ -201,12 +220,30 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1)
201 if (lut == NULL) 220 if (lut == NULL)
202 return ERR_PTR(-ENOMEM); 221 return ERR_PTR(-ENOMEM);
203 222
223 spin_lock_init(&lut->lock);
224
204 lut->entity.ops = &lut_entity_ops; 225 lut->entity.ops = &lut_entity_ops;
205 lut->entity.type = VSP1_ENTITY_LUT; 226 lut->entity.type = VSP1_ENTITY_LUT;
206 227
207 ret = vsp1_entity_init(vsp1, &lut->entity, "lut", 2, &lut_ops); 228 ret = vsp1_entity_init(vsp1, &lut->entity, "lut", 2, &lut_ops,
229 MEDIA_ENT_F_PROC_VIDEO_LUT);
208 if (ret < 0) 230 if (ret < 0)
209 return ERR_PTR(ret); 231 return ERR_PTR(ret);
210 232
233 /* Initialize the control handler. */
234 v4l2_ctrl_handler_init(&lut->ctrls, 1);
235 v4l2_ctrl_new_custom(&lut->ctrls, &lut_table_control, NULL);
236
237 lut->entity.subdev.ctrl_handler = &lut->ctrls;
238
239 if (lut->ctrls.error) {
240 dev_err(vsp1->dev, "lut: failed to initialize controls\n");
241 ret = lut->ctrls.error;
242 vsp1_entity_destroy(&lut->entity);
243 return ERR_PTR(ret);
244 }
245
246 v4l2_ctrl_handler_setup(&lut->ctrls);
247
211 return lut; 248 return lut;
212} 249}
diff --git a/drivers/media/platform/vsp1/vsp1_lut.h b/drivers/media/platform/vsp1/vsp1_lut.h
index cef874f22b6a..f8c4e8f0a79d 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.h
+++ b/drivers/media/platform/vsp1/vsp1_lut.h
@@ -13,9 +13,10 @@
13#ifndef __VSP1_LUT_H__ 13#ifndef __VSP1_LUT_H__
14#define __VSP1_LUT_H__ 14#define __VSP1_LUT_H__
15 15
16#include <linux/mutex.h> 16#include <linux/spinlock.h>
17 17
18#include <media/media-entity.h> 18#include <media/media-entity.h>
19#include <media/v4l2-ctrls.h>
19#include <media/v4l2-subdev.h> 20#include <media/v4l2-subdev.h>
20 21
21#include "vsp1_entity.h" 22#include "vsp1_entity.h"
@@ -28,7 +29,9 @@ struct vsp1_device;
28struct vsp1_lut { 29struct vsp1_lut {
29 struct vsp1_entity entity; 30 struct vsp1_entity entity;
30 31
31 struct mutex lock; 32 struct v4l2_ctrl_handler ctrls;
33
34 spinlock_t lock;
32 struct vsp1_dl_body *lut; 35 struct vsp1_dl_body *lut;
33}; 36};
34 37
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
index 4f3b4a1d028a..3e75fb3fcace 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/vsp1/vsp1_pipe.c
@@ -172,13 +172,17 @@ void vsp1_pipeline_reset(struct vsp1_pipeline *pipe)
172 bru->inputs[i].rpf = NULL; 172 bru->inputs[i].rpf = NULL;
173 } 173 }
174 174
175 for (i = 0; i < pipe->num_inputs; ++i) { 175 for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i) {
176 pipe->inputs[i]->pipe = NULL; 176 if (pipe->inputs[i]) {
177 pipe->inputs[i] = NULL; 177 pipe->inputs[i]->pipe = NULL;
178 pipe->inputs[i] = NULL;
179 }
178 } 180 }
179 181
180 pipe->output->pipe = NULL; 182 if (pipe->output) {
181 pipe->output = NULL; 183 pipe->output->pipe = NULL;
184 pipe->output = NULL;
185 }
182 186
183 INIT_LIST_HEAD(&pipe->entities); 187 INIT_LIST_HEAD(&pipe->entities);
184 pipe->state = VSP1_PIPELINE_STOPPED; 188 pipe->state = VSP1_PIPELINE_STOPPED;
@@ -286,6 +290,8 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
286 290
287 if (pipe->frame_end) 291 if (pipe->frame_end)
288 pipe->frame_end(pipe); 292 pipe->frame_end(pipe);
293
294 pipe->sequence++;
289} 295}
290 296
291/* 297/*
@@ -295,42 +301,20 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
295 * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha 301 * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha
296 * value. The UDS then outputs a fixed alpha value which needs to be programmed 302 * value. The UDS then outputs a fixed alpha value which needs to be programmed
297 * from the input RPF alpha. 303 * from the input RPF alpha.
298 *
299 * This function can only be called from a subdev s_stream handler as it
300 * requires a valid display list context.
301 */ 304 */
302void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, 305void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
303 struct vsp1_entity *input, 306 struct vsp1_dl_list *dl, unsigned int alpha)
304 struct vsp1_dl_list *dl,
305 unsigned int alpha)
306{ 307{
307 struct vsp1_entity *entity; 308 if (!pipe->uds)
308 struct media_pad *pad; 309 return;
309
310 pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
311
312 while (pad) {
313 if (!is_media_entity_v4l2_subdev(pad->entity))
314 break;
315
316 entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
317
318 /* The BRU background color has a fixed alpha value set to 255,
319 * the output alpha value is thus always equal to 255.
320 */
321 if (entity->type == VSP1_ENTITY_BRU)
322 alpha = 255;
323
324 if (entity->type == VSP1_ENTITY_UDS) {
325 struct vsp1_uds *uds = to_uds(&entity->subdev);
326 310
327 vsp1_uds_set_alpha(uds, dl, alpha); 311 /* The BRU background color has a fixed alpha value set to 255, the
328 break; 312 * output alpha value is thus always equal to 255.
329 } 313 */
314 if (pipe->uds_input->type == VSP1_ENTITY_BRU)
315 alpha = 255;
330 316
331 pad = &entity->pads[entity->source_pad]; 317 vsp1_uds_set_alpha(pipe->uds, dl, alpha);
332 pad = media_entity_remote_pad(pad);
333 }
334} 318}
335 319
336void vsp1_pipelines_suspend(struct vsp1_device *vsp1) 320void vsp1_pipelines_suspend(struct vsp1_device *vsp1)
@@ -383,7 +367,7 @@ void vsp1_pipelines_resume(struct vsp1_device *vsp1)
383{ 367{
384 unsigned int i; 368 unsigned int i;
385 369
386 /* Resume pipeline all running pipelines. */ 370 /* Resume all running pipelines. */
387 for (i = 0; i < vsp1->info->wpf_count; ++i) { 371 for (i = 0; i < vsp1->info->wpf_count; ++i) {
388 struct vsp1_rwpf *wpf = vsp1->wpf[i]; 372 struct vsp1_rwpf *wpf = vsp1->wpf[i];
389 struct vsp1_pipeline *pipe; 373 struct vsp1_pipeline *pipe;
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index 7b56113511dd..d20d997b1fda 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -61,12 +61,13 @@ enum vsp1_pipeline_state {
61 * @pipe: the media pipeline 61 * @pipe: the media pipeline
62 * @irqlock: protects the pipeline state 62 * @irqlock: protects the pipeline state
63 * @state: current state 63 * @state: current state
64 * @wq: work queue to wait for state change completion 64 * @wq: wait queue to wait for state change completion
65 * @frame_end: frame end interrupt handler 65 * @frame_end: frame end interrupt handler
66 * @lock: protects the pipeline use count and stream count 66 * @lock: protects the pipeline use count and stream count
67 * @kref: pipeline reference count 67 * @kref: pipeline reference count
68 * @stream_count: number of streaming video nodes 68 * @stream_count: number of streaming video nodes
69 * @buffers_ready: bitmask of RPFs and WPFs with at least one buffer available 69 * @buffers_ready: bitmask of RPFs and WPFs with at least one buffer available
70 * @sequence: frame sequence number
70 * @num_inputs: number of RPFs 71 * @num_inputs: number of RPFs
71 * @inputs: array of RPFs in the pipeline (indexed by RPF index) 72 * @inputs: array of RPFs in the pipeline (indexed by RPF index)
72 * @output: WPF at the output of the pipeline 73 * @output: WPF at the output of the pipeline
@@ -90,6 +91,7 @@ struct vsp1_pipeline {
90 struct kref kref; 91 struct kref kref;
91 unsigned int stream_count; 92 unsigned int stream_count;
92 unsigned int buffers_ready; 93 unsigned int buffers_ready;
94 unsigned int sequence;
93 95
94 unsigned int num_inputs; 96 unsigned int num_inputs;
95 struct vsp1_rwpf *inputs[VSP1_MAX_RPF]; 97 struct vsp1_rwpf *inputs[VSP1_MAX_RPF];
@@ -115,9 +117,7 @@ bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe);
115void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe); 117void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe);
116 118
117void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, 119void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
118 struct vsp1_entity *input, 120 struct vsp1_dl_list *dl, unsigned int alpha);
119 struct vsp1_dl_list *dl,
120 unsigned int alpha);
121 121
122void vsp1_pipelines_suspend(struct vsp1_device *vsp1); 122void vsp1_pipelines_suspend(struct vsp1_device *vsp1);
123void vsp1_pipelines_resume(struct vsp1_device *vsp1); 123void vsp1_pipelines_resume(struct vsp1_device *vsp1);
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 927b5fb94c48..3b03007ba625 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -154,10 +154,10 @@
154#define VI6_RPF_ALPH_SEL_AEXT_EXT (1 << 18) 154#define VI6_RPF_ALPH_SEL_AEXT_EXT (1 << 18)
155#define VI6_RPF_ALPH_SEL_AEXT_ONE (2 << 18) 155#define VI6_RPF_ALPH_SEL_AEXT_ONE (2 << 18)
156#define VI6_RPF_ALPH_SEL_AEXT_MASK (3 << 18) 156#define VI6_RPF_ALPH_SEL_AEXT_MASK (3 << 18)
157#define VI6_RPF_ALPH_SEL_ALPHA0_MASK (0xff << 8) 157#define VI6_RPF_ALPH_SEL_ALPHA1_MASK (0xff << 8)
158#define VI6_RPF_ALPH_SEL_ALPHA0_SHIFT 8 158#define VI6_RPF_ALPH_SEL_ALPHA1_SHIFT 8
159#define VI6_RPF_ALPH_SEL_ALPHA1_MASK (0xff << 0) 159#define VI6_RPF_ALPH_SEL_ALPHA0_MASK (0xff << 0)
160#define VI6_RPF_ALPH_SEL_ALPHA1_SHIFT 0 160#define VI6_RPF_ALPH_SEL_ALPHA0_SHIFT 0
161 161
162#define VI6_RPF_VRTCOL_SET 0x0318 162#define VI6_RPF_VRTCOL_SET 0x0318
163#define VI6_RPF_VRTCOL_SET_LAYA_MASK (0xff << 24) 163#define VI6_RPF_VRTCOL_SET_LAYA_MASK (0xff << 24)
@@ -255,6 +255,8 @@
255#define VI6_WPF_OUTFMT_PDV_MASK (0xff << 24) 255#define VI6_WPF_OUTFMT_PDV_MASK (0xff << 24)
256#define VI6_WPF_OUTFMT_PDV_SHIFT 24 256#define VI6_WPF_OUTFMT_PDV_SHIFT 24
257#define VI6_WPF_OUTFMT_PXA (1 << 23) 257#define VI6_WPF_OUTFMT_PXA (1 << 23)
258#define VI6_WPF_OUTFMT_ROT (1 << 18)
259#define VI6_WPF_OUTFMT_HFLP (1 << 17)
258#define VI6_WPF_OUTFMT_FLP (1 << 16) 260#define VI6_WPF_OUTFMT_FLP (1 << 16)
259#define VI6_WPF_OUTFMT_SPYCS (1 << 15) 261#define VI6_WPF_OUTFMT_SPYCS (1 << 15)
260#define VI6_WPF_OUTFMT_SPUVS (1 << 14) 262#define VI6_WPF_OUTFMT_SPUVS (1 << 14)
@@ -289,6 +291,11 @@
289#define VI6_WPF_RNDCTRL_CLMD_EXT (2 << 12) 291#define VI6_WPF_RNDCTRL_CLMD_EXT (2 << 12)
290#define VI6_WPF_RNDCTRL_CLMD_MASK (3 << 12) 292#define VI6_WPF_RNDCTRL_CLMD_MASK (3 << 12)
291 293
294#define VI6_WPF_ROT_CTRL 0x1018
295#define VI6_WPF_ROT_CTRL_LN16 (1 << 17)
296#define VI6_WPF_ROT_CTRL_LMEM_WD_MASK (0x1fff << 0)
297#define VI6_WPF_ROT_CTRL_LMEM_WD_SHIFT 0
298
292#define VI6_WPF_DSTM_STRIDE_Y 0x101c 299#define VI6_WPF_DSTM_STRIDE_Y 0x101c
293#define VI6_WPF_DSTM_STRIDE_C 0x1020 300#define VI6_WPF_DSTM_STRIDE_C 0x1020
294#define VI6_WPF_DSTM_ADDR_Y 0x1024 301#define VI6_WPF_DSTM_ADDR_Y 0x1024
@@ -444,6 +451,15 @@
444 */ 451 */
445 452
446#define VI6_CLU_CTRL 0x2900 453#define VI6_CLU_CTRL 0x2900
454#define VI6_CLU_CTRL_AAI (1 << 28)
455#define VI6_CLU_CTRL_MVS (1 << 24)
456#define VI6_CLU_CTRL_AX1I_2D (3 << 14)
457#define VI6_CLU_CTRL_AX2I_2D (1 << 12)
458#define VI6_CLU_CTRL_OS0_2D (3 << 8)
459#define VI6_CLU_CTRL_OS1_2D (1 << 6)
460#define VI6_CLU_CTRL_OS2_2D (3 << 4)
461#define VI6_CLU_CTRL_M2D (1 << 1)
462#define VI6_CLU_CTRL_EN (1 << 0)
447 463
448/* ----------------------------------------------------------------------------- 464/* -----------------------------------------------------------------------------
449 * HST Control Registers 465 * HST Control Registers
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 49168db3f529..388838913205 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -38,7 +38,7 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf,
38 * V4L2 Subdevice Operations 38 * V4L2 Subdevice Operations
39 */ 39 */
40 40
41static struct v4l2_subdev_ops rpf_ops = { 41static const struct v4l2_subdev_ops rpf_ops = {
42 .pad = &vsp1_rwpf_pad_ops, 42 .pad = &vsp1_rwpf_pad_ops,
43}; 43};
44 44
@@ -60,7 +60,7 @@ static void rpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
60 60
61static void rpf_configure(struct vsp1_entity *entity, 61static void rpf_configure(struct vsp1_entity *entity,
62 struct vsp1_pipeline *pipe, 62 struct vsp1_pipeline *pipe,
63 struct vsp1_dl_list *dl) 63 struct vsp1_dl_list *dl, bool full)
64{ 64{
65 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); 65 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
66 const struct vsp1_format_info *fmtinfo = rpf->fmtinfo; 66 const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
@@ -73,6 +73,16 @@ static void rpf_configure(struct vsp1_entity *entity,
73 u32 pstride; 73 u32 pstride;
74 u32 infmt; 74 u32 infmt;
75 75
76 if (!full) {
77 vsp1_rpf_write(rpf, dl, VI6_RPF_VRTCOL_SET,
78 rpf->alpha << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
79 vsp1_rpf_write(rpf, dl, VI6_RPF_MULT_ALPHA, rpf->mult_alpha |
80 (rpf->alpha << VI6_RPF_MULT_ALPHA_RATIO_SHIFT));
81
82 vsp1_pipeline_propagate_alpha(pipe, dl, rpf->alpha);
83 return;
84 }
85
76 /* Source size, stride and crop offsets. 86 /* Source size, stride and crop offsets.
77 * 87 *
78 * The crop offsets correspond to the location of the crop rectangle top 88 * The crop offsets correspond to the location of the crop rectangle top
@@ -130,9 +140,10 @@ static void rpf_configure(struct vsp1_entity *entity,
130 if (pipe->bru) { 140 if (pipe->bru) {
131 const struct v4l2_rect *compose; 141 const struct v4l2_rect *compose;
132 142
133 compose = vsp1_entity_get_pad_compose(pipe->bru, 143 compose = vsp1_entity_get_pad_selection(pipe->bru,
134 pipe->bru->config, 144 pipe->bru->config,
135 rpf->bru_input); 145 rpf->bru_input,
146 V4L2_SEL_TGT_COMPOSE);
136 left = compose->left; 147 left = compose->left;
137 top = compose->top; 148 top = compose->top;
138 } 149 }
@@ -167,9 +178,6 @@ static void rpf_configure(struct vsp1_entity *entity,
167 (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED 178 (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED
168 : VI6_RPF_ALPH_SEL_ASEL_FIXED)); 179 : VI6_RPF_ALPH_SEL_ASEL_FIXED));
169 180
170 vsp1_rpf_write(rpf, dl, VI6_RPF_VRTCOL_SET,
171 rpf->alpha << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
172
173 if (entity->vsp1->info->gen == 3) { 181 if (entity->vsp1->info->gen == 3) {
174 u32 mult; 182 u32 mult;
175 183
@@ -187,8 +195,7 @@ static void rpf_configure(struct vsp1_entity *entity,
187 mult = VI6_RPF_MULT_ALPHA_A_MMD_RATIO 195 mult = VI6_RPF_MULT_ALPHA_A_MMD_RATIO
188 | (premultiplied ? 196 | (premultiplied ?
189 VI6_RPF_MULT_ALPHA_P_MMD_RATIO : 197 VI6_RPF_MULT_ALPHA_P_MMD_RATIO :
190 VI6_RPF_MULT_ALPHA_P_MMD_NONE) 198 VI6_RPF_MULT_ALPHA_P_MMD_NONE);
191 | (rpf->alpha << VI6_RPF_MULT_ALPHA_RATIO_SHIFT);
192 } else { 199 } else {
193 /* When the input doesn't contain an alpha channel the 200 /* When the input doesn't contain an alpha channel the
194 * global alpha value is applied in the unpacking unit, 201 * global alpha value is applied in the unpacking unit,
@@ -199,11 +206,9 @@ static void rpf_configure(struct vsp1_entity *entity,
199 | VI6_RPF_MULT_ALPHA_P_MMD_NONE; 206 | VI6_RPF_MULT_ALPHA_P_MMD_NONE;
200 } 207 }
201 208
202 vsp1_rpf_write(rpf, dl, VI6_RPF_MULT_ALPHA, mult); 209 rpf->mult_alpha = mult;
203 } 210 }
204 211
205 vsp1_pipeline_propagate_alpha(pipe, &rpf->entity, dl, rpf->alpha);
206
207 vsp1_rpf_write(rpf, dl, VI6_RPF_MSK_CTRL, 0); 212 vsp1_rpf_write(rpf, dl, VI6_RPF_MSK_CTRL, 0);
208 vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, 0); 213 vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, 0);
209 214
@@ -236,18 +241,21 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
236 rpf->entity.index = index; 241 rpf->entity.index = index;
237 242
238 sprintf(name, "rpf.%u", index); 243 sprintf(name, "rpf.%u", index);
239 ret = vsp1_entity_init(vsp1, &rpf->entity, name, 2, &rpf_ops); 244 ret = vsp1_entity_init(vsp1, &rpf->entity, name, 2, &rpf_ops,
245 MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER);
240 if (ret < 0) 246 if (ret < 0)
241 return ERR_PTR(ret); 247 return ERR_PTR(ret);
242 248
243 /* Initialize the control handler. */ 249 /* Initialize the control handler. */
244 ret = vsp1_rwpf_init_ctrls(rpf); 250 ret = vsp1_rwpf_init_ctrls(rpf, 0);
245 if (ret < 0) { 251 if (ret < 0) {
246 dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n", 252 dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n",
247 index); 253 index);
248 goto error; 254 goto error;
249 } 255 }
250 256
257 v4l2_ctrl_handler_setup(&rpf->ctrls);
258
251 return rpf; 259 return rpf;
252 260
253error: 261error:
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index 3b6e032e7806..8d461b375e91 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -241,11 +241,9 @@ static const struct v4l2_ctrl_ops vsp1_rwpf_ctrl_ops = {
241 .s_ctrl = vsp1_rwpf_s_ctrl, 241 .s_ctrl = vsp1_rwpf_s_ctrl,
242}; 242};
243 243
244int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf) 244int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf, unsigned int ncontrols)
245{ 245{
246 rwpf->alpha = 255; 246 v4l2_ctrl_handler_init(&rwpf->ctrls, ncontrols + 1);
247
248 v4l2_ctrl_handler_init(&rwpf->ctrls, 1);
249 v4l2_ctrl_new_std(&rwpf->ctrls, &vsp1_rwpf_ctrl_ops, 247 v4l2_ctrl_new_std(&rwpf->ctrls, &vsp1_rwpf_ctrl_ops,
250 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); 248 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
251 249
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 9ff7c78f239e..cb20484e80da 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -13,6 +13,8 @@
13#ifndef __VSP1_RWPF_H__ 13#ifndef __VSP1_RWPF_H__
14#define __VSP1_RWPF_H__ 14#define __VSP1_RWPF_H__
15 15
16#include <linux/spinlock.h>
17
16#include <media/media-entity.h> 18#include <media/media-entity.h>
17#include <media/v4l2-ctrls.h> 19#include <media/v4l2-ctrls.h>
18#include <media/v4l2-subdev.h> 20#include <media/v4l2-subdev.h>
@@ -49,6 +51,16 @@ struct vsp1_rwpf {
49 51
50 unsigned int alpha; 52 unsigned int alpha;
51 53
54 u32 mult_alpha;
55 u32 outfmt;
56
57 struct {
58 spinlock_t lock;
59 struct v4l2_ctrl *ctrls[2];
60 unsigned int pending;
61 unsigned int active;
62 } flip;
63
52 unsigned int offsets[2]; 64 unsigned int offsets[2];
53 struct vsp1_rwpf_memory mem; 65 struct vsp1_rwpf_memory mem;
54 66
@@ -68,7 +80,7 @@ static inline struct vsp1_rwpf *entity_to_rwpf(struct vsp1_entity *entity)
68struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); 80struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index);
69struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); 81struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index);
70 82
71int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf); 83int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf, unsigned int ncontrols);
72 84
73extern const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops; 85extern const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops;
74 86
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 97ef997ae735..47f5e0cea2ce 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -37,7 +37,7 @@ static inline void vsp1_sru_write(struct vsp1_sru *sru, struct vsp1_dl_list *dl,
37 * Controls 37 * Controls
38 */ 38 */
39 39
40#define V4L2_CID_VSP1_SRU_INTENSITY (V4L2_CID_USER_BASE + 1) 40#define V4L2_CID_VSP1_SRU_INTENSITY (V4L2_CID_USER_BASE | 0x1001)
41 41
42struct vsp1_sru_param { 42struct vsp1_sru_param {
43 u32 ctrl0; 43 u32 ctrl0;
@@ -239,7 +239,7 @@ static int sru_set_format(struct v4l2_subdev *subdev,
239 return 0; 239 return 0;
240} 240}
241 241
242static struct v4l2_subdev_pad_ops sru_pad_ops = { 242static const struct v4l2_subdev_pad_ops sru_pad_ops = {
243 .init_cfg = vsp1_entity_init_cfg, 243 .init_cfg = vsp1_entity_init_cfg,
244 .enum_mbus_code = sru_enum_mbus_code, 244 .enum_mbus_code = sru_enum_mbus_code,
245 .enum_frame_size = sru_enum_frame_size, 245 .enum_frame_size = sru_enum_frame_size,
@@ -247,7 +247,7 @@ static struct v4l2_subdev_pad_ops sru_pad_ops = {
247 .set_fmt = sru_set_format, 247 .set_fmt = sru_set_format,
248}; 248};
249 249
250static struct v4l2_subdev_ops sru_ops = { 250static const struct v4l2_subdev_ops sru_ops = {
251 .pad = &sru_pad_ops, 251 .pad = &sru_pad_ops,
252}; 252};
253 253
@@ -257,7 +257,7 @@ static struct v4l2_subdev_ops sru_ops = {
257 257
258static void sru_configure(struct vsp1_entity *entity, 258static void sru_configure(struct vsp1_entity *entity,
259 struct vsp1_pipeline *pipe, 259 struct vsp1_pipeline *pipe,
260 struct vsp1_dl_list *dl) 260 struct vsp1_dl_list *dl, bool full)
261{ 261{
262 const struct vsp1_sru_param *param; 262 const struct vsp1_sru_param *param;
263 struct vsp1_sru *sru = to_sru(&entity->subdev); 263 struct vsp1_sru *sru = to_sru(&entity->subdev);
@@ -265,6 +265,9 @@ static void sru_configure(struct vsp1_entity *entity,
265 struct v4l2_mbus_framefmt *output; 265 struct v4l2_mbus_framefmt *output;
266 u32 ctrl0; 266 u32 ctrl0;
267 267
268 if (!full)
269 return;
270
268 input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, 271 input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
269 SRU_PAD_SINK); 272 SRU_PAD_SINK);
270 output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config, 273 output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
@@ -308,7 +311,8 @@ struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
308 sru->entity.ops = &sru_entity_ops; 311 sru->entity.ops = &sru_entity_ops;
309 sru->entity.type = VSP1_ENTITY_SRU; 312 sru->entity.type = VSP1_ENTITY_SRU;
310 313
311 ret = vsp1_entity_init(vsp1, &sru->entity, "sru", 2, &sru_ops); 314 ret = vsp1_entity_init(vsp1, &sru->entity, "sru", 2, &sru_ops,
315 MEDIA_ENT_F_PROC_VIDEO_SCALER);
312 if (ret < 0) 316 if (ret < 0)
313 return ERR_PTR(ret); 317 return ERR_PTR(ret);
314 318
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 1875e29da184..652dcd895022 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -40,9 +40,11 @@ static inline void vsp1_uds_write(struct vsp1_uds *uds, struct vsp1_dl_list *dl,
40 * Scaling Computation 40 * Scaling Computation
41 */ 41 */
42 42
43void vsp1_uds_set_alpha(struct vsp1_uds *uds, struct vsp1_dl_list *dl, 43void vsp1_uds_set_alpha(struct vsp1_entity *entity, struct vsp1_dl_list *dl,
44 unsigned int alpha) 44 unsigned int alpha)
45{ 45{
46 struct vsp1_uds *uds = to_uds(&entity->subdev);
47
46 vsp1_uds_write(uds, dl, VI6_UDS_ALPVAL, 48 vsp1_uds_write(uds, dl, VI6_UDS_ALPVAL,
47 alpha << VI6_UDS_ALPVAL_VAL0_SHIFT); 49 alpha << VI6_UDS_ALPVAL_VAL0_SHIFT);
48} 50}
@@ -226,7 +228,7 @@ static int uds_set_format(struct v4l2_subdev *subdev,
226 * V4L2 Subdevice Operations 228 * V4L2 Subdevice Operations
227 */ 229 */
228 230
229static struct v4l2_subdev_pad_ops uds_pad_ops = { 231static const struct v4l2_subdev_pad_ops uds_pad_ops = {
230 .init_cfg = vsp1_entity_init_cfg, 232 .init_cfg = vsp1_entity_init_cfg,
231 .enum_mbus_code = uds_enum_mbus_code, 233 .enum_mbus_code = uds_enum_mbus_code,
232 .enum_frame_size = uds_enum_frame_size, 234 .enum_frame_size = uds_enum_frame_size,
@@ -234,7 +236,7 @@ static struct v4l2_subdev_pad_ops uds_pad_ops = {
234 .set_fmt = uds_set_format, 236 .set_fmt = uds_set_format,
235}; 237};
236 238
237static struct v4l2_subdev_ops uds_ops = { 239static const struct v4l2_subdev_ops uds_ops = {
238 .pad = &uds_pad_ops, 240 .pad = &uds_pad_ops,
239}; 241};
240 242
@@ -244,7 +246,7 @@ static struct v4l2_subdev_ops uds_ops = {
244 246
245static void uds_configure(struct vsp1_entity *entity, 247static void uds_configure(struct vsp1_entity *entity,
246 struct vsp1_pipeline *pipe, 248 struct vsp1_pipeline *pipe,
247 struct vsp1_dl_list *dl) 249 struct vsp1_dl_list *dl, bool full)
248{ 250{
249 struct vsp1_uds *uds = to_uds(&entity->subdev); 251 struct vsp1_uds *uds = to_uds(&entity->subdev);
250 const struct v4l2_mbus_framefmt *output; 252 const struct v4l2_mbus_framefmt *output;
@@ -253,6 +255,9 @@ static void uds_configure(struct vsp1_entity *entity,
253 unsigned int vscale; 255 unsigned int vscale;
254 bool multitap; 256 bool multitap;
255 257
258 if (!full)
259 return;
260
256 input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, 261 input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
257 UDS_PAD_SINK); 262 UDS_PAD_SINK);
258 output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config, 263 output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
@@ -314,7 +319,8 @@ struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index)
314 uds->entity.index = index; 319 uds->entity.index = index;
315 320
316 sprintf(name, "uds.%u", index); 321 sprintf(name, "uds.%u", index);
317 ret = vsp1_entity_init(vsp1, &uds->entity, name, 2, &uds_ops); 322 ret = vsp1_entity_init(vsp1, &uds->entity, name, 2, &uds_ops,
323 MEDIA_ENT_F_PROC_VIDEO_SCALER);
318 if (ret < 0) 324 if (ret < 0)
319 return ERR_PTR(ret); 325 return ERR_PTR(ret);
320 326
diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h
index 5c8cbfcad4cc..7bf3cdcffc65 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.h
+++ b/drivers/media/platform/vsp1/vsp1_uds.h
@@ -35,7 +35,7 @@ static inline struct vsp1_uds *to_uds(struct v4l2_subdev *subdev)
35 35
36struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index); 36struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index);
37 37
38void vsp1_uds_set_alpha(struct vsp1_uds *uds, struct vsp1_dl_list *dl, 38void vsp1_uds_set_alpha(struct vsp1_entity *uds, struct vsp1_dl_list *dl,
39 unsigned int alpha); 39 unsigned int alpha);
40 40
41#endif /* __VSP1_UDS_H__ */ 41#endif /* __VSP1_UDS_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index a9aec5c0bec6..01654232b695 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -219,7 +219,7 @@ vsp1_video_complete_buffer(struct vsp1_video *video)
219 219
220 spin_unlock_irqrestore(&video->irqlock, flags); 220 spin_unlock_irqrestore(&video->irqlock, flags);
221 221
222 done->buf.sequence = video->sequence++; 222 done->buf.sequence = pipe->sequence;
223 done->buf.vb2_buf.timestamp = ktime_get_ns(); 223 done->buf.vb2_buf.timestamp = ktime_get_ns();
224 for (i = 0; i < done->buf.vb2_buf.num_planes; ++i) 224 for (i = 0; i < done->buf.vb2_buf.num_planes; ++i)
225 vb2_set_plane_payload(&done->buf.vb2_buf, i, 225 vb2_set_plane_payload(&done->buf.vb2_buf, i,
@@ -251,11 +251,17 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
251static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe) 251static void vsp1_video_pipeline_run(struct vsp1_pipeline *pipe)
252{ 252{
253 struct vsp1_device *vsp1 = pipe->output->entity.vsp1; 253 struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
254 struct vsp1_entity *entity;
254 unsigned int i; 255 unsigned int i;
255 256
256 if (!pipe->dl) 257 if (!pipe->dl)
257 pipe->dl = vsp1_dl_list_get(pipe->output->dlm); 258 pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
258 259
260 list_for_each_entry(entity, &pipe->entities, list_pipe) {
261 if (entity->ops->configure)
262 entity->ops->configure(entity, pipe, pipe->dl, false);
263 }
264
259 for (i = 0; i < vsp1->info->rpf_count; ++i) { 265 for (i = 0; i < vsp1->info->rpf_count; ++i) {
260 struct vsp1_rwpf *rwpf = pipe->inputs[i]; 266 struct vsp1_rwpf *rwpf = pipe->inputs[i];
261 267
@@ -632,7 +638,7 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
632 vsp1_entity_route_setup(entity, pipe->dl); 638 vsp1_entity_route_setup(entity, pipe->dl);
633 639
634 if (entity->ops->configure) 640 if (entity->ops->configure)
635 entity->ops->configure(entity, pipe, pipe->dl); 641 entity->ops->configure(entity, pipe, pipe->dl, true);
636 } 642 }
637 643
638 return 0; 644 return 0;
@@ -674,7 +680,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
674 int ret; 680 int ret;
675 681
676 mutex_lock(&pipe->lock); 682 mutex_lock(&pipe->lock);
677 if (--pipe->stream_count == 0) { 683 if (--pipe->stream_count == pipe->num_inputs) {
678 /* Stop the pipeline. */ 684 /* Stop the pipeline. */
679 ret = vsp1_pipeline_stop(pipe); 685 ret = vsp1_pipeline_stop(pipe);
680 if (ret == -ETIMEDOUT) 686 if (ret == -ETIMEDOUT)
@@ -696,7 +702,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
696 spin_unlock_irqrestore(&video->irqlock, flags); 702 spin_unlock_irqrestore(&video->irqlock, flags);
697} 703}
698 704
699static struct vb2_ops vsp1_video_queue_qops = { 705static const struct vb2_ops vsp1_video_queue_qops = {
700 .queue_setup = vsp1_video_queue_setup, 706 .queue_setup = vsp1_video_queue_setup,
701 .buf_prepare = vsp1_video_buffer_prepare, 707 .buf_prepare = vsp1_video_buffer_prepare,
702 .buf_queue = vsp1_video_buffer_queue, 708 .buf_queue = vsp1_video_buffer_queue,
@@ -805,8 +811,6 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
805 if (video->queue.owner && video->queue.owner != file->private_data) 811 if (video->queue.owner && video->queue.owner != file->private_data)
806 return -EBUSY; 812 return -EBUSY;
807 813
808 video->sequence = 0;
809
810 /* Get a pipeline for the video node and start streaming on it. No link 814 /* Get a pipeline for the video node and start streaming on it. No link
811 * touching an entity in the pipeline can be activated or deactivated 815 * touching an entity in the pipeline can be activated or deactivated
812 * once streaming is started. 816 * once streaming is started.
@@ -915,7 +919,7 @@ static int vsp1_video_release(struct file *file)
915 return 0; 919 return 0;
916} 920}
917 921
918static struct v4l2_file_operations vsp1_video_fops = { 922static const struct v4l2_file_operations vsp1_video_fops = {
919 .owner = THIS_MODULE, 923 .owner = THIS_MODULE,
920 .unlocked_ioctl = video_ioctl2, 924 .unlocked_ioctl = video_ioctl2,
921 .open = vsp1_video_open, 925 .open = vsp1_video_open,
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 867b00807c46..1595fd587fbc 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -49,7 +49,6 @@ struct vsp1_video {
49 void *alloc_ctx; 49 void *alloc_ctx;
50 spinlock_t irqlock; 50 spinlock_t irqlock;
51 struct list_head irqqueue; 51 struct list_head irqqueue;
52 unsigned int sequence;
53}; 52};
54 53
55static inline struct vsp1_video *to_vsp1_video(struct video_device *vdev) 54static inline struct vsp1_video *to_vsp1_video(struct video_device *vdev)
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 6c91eaa35e75..31983169c24a 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -37,6 +37,97 @@ static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf,
37} 37}
38 38
39/* ----------------------------------------------------------------------------- 39/* -----------------------------------------------------------------------------
40 * Controls
41 */
42
43enum wpf_flip_ctrl {
44 WPF_CTRL_VFLIP = 0,
45 WPF_CTRL_HFLIP = 1,
46 WPF_CTRL_MAX,
47};
48
49static int vsp1_wpf_s_ctrl(struct v4l2_ctrl *ctrl)
50{
51 struct vsp1_rwpf *wpf =
52 container_of(ctrl->handler, struct vsp1_rwpf, ctrls);
53 unsigned int i;
54 u32 flip = 0;
55
56 switch (ctrl->id) {
57 case V4L2_CID_HFLIP:
58 case V4L2_CID_VFLIP:
59 for (i = 0; i < WPF_CTRL_MAX; ++i) {
60 if (wpf->flip.ctrls[i])
61 flip |= wpf->flip.ctrls[i]->val ? BIT(i) : 0;
62 }
63
64 spin_lock_irq(&wpf->flip.lock);
65 wpf->flip.pending = flip;
66 spin_unlock_irq(&wpf->flip.lock);
67 break;
68
69 default:
70 return -EINVAL;
71 }
72
73 return 0;
74}
75
76static const struct v4l2_ctrl_ops vsp1_wpf_ctrl_ops = {
77 .s_ctrl = vsp1_wpf_s_ctrl,
78};
79
80static int wpf_init_controls(struct vsp1_rwpf *wpf)
81{
82 struct vsp1_device *vsp1 = wpf->entity.vsp1;
83 unsigned int num_flip_ctrls;
84
85 spin_lock_init(&wpf->flip.lock);
86
87 if (wpf->entity.index != 0) {
88 /* Only WPF0 supports flipping. */
89 num_flip_ctrls = 0;
90 } else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) {
91 /* When horizontal flip is supported the WPF implements two
92 * controls (horizontal flip and vertical flip).
93 */
94 num_flip_ctrls = 2;
95 } else if (vsp1->info->features & VSP1_HAS_WPF_VFLIP) {
96 /* When only vertical flip is supported the WPF implements a
97 * single control (vertical flip).
98 */
99 num_flip_ctrls = 1;
100 } else {
101 /* Otherwise flipping is not supported. */
102 num_flip_ctrls = 0;
103 }
104
105 vsp1_rwpf_init_ctrls(wpf, num_flip_ctrls);
106
107 if (num_flip_ctrls >= 1) {
108 wpf->flip.ctrls[WPF_CTRL_VFLIP] =
109 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
110 V4L2_CID_VFLIP, 0, 1, 1, 0);
111 }
112
113 if (num_flip_ctrls == 2) {
114 wpf->flip.ctrls[WPF_CTRL_HFLIP] =
115 v4l2_ctrl_new_std(&wpf->ctrls, &vsp1_wpf_ctrl_ops,
116 V4L2_CID_HFLIP, 0, 1, 1, 0);
117
118 v4l2_ctrl_cluster(2, wpf->flip.ctrls);
119 }
120
121 if (wpf->ctrls.error) {
122 dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n",
123 wpf->entity.index);
124 return wpf->ctrls.error;
125 }
126
127 return 0;
128}
129
130/* -----------------------------------------------------------------------------
40 * V4L2 Subdevice Core Operations 131 * V4L2 Subdevice Core Operations
41 */ 132 */
42 133
@@ -62,11 +153,11 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
62 * V4L2 Subdevice Operations 153 * V4L2 Subdevice Operations
63 */ 154 */
64 155
65static struct v4l2_subdev_video_ops wpf_video_ops = { 156static const struct v4l2_subdev_video_ops wpf_video_ops = {
66 .s_stream = wpf_s_stream, 157 .s_stream = wpf_s_stream,
67}; 158};
68 159
69static struct v4l2_subdev_ops wpf_ops = { 160static const struct v4l2_subdev_ops wpf_ops = {
70 .video = &wpf_video_ops, 161 .video = &wpf_video_ops,
71 .pad = &vsp1_rwpf_pad_ops, 162 .pad = &vsp1_rwpf_pad_ops,
72}; 163};
@@ -85,15 +176,37 @@ static void vsp1_wpf_destroy(struct vsp1_entity *entity)
85static void wpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl) 176static void wpf_set_memory(struct vsp1_entity *entity, struct vsp1_dl_list *dl)
86{ 177{
87 struct vsp1_rwpf *wpf = entity_to_rwpf(entity); 178 struct vsp1_rwpf *wpf = entity_to_rwpf(entity);
179 const struct v4l2_pix_format_mplane *format = &wpf->format;
180 struct vsp1_rwpf_memory mem = wpf->mem;
181 unsigned int flip = wpf->flip.active;
182 unsigned int offset;
183
184 /* Update the memory offsets based on flipping configuration. The
185 * destination addresses point to the locations where the VSP starts
186 * writing to memory, which can be different corners of the image
187 * depending on vertical flipping. Horizontal flipping is handled
188 * through a line buffer and doesn't modify the start address.
189 */
190 if (flip & BIT(WPF_CTRL_VFLIP)) {
191 mem.addr[0] += (format->height - 1)
192 * format->plane_fmt[0].bytesperline;
193
194 if (format->num_planes > 1) {
195 offset = (format->height / wpf->fmtinfo->vsub - 1)
196 * format->plane_fmt[1].bytesperline;
197 mem.addr[1] += offset;
198 mem.addr[2] += offset;
199 }
200 }
88 201
89 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, wpf->mem.addr[0]); 202 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_Y, mem.addr[0]);
90 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, wpf->mem.addr[1]); 203 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C0, mem.addr[1]);
91 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, wpf->mem.addr[2]); 204 vsp1_wpf_write(wpf, dl, VI6_WPF_DSTM_ADDR_C1, mem.addr[2]);
92} 205}
93 206
94static void wpf_configure(struct vsp1_entity *entity, 207static void wpf_configure(struct vsp1_entity *entity,
95 struct vsp1_pipeline *pipe, 208 struct vsp1_pipeline *pipe,
96 struct vsp1_dl_list *dl) 209 struct vsp1_dl_list *dl, bool full)
97{ 210{
98 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev); 211 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
99 struct vsp1_device *vsp1 = wpf->entity.vsp1; 212 struct vsp1_device *vsp1 = wpf->entity.vsp1;
@@ -104,6 +217,26 @@ static void wpf_configure(struct vsp1_entity *entity,
104 u32 outfmt = 0; 217 u32 outfmt = 0;
105 u32 srcrpf = 0; 218 u32 srcrpf = 0;
106 219
220 if (!full) {
221 const unsigned int mask = BIT(WPF_CTRL_VFLIP)
222 | BIT(WPF_CTRL_HFLIP);
223
224 spin_lock(&wpf->flip.lock);
225 wpf->flip.active = (wpf->flip.active & ~mask)
226 | (wpf->flip.pending & mask);
227 spin_unlock(&wpf->flip.lock);
228
229 outfmt = (wpf->alpha << VI6_WPF_OUTFMT_PDV_SHIFT) | wpf->outfmt;
230
231 if (wpf->flip.active & BIT(WPF_CTRL_VFLIP))
232 outfmt |= VI6_WPF_OUTFMT_FLP;
233 if (wpf->flip.active & BIT(WPF_CTRL_HFLIP))
234 outfmt |= VI6_WPF_OUTFMT_HFLP;
235
236 vsp1_wpf_write(wpf, dl, VI6_WPF_OUTFMT, outfmt);
237 return;
238 }
239
107 /* Cropping */ 240 /* Cropping */
108 crop = vsp1_rwpf_get_crop(wpf, wpf->entity.config); 241 crop = vsp1_rwpf_get_crop(wpf, wpf->entity.config);
109 242
@@ -143,13 +276,18 @@ static void wpf_configure(struct vsp1_entity *entity,
143 format->plane_fmt[1].bytesperline); 276 format->plane_fmt[1].bytesperline);
144 277
145 vsp1_wpf_write(wpf, dl, VI6_WPF_DSWAP, fmtinfo->swap); 278 vsp1_wpf_write(wpf, dl, VI6_WPF_DSWAP, fmtinfo->swap);
279
280 if (vsp1->info->features & VSP1_HAS_WPF_HFLIP &&
281 wpf->entity.index == 0)
282 vsp1_wpf_write(wpf, dl, VI6_WPF_ROT_CTRL,
283 VI6_WPF_ROT_CTRL_LN16 |
284 (256 << VI6_WPF_ROT_CTRL_LMEM_WD_SHIFT));
146 } 285 }
147 286
148 if (sink_format->code != source_format->code) 287 if (sink_format->code != source_format->code)
149 outfmt |= VI6_WPF_OUTFMT_CSC; 288 outfmt |= VI6_WPF_OUTFMT_CSC;
150 289
151 outfmt |= wpf->alpha << VI6_WPF_OUTFMT_PDV_SHIFT; 290 wpf->outfmt = outfmt;
152 vsp1_wpf_write(wpf, dl, VI6_WPF_OUTFMT, outfmt);
153 291
154 vsp1_dl_list_write(dl, VI6_DPR_WPF_FPORCH(wpf->entity.index), 292 vsp1_dl_list_write(dl, VI6_DPR_WPF_FPORCH(wpf->entity.index),
155 VI6_DPR_WPF_FPORCH_FP_WPFN); 293 VI6_DPR_WPF_FPORCH_FP_WPFN);
@@ -216,7 +354,8 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
216 wpf->entity.index = index; 354 wpf->entity.index = index;
217 355
218 sprintf(name, "wpf.%u", index); 356 sprintf(name, "wpf.%u", index);
219 ret = vsp1_entity_init(vsp1, &wpf->entity, name, 2, &wpf_ops); 357 ret = vsp1_entity_init(vsp1, &wpf->entity, name, 2, &wpf_ops,
358 MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER);
220 if (ret < 0) 359 if (ret < 0)
221 return ERR_PTR(ret); 360 return ERR_PTR(ret);
222 361
@@ -228,13 +367,15 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
228 } 367 }
229 368
230 /* Initialize the control handler. */ 369 /* Initialize the control handler. */
231 ret = vsp1_rwpf_init_ctrls(wpf); 370 ret = wpf_init_controls(wpf);
232 if (ret < 0) { 371 if (ret < 0) {
233 dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n", 372 dev_err(vsp1->dev, "wpf%u: failed to initialize controls\n",
234 index); 373 index);
235 goto error; 374 goto error;
236 } 375 }
237 376
377 v4l2_ctrl_handler_setup(&wpf->ctrls);
378
238 return wpf; 379 return wpf;
239 380
240error: 381error:
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index 6457ac91ef09..7f0b9d5940db 100644
--- a/drivers/media/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -24,6 +24,7 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/videodev2.h> 26#include <linux/videodev2.h>
27#include <linux/gcd.h>
27 28
28#include "mt2063.h" 29#include "mt2063.h"
29 30
@@ -665,27 +666,6 @@ static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
665} 666}
666 667
667/** 668/**
668 * gcd() - Uses Euclid's algorithm
669 *
670 * @u, @v: Unsigned values whose GCD is desired.
671 *
672 * Returns THE greatest common divisor of u and v, if either value is 0,
673 * the other value is returned as the result.
674 */
675static u32 MT2063_gcd(u32 u, u32 v)
676{
677 u32 r;
678
679 while (v != 0) {
680 r = u % v;
681 u = v;
682 v = r;
683 }
684
685 return u;
686}
687
688/**
689 * IsSpurInBand() - Checks to see if a spur will be present within the IF's 669 * IsSpurInBand() - Checks to see if a spur will be present within the IF's
690 * bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW) 670 * bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
691 * 671 *
@@ -731,12 +711,12 @@ static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
731 ** of f_LO1, f_LO2 and the edge value. Use the larger of this 711 ** of f_LO1, f_LO2 and the edge value. Use the larger of this
732 ** gcd-based scale factor or f_Scale. 712 ** gcd-based scale factor or f_Scale.
733 */ 713 */
734 lo_gcd = MT2063_gcd(f_LO1, f_LO2); 714 lo_gcd = gcd(f_LO1, f_LO2);
735 gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale); 715 gd_Scale = max((u32) gcd(lo_gcd, d), f_Scale);
736 hgds = gd_Scale / 2; 716 hgds = gd_Scale / 2;
737 gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale); 717 gc_Scale = max((u32) gcd(lo_gcd, c), f_Scale);
738 hgcs = gc_Scale / 2; 718 hgcs = gc_Scale / 2;
739 gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale); 719 gf_Scale = max((u32) gcd(lo_gcd, f), f_Scale);
740 hgfs = gf_Scale / 2; 720 hgfs = gf_Scale / 2;
741 721
742 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2); 722 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 321ea5cf1329..bf53553d2624 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -142,7 +142,7 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
142 struct media_device *mdev = dev->media_dev; 142 struct media_device *mdev = dev->media_dev;
143 struct media_entity_notify *notify, *nextp; 143 struct media_entity_notify *notify, *nextp;
144 144
145 if (!mdev || !media_devnode_is_registered(&mdev->devnode)) 145 if (!mdev || !media_devnode_is_registered(mdev->devnode))
146 return; 146 return;
147 147
148 /* Remove au0828 entity_notify callbacks */ 148 /* Remove au0828 entity_notify callbacks */
@@ -482,7 +482,7 @@ static int au0828_media_device_register(struct au0828_dev *dev,
482 if (!dev->media_dev) 482 if (!dev->media_dev)
483 return 0; 483 return 0;
484 484
485 if (!media_devnode_is_registered(&dev->media_dev->devnode)) { 485 if (!media_devnode_is_registered(dev->media_dev->devnode)) {
486 486
487 /* register media device */ 487 /* register media device */
488 ret = media_device_register(dev->media_dev); 488 ret = media_device_register(dev->media_dev);
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index 3dc8ef004f8b..524533d3eb29 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -127,17 +127,22 @@ config DVB_USB_MXL111SF
127config DVB_USB_RTL28XXU 127config DVB_USB_RTL28XXU
128 tristate "Realtek RTL28xxU DVB USB support" 128 tristate "Realtek RTL28xxU DVB USB support"
129 depends on DVB_USB_V2 && I2C_MUX 129 depends on DVB_USB_V2 && I2C_MUX
130 select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
131 select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT
130 select DVB_RTL2830 132 select DVB_RTL2830
131 select DVB_RTL2832 133 select DVB_RTL2832
132 select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT) 134 select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
133 select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT 135 select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
134 select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT 136 select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT
135 select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
136 select MEDIA_TUNER_FC0012 if MEDIA_SUBDRV_AUTOSELECT 137 select MEDIA_TUNER_FC0012 if MEDIA_SUBDRV_AUTOSELECT
137 select MEDIA_TUNER_FC0013 if MEDIA_SUBDRV_AUTOSELECT 138 select MEDIA_TUNER_FC0013 if MEDIA_SUBDRV_AUTOSELECT
138 select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT
139 select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT 139 select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT
140 select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
141 select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
142 select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
140 select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT 143 select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT
144 select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
145 select MEDIA_TUNER_TUA9001 if MEDIA_SUBDRV_AUTOSELECT
141 help 146 help
142 Say Y here to support the Realtek RTL28xxU DVB USB receiver. 147 Say Y here to support the Realtek RTL28xxU DVB USB receiver.
143 148
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 2638e3251f2a..eabede44ad88 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -49,6 +49,7 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
49#define CHECKSUM_LEN 2 49#define CHECKSUM_LEN 2
50#define USB_TIMEOUT 2000 50#define USB_TIMEOUT 2000
51 struct state *state = d_to_priv(d); 51 struct state *state = d_to_priv(d);
52 struct usb_interface *intf = d->intf;
52 int ret, wlen, rlen; 53 int ret, wlen, rlen;
53 u16 checksum, tmp_checksum; 54 u16 checksum, tmp_checksum;
54 55
@@ -57,8 +58,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
57 /* buffer overflow check */ 58 /* buffer overflow check */
58 if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) || 59 if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
59 req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) { 60 req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
60 dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n", 61 dev_err(&intf->dev, "too much data wlen=%d rlen=%d\n",
61 KBUILD_MODNAME, req->wlen, req->rlen); 62 req->wlen, req->rlen);
62 ret = -EINVAL; 63 ret = -EINVAL;
63 goto exit; 64 goto exit;
64 } 65 }
@@ -94,10 +95,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
94 checksum = af9035_checksum(state->buf, rlen - 2); 95 checksum = af9035_checksum(state->buf, rlen - 2);
95 tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1]; 96 tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1];
96 if (tmp_checksum != checksum) { 97 if (tmp_checksum != checksum) {
97 dev_err(&d->udev->dev, 98 dev_err(&intf->dev, "command=%02x checksum mismatch (%04x != %04x)\n",
98 "%s: command=%02x checksum mismatch (%04x != %04x)\n", 99 req->cmd, tmp_checksum, checksum);
99 KBUILD_MODNAME, req->cmd, tmp_checksum,
100 checksum);
101 ret = -EIO; 100 ret = -EIO;
102 goto exit; 101 goto exit;
103 } 102 }
@@ -110,8 +109,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
110 goto exit; 109 goto exit;
111 } 110 }
112 111
113 dev_dbg(&d->udev->dev, "%s: command=%02x failed fw error=%d\n", 112 dev_dbg(&intf->dev, "command=%02x failed fw error=%d\n",
114 __func__, req->cmd, state->buf[2]); 113 req->cmd, state->buf[2]);
115 ret = -EIO; 114 ret = -EIO;
116 goto exit; 115 goto exit;
117 } 116 }
@@ -122,20 +121,20 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
122exit: 121exit:
123 mutex_unlock(&d->usb_mutex); 122 mutex_unlock(&d->usb_mutex);
124 if (ret < 0) 123 if (ret < 0)
125 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 124 dev_dbg(&intf->dev, "failed=%d\n", ret);
126 return ret; 125 return ret;
127} 126}
128 127
129/* write multiple registers */ 128/* write multiple registers */
130static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len) 129static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
131{ 130{
131 struct usb_interface *intf = d->intf;
132 u8 wbuf[MAX_XFER_SIZE]; 132 u8 wbuf[MAX_XFER_SIZE];
133 u8 mbox = (reg >> 16) & 0xff; 133 u8 mbox = (reg >> 16) & 0xff;
134 struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL }; 134 struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL };
135 135
136 if (6 + len > sizeof(wbuf)) { 136 if (6 + len > sizeof(wbuf)) {
137 dev_warn(&d->udev->dev, "%s: i2c wr: len=%d is too big!\n", 137 dev_warn(&intf->dev, "i2c wr: len=%d is too big!\n", len);
138 KBUILD_MODNAME, len);
139 return -EOPNOTSUPP; 138 return -EOPNOTSUPP;
140 } 139 }
141 140
@@ -198,6 +197,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
198{ 197{
199 int ret, num; 198 int ret, num;
200 struct state *state = d_to_priv(d); 199 struct state *state = d_to_priv(d);
200 struct usb_interface *intf = d->intf;
201 struct i2c_client *client; 201 struct i2c_client *client;
202 struct i2c_board_info board_info = { 202 struct i2c_board_info board_info = {
203 .addr = addr, 203 .addr = addr,
@@ -212,11 +212,10 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
212 break; 212 break;
213 } 213 }
214 214
215 dev_dbg(&d->udev->dev, "%s: num=%d\n", __func__, num); 215 dev_dbg(&intf->dev, "num=%d\n", num);
216 216
217 if (num == AF9035_I2C_CLIENT_MAX) { 217 if (num == AF9035_I2C_CLIENT_MAX) {
218 dev_err(&d->udev->dev, "%s: I2C client out of index\n", 218 dev_err(&intf->dev, "I2C client out of index\n");
219 KBUILD_MODNAME);
220 ret = -ENODEV; 219 ret = -ENODEV;
221 goto err; 220 goto err;
222 } 221 }
@@ -240,7 +239,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
240 state->i2c_client[num] = client; 239 state->i2c_client[num] = client;
241 return 0; 240 return 0;
242err: 241err:
243 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 242 dev_dbg(&intf->dev, "failed=%d\n", ret);
244 return ret; 243 return ret;
245} 244}
246 245
@@ -248,6 +247,7 @@ static void af9035_del_i2c_dev(struct dvb_usb_device *d)
248{ 247{
249 int num; 248 int num;
250 struct state *state = d_to_priv(d); 249 struct state *state = d_to_priv(d);
250 struct usb_interface *intf = d->intf;
251 struct i2c_client *client; 251 struct i2c_client *client;
252 252
253 /* find last used client */ 253 /* find last used client */
@@ -257,11 +257,10 @@ static void af9035_del_i2c_dev(struct dvb_usb_device *d)
257 break; 257 break;
258 } 258 }
259 259
260 dev_dbg(&d->udev->dev, "%s: num=%d\n", __func__, num); 260 dev_dbg(&intf->dev, "num=%d\n", num);
261 261
262 if (num == -1) { 262 if (num == -1) {
263 dev_err(&d->udev->dev, "%s: I2C client out of index\n", 263 dev_err(&intf->dev, "I2C client out of index\n");
264 KBUILD_MODNAME);
265 goto err; 264 goto err;
266 } 265 }
267 266
@@ -276,7 +275,7 @@ static void af9035_del_i2c_dev(struct dvb_usb_device *d)
276 state->i2c_client[num] = NULL; 275 state->i2c_client[num] = NULL;
277 return; 276 return;
278err: 277err:
279 dev_dbg(&d->udev->dev, "%s: failed\n", __func__); 278 dev_dbg(&intf->dev, "failed\n");
280} 279}
281 280
282static int af9035_i2c_master_xfer(struct i2c_adapter *adap, 281static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
@@ -348,6 +347,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
348 347
349 ret = af9035_rd_regs(d, reg, &msg[1].buf[0], 348 ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
350 msg[1].len); 349 msg[1].len);
350 } else if (state->no_read) {
351 memset(msg[1].buf, 0, msg[1].len);
352 ret = 0;
351 } else { 353 } else {
352 /* I2C write + read */ 354 /* I2C write + read */
353 u8 buf[MAX_XFER_SIZE]; 355 u8 buf[MAX_XFER_SIZE];
@@ -367,10 +369,25 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
367 memcpy(&buf[3], msg[0].buf, msg[0].len); 369 memcpy(&buf[3], msg[0].buf, msg[0].len);
368 } else { 370 } else {
369 buf[1] = msg[0].addr << 1; 371 buf[1] = msg[0].addr << 1;
370 buf[2] = 0x00; /* reg addr len */
371 buf[3] = 0x00; /* reg addr MSB */ 372 buf[3] = 0x00; /* reg addr MSB */
372 buf[4] = 0x00; /* reg addr LSB */ 373 buf[4] = 0x00; /* reg addr LSB */
373 memcpy(&buf[5], msg[0].buf, msg[0].len); 374
375 /* Keep prev behavior for write req len > 2*/
376 if (msg[0].len > 2) {
377 buf[2] = 0x00; /* reg addr len */
378 memcpy(&buf[5], msg[0].buf, msg[0].len);
379
380 /* Use reg addr fields if write req len <= 2 */
381 } else {
382 req.wlen = 5;
383 buf[2] = msg[0].len;
384 if (msg[0].len == 2) {
385 buf[3] = msg[0].buf[0];
386 buf[4] = msg[0].buf[1];
387 } else if (msg[0].len == 1) {
388 buf[4] = msg[0].buf[0];
389 }
390 }
374 } 391 }
375 ret = af9035_ctrl_msg(d, &req); 392 ret = af9035_ctrl_msg(d, &req);
376 } 393 }
@@ -421,6 +438,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
421 if (msg[0].len > 40) { 438 if (msg[0].len > 40) {
422 /* TODO: correct limits > 40 */ 439 /* TODO: correct limits > 40 */
423 ret = -EOPNOTSUPP; 440 ret = -EOPNOTSUPP;
441 } else if (state->no_read) {
442 memset(msg[0].buf, 0, msg[0].len);
443 ret = 0;
424 } else { 444 } else {
425 /* I2C read */ 445 /* I2C read */
426 u8 buf[5]; 446 u8 buf[5];
@@ -475,6 +495,7 @@ static struct i2c_algorithm af9035_i2c_algo = {
475static int af9035_identify_state(struct dvb_usb_device *d, const char **name) 495static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
476{ 496{
477 struct state *state = d_to_priv(d); 497 struct state *state = d_to_priv(d);
498 struct usb_interface *intf = d->intf;
478 int ret; 499 int ret;
479 u8 wbuf[1] = { 1 }; 500 u8 wbuf[1] = { 1 };
480 u8 rbuf[4]; 501 u8 rbuf[4];
@@ -492,10 +513,8 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
492 if (ret < 0) 513 if (ret < 0)
493 goto err; 514 goto err;
494 515
495 dev_info(&d->udev->dev, 516 dev_info(&intf->dev, "prechip_version=%02x chip_version=%02x chip_type=%04x\n",
496 "%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n", 517 state->prechip_version, state->chip_version, state->chip_type);
497 KBUILD_MODNAME, state->prechip_version,
498 state->chip_version, state->chip_type);
499 518
500 if (state->chip_type == 0x9135) { 519 if (state->chip_type == 0x9135) {
501 if (state->chip_version == 0x02) 520 if (state->chip_version == 0x02)
@@ -515,7 +534,7 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
515 if (ret < 0) 534 if (ret < 0)
516 goto err; 535 goto err;
517 536
518 dev_dbg(&d->udev->dev, "%s: reply=%*ph\n", __func__, 4, rbuf); 537 dev_dbg(&intf->dev, "reply=%*ph\n", 4, rbuf);
519 if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3]) 538 if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
520 ret = WARM; 539 ret = WARM;
521 else 540 else
@@ -524,7 +543,7 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
524 return ret; 543 return ret;
525 544
526err: 545err:
527 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 546 dev_dbg(&intf->dev, "failed=%d\n", ret);
528 547
529 return ret; 548 return ret;
530} 549}
@@ -532,6 +551,7 @@ err:
532static int af9035_download_firmware_old(struct dvb_usb_device *d, 551static int af9035_download_firmware_old(struct dvb_usb_device *d,
533 const struct firmware *fw) 552 const struct firmware *fw)
534{ 553{
554 struct usb_interface *intf = d->intf;
535 int ret, i, j, len; 555 int ret, i, j, len;
536 u8 wbuf[1]; 556 u8 wbuf[1];
537 struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; 557 struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
@@ -562,14 +582,12 @@ static int af9035_download_firmware_old(struct dvb_usb_device *d,
562 hdr_checksum = fw->data[fw->size - i + 5] << 8; 582 hdr_checksum = fw->data[fw->size - i + 5] << 8;
563 hdr_checksum |= fw->data[fw->size - i + 6] << 0; 583 hdr_checksum |= fw->data[fw->size - i + 6] << 0;
564 584
565 dev_dbg(&d->udev->dev, 585 dev_dbg(&intf->dev, "core=%d addr=%04x data_len=%d checksum=%04x\n",
566 "%s: core=%d addr=%04x data_len=%d checksum=%04x\n", 586 hdr_core, hdr_addr, hdr_data_len, hdr_checksum);
567 __func__, hdr_core, hdr_addr, hdr_data_len,
568 hdr_checksum);
569 587
570 if (((hdr_core != 1) && (hdr_core != 2)) || 588 if (((hdr_core != 1) && (hdr_core != 2)) ||
571 (hdr_data_len > i)) { 589 (hdr_data_len > i)) {
572 dev_dbg(&d->udev->dev, "%s: bad firmware\n", __func__); 590 dev_dbg(&intf->dev, "bad firmware\n");
573 break; 591 break;
574 } 592 }
575 593
@@ -600,18 +618,17 @@ static int af9035_download_firmware_old(struct dvb_usb_device *d,
600 618
601 i -= hdr_data_len + HDR_SIZE; 619 i -= hdr_data_len + HDR_SIZE;
602 620
603 dev_dbg(&d->udev->dev, "%s: data uploaded=%zu\n", 621 dev_dbg(&intf->dev, "data uploaded=%zu\n", fw->size - i);
604 __func__, fw->size - i);
605 } 622 }
606 623
607 /* print warn if firmware is bad, continue and see what happens */ 624 /* print warn if firmware is bad, continue and see what happens */
608 if (i) 625 if (i)
609 dev_warn(&d->udev->dev, "%s: bad firmware\n", KBUILD_MODNAME); 626 dev_warn(&intf->dev, "bad firmware\n");
610 627
611 return 0; 628 return 0;
612 629
613err: 630err:
614 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 631 dev_dbg(&intf->dev, "failed=%d\n", ret);
615 632
616 return ret; 633 return ret;
617} 634}
@@ -619,6 +636,7 @@ err:
619static int af9035_download_firmware_new(struct dvb_usb_device *d, 636static int af9035_download_firmware_new(struct dvb_usb_device *d,
620 const struct firmware *fw) 637 const struct firmware *fw)
621{ 638{
639 struct usb_interface *intf = d->intf;
622 int ret, i, i_prev; 640 int ret, i, i_prev;
623 struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL }; 641 struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
624 #define HDR_SIZE 7 642 #define HDR_SIZE 7
@@ -648,15 +666,14 @@ static int af9035_download_firmware_new(struct dvb_usb_device *d,
648 if (ret < 0) 666 if (ret < 0)
649 goto err; 667 goto err;
650 668
651 dev_dbg(&d->udev->dev, "%s: data uploaded=%d\n", 669 dev_dbg(&intf->dev, "data uploaded=%d\n", i);
652 __func__, i);
653 } 670 }
654 } 671 }
655 672
656 return 0; 673 return 0;
657 674
658err: 675err:
659 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 676 dev_dbg(&intf->dev, "failed=%d\n", ret);
660 677
661 return ret; 678 return ret;
662} 679}
@@ -664,6 +681,7 @@ err:
664static int af9035_download_firmware(struct dvb_usb_device *d, 681static int af9035_download_firmware(struct dvb_usb_device *d,
665 const struct firmware *fw) 682 const struct firmware *fw)
666{ 683{
684 struct usb_interface *intf = d->intf;
667 struct state *state = d_to_priv(d); 685 struct state *state = d_to_priv(d);
668 int ret; 686 int ret;
669 u8 wbuf[1]; 687 u8 wbuf[1];
@@ -672,7 +690,7 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
672 struct usb_req req = { 0, 0, 0, NULL, 0, NULL }; 690 struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
673 struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf }; 691 struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf };
674 692
675 dev_dbg(&d->udev->dev, "%s:\n", __func__); 693 dev_dbg(&intf->dev, "\n");
676 694
677 /* 695 /*
678 * In case of dual tuner configuration we need to do some extra 696 * In case of dual tuner configuration we need to do some extra
@@ -752,25 +770,25 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
752 goto err; 770 goto err;
753 771
754 if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) { 772 if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
755 dev_err(&d->udev->dev, "%s: firmware did not run\n", 773 dev_err(&intf->dev, "firmware did not run\n");
756 KBUILD_MODNAME);
757 ret = -ENODEV; 774 ret = -ENODEV;
758 goto err; 775 goto err;
759 } 776 }
760 777
761 dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d", 778 dev_info(&intf->dev, "firmware version=%d.%d.%d.%d",
762 KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]); 779 rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
763 780
764 return 0; 781 return 0;
765 782
766err: 783err:
767 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 784 dev_dbg(&intf->dev, "failed=%d\n", ret);
768 785
769 return ret; 786 return ret;
770} 787}
771 788
772static int af9035_read_config(struct dvb_usb_device *d) 789static int af9035_read_config(struct dvb_usb_device *d)
773{ 790{
791 struct usb_interface *intf = d->intf;
774 struct state *state = d_to_priv(d); 792 struct state *state = d_to_priv(d);
775 int ret, i; 793 int ret, i;
776 u8 tmp; 794 u8 tmp;
@@ -805,7 +823,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
805 goto err; 823 goto err;
806 824
807 if (tmp == 0x00) { 825 if (tmp == 0x00) {
808 dev_dbg(&d->udev->dev, "%s: no eeprom\n", __func__); 826 dev_dbg(&intf->dev, "no eeprom\n");
809 goto skip_eeprom; 827 goto skip_eeprom;
810 } 828 }
811 } else if (state->chip_type == 0x9306) { 829 } else if (state->chip_type == 0x9306) {
@@ -826,8 +844,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
826 if (tmp == 1 || tmp == 3 || tmp == 5) 844 if (tmp == 1 || tmp == 3 || tmp == 5)
827 state->dual_mode = true; 845 state->dual_mode = true;
828 846
829 dev_dbg(&d->udev->dev, "%s: ts mode=%d dual mode=%d\n", __func__, 847 dev_dbg(&intf->dev, "ts mode=%d dual mode=%d\n", tmp, state->dual_mode);
830 tmp, state->dual_mode);
831 848
832 if (state->dual_mode) { 849 if (state->dual_mode) {
833 /* read 2nd demodulator I2C address */ 850 /* read 2nd demodulator I2C address */
@@ -840,8 +857,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
840 if (tmp) 857 if (tmp)
841 state->af9033_i2c_addr[1] = tmp; 858 state->af9033_i2c_addr[1] = tmp;
842 859
843 dev_dbg(&d->udev->dev, "%s: 2nd demod I2C addr=%02x\n", 860 dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n", tmp);
844 __func__, tmp);
845 } 861 }
846 862
847 addr = state->eeprom_addr; 863 addr = state->eeprom_addr;
@@ -852,8 +868,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
852 if (ret < 0) 868 if (ret < 0)
853 goto err; 869 goto err;
854 870
855 dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n", 871 dev_dbg(&intf->dev, "[%d]tuner=%02x\n", i, tmp);
856 __func__, i, tmp);
857 872
858 /* tuner sanity check */ 873 /* tuner sanity check */
859 if (state->chip_type == 0x9135) { 874 if (state->chip_type == 0x9135) {
@@ -882,10 +897,8 @@ static int af9035_read_config(struct dvb_usb_device *d)
882 } 897 }
883 898
884 if (state->af9033_config[i].tuner != tmp) { 899 if (state->af9033_config[i].tuner != tmp) {
885 dev_info(&d->udev->dev, 900 dev_info(&intf->dev, "[%d] overriding tuner from %02x to %02x\n",
886 "%s: [%d] overriding tuner from %02x to %02x\n", 901 i, tmp, state->af9033_config[i].tuner);
887 KBUILD_MODNAME, i, tmp,
888 state->af9033_config[i].tuner);
889 } 902 }
890 903
891 switch (state->af9033_config[i].tuner) { 904 switch (state->af9033_config[i].tuner) {
@@ -905,9 +918,8 @@ static int af9035_read_config(struct dvb_usb_device *d)
905 case AF9033_TUNER_IT9135_62: 918 case AF9033_TUNER_IT9135_62:
906 break; 919 break;
907 default: 920 default:
908 dev_warn(&d->udev->dev, 921 dev_warn(&intf->dev, "tuner id=%02x not supported, please report!",
909 "%s: tuner id=%02x not supported, please report!", 922 tmp);
910 KBUILD_MODNAME, tmp);
911 } 923 }
912 924
913 /* disable dual mode if driver does not support it */ 925 /* disable dual mode if driver does not support it */
@@ -924,9 +936,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
924 break; 936 break;
925 default: 937 default:
926 state->dual_mode = false; 938 state->dual_mode = false;
927 dev_info(&d->udev->dev, 939 dev_info(&intf->dev, "driver does not support 2nd tuner and will disable it");
928 "%s: driver does not support 2nd tuner and will disable it",
929 KBUILD_MODNAME);
930 } 940 }
931 941
932 /* tuner IF frequency */ 942 /* tuner IF frequency */
@@ -942,7 +952,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
942 952
943 tmp16 |= tmp << 8; 953 tmp16 |= tmp << 8;
944 954
945 dev_dbg(&d->udev->dev, "%s: [%d]IF=%d\n", __func__, i, tmp16); 955 dev_dbg(&intf->dev, "[%d]IF=%d\n", i, tmp16);
946 956
947 addr += 0x10; /* shift for the 2nd tuner params */ 957 addr += 0x10; /* shift for the 2nd tuner params */
948 } 958 }
@@ -962,10 +972,24 @@ skip_eeprom:
962 state->af9033_config[i].clock = clock_lut_af9035[tmp]; 972 state->af9033_config[i].clock = clock_lut_af9035[tmp];
963 } 973 }
964 974
975 state->no_read = false;
976 /* Some MXL5007T devices cannot properly handle tuner I2C read ops. */
977 if (state->af9033_config[0].tuner == AF9033_TUNER_MXL5007T &&
978 le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA)
979
980 switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
981 case USB_PID_AVERMEDIA_A867:
982 case USB_PID_AVERMEDIA_TWINSTAR:
983 dev_info(&intf->dev,
984 "Device may have issues with I2C read operations. Enabling fix.\n");
985 state->no_read = true;
986 break;
987 }
988
965 return 0; 989 return 0;
966 990
967err: 991err:
968 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 992 dev_dbg(&intf->dev, "failed=%d\n", ret);
969 993
970 return ret; 994 return ret;
971} 995}
@@ -973,10 +997,11 @@ err:
973static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d, 997static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d,
974 int cmd, int arg) 998 int cmd, int arg)
975{ 999{
1000 struct usb_interface *intf = d->intf;
976 int ret; 1001 int ret;
977 u8 val; 1002 u8 val;
978 1003
979 dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg); 1004 dev_dbg(&intf->dev, "cmd=%d arg=%d\n", cmd, arg);
980 1005
981 /* 1006 /*
982 * CEN always enabled by hardware wiring 1007 * CEN always enabled by hardware wiring
@@ -1010,7 +1035,7 @@ static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d,
1010 return 0; 1035 return 0;
1011 1036
1012err: 1037err:
1013 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1038 dev_dbg(&intf->dev, "failed=%d\n", ret);
1014 1039
1015 return ret; 1040 return ret;
1016} 1041}
@@ -1019,6 +1044,7 @@ err:
1019static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d, 1044static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
1020 int cmd, int arg) 1045 int cmd, int arg)
1021{ 1046{
1047 struct usb_interface *intf = d->intf;
1022 int ret; 1048 int ret;
1023 1049
1024 switch (cmd) { 1050 switch (cmd) {
@@ -1076,7 +1102,7 @@ static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
1076 return 0; 1102 return 0;
1077 1103
1078err: 1104err:
1079 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1105 dev_dbg(&intf->dev, "failed=%d\n", ret);
1080 1106
1081 return ret; 1107 return ret;
1082} 1108}
@@ -1102,9 +1128,10 @@ static int af9035_frontend_callback(void *adapter_priv, int component,
1102{ 1128{
1103 struct i2c_adapter *adap = adapter_priv; 1129 struct i2c_adapter *adap = adapter_priv;
1104 struct dvb_usb_device *d = i2c_get_adapdata(adap); 1130 struct dvb_usb_device *d = i2c_get_adapdata(adap);
1131 struct usb_interface *intf = d->intf;
1105 1132
1106 dev_dbg(&d->udev->dev, "%s: component=%d cmd=%d arg=%d\n", 1133 dev_dbg(&intf->dev, "component=%d cmd=%d arg=%d\n",
1107 __func__, component, cmd, arg); 1134 component, cmd, arg);
1108 1135
1109 switch (component) { 1136 switch (component) {
1110 case DVB_FRONTEND_COMPONENT_TUNER: 1137 case DVB_FRONTEND_COMPONENT_TUNER:
@@ -1127,9 +1154,10 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
1127{ 1154{
1128 struct state *state = adap_to_priv(adap); 1155 struct state *state = adap_to_priv(adap);
1129 struct dvb_usb_device *d = adap_to_d(adap); 1156 struct dvb_usb_device *d = adap_to_d(adap);
1157 struct usb_interface *intf = d->intf;
1130 int ret; 1158 int ret;
1131 1159
1132 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); 1160 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1133 1161
1134 if (!state->af9033_config[adap->id].tuner) { 1162 if (!state->af9033_config[adap->id].tuner) {
1135 /* unsupported tuner */ 1163 /* unsupported tuner */
@@ -1156,7 +1184,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
1156 return 0; 1184 return 0;
1157 1185
1158err: 1186err:
1159 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1187 dev_dbg(&intf->dev, "failed=%d\n", ret);
1160 1188
1161 return ret; 1189 return ret;
1162} 1190}
@@ -1165,11 +1193,12 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
1165{ 1193{
1166 struct state *state = adap_to_priv(adap); 1194 struct state *state = adap_to_priv(adap);
1167 struct dvb_usb_device *d = adap_to_d(adap); 1195 struct dvb_usb_device *d = adap_to_d(adap);
1196 struct usb_interface *intf = d->intf;
1168 int ret; 1197 int ret;
1169 struct si2168_config si2168_config; 1198 struct si2168_config si2168_config;
1170 struct i2c_adapter *adapter; 1199 struct i2c_adapter *adapter;
1171 1200
1172 dev_dbg(&d->udev->dev, "adap->id=%d\n", adap->id); 1201 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1173 1202
1174 memset(&si2168_config, 0, sizeof(si2168_config)); 1203 memset(&si2168_config, 0, sizeof(si2168_config));
1175 si2168_config.i2c_adapter = &adapter; 1204 si2168_config.i2c_adapter = &adapter;
@@ -1192,7 +1221,7 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
1192 return 0; 1221 return 0;
1193 1222
1194err: 1223err:
1195 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1224 dev_dbg(&intf->dev, "failed=%d\n", ret);
1196 1225
1197 return ret; 1226 return ret;
1198} 1227}
@@ -1201,9 +1230,10 @@ static int af9035_frontend_detach(struct dvb_usb_adapter *adap)
1201{ 1230{
1202 struct state *state = adap_to_priv(adap); 1231 struct state *state = adap_to_priv(adap);
1203 struct dvb_usb_device *d = adap_to_d(adap); 1232 struct dvb_usb_device *d = adap_to_d(adap);
1233 struct usb_interface *intf = d->intf;
1204 int demod2; 1234 int demod2;
1205 1235
1206 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); 1236 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1207 1237
1208 /* 1238 /*
1209 * For dual tuner devices we have to resolve 2nd demod client, as there 1239 * For dual tuner devices we have to resolve 2nd demod client, as there
@@ -1279,12 +1309,13 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
1279{ 1309{
1280 struct state *state = adap_to_priv(adap); 1310 struct state *state = adap_to_priv(adap);
1281 struct dvb_usb_device *d = adap_to_d(adap); 1311 struct dvb_usb_device *d = adap_to_d(adap);
1312 struct usb_interface *intf = d->intf;
1282 int ret; 1313 int ret;
1283 struct dvb_frontend *fe; 1314 struct dvb_frontend *fe;
1284 struct i2c_msg msg[1]; 1315 struct i2c_msg msg[1];
1285 u8 tuner_addr; 1316 u8 tuner_addr;
1286 1317
1287 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); 1318 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1288 1319
1289 /* 1320 /*
1290 * XXX: Hack used in that function: we abuse unused I2C address bit [7] 1321 * XXX: Hack used in that function: we abuse unused I2C address bit [7]
@@ -1522,7 +1553,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
1522 return 0; 1553 return 0;
1523 1554
1524err: 1555err:
1525 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1556 dev_dbg(&intf->dev, "failed=%d\n", ret);
1526 1557
1527 return ret; 1558 return ret;
1528} 1559}
@@ -1531,10 +1562,11 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap)
1531{ 1562{
1532 struct state *state = adap_to_priv(adap); 1563 struct state *state = adap_to_priv(adap);
1533 struct dvb_usb_device *d = adap_to_d(adap); 1564 struct dvb_usb_device *d = adap_to_d(adap);
1565 struct usb_interface *intf = d->intf;
1534 int ret; 1566 int ret;
1535 struct si2157_config si2157_config; 1567 struct si2157_config si2157_config;
1536 1568
1537 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); 1569 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1538 1570
1539 /* I2C master bus 2 clock speed 300k */ 1571 /* I2C master bus 2 clock speed 300k */
1540 ret = af9035_wr_reg(d, 0x00f6a7, 0x07); 1572 ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
@@ -1590,7 +1622,7 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap)
1590 return 0; 1622 return 0;
1591 1623
1592err: 1624err:
1593 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1625 dev_dbg(&intf->dev, "failed=%d\n", ret);
1594 1626
1595 return ret; 1627 return ret;
1596} 1628}
@@ -1600,8 +1632,9 @@ static int it930x_tuner_detach(struct dvb_usb_adapter *adap)
1600{ 1632{
1601 struct state *state = adap_to_priv(adap); 1633 struct state *state = adap_to_priv(adap);
1602 struct dvb_usb_device *d = adap_to_d(adap); 1634 struct dvb_usb_device *d = adap_to_d(adap);
1635 struct usb_interface *intf = d->intf;
1603 1636
1604 dev_dbg(&d->udev->dev, "adap->id=%d\n", adap->id); 1637 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1605 1638
1606 if (adap->id == 1) { 1639 if (adap->id == 1) {
1607 if (state->i2c_client[3]) 1640 if (state->i2c_client[3])
@@ -1619,8 +1652,9 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
1619{ 1652{
1620 struct state *state = adap_to_priv(adap); 1653 struct state *state = adap_to_priv(adap);
1621 struct dvb_usb_device *d = adap_to_d(adap); 1654 struct dvb_usb_device *d = adap_to_d(adap);
1655 struct usb_interface *intf = d->intf;
1622 1656
1623 dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id); 1657 dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1624 1658
1625 switch (state->af9033_config[adap->id].tuner) { 1659 switch (state->af9033_config[adap->id].tuner) {
1626 case AF9033_TUNER_TUA9001: 1660 case AF9033_TUNER_TUA9001:
@@ -1646,6 +1680,7 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
1646static int af9035_init(struct dvb_usb_device *d) 1680static int af9035_init(struct dvb_usb_device *d)
1647{ 1681{
1648 struct state *state = d_to_priv(d); 1682 struct state *state = d_to_priv(d);
1683 struct usb_interface *intf = d->intf;
1649 int ret, i; 1684 int ret, i;
1650 u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4; 1685 u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4;
1651 u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4; 1686 u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
@@ -1670,9 +1705,8 @@ static int af9035_init(struct dvb_usb_device *d)
1670 { 0x80f9a4, 0x00, 0x01 }, 1705 { 0x80f9a4, 0x00, 0x01 },
1671 }; 1706 };
1672 1707
1673 dev_dbg(&d->udev->dev, 1708 dev_dbg(&intf->dev, "USB speed=%d frame_size=%04x packet_size=%02x\n",
1674 "%s: USB speed=%d frame_size=%04x packet_size=%02x\n", 1709 d->udev->speed, frame_size, packet_size);
1675 __func__, d->udev->speed, frame_size, packet_size);
1676 1710
1677 /* init endpoints */ 1711 /* init endpoints */
1678 for (i = 0; i < ARRAY_SIZE(tab); i++) { 1712 for (i = 0; i < ARRAY_SIZE(tab); i++) {
@@ -1685,7 +1719,7 @@ static int af9035_init(struct dvb_usb_device *d)
1685 return 0; 1719 return 0;
1686 1720
1687err: 1721err:
1688 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1722 dev_dbg(&intf->dev, "failed=%d\n", ret);
1689 1723
1690 return ret; 1724 return ret;
1691} 1725}
@@ -1693,6 +1727,7 @@ err:
1693static int it930x_init(struct dvb_usb_device *d) 1727static int it930x_init(struct dvb_usb_device *d)
1694{ 1728{
1695 struct state *state = d_to_priv(d); 1729 struct state *state = d_to_priv(d);
1730 struct usb_interface *intf = d->intf;
1696 int ret, i; 1731 int ret, i;
1697 u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 816) * 188 / 4; 1732 u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 816) * 188 / 4;
1698 u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4; 1733 u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
@@ -1752,9 +1787,8 @@ static int it930x_init(struct dvb_usb_device *d)
1752 { 0x00da5a, 0x1f, 0xff }, /* ts_fail_ignore */ 1787 { 0x00da5a, 0x1f, 0xff }, /* ts_fail_ignore */
1753 }; 1788 };
1754 1789
1755 dev_dbg(&d->udev->dev, 1790 dev_dbg(&intf->dev, "USB speed=%d frame_size=%04x packet_size=%02x\n",
1756 "%s: USB speed=%d frame_size=%04x packet_size=%02x\n", 1791 d->udev->speed, frame_size, packet_size);
1757 __func__, d->udev->speed, frame_size, packet_size);
1758 1792
1759 /* init endpoints */ 1793 /* init endpoints */
1760 for (i = 0; i < ARRAY_SIZE(tab); i++) { 1794 for (i = 0; i < ARRAY_SIZE(tab); i++) {
@@ -1767,7 +1801,7 @@ static int it930x_init(struct dvb_usb_device *d)
1767 1801
1768 return 0; 1802 return 0;
1769err: 1803err:
1770 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1804 dev_dbg(&intf->dev, "failed=%d\n", ret);
1771 1805
1772 return ret; 1806 return ret;
1773} 1807}
@@ -1776,6 +1810,7 @@ err:
1776#if IS_ENABLED(CONFIG_RC_CORE) 1810#if IS_ENABLED(CONFIG_RC_CORE)
1777static int af9035_rc_query(struct dvb_usb_device *d) 1811static int af9035_rc_query(struct dvb_usb_device *d)
1778{ 1812{
1813 struct usb_interface *intf = d->intf;
1779 int ret; 1814 int ret;
1780 u32 key; 1815 u32 key;
1781 u8 buf[4]; 1816 u8 buf[4];
@@ -1801,14 +1836,14 @@ static int af9035_rc_query(struct dvb_usb_device *d)
1801 buf[2] << 8 | buf[3]); 1836 buf[2] << 8 | buf[3]);
1802 } 1837 }
1803 1838
1804 dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 4, buf); 1839 dev_dbg(&intf->dev, "%*ph\n", 4, buf);
1805 1840
1806 rc_keydown(d->rc_dev, RC_TYPE_NEC, key, 0); 1841 rc_keydown(d->rc_dev, RC_TYPE_NEC, key, 0);
1807 1842
1808 return 0; 1843 return 0;
1809 1844
1810err: 1845err:
1811 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1846 dev_dbg(&intf->dev, "failed=%d\n", ret);
1812 1847
1813 return ret; 1848 return ret;
1814} 1849}
@@ -1816,6 +1851,7 @@ err:
1816static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) 1851static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1817{ 1852{
1818 struct state *state = d_to_priv(d); 1853 struct state *state = d_to_priv(d);
1854 struct usb_interface *intf = d->intf;
1819 int ret; 1855 int ret;
1820 u8 tmp; 1856 u8 tmp;
1821 1857
@@ -1823,7 +1859,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1823 if (ret < 0) 1859 if (ret < 0)
1824 goto err; 1860 goto err;
1825 1861
1826 dev_dbg(&d->udev->dev, "%s: ir_mode=%02x\n", __func__, tmp); 1862 dev_dbg(&intf->dev, "ir_mode=%02x\n", tmp);
1827 1863
1828 /* don't activate rc if in HID mode or if not available */ 1864 /* don't activate rc if in HID mode or if not available */
1829 if (tmp == 5) { 1865 if (tmp == 5) {
@@ -1832,7 +1868,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1832 if (ret < 0) 1868 if (ret < 0)
1833 goto err; 1869 goto err;
1834 1870
1835 dev_dbg(&d->udev->dev, "%s: ir_type=%02x\n", __func__, tmp); 1871 dev_dbg(&intf->dev, "ir_type=%02x\n", tmp);
1836 1872
1837 switch (tmp) { 1873 switch (tmp) {
1838 case 0: /* NEC */ 1874 case 0: /* NEC */
@@ -1855,7 +1891,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1855 return 0; 1891 return 0;
1856 1892
1857err: 1893err:
1858 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 1894 dev_dbg(&intf->dev, "failed=%d\n", ret);
1859 1895
1860 return ret; 1896 return ret;
1861} 1897}
@@ -1867,8 +1903,9 @@ static int af9035_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
1867 struct usb_data_stream_properties *stream) 1903 struct usb_data_stream_properties *stream)
1868{ 1904{
1869 struct dvb_usb_device *d = fe_to_d(fe); 1905 struct dvb_usb_device *d = fe_to_d(fe);
1906 struct usb_interface *intf = d->intf;
1870 1907
1871 dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, fe_to_adap(fe)->id); 1908 dev_dbg(&intf->dev, "adap=%d\n", fe_to_adap(fe)->id);
1872 1909
1873 if (d->udev->speed == USB_SPEED_FULL) 1910 if (d->udev->speed == USB_SPEED_FULL)
1874 stream->u.bulk.buffersize = 5 * 188; 1911 stream->u.bulk.buffersize = 5 * 188;
@@ -1920,7 +1957,7 @@ static int af9035_probe(struct usb_interface *intf,
1920 if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) && 1957 if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) &&
1921 (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) { 1958 (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) {
1922 if (!strcmp("Afatech", manufacturer)) { 1959 if (!strcmp("Afatech", manufacturer)) {
1923 dev_dbg(&udev->dev, "%s: rejecting device\n", __func__); 1960 dev_dbg(&udev->dev, "rejecting device\n");
1924 return -ENODEV; 1961 return -ENODEV;
1925 } 1962 }
1926 } 1963 }
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
index 89e629a24aec..c91d1a3789e6 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.h
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -62,6 +62,7 @@ struct state {
62 u8 chip_version; 62 u8 chip_version;
63 u16 chip_type; 63 u16 chip_type;
64 u8 dual_mode:1; 64 u8 dual_mode:1;
65 u8 no_read:1;
65 u16 eeprom_addr; 66 u16 eeprom_addr;
66 u8 af9033_i2c_addr[2]; 67 u8 af9033_i2c_addr[2];
67 struct af9033_config af9033_config[2]; 68 struct af9033_config af9033_config[2];
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index eb7af8cb8aca..6643762a9ff7 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -624,7 +624,7 @@ static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name)
624 dev_dbg(&d->intf->dev, "chip_id=%u\n", dev->chip_id); 624 dev_dbg(&d->intf->dev, "chip_id=%u\n", dev->chip_id);
625 625
626 /* Retry failed I2C messages */ 626 /* Retry failed I2C messages */
627 d->i2c_adap.retries = 1; 627 d->i2c_adap.retries = 3;
628 d->i2c_adap.timeout = msecs_to_jiffies(10); 628 d->i2c_adap.timeout = msecs_to_jiffies(10);
629 629
630 return WARM; 630 return WARM;
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index a19b5c8b56ff..1a9e1e556706 100644
--- a/drivers/media/usb/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -507,9 +507,8 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
507 if (dev->disconnected) 507 if (dev->disconnected)
508 return -ENODEV; 508 return -ENODEV;
509 509
510 rc = rt_mutex_trylock(&dev->i2c_bus_lock); 510 if (!rt_mutex_trylock(&dev->i2c_bus_lock))
511 if (rc < 0) 511 return -EAGAIN;
512 return rc;
513 512
514 /* Switch I2C bus if needed */ 513 /* Switch I2C bus if needed */
515 if (bus != dev->cur_i2c_bus && 514 if (bus != dev->cur_i2c_bus &&
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 451e84e962e2..302e284a95eb 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1674,7 +1674,7 @@ static void uvc_delete(struct uvc_device *dev)
1674 if (dev->vdev.dev) 1674 if (dev->vdev.dev)
1675 v4l2_device_unregister(&dev->vdev); 1675 v4l2_device_unregister(&dev->vdev);
1676#ifdef CONFIG_MEDIA_CONTROLLER 1676#ifdef CONFIG_MEDIA_CONTROLLER
1677 if (media_devnode_is_registered(&dev->mdev.devnode)) 1677 if (media_devnode_is_registered(dev->mdev.devnode))
1678 media_device_unregister(&dev->mdev); 1678 media_device_unregister(&dev->mdev);
1679 media_device_cleanup(&dev->mdev); 1679 media_device_cleanup(&dev->mdev);
1680#endif 1680#endif
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index c04bc6afb965..05eed4be25df 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -142,6 +142,21 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
142 return interval; 142 return interval;
143} 143}
144 144
145static __u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format,
146 const struct uvc_frame *frame)
147{
148 switch (format->fcc) {
149 case V4L2_PIX_FMT_NV12:
150 case V4L2_PIX_FMT_YVU420:
151 case V4L2_PIX_FMT_YUV420:
152 case V4L2_PIX_FMT_M420:
153 return frame->wWidth;
154
155 default:
156 return format->bpp * frame->wWidth / 8;
157 }
158}
159
145static int uvc_v4l2_try_format(struct uvc_streaming *stream, 160static int uvc_v4l2_try_format(struct uvc_streaming *stream,
146 struct v4l2_format *fmt, struct uvc_streaming_control *probe, 161 struct v4l2_format *fmt, struct uvc_streaming_control *probe,
147 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame) 162 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
@@ -245,7 +260,7 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
245 fmt->fmt.pix.width = frame->wWidth; 260 fmt->fmt.pix.width = frame->wWidth;
246 fmt->fmt.pix.height = frame->wHeight; 261 fmt->fmt.pix.height = frame->wHeight;
247 fmt->fmt.pix.field = V4L2_FIELD_NONE; 262 fmt->fmt.pix.field = V4L2_FIELD_NONE;
248 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; 263 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
249 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize; 264 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
250 fmt->fmt.pix.colorspace = format->colorspace; 265 fmt->fmt.pix.colorspace = format->colorspace;
251 fmt->fmt.pix.priv = 0; 266 fmt->fmt.pix.priv = 0;
@@ -282,7 +297,7 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream,
282 fmt->fmt.pix.width = frame->wWidth; 297 fmt->fmt.pix.width = frame->wWidth;
283 fmt->fmt.pix.height = frame->wHeight; 298 fmt->fmt.pix.height = frame->wHeight;
284 fmt->fmt.pix.field = V4L2_FIELD_NONE; 299 fmt->fmt.pix.field = V4L2_FIELD_NONE;
285 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8; 300 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
286 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize; 301 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
287 fmt->fmt.pix.colorspace = format->colorspace; 302 fmt->fmt.pix.colorspace = format->colorspace;
288 fmt->fmt.pix.priv = 0; 303 fmt->fmt.pix.priv = 0;
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 075a0fe77485..b5589d5f5da4 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1470,6 +1470,7 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
1470 1470
1471 switch (dev->speed) { 1471 switch (dev->speed) {
1472 case USB_SPEED_SUPER: 1472 case USB_SPEED_SUPER:
1473 case USB_SPEED_SUPER_PLUS:
1473 return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); 1474 return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
1474 case USB_SPEED_HIGH: 1475 case USB_SPEED_HIGH:
1475 psize = usb_endpoint_maxp(&ep->desc); 1476 psize = usb_endpoint_maxp(&ep->desc);
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 9fbcb67a9ee6..633fc1ab1d7a 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1648,7 +1648,7 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
1648 void *pb, int nonblocking) 1648 void *pb, int nonblocking)
1649{ 1649{
1650 unsigned long flags; 1650 unsigned long flags;
1651 int ret; 1651 int ret = 0;
1652 1652
1653 /* 1653 /*
1654 * Wait for at least one buffer to become available on the done_list. 1654 * Wait for at least one buffer to become available on the done_list.
@@ -1664,10 +1664,12 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
1664 spin_lock_irqsave(&q->done_lock, flags); 1664 spin_lock_irqsave(&q->done_lock, flags);
1665 *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry); 1665 *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
1666 /* 1666 /*
1667 * Only remove the buffer from done_list if v4l2_buffer can handle all 1667 * Only remove the buffer from done_list if all planes can be
1668 * the planes. 1668 * handled. Some cases such as V4L2 file I/O and DVB have pb
1669 * == NULL; skip the check then as there's nothing to verify.
1669 */ 1670 */
1670 ret = call_bufop(q, verify_planes_array, *vb, pb); 1671 if (pb)
1672 ret = call_bufop(q, verify_planes_array, *vb, pb);
1671 if (!ret) 1673 if (!ret)
1672 list_del(&(*vb)->done_entry); 1674 list_del(&(*vb)->done_entry);
1673 spin_unlock_irqrestore(&q->done_lock, flags); 1675 spin_unlock_irqrestore(&q->done_lock, flags);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 5361197f3e57..e3e47ace7daf 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -753,6 +753,59 @@ void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
753} 753}
754EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx); 754EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
755 755
756/**
757 * vb2_dma_contig_set_max_seg_size() - configure DMA max segment size
758 * @dev: device for configuring DMA parameters
759 * @size: size of DMA max segment size to set
760 *
761 * To allow mapping the scatter-list into a single chunk in the DMA
762 * address space, the device is required to have the DMA max segment
763 * size parameter set to a value larger than the buffer size. Otherwise,
764 * the DMA-mapping subsystem will split the mapping into max segment
765 * size chunks. This function sets the DMA max segment size
766 * parameter to let DMA-mapping map a buffer as a single chunk in DMA
767 * address space.
768 * This code assumes that the DMA-mapping subsystem will merge all
769 * scatterlist segments if this is really possible (for example when
770 * an IOMMU is available and enabled).
771 * Ideally, this parameter should be set by the generic bus code, but it
772 * is left with the default 64KiB value due to historical litmiations in
773 * other subsystems (like limited USB host drivers) and there no good
774 * place to set it to the proper value.
775 * This function should be called from the drivers, which are known to
776 * operate on platforms with IOMMU and provide access to shared buffers
777 * (either USERPTR or DMABUF). This should be done before initializing
778 * videobuf2 queue.
779 */
780int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size)
781{
782 if (!dev->dma_parms) {
783 dev->dma_parms = kzalloc(sizeof(dev->dma_parms), GFP_KERNEL);
784 if (!dev->dma_parms)
785 return -ENOMEM;
786 }
787 if (dma_get_max_seg_size(dev) < size)
788 return dma_set_max_seg_size(dev, size);
789
790 return 0;
791}
792EXPORT_SYMBOL_GPL(vb2_dma_contig_set_max_seg_size);
793
794/*
795 * vb2_dma_contig_clear_max_seg_size() - release resources for DMA parameters
796 * @dev: device for configuring DMA parameters
797 *
798 * This function releases resources allocated to configure DMA parameters
799 * (see vb2_dma_contig_set_max_seg_size() function). It should be called from
800 * device drivers on driver remove.
801 */
802void vb2_dma_contig_clear_max_seg_size(struct device *dev)
803{
804 kfree(dev->dma_parms);
805 dev->dma_parms = NULL;
806}
807EXPORT_SYMBOL_GPL(vb2_dma_contig_clear_max_seg_size);
808
756MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2"); 809MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
757MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>"); 810MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
758MODULE_LICENSE("GPL"); 811MODULE_LICENSE("GPL");
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c
index 0b1b8c7b6ce5..7f366f1b0377 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/v4l2-core/videobuf2-v4l2.c
@@ -74,6 +74,11 @@ static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer
74 return 0; 74 return 0;
75} 75}
76 76
77static int __verify_planes_array_core(struct vb2_buffer *vb, const void *pb)
78{
79 return __verify_planes_array(vb, pb);
80}
81
77/** 82/**
78 * __verify_length() - Verify that the bytesused value for each plane fits in 83 * __verify_length() - Verify that the bytesused value for each plane fits in
79 * the plane length and that the data offset doesn't exceed the bytesused value. 84 * the plane length and that the data offset doesn't exceed the bytesused value.
@@ -437,6 +442,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
437} 442}
438 443
439static const struct vb2_buf_ops v4l2_buf_ops = { 444static const struct vb2_buf_ops v4l2_buf_ops = {
445 .verify_planes_array = __verify_planes_array_core,
440 .fill_user_buffer = __fill_v4l2_buffer, 446 .fill_user_buffer = __fill_v4l2_buffer,
441 .fill_vb2_buffer = __fill_vb2_buffer, 447 .fill_vb2_buffer = __fill_vb2_buffer,
442 .copy_timestamp = __copy_timestamp, 448 .copy_timestamp = __copy_timestamp,
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 216648233874..06af99f64ad8 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -21,6 +21,7 @@
21#include <linux/sizes.h> 21#include <linux/sizes.h>
22#include <linux/of_reserved_mem.h> 22#include <linux/of_reserved_mem.h>
23#include <linux/sort.h> 23#include <linux/sort.h>
24#include <linux/slab.h>
24 25
25#define MAX_RESERVED_REGIONS 16 26#define MAX_RESERVED_REGIONS 16
26static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; 27static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -296,53 +297,95 @@ static inline struct reserved_mem *__find_rmem(struct device_node *node)
296 return NULL; 297 return NULL;
297} 298}
298 299
300struct rmem_assigned_device {
301 struct device *dev;
302 struct reserved_mem *rmem;
303 struct list_head list;
304};
305
306static LIST_HEAD(of_rmem_assigned_device_list);
307static DEFINE_MUTEX(of_rmem_assigned_device_mutex);
308
299/** 309/**
300 * of_reserved_mem_device_init() - assign reserved memory region to given device 310 * of_reserved_mem_device_init_by_idx() - assign reserved memory region to
311 * given device
312 * @dev: Pointer to the device to configure
313 * @np: Pointer to the device_node with 'reserved-memory' property
314 * @idx: Index of selected region
301 * 315 *
302 * This function assign memory region pointed by "memory-region" device tree 316 * This function assigns respective DMA-mapping operations based on reserved
303 * property to the given device. 317 * memory region specified by 'memory-region' property in @np node to the @dev
318 * device. When driver needs to use more than one reserved memory region, it
319 * should allocate child devices and initialize regions by name for each of
320 * child device.
321 *
322 * Returns error code or zero on success.
304 */ 323 */
305int of_reserved_mem_device_init(struct device *dev) 324int of_reserved_mem_device_init_by_idx(struct device *dev,
325 struct device_node *np, int idx)
306{ 326{
327 struct rmem_assigned_device *rd;
328 struct device_node *target;
307 struct reserved_mem *rmem; 329 struct reserved_mem *rmem;
308 struct device_node *np;
309 int ret; 330 int ret;
310 331
311 np = of_parse_phandle(dev->of_node, "memory-region", 0); 332 if (!np || !dev)
312 if (!np) 333 return -EINVAL;
334
335 target = of_parse_phandle(np, "memory-region", idx);
336 if (!target)
313 return -ENODEV; 337 return -ENODEV;
314 338
315 rmem = __find_rmem(np); 339 rmem = __find_rmem(target);
316 of_node_put(np); 340 of_node_put(target);
317 341
318 if (!rmem || !rmem->ops || !rmem->ops->device_init) 342 if (!rmem || !rmem->ops || !rmem->ops->device_init)
319 return -EINVAL; 343 return -EINVAL;
320 344
345 rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL);
346 if (!rd)
347 return -ENOMEM;
348
321 ret = rmem->ops->device_init(rmem, dev); 349 ret = rmem->ops->device_init(rmem, dev);
322 if (ret == 0) 350 if (ret == 0) {
351 rd->dev = dev;
352 rd->rmem = rmem;
353
354 mutex_lock(&of_rmem_assigned_device_mutex);
355 list_add(&rd->list, &of_rmem_assigned_device_list);
356 mutex_unlock(&of_rmem_assigned_device_mutex);
357
323 dev_info(dev, "assigned reserved memory node %s\n", rmem->name); 358 dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
359 } else {
360 kfree(rd);
361 }
324 362
325 return ret; 363 return ret;
326} 364}
327EXPORT_SYMBOL_GPL(of_reserved_mem_device_init); 365EXPORT_SYMBOL_GPL(of_reserved_mem_device_init_by_idx);
328 366
329/** 367/**
330 * of_reserved_mem_device_release() - release reserved memory device structures 368 * of_reserved_mem_device_release() - release reserved memory device structures
369 * @dev: Pointer to the device to deconfigure
331 * 370 *
332 * This function releases structures allocated for memory region handling for 371 * This function releases structures allocated for memory region handling for
333 * the given device. 372 * the given device.
334 */ 373 */
335void of_reserved_mem_device_release(struct device *dev) 374void of_reserved_mem_device_release(struct device *dev)
336{ 375{
337 struct reserved_mem *rmem; 376 struct rmem_assigned_device *rd;
338 struct device_node *np; 377 struct reserved_mem *rmem = NULL;
339 378
340 np = of_parse_phandle(dev->of_node, "memory-region", 0); 379 mutex_lock(&of_rmem_assigned_device_mutex);
341 if (!np) 380 list_for_each_entry(rd, &of_rmem_assigned_device_list, list) {
342 return; 381 if (rd->dev == dev) {
343 382 rmem = rd->rmem;
344 rmem = __find_rmem(np); 383 list_del(&rd->list);
345 of_node_put(np); 384 kfree(rd);
385 break;
386 }
387 }
388 mutex_unlock(&of_rmem_assigned_device_mutex);
346 389
347 if (!rmem || !rmem->ops || !rmem->ops->device_release) 390 if (!rmem || !rmem->ops || !rmem->ops->device_release)
348 return; 391 return;
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index de7e9f52e7eb..ee9186843371 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -25,18 +25,8 @@ source "drivers/staging/media/cxd2099/Kconfig"
25 25
26source "drivers/staging/media/davinci_vpfe/Kconfig" 26source "drivers/staging/media/davinci_vpfe/Kconfig"
27 27
28source "drivers/staging/media/mn88472/Kconfig"
29
30source "drivers/staging/media/mx2/Kconfig"
31
32source "drivers/staging/media/mx3/Kconfig"
33
34source "drivers/staging/media/omap1/Kconfig"
35
36source "drivers/staging/media/omap4iss/Kconfig" 28source "drivers/staging/media/omap4iss/Kconfig"
37 29
38source "drivers/staging/media/timb/Kconfig"
39
40source "drivers/staging/media/tw686x-kh/Kconfig" 30source "drivers/staging/media/tw686x-kh/Kconfig"
41 31
42# Keep LIRC at the end, as it has sub-menus 32# Keep LIRC at the end, as it has sub-menus
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 60a35b3a47e7..8c05d0ace0fb 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -2,10 +2,5 @@ obj-$(CONFIG_I2C_BCM2048) += bcm2048/
2obj-$(CONFIG_DVB_CXD2099) += cxd2099/ 2obj-$(CONFIG_DVB_CXD2099) += cxd2099/
3obj-$(CONFIG_LIRC_STAGING) += lirc/ 3obj-$(CONFIG_LIRC_STAGING) += lirc/
4obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ 4obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
5obj-$(CONFIG_VIDEO_MX2) += mx2/
6obj-$(CONFIG_VIDEO_MX3) += mx3/
7obj-$(CONFIG_VIDEO_OMAP1) += omap1/
8obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ 5obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
9obj-$(CONFIG_DVB_MN88472) += mn88472/
10obj-$(CONFIG_VIDEO_TIMBERDALE) += timb/
11obj-$(CONFIG_VIDEO_TW686X_KH) += tw686x-kh/ 6obj-$(CONFIG_VIDEO_TW686X_KH) += tw686x-kh/
diff --git a/drivers/staging/media/mn88472/Kconfig b/drivers/staging/media/mn88472/Kconfig
deleted file mode 100644
index a85c90a60bce..000000000000
--- a/drivers/staging/media/mn88472/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
1config DVB_MN88472
2 tristate "Panasonic MN88472"
3 depends on DVB_CORE && I2C
4 select REGMAP_I2C
5 default m if !MEDIA_SUBDRV_AUTOSELECT
6 help
7 Say Y when you want to support this frontend.
diff --git a/drivers/staging/media/mn88472/Makefile b/drivers/staging/media/mn88472/Makefile
deleted file mode 100644
index 5987b7e6d82a..000000000000
--- a/drivers/staging/media/mn88472/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1obj-$(CONFIG_DVB_MN88472) += mn88472.o
2
3ccflags-y += -Idrivers/media/dvb-core/
4ccflags-y += -Idrivers/media/dvb-frontends/
5ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/staging/media/mn88472/TODO b/drivers/staging/media/mn88472/TODO
deleted file mode 100644
index b90a14be3beb..000000000000
--- a/drivers/staging/media/mn88472/TODO
+++ /dev/null
@@ -1,21 +0,0 @@
1Driver general quality is not good enough for mainline. Also, other
2device drivers (USB-bridge, tuner) needed for Astrometa receiver in
3question could need some changes. However, if that driver is mainlined
4due to some other device than Astrometa, unrelated TODOs could be
5skipped. In that case rtl28xxu driver needs module parameter to prevent
6driver loading.
7
8Required TODOs:
9* missing lock flags
10* I2C errors
11* tuner sensitivity
12
13*Do not* send any patch fixing checkpatch.pl issues. Currently it passes
14checkpatch.pl tests. I don't want waste my time to review this kind of
15trivial stuff. *Do not* add missing register I/O error checks. Those are
16missing for the reason it is much easier to compare I2C data sniffs when
17there is less lines. Those error checks are about the last thing to be added.
18
19Patches should be submitted to:
20linux-media@vger.kernel.org and Antti Palosaari <crope@iki.fi>
21
diff --git a/drivers/staging/media/mx2/Kconfig b/drivers/staging/media/mx2/Kconfig
deleted file mode 100644
index beaa885cf104..000000000000
--- a/drivers/staging/media/mx2/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
1config VIDEO_MX2
2 tristate "i.MX27 Camera Sensor Interface driver"
3 depends on VIDEO_DEV && SOC_CAMERA
4 depends on SOC_IMX27 || COMPILE_TEST
5 depends on HAS_DMA
6 select VIDEOBUF2_DMA_CONTIG
7 ---help---
8 This is a v4l2 driver for the i.MX27 Camera Sensor Interface
9
10 This driver is deprecated: it should become a stand-alone driver
11 instead of using the soc-camera framework.
12
13 Unless someone is willing to take this on (unlikely with such
14 ancient hardware) it is going to be removed from the kernel
15 soon.
diff --git a/drivers/staging/media/mx2/Makefile b/drivers/staging/media/mx2/Makefile
deleted file mode 100644
index fc5b2826a558..000000000000
--- a/drivers/staging/media/mx2/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1# Makefile for i.MX27 Camera Sensor driver
2
3obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o
diff --git a/drivers/staging/media/mx2/TODO b/drivers/staging/media/mx2/TODO
deleted file mode 100644
index bc68fa443a3e..000000000000
--- a/drivers/staging/media/mx2/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
1This driver is deprecated: it should become a stand-alone driver instead of
2using the soc-camera framework.
3
4Unless someone is willing to take this on (unlikely with such ancient
5hardware) it is going to be removed from the kernel soon.
6
7Note that trivial patches will not be accepted anymore, only a full conversion.
8
9If you want to convert this driver, please contact the linux-media mailinglist
10(see http://linuxtv.org/lists.php).
diff --git a/drivers/staging/media/mx2/mx2_camera.c b/drivers/staging/media/mx2/mx2_camera.c
deleted file mode 100644
index 48dd5b7851b5..000000000000
--- a/drivers/staging/media/mx2/mx2_camera.c
+++ /dev/null
@@ -1,1636 +0,0 @@
1/*
2 * V4L2 Driver for i.MX27 camera host
3 *
4 * Copyright (C) 2008, Sascha Hauer, Pengutronix
5 * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography
6 * Copyright (C) 2012, Javier Martin, Vista Silicon S.L.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/io.h>
17#include <linux/delay.h>
18#include <linux/slab.h>
19#include <linux/dma-mapping.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/gcd.h>
23#include <linux/interrupt.h>
24#include <linux/kernel.h>
25#include <linux/math64.h>
26#include <linux/mm.h>
27#include <linux/moduleparam.h>
28#include <linux/time.h>
29#include <linux/device.h>
30#include <linux/platform_device.h>
31#include <linux/clk.h>
32
33#include <media/v4l2-common.h>
34#include <media/v4l2-dev.h>
35#include <media/videobuf2-v4l2.h>
36#include <media/videobuf2-dma-contig.h>
37#include <media/soc_camera.h>
38#include <media/drv-intf/soc_mediabus.h>
39
40#include <linux/videodev2.h>
41
42#include <linux/platform_data/media/camera-mx2.h>
43
44#include <asm/dma.h>
45
46#define MX2_CAM_DRV_NAME "mx2-camera"
47#define MX2_CAM_VERSION "0.0.6"
48#define MX2_CAM_DRIVER_DESCRIPTION "i.MX2x_Camera"
49
50/* reset values */
51#define CSICR1_RESET_VAL 0x40000800
52#define CSICR2_RESET_VAL 0x0
53#define CSICR3_RESET_VAL 0x0
54
55/* csi control reg 1 */
56#define CSICR1_SWAP16_EN (1 << 31)
57#define CSICR1_EXT_VSYNC (1 << 30)
58#define CSICR1_EOF_INTEN (1 << 29)
59#define CSICR1_PRP_IF_EN (1 << 28)
60#define CSICR1_CCIR_MODE (1 << 27)
61#define CSICR1_COF_INTEN (1 << 26)
62#define CSICR1_SF_OR_INTEN (1 << 25)
63#define CSICR1_RF_OR_INTEN (1 << 24)
64#define CSICR1_STATFF_LEVEL (3 << 22)
65#define CSICR1_STATFF_INTEN (1 << 21)
66#define CSICR1_RXFF_LEVEL(l) (((l) & 3) << 19)
67#define CSICR1_RXFF_INTEN (1 << 18)
68#define CSICR1_SOF_POL (1 << 17)
69#define CSICR1_SOF_INTEN (1 << 16)
70#define CSICR1_MCLKDIV(d) (((d) & 0xF) << 12)
71#define CSICR1_HSYNC_POL (1 << 11)
72#define CSICR1_CCIR_EN (1 << 10)
73#define CSICR1_MCLKEN (1 << 9)
74#define CSICR1_FCC (1 << 8)
75#define CSICR1_PACK_DIR (1 << 7)
76#define CSICR1_CLR_STATFIFO (1 << 6)
77#define CSICR1_CLR_RXFIFO (1 << 5)
78#define CSICR1_GCLK_MODE (1 << 4)
79#define CSICR1_INV_DATA (1 << 3)
80#define CSICR1_INV_PCLK (1 << 2)
81#define CSICR1_REDGE (1 << 1)
82#define CSICR1_FMT_MASK (CSICR1_PACK_DIR | CSICR1_SWAP16_EN)
83
84#define SHIFT_STATFF_LEVEL 22
85#define SHIFT_RXFF_LEVEL 19
86#define SHIFT_MCLKDIV 12
87
88#define SHIFT_FRMCNT 16
89
90#define CSICR1 0x00
91#define CSICR2 0x04
92#define CSISR 0x08
93#define CSISTATFIFO 0x0c
94#define CSIRFIFO 0x10
95#define CSIRXCNT 0x14
96#define CSICR3 0x1c
97#define CSIDMASA_STATFIFO 0x20
98#define CSIDMATA_STATFIFO 0x24
99#define CSIDMASA_FB1 0x28
100#define CSIDMASA_FB2 0x2c
101#define CSIFBUF_PARA 0x30
102#define CSIIMAG_PARA 0x34
103
104/* EMMA PrP */
105#define PRP_CNTL 0x00
106#define PRP_INTR_CNTL 0x04
107#define PRP_INTRSTATUS 0x08
108#define PRP_SOURCE_Y_PTR 0x0c
109#define PRP_SOURCE_CB_PTR 0x10
110#define PRP_SOURCE_CR_PTR 0x14
111#define PRP_DEST_RGB1_PTR 0x18
112#define PRP_DEST_RGB2_PTR 0x1c
113#define PRP_DEST_Y_PTR 0x20
114#define PRP_DEST_CB_PTR 0x24
115#define PRP_DEST_CR_PTR 0x28
116#define PRP_SRC_FRAME_SIZE 0x2c
117#define PRP_DEST_CH1_LINE_STRIDE 0x30
118#define PRP_SRC_PIXEL_FORMAT_CNTL 0x34
119#define PRP_CH1_PIXEL_FORMAT_CNTL 0x38
120#define PRP_CH1_OUT_IMAGE_SIZE 0x3c
121#define PRP_CH2_OUT_IMAGE_SIZE 0x40
122#define PRP_SRC_LINE_STRIDE 0x44
123#define PRP_CSC_COEF_012 0x48
124#define PRP_CSC_COEF_345 0x4c
125#define PRP_CSC_COEF_678 0x50
126#define PRP_CH1_RZ_HORI_COEF1 0x54
127#define PRP_CH1_RZ_HORI_COEF2 0x58
128#define PRP_CH1_RZ_HORI_VALID 0x5c
129#define PRP_CH1_RZ_VERT_COEF1 0x60
130#define PRP_CH1_RZ_VERT_COEF2 0x64
131#define PRP_CH1_RZ_VERT_VALID 0x68
132#define PRP_CH2_RZ_HORI_COEF1 0x6c
133#define PRP_CH2_RZ_HORI_COEF2 0x70
134#define PRP_CH2_RZ_HORI_VALID 0x74
135#define PRP_CH2_RZ_VERT_COEF1 0x78
136#define PRP_CH2_RZ_VERT_COEF2 0x7c
137#define PRP_CH2_RZ_VERT_VALID 0x80
138
139#define PRP_CNTL_CH1EN (1 << 0)
140#define PRP_CNTL_CH2EN (1 << 1)
141#define PRP_CNTL_CSIEN (1 << 2)
142#define PRP_CNTL_DATA_IN_YUV420 (0 << 3)
143#define PRP_CNTL_DATA_IN_YUV422 (1 << 3)
144#define PRP_CNTL_DATA_IN_RGB16 (2 << 3)
145#define PRP_CNTL_DATA_IN_RGB32 (3 << 3)
146#define PRP_CNTL_CH1_OUT_RGB8 (0 << 5)
147#define PRP_CNTL_CH1_OUT_RGB16 (1 << 5)
148#define PRP_CNTL_CH1_OUT_RGB32 (2 << 5)
149#define PRP_CNTL_CH1_OUT_YUV422 (3 << 5)
150#define PRP_CNTL_CH2_OUT_YUV420 (0 << 7)
151#define PRP_CNTL_CH2_OUT_YUV422 (1 << 7)
152#define PRP_CNTL_CH2_OUT_YUV444 (2 << 7)
153#define PRP_CNTL_CH1_LEN (1 << 9)
154#define PRP_CNTL_CH2_LEN (1 << 10)
155#define PRP_CNTL_SKIP_FRAME (1 << 11)
156#define PRP_CNTL_SWRST (1 << 12)
157#define PRP_CNTL_CLKEN (1 << 13)
158#define PRP_CNTL_WEN (1 << 14)
159#define PRP_CNTL_CH1BYP (1 << 15)
160#define PRP_CNTL_IN_TSKIP(x) ((x) << 16)
161#define PRP_CNTL_CH1_TSKIP(x) ((x) << 19)
162#define PRP_CNTL_CH2_TSKIP(x) ((x) << 22)
163#define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25)
164#define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27)
165#define PRP_CNTL_CH2B1EN (1 << 29)
166#define PRP_CNTL_CH2B2EN (1 << 30)
167#define PRP_CNTL_CH2FEN (1 << 31)
168
169/* IRQ Enable and status register */
170#define PRP_INTR_RDERR (1 << 0)
171#define PRP_INTR_CH1WERR (1 << 1)
172#define PRP_INTR_CH2WERR (1 << 2)
173#define PRP_INTR_CH1FC (1 << 3)
174#define PRP_INTR_CH2FC (1 << 5)
175#define PRP_INTR_LBOVF (1 << 7)
176#define PRP_INTR_CH2OVF (1 << 8)
177
178/* Resizing registers */
179#define PRP_RZ_VALID_TBL_LEN(x) ((x) << 24)
180#define PRP_RZ_VALID_BILINEAR (1 << 31)
181
182#define MAX_VIDEO_MEM 16
183
184#define RESIZE_NUM_MIN 1
185#define RESIZE_NUM_MAX 20
186#define BC_COEF 3
187#define SZ_COEF (1 << BC_COEF)
188
189#define RESIZE_DIR_H 0
190#define RESIZE_DIR_V 1
191
192#define RESIZE_ALGO_BILINEAR 0
193#define RESIZE_ALGO_AVERAGING 1
194
195struct mx2_prp_cfg {
196 int channel;
197 u32 in_fmt;
198 u32 out_fmt;
199 u32 src_pixel;
200 u32 ch1_pixel;
201 u32 irq_flags;
202 u32 csicr1;
203};
204
205/* prp resizing parameters */
206struct emma_prp_resize {
207 int algo; /* type of algorithm used */
208 int len; /* number of coefficients */
209 unsigned char s[RESIZE_NUM_MAX]; /* table of coefficients */
210};
211
212/* prp configuration for a client-host fmt pair */
213struct mx2_fmt_cfg {
214 u32 in_fmt;
215 u32 out_fmt;
216 struct mx2_prp_cfg cfg;
217};
218
219struct mx2_buf_internal {
220 struct list_head queue;
221 int bufnum;
222 bool discard;
223};
224
225/* buffer for one video frame */
226struct mx2_buffer {
227 /* common v4l buffer stuff -- must be first */
228 struct vb2_v4l2_buffer vb;
229 struct mx2_buf_internal internal;
230};
231
232enum mx2_camera_type {
233 IMX27_CAMERA,
234};
235
236struct mx2_camera_dev {
237 struct device *dev;
238 struct soc_camera_host soc_host;
239 struct clk *clk_emma_ahb, *clk_emma_ipg;
240 struct clk *clk_csi_ahb, *clk_csi_per;
241
242 void __iomem *base_csi, *base_emma;
243
244 struct mx2_camera_platform_data *pdata;
245 unsigned long platform_flags;
246
247 struct list_head capture;
248 struct list_head active_bufs;
249 struct list_head discard;
250
251 spinlock_t lock;
252
253 int dma;
254 struct mx2_buffer *active;
255 struct mx2_buffer *fb1_active;
256 struct mx2_buffer *fb2_active;
257
258 u32 csicr1;
259 enum mx2_camera_type devtype;
260
261 struct mx2_buf_internal buf_discard[2];
262 void *discard_buffer;
263 dma_addr_t discard_buffer_dma;
264 size_t discard_size;
265 struct mx2_fmt_cfg *emma_prp;
266 struct emma_prp_resize resizing[2];
267 unsigned int s_width, s_height;
268 u32 frame_count;
269 struct vb2_alloc_ctx *alloc_ctx;
270};
271
272static struct platform_device_id mx2_camera_devtype[] = {
273 {
274 .name = "imx27-camera",
275 .driver_data = IMX27_CAMERA,
276 }, {
277 /* sentinel */
278 }
279};
280MODULE_DEVICE_TABLE(platform, mx2_camera_devtype);
281
282static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf)
283{
284 return container_of(int_buf, struct mx2_buffer, internal);
285}
286
287static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
288 /*
289 * This is a generic configuration which is valid for most
290 * prp input-output format combinations.
291 * We set the incoming and outgoing pixelformat to a
292 * 16 Bit wide format and adjust the bytesperline
293 * accordingly. With this configuration the inputdata
294 * will not be changed by the emma and could be any type
295 * of 16 Bit Pixelformat.
296 */
297 {
298 .in_fmt = 0,
299 .out_fmt = 0,
300 .cfg = {
301 .channel = 1,
302 .in_fmt = PRP_CNTL_DATA_IN_RGB16,
303 .out_fmt = PRP_CNTL_CH1_OUT_RGB16,
304 .src_pixel = 0x2ca00565, /* RGB565 */
305 .ch1_pixel = 0x2ca00565, /* RGB565 */
306 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
307 PRP_INTR_CH1FC | PRP_INTR_LBOVF,
308 .csicr1 = 0,
309 }
310 },
311 {
312 .in_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
313 .out_fmt = V4L2_PIX_FMT_YUYV,
314 .cfg = {
315 .channel = 1,
316 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
317 .out_fmt = PRP_CNTL_CH1_OUT_YUV422,
318 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
319 .ch1_pixel = 0x62000888, /* YUV422 (YUYV) */
320 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
321 PRP_INTR_CH1FC | PRP_INTR_LBOVF,
322 .csicr1 = CSICR1_SWAP16_EN,
323 }
324 },
325 {
326 .in_fmt = MEDIA_BUS_FMT_YUYV8_2X8,
327 .out_fmt = V4L2_PIX_FMT_YUYV,
328 .cfg = {
329 .channel = 1,
330 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
331 .out_fmt = PRP_CNTL_CH1_OUT_YUV422,
332 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
333 .ch1_pixel = 0x62000888, /* YUV422 (YUYV) */
334 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
335 PRP_INTR_CH1FC | PRP_INTR_LBOVF,
336 .csicr1 = CSICR1_PACK_DIR,
337 }
338 },
339 {
340 .in_fmt = MEDIA_BUS_FMT_YUYV8_2X8,
341 .out_fmt = V4L2_PIX_FMT_YUV420,
342 .cfg = {
343 .channel = 2,
344 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
345 .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
346 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
347 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
348 PRP_INTR_CH2FC | PRP_INTR_LBOVF |
349 PRP_INTR_CH2OVF,
350 .csicr1 = CSICR1_PACK_DIR,
351 }
352 },
353 {
354 .in_fmt = MEDIA_BUS_FMT_UYVY8_2X8,
355 .out_fmt = V4L2_PIX_FMT_YUV420,
356 .cfg = {
357 .channel = 2,
358 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
359 .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
360 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
361 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
362 PRP_INTR_CH2FC | PRP_INTR_LBOVF |
363 PRP_INTR_CH2OVF,
364 .csicr1 = CSICR1_SWAP16_EN,
365 }
366 },
367};
368
369static struct mx2_fmt_cfg *mx27_emma_prp_get_format(u32 in_fmt, u32 out_fmt)
370{
371 int i;
372
373 for (i = 1; i < ARRAY_SIZE(mx27_emma_prp_table); i++)
374 if ((mx27_emma_prp_table[i].in_fmt == in_fmt) &&
375 (mx27_emma_prp_table[i].out_fmt == out_fmt)) {
376 return &mx27_emma_prp_table[i];
377 }
378 /* If no match return the most generic configuration */
379 return &mx27_emma_prp_table[0];
380};
381
382static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
383 unsigned long phys, int bufnum)
384{
385 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
386
387 if (prp->cfg.channel == 1) {
388 writel(phys, pcdev->base_emma +
389 PRP_DEST_RGB1_PTR + 4 * bufnum);
390 } else {
391 writel(phys, pcdev->base_emma +
392 PRP_DEST_Y_PTR - 0x14 * bufnum);
393 if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
394 u32 imgsize = pcdev->soc_host.icd->user_height *
395 pcdev->soc_host.icd->user_width;
396
397 writel(phys + imgsize, pcdev->base_emma +
398 PRP_DEST_CB_PTR - 0x14 * bufnum);
399 writel(phys + ((5 * imgsize) / 4), pcdev->base_emma +
400 PRP_DEST_CR_PTR - 0x14 * bufnum);
401 }
402 }
403}
404
405static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
406{
407 clk_disable_unprepare(pcdev->clk_csi_ahb);
408 clk_disable_unprepare(pcdev->clk_csi_per);
409 writel(0, pcdev->base_csi + CSICR1);
410 writel(0, pcdev->base_emma + PRP_CNTL);
411}
412
413static int mx2_camera_add_device(struct soc_camera_device *icd)
414{
415 dev_info(icd->parent, "Camera driver attached to camera %d\n",
416 icd->devnum);
417
418 return 0;
419}
420
421static void mx2_camera_remove_device(struct soc_camera_device *icd)
422{
423 dev_info(icd->parent, "Camera driver detached from camera %d\n",
424 icd->devnum);
425}
426
427/*
428 * The following two functions absolutely depend on the fact, that
429 * there can be only one camera on mx2 camera sensor interface
430 */
431static int mx2_camera_clock_start(struct soc_camera_host *ici)
432{
433 struct mx2_camera_dev *pcdev = ici->priv;
434 int ret;
435 u32 csicr1;
436
437 ret = clk_prepare_enable(pcdev->clk_csi_ahb);
438 if (ret < 0)
439 return ret;
440
441 ret = clk_prepare_enable(pcdev->clk_csi_per);
442 if (ret < 0)
443 goto exit_csi_ahb;
444
445 csicr1 = CSICR1_MCLKEN | CSICR1_PRP_IF_EN | CSICR1_FCC |
446 CSICR1_RXFF_LEVEL(0);
447
448 pcdev->csicr1 = csicr1;
449 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
450
451 pcdev->frame_count = 0;
452
453 return 0;
454
455exit_csi_ahb:
456 clk_disable_unprepare(pcdev->clk_csi_ahb);
457
458 return ret;
459}
460
461static void mx2_camera_clock_stop(struct soc_camera_host *ici)
462{
463 struct mx2_camera_dev *pcdev = ici->priv;
464
465 mx2_camera_deactivate(pcdev);
466}
467
468/*
469 * Videobuf operations
470 */
471static int mx2_videobuf_setup(struct vb2_queue *vq,
472 unsigned int *count, unsigned int *num_planes,
473 unsigned int sizes[], void *alloc_ctxs[])
474{
475 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
476 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
477 struct mx2_camera_dev *pcdev = ici->priv;
478
479 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]);
480
481 alloc_ctxs[0] = pcdev->alloc_ctx;
482
483 sizes[0] = icd->sizeimage;
484
485 if (0 == *count)
486 *count = 32;
487 if (!*num_planes &&
488 sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
489 *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0];
490
491 *num_planes = 1;
492
493 return 0;
494}
495
496static int mx2_videobuf_prepare(struct vb2_buffer *vb)
497{
498 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
499 int ret = 0;
500
501 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
502 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
503
504#ifdef DEBUG
505 /*
506 * This can be useful if you want to see if we actually fill
507 * the buffer with something
508 */
509 memset((void *)vb2_plane_vaddr(vb, 0),
510 0xaa, vb2_get_plane_payload(vb, 0));
511#endif
512
513 vb2_set_plane_payload(vb, 0, icd->sizeimage);
514 if (vb2_plane_vaddr(vb, 0) &&
515 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
516 ret = -EINVAL;
517 goto out;
518 }
519
520 return 0;
521
522out:
523 return ret;
524}
525
526static void mx2_videobuf_queue(struct vb2_buffer *vb)
527{
528 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
529 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
530 struct soc_camera_host *ici =
531 to_soc_camera_host(icd->parent);
532 struct mx2_camera_dev *pcdev = ici->priv;
533 struct mx2_buffer *buf = container_of(vbuf, struct mx2_buffer, vb);
534 unsigned long flags;
535
536 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
537 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
538
539 spin_lock_irqsave(&pcdev->lock, flags);
540
541 list_add_tail(&buf->internal.queue, &pcdev->capture);
542
543 spin_unlock_irqrestore(&pcdev->lock, flags);
544}
545
546static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
547 int bytesperline)
548{
549 struct soc_camera_host *ici =
550 to_soc_camera_host(icd->parent);
551 struct mx2_camera_dev *pcdev = ici->priv;
552 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
553
554 writel((pcdev->s_width << 16) | pcdev->s_height,
555 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
556 writel(prp->cfg.src_pixel,
557 pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL);
558 if (prp->cfg.channel == 1) {
559 writel((icd->user_width << 16) | icd->user_height,
560 pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE);
561 writel(bytesperline,
562 pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE);
563 writel(prp->cfg.ch1_pixel,
564 pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL);
565 } else { /* channel 2 */
566 writel((icd->user_width << 16) | icd->user_height,
567 pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
568 }
569
570 /* Enable interrupts */
571 writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL);
572}
573
574static void mx2_prp_resize_commit(struct mx2_camera_dev *pcdev)
575{
576 int dir;
577
578 for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
579 unsigned char *s = pcdev->resizing[dir].s;
580 int len = pcdev->resizing[dir].len;
581 unsigned int coeff[2] = {0, 0};
582 unsigned int valid = 0;
583 int i;
584
585 if (len == 0)
586 continue;
587
588 for (i = RESIZE_NUM_MAX - 1; i >= 0; i--) {
589 int j;
590
591 j = i > 9 ? 1 : 0;
592 coeff[j] = (coeff[j] << BC_COEF) |
593 (s[i] & (SZ_COEF - 1));
594
595 if (i == 5 || i == 15)
596 coeff[j] <<= 1;
597
598 valid = (valid << 1) | (s[i] >> BC_COEF);
599 }
600
601 valid |= PRP_RZ_VALID_TBL_LEN(len);
602
603 if (pcdev->resizing[dir].algo == RESIZE_ALGO_BILINEAR)
604 valid |= PRP_RZ_VALID_BILINEAR;
605
606 if (pcdev->emma_prp->cfg.channel == 1) {
607 if (dir == RESIZE_DIR_H) {
608 writel(coeff[0], pcdev->base_emma +
609 PRP_CH1_RZ_HORI_COEF1);
610 writel(coeff[1], pcdev->base_emma +
611 PRP_CH1_RZ_HORI_COEF2);
612 writel(valid, pcdev->base_emma +
613 PRP_CH1_RZ_HORI_VALID);
614 } else {
615 writel(coeff[0], pcdev->base_emma +
616 PRP_CH1_RZ_VERT_COEF1);
617 writel(coeff[1], pcdev->base_emma +
618 PRP_CH1_RZ_VERT_COEF2);
619 writel(valid, pcdev->base_emma +
620 PRP_CH1_RZ_VERT_VALID);
621 }
622 } else {
623 if (dir == RESIZE_DIR_H) {
624 writel(coeff[0], pcdev->base_emma +
625 PRP_CH2_RZ_HORI_COEF1);
626 writel(coeff[1], pcdev->base_emma +
627 PRP_CH2_RZ_HORI_COEF2);
628 writel(valid, pcdev->base_emma +
629 PRP_CH2_RZ_HORI_VALID);
630 } else {
631 writel(coeff[0], pcdev->base_emma +
632 PRP_CH2_RZ_VERT_COEF1);
633 writel(coeff[1], pcdev->base_emma +
634 PRP_CH2_RZ_VERT_COEF2);
635 writel(valid, pcdev->base_emma +
636 PRP_CH2_RZ_VERT_VALID);
637 }
638 }
639 }
640}
641
642static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
643{
644 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
645 struct soc_camera_host *ici =
646 to_soc_camera_host(icd->parent);
647 struct mx2_camera_dev *pcdev = ici->priv;
648 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
649 struct vb2_buffer *vb;
650 struct mx2_buffer *buf;
651 unsigned long phys;
652 int bytesperline;
653 unsigned long flags;
654
655 if (count < 2)
656 return -ENOBUFS;
657
658 spin_lock_irqsave(&pcdev->lock, flags);
659
660 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
661 internal.queue);
662 buf->internal.bufnum = 0;
663 vb = &buf->vb.vb2_buf;
664
665 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
666 mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
667 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
668
669 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
670 internal.queue);
671 buf->internal.bufnum = 1;
672 vb = &buf->vb.vb2_buf;
673
674 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
675 mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
676 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
677
678 bytesperline = soc_mbus_bytes_per_line(icd->user_width,
679 icd->current_fmt->host_fmt);
680 if (bytesperline < 0) {
681 spin_unlock_irqrestore(&pcdev->lock, flags);
682 return bytesperline;
683 }
684
685 /*
686 * I didn't manage to properly enable/disable the prp
687 * on a per frame basis during running transfers,
688 * thus we allocate a buffer here and use it to
689 * discard frames when no buffer is available.
690 * Feel free to work on this ;)
691 */
692 pcdev->discard_size = icd->user_height * bytesperline;
693 pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
694 pcdev->discard_size,
695 &pcdev->discard_buffer_dma, GFP_ATOMIC);
696 if (!pcdev->discard_buffer) {
697 spin_unlock_irqrestore(&pcdev->lock, flags);
698 return -ENOMEM;
699 }
700
701 pcdev->buf_discard[0].discard = true;
702 list_add_tail(&pcdev->buf_discard[0].queue,
703 &pcdev->discard);
704
705 pcdev->buf_discard[1].discard = true;
706 list_add_tail(&pcdev->buf_discard[1].queue,
707 &pcdev->discard);
708
709 mx2_prp_resize_commit(pcdev);
710
711 mx27_camera_emma_buf_init(icd, bytesperline);
712
713 if (prp->cfg.channel == 1) {
714 writel(PRP_CNTL_CH1EN |
715 PRP_CNTL_CSIEN |
716 prp->cfg.in_fmt |
717 prp->cfg.out_fmt |
718 PRP_CNTL_CH1_LEN |
719 PRP_CNTL_CH1BYP |
720 PRP_CNTL_CH1_TSKIP(0) |
721 PRP_CNTL_IN_TSKIP(0),
722 pcdev->base_emma + PRP_CNTL);
723 } else {
724 writel(PRP_CNTL_CH2EN |
725 PRP_CNTL_CSIEN |
726 prp->cfg.in_fmt |
727 prp->cfg.out_fmt |
728 PRP_CNTL_CH2_LEN |
729 PRP_CNTL_CH2_TSKIP(0) |
730 PRP_CNTL_IN_TSKIP(0),
731 pcdev->base_emma + PRP_CNTL);
732 }
733 spin_unlock_irqrestore(&pcdev->lock, flags);
734
735 return 0;
736}
737
738static void mx2_stop_streaming(struct vb2_queue *q)
739{
740 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
741 struct soc_camera_host *ici =
742 to_soc_camera_host(icd->parent);
743 struct mx2_camera_dev *pcdev = ici->priv;
744 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
745 unsigned long flags;
746 void *b;
747 u32 cntl;
748
749 spin_lock_irqsave(&pcdev->lock, flags);
750
751 cntl = readl(pcdev->base_emma + PRP_CNTL);
752 if (prp->cfg.channel == 1) {
753 writel(cntl & ~PRP_CNTL_CH1EN,
754 pcdev->base_emma + PRP_CNTL);
755 } else {
756 writel(cntl & ~PRP_CNTL_CH2EN,
757 pcdev->base_emma + PRP_CNTL);
758 }
759 INIT_LIST_HEAD(&pcdev->capture);
760 INIT_LIST_HEAD(&pcdev->active_bufs);
761 INIT_LIST_HEAD(&pcdev->discard);
762
763 b = pcdev->discard_buffer;
764 pcdev->discard_buffer = NULL;
765
766 spin_unlock_irqrestore(&pcdev->lock, flags);
767
768 dma_free_coherent(ici->v4l2_dev.dev,
769 pcdev->discard_size, b, pcdev->discard_buffer_dma);
770}
771
772static struct vb2_ops mx2_videobuf_ops = {
773 .queue_setup = mx2_videobuf_setup,
774 .buf_prepare = mx2_videobuf_prepare,
775 .buf_queue = mx2_videobuf_queue,
776 .start_streaming = mx2_start_streaming,
777 .stop_streaming = mx2_stop_streaming,
778};
779
780static int mx2_camera_init_videobuf(struct vb2_queue *q,
781 struct soc_camera_device *icd)
782{
783 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
784 q->io_modes = VB2_MMAP | VB2_USERPTR;
785 q->drv_priv = icd;
786 q->ops = &mx2_videobuf_ops;
787 q->mem_ops = &vb2_dma_contig_memops;
788 q->buf_struct_size = sizeof(struct mx2_buffer);
789 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
790
791 return vb2_queue_init(q);
792}
793
794#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
795 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
796 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
797 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
798 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
799 V4L2_MBUS_PCLK_SAMPLE_RISING | \
800 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
801 V4L2_MBUS_DATA_ACTIVE_HIGH | \
802 V4L2_MBUS_DATA_ACTIVE_LOW)
803
804static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
805{
806 int count = 0;
807
808 readl(pcdev->base_emma + PRP_CNTL);
809 writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
810 while (count++ < 100) {
811 if (!(readl(pcdev->base_emma + PRP_CNTL) & PRP_CNTL_SWRST))
812 return 0;
813 barrier();
814 udelay(1);
815 }
816
817 return -ETIMEDOUT;
818}
819
820static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
821{
822 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
823 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
824 struct mx2_camera_dev *pcdev = ici->priv;
825 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
826 unsigned long common_flags;
827 int ret;
828 int bytesperline;
829 u32 csicr1 = pcdev->csicr1;
830
831 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
832 if (!ret) {
833 common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
834 if (!common_flags) {
835 dev_warn(icd->parent,
836 "Flags incompatible: camera 0x%x, host 0x%x\n",
837 cfg.flags, MX2_BUS_FLAGS);
838 return -EINVAL;
839 }
840 } else if (ret != -ENOIOCTLCMD) {
841 return ret;
842 } else {
843 common_flags = MX2_BUS_FLAGS;
844 }
845
846 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
847 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
848 if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
849 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
850 else
851 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
852 }
853
854 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
855 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
856 if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
857 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
858 else
859 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
860 }
861
862 cfg.flags = common_flags;
863 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
864 if (ret < 0 && ret != -ENOIOCTLCMD) {
865 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
866 common_flags, ret);
867 return ret;
868 }
869
870 csicr1 = (csicr1 & ~CSICR1_FMT_MASK) | pcdev->emma_prp->cfg.csicr1;
871
872 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
873 csicr1 |= CSICR1_REDGE;
874 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
875 csicr1 |= CSICR1_SOF_POL;
876 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
877 csicr1 |= CSICR1_HSYNC_POL;
878 if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC)
879 csicr1 |= CSICR1_EXT_VSYNC;
880 if (pcdev->platform_flags & MX2_CAMERA_CCIR)
881 csicr1 |= CSICR1_CCIR_EN;
882 if (pcdev->platform_flags & MX2_CAMERA_CCIR_INTERLACE)
883 csicr1 |= CSICR1_CCIR_MODE;
884 if (pcdev->platform_flags & MX2_CAMERA_GATED_CLOCK)
885 csicr1 |= CSICR1_GCLK_MODE;
886 if (pcdev->platform_flags & MX2_CAMERA_INV_DATA)
887 csicr1 |= CSICR1_INV_DATA;
888
889 pcdev->csicr1 = csicr1;
890
891 bytesperline = soc_mbus_bytes_per_line(icd->user_width,
892 icd->current_fmt->host_fmt);
893 if (bytesperline < 0)
894 return bytesperline;
895
896 ret = mx27_camera_emma_prp_reset(pcdev);
897 if (ret)
898 return ret;
899
900 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
901
902 return 0;
903}
904
905static int mx2_camera_set_crop(struct soc_camera_device *icd,
906 const struct v4l2_crop *a)
907{
908 struct v4l2_crop a_writable = *a;
909 struct v4l2_rect *rect = &a_writable.c;
910 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
911 struct v4l2_subdev_format fmt = {
912 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
913 };
914 struct v4l2_mbus_framefmt *mf = &fmt.format;
915 int ret;
916
917 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
918 soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
919
920 ret = v4l2_subdev_call(sd, video, s_crop, a);
921 if (ret < 0)
922 return ret;
923
924 /* The capture device might have changed its output */
925 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
926 if (ret < 0)
927 return ret;
928
929 dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
930 mf->width, mf->height);
931
932 icd->user_width = mf->width;
933 icd->user_height = mf->height;
934
935 return ret;
936}
937
938static int mx2_camera_get_formats(struct soc_camera_device *icd,
939 unsigned int idx,
940 struct soc_camera_format_xlate *xlate)
941{
942 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
943 const struct soc_mbus_pixelfmt *fmt;
944 struct device *dev = icd->parent;
945 struct v4l2_subdev_mbus_code_enum code = {
946 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
947 .index = idx,
948 };
949 int ret, formats = 0;
950
951 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
952 if (ret < 0)
953 /* no more formats */
954 return 0;
955
956 fmt = soc_mbus_get_fmtdesc(code.code);
957 if (!fmt) {
958 dev_err(dev, "Invalid format code #%u: %d\n", idx, code.code);
959 return 0;
960 }
961
962 if (code.code == MEDIA_BUS_FMT_YUYV8_2X8 ||
963 code.code == MEDIA_BUS_FMT_UYVY8_2X8) {
964 formats++;
965 if (xlate) {
966 /*
967 * CH2 can output YUV420 which is a standard format in
968 * soc_mediabus.c
969 */
970 xlate->host_fmt =
971 soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_1_5X8);
972 xlate->code = code.code;
973 dev_dbg(dev, "Providing host format %s for sensor code %d\n",
974 xlate->host_fmt->name, code.code);
975 xlate++;
976 }
977 }
978
979 if (code.code == MEDIA_BUS_FMT_UYVY8_2X8) {
980 formats++;
981 if (xlate) {
982 xlate->host_fmt =
983 soc_mbus_get_fmtdesc(MEDIA_BUS_FMT_YUYV8_2X8);
984 xlate->code = code.code;
985 dev_dbg(dev, "Providing host format %s for sensor code %d\n",
986 xlate->host_fmt->name, code.code);
987 xlate++;
988 }
989 }
990
991 /* Generic pass-trough */
992 formats++;
993 if (xlate) {
994 xlate->host_fmt = fmt;
995 xlate->code = code.code;
996 xlate++;
997 }
998 return formats;
999}
1000
1001static int mx2_emmaprp_resize(struct mx2_camera_dev *pcdev,
1002 struct v4l2_mbus_framefmt *mf_in,
1003 struct v4l2_pix_format *pix_out, bool apply)
1004{
1005 unsigned int num, den;
1006 unsigned long m;
1007 int i, dir;
1008
1009 for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
1010 struct emma_prp_resize tmprsz;
1011 unsigned char *s = tmprsz.s;
1012 int len = 0;
1013 int in, out;
1014
1015 if (dir == RESIZE_DIR_H) {
1016 in = mf_in->width;
1017 out = pix_out->width;
1018 } else {
1019 in = mf_in->height;
1020 out = pix_out->height;
1021 }
1022
1023 if (in < out)
1024 return -EINVAL;
1025 else if (in == out)
1026 continue;
1027
1028 /* Calculate ratio */
1029 m = gcd(in, out);
1030 num = in / m;
1031 den = out / m;
1032 if (num > RESIZE_NUM_MAX)
1033 return -EINVAL;
1034
1035 if ((num >= 2 * den) && (den == 1) &&
1036 (num < 9) && (!(num & 0x01))) {
1037 int sum = 0;
1038 int j;
1039
1040 /* Average scaling for >= 2:1 ratios */
1041 /* Support can be added for num >=9 and odd values */
1042
1043 tmprsz.algo = RESIZE_ALGO_AVERAGING;
1044 len = num;
1045
1046 for (i = 0; i < (len / 2); i++)
1047 s[i] = 8;
1048
1049 do {
1050 for (i = 0; i < (len / 2); i++) {
1051 s[i] = s[i] >> 1;
1052 sum = 0;
1053 for (j = 0; j < (len / 2); j++)
1054 sum += s[j];
1055 if (sum == 4)
1056 break;
1057 }
1058 } while (sum != 4);
1059
1060 for (i = (len / 2); i < len; i++)
1061 s[i] = s[len - i - 1];
1062
1063 s[len - 1] |= SZ_COEF;
1064 } else {
1065 /* bilinear scaling for < 2:1 ratios */
1066 int v; /* overflow counter */
1067 int coeff, nxt; /* table output */
1068 int in_pos_inc = 2 * den;
1069 int out_pos = num;
1070 int out_pos_inc = 2 * num;
1071 int init_carry = num - den;
1072 int carry = init_carry;
1073
1074 tmprsz.algo = RESIZE_ALGO_BILINEAR;
1075 v = den + in_pos_inc;
1076 do {
1077 coeff = v - out_pos;
1078 out_pos += out_pos_inc;
1079 carry += out_pos_inc;
1080 for (nxt = 0; v < out_pos; nxt++) {
1081 v += in_pos_inc;
1082 carry -= in_pos_inc;
1083 }
1084
1085 if (len > RESIZE_NUM_MAX)
1086 return -EINVAL;
1087
1088 coeff = ((coeff << BC_COEF) +
1089 (in_pos_inc >> 1)) / in_pos_inc;
1090
1091 if (coeff >= (SZ_COEF - 1))
1092 coeff--;
1093
1094 coeff |= SZ_COEF;
1095 s[len] = (unsigned char)coeff;
1096 len++;
1097
1098 for (i = 1; i < nxt; i++) {
1099 if (len >= RESIZE_NUM_MAX)
1100 return -EINVAL;
1101 s[len] = 0;
1102 len++;
1103 }
1104 } while (carry != init_carry);
1105 }
1106 tmprsz.len = len;
1107 if (dir == RESIZE_DIR_H)
1108 mf_in->width = pix_out->width;
1109 else
1110 mf_in->height = pix_out->height;
1111
1112 if (apply)
1113 memcpy(&pcdev->resizing[dir], &tmprsz, sizeof(tmprsz));
1114 }
1115 return 0;
1116}
1117
1118static int mx2_camera_set_fmt(struct soc_camera_device *icd,
1119 struct v4l2_format *f)
1120{
1121 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1122 struct mx2_camera_dev *pcdev = ici->priv;
1123 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1124 const struct soc_camera_format_xlate *xlate;
1125 struct v4l2_pix_format *pix = &f->fmt.pix;
1126 struct v4l2_subdev_format format = {
1127 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1128 };
1129 struct v4l2_mbus_framefmt *mf = &format.format;
1130 int ret;
1131
1132 dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
1133 __func__, pix->width, pix->height);
1134
1135 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1136 if (!xlate) {
1137 dev_warn(icd->parent, "Format %x not found\n",
1138 pix->pixelformat);
1139 return -EINVAL;
1140 }
1141
1142 mf->width = pix->width;
1143 mf->height = pix->height;
1144 mf->field = pix->field;
1145 mf->colorspace = pix->colorspace;
1146 mf->code = xlate->code;
1147
1148 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format);
1149 if (ret < 0 && ret != -ENOIOCTLCMD)
1150 return ret;
1151
1152 /* Store width and height returned by the sensor for resizing */
1153 pcdev->s_width = mf->width;
1154 pcdev->s_height = mf->height;
1155 dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
1156 __func__, pcdev->s_width, pcdev->s_height);
1157
1158 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
1159 xlate->host_fmt->fourcc);
1160
1161 memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
1162 if ((mf->width != pix->width || mf->height != pix->height) &&
1163 pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1164 if (mx2_emmaprp_resize(pcdev, mf, pix, true) < 0)
1165 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1166 }
1167
1168 if (mf->code != xlate->code)
1169 return -EINVAL;
1170
1171 pix->width = mf->width;
1172 pix->height = mf->height;
1173 pix->field = mf->field;
1174 pix->colorspace = mf->colorspace;
1175 icd->current_fmt = xlate;
1176
1177 dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
1178 __func__, pix->width, pix->height);
1179
1180 return 0;
1181}
1182
1183static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1184 struct v4l2_format *f)
1185{
1186 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1187 const struct soc_camera_format_xlate *xlate;
1188 struct v4l2_pix_format *pix = &f->fmt.pix;
1189 struct v4l2_subdev_pad_config pad_cfg;
1190 struct v4l2_subdev_format format = {
1191 .which = V4L2_SUBDEV_FORMAT_TRY,
1192 };
1193 struct v4l2_mbus_framefmt *mf = &format.format;
1194 __u32 pixfmt = pix->pixelformat;
1195 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1196 struct mx2_camera_dev *pcdev = ici->priv;
1197 struct mx2_fmt_cfg *emma_prp;
1198 int ret;
1199
1200 dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
1201 __func__, pix->width, pix->height);
1202
1203 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1204 if (pixfmt && !xlate) {
1205 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
1206 return -EINVAL;
1207 }
1208
1209 /*
1210 * limit to MX27 hardware capabilities: width must be a multiple of 8 as
1211 * requested by the CSI. (Table 39-2 in the i.MX27 Reference Manual).
1212 */
1213 pix->width &= ~0x7;
1214
1215 /* limit to sensor capabilities */
1216 mf->width = pix->width;
1217 mf->height = pix->height;
1218 mf->field = pix->field;
1219 mf->colorspace = pix->colorspace;
1220 mf->code = xlate->code;
1221
1222 ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
1223 if (ret < 0)
1224 return ret;
1225
1226 dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
1227 __func__, pcdev->s_width, pcdev->s_height);
1228
1229 /* If the sensor does not support image size try PrP resizing */
1230 emma_prp = mx27_emma_prp_get_format(xlate->code,
1231 xlate->host_fmt->fourcc);
1232
1233 if ((mf->width != pix->width || mf->height != pix->height) &&
1234 emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1235 if (mx2_emmaprp_resize(pcdev, mf, pix, false) < 0)
1236 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1237 }
1238
1239 if (mf->field == V4L2_FIELD_ANY)
1240 mf->field = V4L2_FIELD_NONE;
1241 /*
1242 * Driver supports interlaced images provided they have
1243 * both fields so that they can be processed as if they
1244 * were progressive.
1245 */
1246 if (mf->field != V4L2_FIELD_NONE && !V4L2_FIELD_HAS_BOTH(mf->field)) {
1247 dev_err(icd->parent, "Field type %d unsupported.\n",
1248 mf->field);
1249 return -EINVAL;
1250 }
1251
1252 pix->width = mf->width;
1253 pix->height = mf->height;
1254 pix->field = mf->field;
1255 pix->colorspace = mf->colorspace;
1256
1257 dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
1258 __func__, pix->width, pix->height);
1259
1260 return 0;
1261}
1262
1263static int mx2_camera_querycap(struct soc_camera_host *ici,
1264 struct v4l2_capability *cap)
1265{
1266 /* cap->name is set by the friendly caller:-> */
1267 strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card));
1268 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1269 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1270
1271 return 0;
1272}
1273
1274static unsigned int mx2_camera_poll(struct file *file, poll_table *pt)
1275{
1276 struct soc_camera_device *icd = file->private_data;
1277
1278 return vb2_poll(&icd->vb2_vidq, file, pt);
1279}
1280
1281static struct soc_camera_host_ops mx2_soc_camera_host_ops = {
1282 .owner = THIS_MODULE,
1283 .add = mx2_camera_add_device,
1284 .remove = mx2_camera_remove_device,
1285 .clock_start = mx2_camera_clock_start,
1286 .clock_stop = mx2_camera_clock_stop,
1287 .set_fmt = mx2_camera_set_fmt,
1288 .set_crop = mx2_camera_set_crop,
1289 .get_formats = mx2_camera_get_formats,
1290 .try_fmt = mx2_camera_try_fmt,
1291 .init_videobuf2 = mx2_camera_init_videobuf,
1292 .poll = mx2_camera_poll,
1293 .querycap = mx2_camera_querycap,
1294 .set_bus_param = mx2_camera_set_bus_param,
1295};
1296
1297static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
1298 int bufnum, bool err)
1299{
1300#ifdef DEBUG
1301 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
1302#endif
1303 struct mx2_buf_internal *ibuf;
1304 struct mx2_buffer *buf;
1305 struct vb2_buffer *vb;
1306 struct vb2_v4l2_buffer *vbuf;
1307 unsigned long phys;
1308
1309 ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal,
1310 queue);
1311
1312 BUG_ON(ibuf->bufnum != bufnum);
1313
1314 if (ibuf->discard) {
1315 /*
1316 * Discard buffer must not be returned to user space.
1317 * Just return it to the discard queue.
1318 */
1319 list_move_tail(pcdev->active_bufs.next, &pcdev->discard);
1320 } else {
1321 buf = mx2_ibuf_to_buf(ibuf);
1322
1323 vb = &buf->vb.vb2_buf;
1324 vbuf = to_vb2_v4l2_buffer(vb);
1325#ifdef DEBUG
1326 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
1327 if (prp->cfg.channel == 1) {
1328 if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR +
1329 4 * bufnum) != phys) {
1330 dev_err(pcdev->dev, "%lx != %x\n", phys,
1331 readl(pcdev->base_emma +
1332 PRP_DEST_RGB1_PTR + 4 * bufnum));
1333 }
1334 } else {
1335 if (readl(pcdev->base_emma + PRP_DEST_Y_PTR -
1336 0x14 * bufnum) != phys) {
1337 dev_err(pcdev->dev, "%lx != %x\n", phys,
1338 readl(pcdev->base_emma +
1339 PRP_DEST_Y_PTR - 0x14 * bufnum));
1340 }
1341 }
1342#endif
1343 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb,
1344 vb2_plane_vaddr(vb, 0),
1345 vb2_get_plane_payload(vb, 0));
1346
1347 list_del_init(&buf->internal.queue);
1348 vb->timestamp = ktime_get_ns();
1349 vbuf->sequence = pcdev->frame_count;
1350 if (err)
1351 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1352 else
1353 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1354 }
1355
1356 pcdev->frame_count++;
1357
1358 if (list_empty(&pcdev->capture)) {
1359 if (list_empty(&pcdev->discard)) {
1360 dev_warn(pcdev->dev, "%s: trying to access empty discard list\n",
1361 __func__);
1362 return;
1363 }
1364
1365 ibuf = list_first_entry(&pcdev->discard,
1366 struct mx2_buf_internal, queue);
1367 ibuf->bufnum = bufnum;
1368
1369 list_move_tail(pcdev->discard.next, &pcdev->active_bufs);
1370 mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum);
1371 return;
1372 }
1373
1374 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
1375 internal.queue);
1376
1377 buf->internal.bufnum = bufnum;
1378
1379 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
1380
1381 vb = &buf->vb.vb2_buf;
1382
1383 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
1384 mx27_update_emma_buf(pcdev, phys, bufnum);
1385}
1386
1387static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data)
1388{
1389 struct mx2_camera_dev *pcdev = data;
1390 unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS);
1391 struct mx2_buf_internal *ibuf;
1392
1393 spin_lock(&pcdev->lock);
1394
1395 if (list_empty(&pcdev->active_bufs)) {
1396 dev_warn(pcdev->dev, "%s: called while active list is empty\n",
1397 __func__);
1398
1399 if (!status) {
1400 spin_unlock(&pcdev->lock);
1401 return IRQ_NONE;
1402 }
1403 }
1404
1405 if (status & (1 << 7)) { /* overflow */
1406 u32 cntl = readl(pcdev->base_emma + PRP_CNTL);
1407 writel(cntl & ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN),
1408 pcdev->base_emma + PRP_CNTL);
1409 writel(cntl, pcdev->base_emma + PRP_CNTL);
1410
1411 ibuf = list_first_entry(&pcdev->active_bufs,
1412 struct mx2_buf_internal, queue);
1413 mx27_camera_frame_done_emma(pcdev,
1414 ibuf->bufnum, true);
1415
1416 status &= ~(1 << 7);
1417 } else if (((status & (3 << 5)) == (3 << 5)) ||
1418 ((status & (3 << 3)) == (3 << 3))) {
1419 /*
1420 * Both buffers have triggered, process the one we're expecting
1421 * to first
1422 */
1423 ibuf = list_first_entry(&pcdev->active_bufs,
1424 struct mx2_buf_internal, queue);
1425 mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false);
1426 status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */
1427 } else if ((status & (1 << 6)) || (status & (1 << 4))) {
1428 mx27_camera_frame_done_emma(pcdev, 0, false);
1429 } else if ((status & (1 << 5)) || (status & (1 << 3))) {
1430 mx27_camera_frame_done_emma(pcdev, 1, false);
1431 }
1432
1433 spin_unlock(&pcdev->lock);
1434 writel(status, pcdev->base_emma + PRP_INTRSTATUS);
1435
1436 return IRQ_HANDLED;
1437}
1438
1439static int mx27_camera_emma_init(struct platform_device *pdev)
1440{
1441 struct mx2_camera_dev *pcdev = platform_get_drvdata(pdev);
1442 struct resource *res_emma;
1443 int irq_emma;
1444 int err = 0;
1445
1446 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1447 irq_emma = platform_get_irq(pdev, 1);
1448 if (!res_emma || !irq_emma) {
1449 dev_err(pcdev->dev, "no EMMA resources\n");
1450 err = -ENODEV;
1451 goto out;
1452 }
1453
1454 pcdev->base_emma = devm_ioremap_resource(pcdev->dev, res_emma);
1455 if (IS_ERR(pcdev->base_emma)) {
1456 err = PTR_ERR(pcdev->base_emma);
1457 goto out;
1458 }
1459
1460 err = devm_request_irq(pcdev->dev, irq_emma, mx27_camera_emma_irq, 0,
1461 MX2_CAM_DRV_NAME, pcdev);
1462 if (err) {
1463 dev_err(pcdev->dev, "Camera EMMA interrupt register failed\n");
1464 goto out;
1465 }
1466
1467 pcdev->clk_emma_ipg = devm_clk_get(pcdev->dev, "emma-ipg");
1468 if (IS_ERR(pcdev->clk_emma_ipg)) {
1469 err = PTR_ERR(pcdev->clk_emma_ipg);
1470 goto out;
1471 }
1472
1473 clk_prepare_enable(pcdev->clk_emma_ipg);
1474
1475 pcdev->clk_emma_ahb = devm_clk_get(pcdev->dev, "emma-ahb");
1476 if (IS_ERR(pcdev->clk_emma_ahb)) {
1477 err = PTR_ERR(pcdev->clk_emma_ahb);
1478 goto exit_clk_emma_ipg;
1479 }
1480
1481 clk_prepare_enable(pcdev->clk_emma_ahb);
1482
1483 err = mx27_camera_emma_prp_reset(pcdev);
1484 if (err)
1485 goto exit_clk_emma_ahb;
1486
1487 return err;
1488
1489exit_clk_emma_ahb:
1490 clk_disable_unprepare(pcdev->clk_emma_ahb);
1491exit_clk_emma_ipg:
1492 clk_disable_unprepare(pcdev->clk_emma_ipg);
1493out:
1494 return err;
1495}
1496
1497static int mx2_camera_probe(struct platform_device *pdev)
1498{
1499 struct mx2_camera_dev *pcdev;
1500 struct resource *res_csi;
1501 int irq_csi;
1502 int err = 0;
1503
1504 dev_dbg(&pdev->dev, "initialising\n");
1505
1506 res_csi = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1507 irq_csi = platform_get_irq(pdev, 0);
1508 if (res_csi == NULL || irq_csi < 0) {
1509 dev_err(&pdev->dev, "Missing platform resources data\n");
1510 err = -ENODEV;
1511 goto exit;
1512 }
1513
1514 pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
1515 if (!pcdev) {
1516 dev_err(&pdev->dev, "Could not allocate pcdev\n");
1517 err = -ENOMEM;
1518 goto exit;
1519 }
1520
1521 pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
1522 if (IS_ERR(pcdev->clk_csi_ahb)) {
1523 dev_err(&pdev->dev, "Could not get csi ahb clock\n");
1524 err = PTR_ERR(pcdev->clk_csi_ahb);
1525 goto exit;
1526 }
1527
1528 pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
1529 if (IS_ERR(pcdev->clk_csi_per)) {
1530 dev_err(&pdev->dev, "Could not get csi per clock\n");
1531 err = PTR_ERR(pcdev->clk_csi_per);
1532 goto exit;
1533 }
1534
1535 pcdev->pdata = pdev->dev.platform_data;
1536 if (pcdev->pdata) {
1537 long rate;
1538
1539 pcdev->platform_flags = pcdev->pdata->flags;
1540
1541 rate = clk_round_rate(pcdev->clk_csi_per,
1542 pcdev->pdata->clk * 2);
1543 if (rate <= 0) {
1544 err = -ENODEV;
1545 goto exit;
1546 }
1547 err = clk_set_rate(pcdev->clk_csi_per, rate);
1548 if (err < 0)
1549 goto exit;
1550 }
1551
1552 INIT_LIST_HEAD(&pcdev->capture);
1553 INIT_LIST_HEAD(&pcdev->active_bufs);
1554 INIT_LIST_HEAD(&pcdev->discard);
1555 spin_lock_init(&pcdev->lock);
1556
1557 pcdev->base_csi = devm_ioremap_resource(&pdev->dev, res_csi);
1558 if (IS_ERR(pcdev->base_csi)) {
1559 err = PTR_ERR(pcdev->base_csi);
1560 goto exit;
1561 }
1562
1563 pcdev->dev = &pdev->dev;
1564 platform_set_drvdata(pdev, pcdev);
1565
1566 err = mx27_camera_emma_init(pdev);
1567 if (err)
1568 goto exit;
1569
1570 /*
1571 * We're done with drvdata here. Clear the pointer so that
1572 * v4l2 core can start using drvdata on its purpose.
1573 */
1574 platform_set_drvdata(pdev, NULL);
1575
1576 pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME,
1577 pcdev->soc_host.ops = &mx2_soc_camera_host_ops,
1578 pcdev->soc_host.priv = pcdev;
1579 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1580 pcdev->soc_host.nr = pdev->id;
1581
1582 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1583 if (IS_ERR(pcdev->alloc_ctx)) {
1584 err = PTR_ERR(pcdev->alloc_ctx);
1585 goto eallocctx;
1586 }
1587 err = soc_camera_host_register(&pcdev->soc_host);
1588 if (err)
1589 goto exit_free_emma;
1590
1591 dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
1592 clk_get_rate(pcdev->clk_csi_per));
1593
1594 return 0;
1595
1596exit_free_emma:
1597 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1598eallocctx:
1599 clk_disable_unprepare(pcdev->clk_emma_ipg);
1600 clk_disable_unprepare(pcdev->clk_emma_ahb);
1601exit:
1602 return err;
1603}
1604
1605static int mx2_camera_remove(struct platform_device *pdev)
1606{
1607 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1608 struct mx2_camera_dev *pcdev = container_of(soc_host,
1609 struct mx2_camera_dev, soc_host);
1610
1611 soc_camera_host_unregister(&pcdev->soc_host);
1612
1613 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1614
1615 clk_disable_unprepare(pcdev->clk_emma_ipg);
1616 clk_disable_unprepare(pcdev->clk_emma_ahb);
1617
1618 dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
1619
1620 return 0;
1621}
1622
1623static struct platform_driver mx2_camera_driver = {
1624 .driver = {
1625 .name = MX2_CAM_DRV_NAME,
1626 },
1627 .id_table = mx2_camera_devtype,
1628 .remove = mx2_camera_remove,
1629};
1630
1631module_platform_driver_probe(mx2_camera_driver, mx2_camera_probe);
1632
1633MODULE_DESCRIPTION("i.MX27 SoC Camera Host driver");
1634MODULE_AUTHOR("Sascha Hauer <sha@pengutronix.de>");
1635MODULE_LICENSE("GPL");
1636MODULE_VERSION(MX2_CAM_VERSION);
diff --git a/drivers/staging/media/mx3/Kconfig b/drivers/staging/media/mx3/Kconfig
deleted file mode 100644
index 595d5fe7cad1..000000000000
--- a/drivers/staging/media/mx3/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
1config VIDEO_MX3
2 tristate "i.MX3x Camera Sensor Interface driver"
3 depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
4 depends on MX3_IPU || COMPILE_TEST
5 depends on HAS_DMA
6 select VIDEOBUF2_DMA_CONTIG
7 ---help---
8 This is a v4l2 driver for the i.MX3x Camera Sensor Interface
9
10 This driver is deprecated: it should become a stand-alone driver
11 instead of using the soc-camera framework.
12
13 Unless someone is willing to take this on (unlikely with such
14 ancient hardware) it is going to be removed from the kernel
15 soon.
diff --git a/drivers/staging/media/mx3/Makefile b/drivers/staging/media/mx3/Makefile
deleted file mode 100644
index 6d91dcd80c1d..000000000000
--- a/drivers/staging/media/mx3/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1# Makefile for i.MX3x Camera Sensor driver
2
3obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
diff --git a/drivers/staging/media/mx3/TODO b/drivers/staging/media/mx3/TODO
deleted file mode 100644
index bc68fa443a3e..000000000000
--- a/drivers/staging/media/mx3/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
1This driver is deprecated: it should become a stand-alone driver instead of
2using the soc-camera framework.
3
4Unless someone is willing to take this on (unlikely with such ancient
5hardware) it is going to be removed from the kernel soon.
6
7Note that trivial patches will not be accepted anymore, only a full conversion.
8
9If you want to convert this driver, please contact the linux-media mailinglist
10(see http://linuxtv.org/lists.php).
diff --git a/drivers/staging/media/mx3/mx3_camera.c b/drivers/staging/media/mx3/mx3_camera.c
deleted file mode 100644
index aa39e9569b1a..000000000000
--- a/drivers/staging/media/mx3/mx3_camera.c
+++ /dev/null
@@ -1,1264 +0,0 @@
1/*
2 * V4L2 Driver for i.MX3x camera host
3 *
4 * Copyright (C) 2008
5 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/videodev2.h>
15#include <linux/platform_device.h>
16#include <linux/clk.h>
17#include <linux/vmalloc.h>
18#include <linux/interrupt.h>
19#include <linux/sched.h>
20#include <linux/dma/ipu-dma.h>
21
22#include <media/v4l2-common.h>
23#include <media/v4l2-dev.h>
24#include <media/videobuf2-dma-contig.h>
25#include <media/soc_camera.h>
26#include <media/drv-intf/soc_mediabus.h>
27
28#include <linux/platform_data/media/camera-mx3.h>
29#include <linux/platform_data/dma-imx.h>
30
31#define MX3_CAM_DRV_NAME "mx3-camera"
32
33/* CMOS Sensor Interface Registers */
34#define CSI_REG_START 0x60
35
36#define CSI_SENS_CONF (0x60 - CSI_REG_START)
37#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START)
38#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START)
39#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START)
40#define CSI_TST_CTRL (0x70 - CSI_REG_START)
41#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START)
42#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START)
43#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START)
44#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START)
45#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START)
46
47#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0
48#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1
49#define CSI_SENS_CONF_DATA_POL_SHIFT 2
50#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3
51#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4
52#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7
53#define CSI_SENS_CONF_DATA_FMT_SHIFT 8
54#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10
55#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15
56#define CSI_SENS_CONF_DIVRATIO_SHIFT 16
57
58#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
59#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
60#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
61
62#define MAX_VIDEO_MEM 16
63
64struct mx3_camera_buffer {
65 /* common v4l buffer stuff -- must be first */
66 struct vb2_v4l2_buffer vb;
67 struct list_head queue;
68
69 /* One descriptot per scatterlist (per frame) */
70 struct dma_async_tx_descriptor *txd;
71
72 /* We have to "build" a scatterlist ourselves - one element per frame */
73 struct scatterlist sg;
74};
75
76/**
77 * struct mx3_camera_dev - i.MX3x camera (CSI) object
78 * @dev: camera device, to which the coherent buffer is attached
79 * @icd: currently attached camera sensor
80 * @clk: pointer to clock
81 * @base: remapped register base address
82 * @pdata: platform data
83 * @platform_flags: platform flags
84 * @mclk: master clock frequency in Hz
85 * @capture: list of capture videobuffers
86 * @lock: protects video buffer lists
87 * @active: active video buffer
88 * @idmac_channel: array of pointers to IPU DMAC DMA channels
89 * @soc_host: embedded soc_host object
90 */
91struct mx3_camera_dev {
92 /*
93 * i.MX3x is only supposed to handle one camera on its Camera Sensor
94 * Interface. If anyone ever builds hardware to enable more than one
95 * camera _simultaneously_, they will have to modify this driver too
96 */
97 struct clk *clk;
98
99 void __iomem *base;
100
101 struct mx3_camera_pdata *pdata;
102
103 unsigned long platform_flags;
104 unsigned long mclk;
105 u16 width_flags; /* max 15 bits */
106
107 struct list_head capture;
108 spinlock_t lock; /* Protects video buffer lists */
109 struct mx3_camera_buffer *active;
110 size_t buf_total;
111 struct vb2_alloc_ctx *alloc_ctx;
112 enum v4l2_field field;
113 int sequence;
114
115 /* IDMAC / dmaengine interface */
116 struct idmac_channel *idmac_channel[1]; /* We need one channel */
117
118 struct soc_camera_host soc_host;
119};
120
121struct dma_chan_request {
122 struct mx3_camera_dev *mx3_cam;
123 enum ipu_channel id;
124};
125
126static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
127{
128 return __raw_readl(mx3->base + reg);
129}
130
131static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
132{
133 __raw_writel(value, mx3->base + reg);
134}
135
136static struct mx3_camera_buffer *to_mx3_vb(struct vb2_v4l2_buffer *vb)
137{
138 return container_of(vb, struct mx3_camera_buffer, vb);
139}
140
141/* Called from the IPU IDMAC ISR */
142static void mx3_cam_dma_done(void *arg)
143{
144 struct idmac_tx_desc *desc = to_tx_desc(arg);
145 struct dma_chan *chan = desc->txd.chan;
146 struct idmac_channel *ichannel = to_idmac_chan(chan);
147 struct mx3_camera_dev *mx3_cam = ichannel->client;
148
149 dev_dbg(chan->device->dev, "callback cookie %d, active DMA %pad\n",
150 desc->txd.cookie, mx3_cam->active ? &sg_dma_address(&mx3_cam->active->sg) : NULL);
151
152 spin_lock(&mx3_cam->lock);
153 if (mx3_cam->active) {
154 struct vb2_v4l2_buffer *vb = &mx3_cam->active->vb;
155 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
156
157 list_del_init(&buf->queue);
158 vb->vb2_buf.timestamp = ktime_get_ns();
159 vb->field = mx3_cam->field;
160 vb->sequence = mx3_cam->sequence++;
161 vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
162 }
163
164 if (list_empty(&mx3_cam->capture)) {
165 mx3_cam->active = NULL;
166 spin_unlock(&mx3_cam->lock);
167
168 /*
169 * stop capture - without further buffers IPU_CHA_BUF0_RDY will
170 * not get updated
171 */
172 return;
173 }
174
175 mx3_cam->active = list_entry(mx3_cam->capture.next,
176 struct mx3_camera_buffer, queue);
177 spin_unlock(&mx3_cam->lock);
178}
179
180/*
181 * Videobuf operations
182 */
183
184/*
185 * Calculate the __buffer__ (not data) size and number of buffers.
186 */
187static int mx3_videobuf_setup(struct vb2_queue *vq,
188 unsigned int *count, unsigned int *num_planes,
189 unsigned int sizes[], void *alloc_ctxs[])
190{
191 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
192 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
193 struct mx3_camera_dev *mx3_cam = ici->priv;
194
195 if (!mx3_cam->idmac_channel[0])
196 return -EINVAL;
197
198 alloc_ctxs[0] = mx3_cam->alloc_ctx;
199
200 if (!vq->num_buffers)
201 mx3_cam->sequence = 0;
202
203 if (!*count)
204 *count = 2;
205
206 /* Called from VIDIOC_REQBUFS or in compatibility mode */
207 if (!*num_planes)
208 sizes[0] = icd->sizeimage;
209 else if (sizes[0] < icd->sizeimage)
210 return -EINVAL;
211
212 /* If *num_planes != 0, we have already verified *count. */
213 if (sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
214 *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
215 sizes[0];
216
217 *num_planes = 1;
218
219 return 0;
220}
221
222static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
223{
224 /* Add more formats as need arises and test possibilities appear... */
225 switch (fourcc) {
226 case V4L2_PIX_FMT_RGB24:
227 return IPU_PIX_FMT_RGB24;
228 case V4L2_PIX_FMT_UYVY:
229 case V4L2_PIX_FMT_RGB565:
230 default:
231 return IPU_PIX_FMT_GENERIC;
232 }
233}
234
235static void mx3_videobuf_queue(struct vb2_buffer *vb)
236{
237 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
238 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
239 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
240 struct mx3_camera_dev *mx3_cam = ici->priv;
241 struct mx3_camera_buffer *buf = to_mx3_vb(vbuf);
242 struct scatterlist *sg = &buf->sg;
243 struct dma_async_tx_descriptor *txd;
244 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
245 struct idmac_video_param *video = &ichan->params.video;
246 const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
247 dma_cookie_t cookie;
248 size_t new_size;
249
250 new_size = icd->sizeimage;
251
252 if (vb2_plane_size(vb, 0) < new_size) {
253 dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
254 vbuf->vb2_buf.index, vb2_plane_size(vb, 0), new_size);
255 goto error;
256 }
257
258 if (!buf->txd) {
259 sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
260 sg_dma_len(sg) = new_size;
261
262 txd = dmaengine_prep_slave_sg(
263 &ichan->dma_chan, sg, 1, DMA_DEV_TO_MEM,
264 DMA_PREP_INTERRUPT);
265 if (!txd)
266 goto error;
267
268 txd->callback_param = txd;
269 txd->callback = mx3_cam_dma_done;
270
271 buf->txd = txd;
272 } else {
273 txd = buf->txd;
274 }
275
276 vb2_set_plane_payload(vb, 0, new_size);
277
278 /* This is the configuration of one sg-element */
279 video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
280
281 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
282 /*
283 * If the IPU DMA channel is configured to transfer generic
284 * 8-bit data, we have to set up the geometry parameters
285 * correctly, according to the current pixel format. The DMA
286 * horizontal parameters in this case are expressed in bytes,
287 * not in pixels.
288 */
289 video->out_width = icd->bytesperline;
290 video->out_height = icd->user_height;
291 video->out_stride = icd->bytesperline;
292 } else {
293 /*
294 * For IPU known formats the pixel unit will be managed
295 * successfully by the IPU code
296 */
297 video->out_width = icd->user_width;
298 video->out_height = icd->user_height;
299 video->out_stride = icd->user_width;
300 }
301
302#ifdef DEBUG
303 /* helps to see what DMA actually has written */
304 if (vb2_plane_vaddr(vb, 0))
305 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
306#endif
307
308 spin_lock_irq(&mx3_cam->lock);
309 list_add_tail(&buf->queue, &mx3_cam->capture);
310
311 if (!mx3_cam->active)
312 mx3_cam->active = buf;
313
314 spin_unlock_irq(&mx3_cam->lock);
315
316 cookie = txd->tx_submit(txd);
317 dev_dbg(icd->parent, "Submitted cookie %d DMA %pad\n",
318 cookie, &sg_dma_address(&buf->sg));
319
320 if (cookie >= 0)
321 return;
322
323 spin_lock_irq(&mx3_cam->lock);
324
325 /* Submit error */
326 list_del_init(&buf->queue);
327
328 if (mx3_cam->active == buf)
329 mx3_cam->active = NULL;
330
331 spin_unlock_irq(&mx3_cam->lock);
332error:
333 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
334}
335
336static void mx3_videobuf_release(struct vb2_buffer *vb)
337{
338 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
339 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
340 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
341 struct mx3_camera_dev *mx3_cam = ici->priv;
342 struct mx3_camera_buffer *buf = to_mx3_vb(vbuf);
343 struct dma_async_tx_descriptor *txd = buf->txd;
344 unsigned long flags;
345
346 dev_dbg(icd->parent,
347 "Release%s DMA %pad, queue %sempty\n",
348 mx3_cam->active == buf ? " active" : "", &sg_dma_address(&buf->sg),
349 list_empty(&buf->queue) ? "" : "not ");
350
351 spin_lock_irqsave(&mx3_cam->lock, flags);
352
353 if (mx3_cam->active == buf)
354 mx3_cam->active = NULL;
355
356 /* Doesn't hurt also if the list is empty */
357 list_del_init(&buf->queue);
358
359 if (txd) {
360 buf->txd = NULL;
361 if (mx3_cam->idmac_channel[0])
362 async_tx_ack(txd);
363 }
364
365 spin_unlock_irqrestore(&mx3_cam->lock, flags);
366
367 mx3_cam->buf_total -= vb2_plane_size(vb, 0);
368}
369
370static int mx3_videobuf_init(struct vb2_buffer *vb)
371{
372 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
373 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
374 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
375 struct mx3_camera_dev *mx3_cam = ici->priv;
376 struct mx3_camera_buffer *buf = to_mx3_vb(vbuf);
377
378 if (!buf->txd) {
379 /* This is for locking debugging only */
380 INIT_LIST_HEAD(&buf->queue);
381 sg_init_table(&buf->sg, 1);
382
383 mx3_cam->buf_total += vb2_plane_size(vb, 0);
384 }
385
386 return 0;
387}
388
389static void mx3_stop_streaming(struct vb2_queue *q)
390{
391 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
392 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
393 struct mx3_camera_dev *mx3_cam = ici->priv;
394 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
395 struct mx3_camera_buffer *buf, *tmp;
396 unsigned long flags;
397
398 if (ichan)
399 dmaengine_pause(&ichan->dma_chan);
400
401 spin_lock_irqsave(&mx3_cam->lock, flags);
402
403 mx3_cam->active = NULL;
404
405 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
406 list_del_init(&buf->queue);
407 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
408 }
409
410 spin_unlock_irqrestore(&mx3_cam->lock, flags);
411}
412
413static struct vb2_ops mx3_videobuf_ops = {
414 .queue_setup = mx3_videobuf_setup,
415 .buf_queue = mx3_videobuf_queue,
416 .buf_cleanup = mx3_videobuf_release,
417 .buf_init = mx3_videobuf_init,
418 .wait_prepare = vb2_ops_wait_prepare,
419 .wait_finish = vb2_ops_wait_finish,
420 .stop_streaming = mx3_stop_streaming,
421};
422
423static int mx3_camera_init_videobuf(struct vb2_queue *q,
424 struct soc_camera_device *icd)
425{
426 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
427
428 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
429 q->io_modes = VB2_MMAP | VB2_USERPTR;
430 q->drv_priv = icd;
431 q->ops = &mx3_videobuf_ops;
432 q->mem_ops = &vb2_dma_contig_memops;
433 q->buf_struct_size = sizeof(struct mx3_camera_buffer);
434 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
435 q->lock = &ici->host_lock;
436
437 return vb2_queue_init(q);
438}
439
440/* First part of ipu_csi_init_interface() */
441static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam)
442{
443 u32 conf;
444 long rate;
445
446 /* Set default size: ipu_csi_set_window_size() */
447 csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
448 /* ...and position to 0:0: ipu_csi_set_window_pos() */
449 conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
450 csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
451
452 /* We use only gated clock synchronisation mode so far */
453 conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
454
455 /* Set generic data, platform-biggest bus-width */
456 conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
457
458 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
459 conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
460 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
461 conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
462 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
463 conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
464 else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
465 conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
466
467 if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
468 conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
469 if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
470 conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
471 if (mx3_cam->platform_flags & MX3_CAMERA_DP)
472 conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
473 if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
474 conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
475 if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
476 conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
477 if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
478 conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
479
480 /* ipu_csi_init_interface() */
481 csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
482
483 clk_prepare_enable(mx3_cam->clk);
484 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
485 dev_dbg(mx3_cam->soc_host.v4l2_dev.dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
486 if (rate)
487 clk_set_rate(mx3_cam->clk, rate);
488}
489
490static int mx3_camera_add_device(struct soc_camera_device *icd)
491{
492 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
493 icd->devnum);
494
495 return 0;
496}
497
498static void mx3_camera_remove_device(struct soc_camera_device *icd)
499{
500 dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
501 icd->devnum);
502}
503
504/* Called with .host_lock held */
505static int mx3_camera_clock_start(struct soc_camera_host *ici)
506{
507 struct mx3_camera_dev *mx3_cam = ici->priv;
508
509 mx3_camera_activate(mx3_cam);
510
511 mx3_cam->buf_total = 0;
512
513 return 0;
514}
515
516/* Called with .host_lock held */
517static void mx3_camera_clock_stop(struct soc_camera_host *ici)
518{
519 struct mx3_camera_dev *mx3_cam = ici->priv;
520 struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
521
522 if (*ichan) {
523 dma_release_channel(&(*ichan)->dma_chan);
524 *ichan = NULL;
525 }
526
527 clk_disable_unprepare(mx3_cam->clk);
528}
529
530static int test_platform_param(struct mx3_camera_dev *mx3_cam,
531 unsigned char buswidth, unsigned long *flags)
532{
533 /*
534 * If requested data width is supported by the platform, use it or any
535 * possible lower value - i.MX31 is smart enough to shift bits
536 */
537 if (buswidth > fls(mx3_cam->width_flags))
538 return -EINVAL;
539
540 /*
541 * Platform specified synchronization and pixel clock polarities are
542 * only a recommendation and are only used during probing. MX3x
543 * camera interface only works in master mode, i.e., uses HSYNC and
544 * VSYNC signals from the sensor
545 */
546 *flags = V4L2_MBUS_MASTER |
547 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
548 V4L2_MBUS_HSYNC_ACTIVE_LOW |
549 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
550 V4L2_MBUS_VSYNC_ACTIVE_LOW |
551 V4L2_MBUS_PCLK_SAMPLE_RISING |
552 V4L2_MBUS_PCLK_SAMPLE_FALLING |
553 V4L2_MBUS_DATA_ACTIVE_HIGH |
554 V4L2_MBUS_DATA_ACTIVE_LOW;
555
556 return 0;
557}
558
559static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
560 const unsigned int depth)
561{
562 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
563 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
564 struct mx3_camera_dev *mx3_cam = ici->priv;
565 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
566 unsigned long bus_flags, common_flags;
567 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
568
569 dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
570
571 if (ret < 0)
572 return ret;
573
574 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
575 if (!ret) {
576 common_flags = soc_mbus_config_compatible(&cfg,
577 bus_flags);
578 if (!common_flags) {
579 dev_warn(icd->parent,
580 "Flags incompatible: camera 0x%x, host 0x%lx\n",
581 cfg.flags, bus_flags);
582 return -EINVAL;
583 }
584 } else if (ret != -ENOIOCTLCMD) {
585 return ret;
586 }
587
588 return 0;
589}
590
591static bool chan_filter(struct dma_chan *chan, void *arg)
592{
593 struct dma_chan_request *rq = arg;
594 struct mx3_camera_pdata *pdata;
595
596 if (!imx_dma_is_ipu(chan))
597 return false;
598
599 if (!rq)
600 return false;
601
602 pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
603
604 return rq->id == chan->chan_id &&
605 pdata->dma_dev == chan->device->dev;
606}
607
608static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
609 {
610 .fourcc = V4L2_PIX_FMT_SBGGR8,
611 .name = "Bayer BGGR (sRGB) 8 bit",
612 .bits_per_sample = 8,
613 .packing = SOC_MBUS_PACKING_NONE,
614 .order = SOC_MBUS_ORDER_LE,
615 .layout = SOC_MBUS_LAYOUT_PACKED,
616 }, {
617 .fourcc = V4L2_PIX_FMT_GREY,
618 .name = "Monochrome 8 bit",
619 .bits_per_sample = 8,
620 .packing = SOC_MBUS_PACKING_NONE,
621 .order = SOC_MBUS_ORDER_LE,
622 .layout = SOC_MBUS_LAYOUT_PACKED,
623 },
624};
625
626/* This will be corrected as we get more formats */
627static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
628{
629 return fmt->packing == SOC_MBUS_PACKING_NONE ||
630 (fmt->bits_per_sample == 8 &&
631 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
632 (fmt->bits_per_sample > 8 &&
633 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
634}
635
636static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
637 struct soc_camera_format_xlate *xlate)
638{
639 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
640 struct device *dev = icd->parent;
641 int formats = 0, ret;
642 struct v4l2_subdev_mbus_code_enum code = {
643 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
644 .index = idx,
645 };
646 const struct soc_mbus_pixelfmt *fmt;
647
648 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
649 if (ret < 0)
650 /* No more formats */
651 return 0;
652
653 fmt = soc_mbus_get_fmtdesc(code.code);
654 if (!fmt) {
655 dev_warn(icd->parent,
656 "Unsupported format code #%u: 0x%x\n", idx, code.code);
657 return 0;
658 }
659
660 /* This also checks support for the requested bits-per-sample */
661 ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
662 if (ret < 0)
663 return 0;
664
665 switch (code.code) {
666 case MEDIA_BUS_FMT_SBGGR10_1X10:
667 formats++;
668 if (xlate) {
669 xlate->host_fmt = &mx3_camera_formats[0];
670 xlate->code = code.code;
671 xlate++;
672 dev_dbg(dev, "Providing format %s using code 0x%x\n",
673 mx3_camera_formats[0].name, code.code);
674 }
675 break;
676 case MEDIA_BUS_FMT_Y10_1X10:
677 formats++;
678 if (xlate) {
679 xlate->host_fmt = &mx3_camera_formats[1];
680 xlate->code = code.code;
681 xlate++;
682 dev_dbg(dev, "Providing format %s using code 0x%x\n",
683 mx3_camera_formats[1].name, code.code);
684 }
685 break;
686 default:
687 if (!mx3_camera_packing_supported(fmt))
688 return 0;
689 }
690
691 /* Generic pass-through */
692 formats++;
693 if (xlate) {
694 xlate->host_fmt = fmt;
695 xlate->code = code.code;
696 dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
697 (fmt->fourcc >> (0*8)) & 0xFF,
698 (fmt->fourcc >> (1*8)) & 0xFF,
699 (fmt->fourcc >> (2*8)) & 0xFF,
700 (fmt->fourcc >> (3*8)) & 0xFF);
701 xlate++;
702 }
703
704 return formats;
705}
706
707static void configure_geometry(struct mx3_camera_dev *mx3_cam,
708 unsigned int width, unsigned int height,
709 const struct soc_mbus_pixelfmt *fmt)
710{
711 u32 ctrl, width_field, height_field;
712
713 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
714 /*
715 * As the CSI will be configured to output BAYER, here
716 * the width parameter count the number of samples to
717 * capture to complete the whole image width.
718 */
719 unsigned int num, den;
720 int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
721 BUG_ON(ret < 0);
722 width = width * num / den;
723 }
724
725 /* Setup frame size - this cannot be changed on-the-fly... */
726 width_field = width - 1;
727 height_field = height - 1;
728 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
729
730 csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
731 csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
732
733 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
734
735 /* ...and position */
736 ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
737 /* Sensor does the cropping */
738 csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
739}
740
741static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
742{
743 dma_cap_mask_t mask;
744 struct dma_chan *chan;
745 struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
746 /* We have to use IDMAC_IC_7 for Bayer / generic data */
747 struct dma_chan_request rq = {.mx3_cam = mx3_cam,
748 .id = IDMAC_IC_7};
749
750 dma_cap_zero(mask);
751 dma_cap_set(DMA_SLAVE, mask);
752 dma_cap_set(DMA_PRIVATE, mask);
753 chan = dma_request_channel(mask, chan_filter, &rq);
754 if (!chan)
755 return -EBUSY;
756
757 *ichan = to_idmac_chan(chan);
758 (*ichan)->client = mx3_cam;
759
760 return 0;
761}
762
763/*
764 * FIXME: learn to use stride != width, then we can keep stride properly aligned
765 * and support arbitrary (even) widths.
766 */
767static inline void stride_align(__u32 *width)
768{
769 if (ALIGN(*width, 8) < 4096)
770 *width = ALIGN(*width, 8);
771 else
772 *width = *width & ~7;
773}
774
775/*
776 * As long as we don't implement host-side cropping and scaling, we can use
777 * default g_crop and cropcap from soc_camera.c
778 */
779static int mx3_camera_set_crop(struct soc_camera_device *icd,
780 const struct v4l2_crop *a)
781{
782 struct v4l2_crop a_writable = *a;
783 struct v4l2_rect *rect = &a_writable.c;
784 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
785 struct mx3_camera_dev *mx3_cam = ici->priv;
786 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
787 struct v4l2_subdev_format fmt = {
788 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
789 };
790 struct v4l2_mbus_framefmt *mf = &fmt.format;
791 int ret;
792
793 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
794 soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
795
796 ret = v4l2_subdev_call(sd, video, s_crop, a);
797 if (ret < 0)
798 return ret;
799
800 /* The capture device might have changed its output sizes */
801 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
802 if (ret < 0)
803 return ret;
804
805 if (mf->code != icd->current_fmt->code)
806 return -EINVAL;
807
808 if (mf->width & 7) {
809 /* Ouch! We can only handle 8-byte aligned width... */
810 stride_align(&mf->width);
811 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &fmt);
812 if (ret < 0)
813 return ret;
814 }
815
816 if (mf->width != icd->user_width || mf->height != icd->user_height)
817 configure_geometry(mx3_cam, mf->width, mf->height,
818 icd->current_fmt->host_fmt);
819
820 dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
821 mf->width, mf->height);
822
823 icd->user_width = mf->width;
824 icd->user_height = mf->height;
825
826 return ret;
827}
828
829static int mx3_camera_set_fmt(struct soc_camera_device *icd,
830 struct v4l2_format *f)
831{
832 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
833 struct mx3_camera_dev *mx3_cam = ici->priv;
834 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
835 const struct soc_camera_format_xlate *xlate;
836 struct v4l2_pix_format *pix = &f->fmt.pix;
837 struct v4l2_subdev_format format = {
838 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
839 };
840 struct v4l2_mbus_framefmt *mf = &format.format;
841 int ret;
842
843 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
844 if (!xlate) {
845 dev_warn(icd->parent, "Format %x not found\n",
846 pix->pixelformat);
847 return -EINVAL;
848 }
849
850 stride_align(&pix->width);
851 dev_dbg(icd->parent, "Set format %dx%d\n", pix->width, pix->height);
852
853 /*
854 * Might have to perform a complete interface initialisation like in
855 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
856 * mxc_v4l2_s_fmt()
857 */
858
859 configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
860
861 mf->width = pix->width;
862 mf->height = pix->height;
863 mf->field = pix->field;
864 mf->colorspace = pix->colorspace;
865 mf->code = xlate->code;
866
867 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format);
868 if (ret < 0)
869 return ret;
870
871 if (mf->code != xlate->code)
872 return -EINVAL;
873
874 if (!mx3_cam->idmac_channel[0]) {
875 ret = acquire_dma_channel(mx3_cam);
876 if (ret < 0)
877 return ret;
878 }
879
880 pix->width = mf->width;
881 pix->height = mf->height;
882 pix->field = mf->field;
883 mx3_cam->field = mf->field;
884 pix->colorspace = mf->colorspace;
885 icd->current_fmt = xlate;
886
887 dev_dbg(icd->parent, "Sensor set %dx%d\n", pix->width, pix->height);
888
889 return ret;
890}
891
892static int mx3_camera_try_fmt(struct soc_camera_device *icd,
893 struct v4l2_format *f)
894{
895 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
896 const struct soc_camera_format_xlate *xlate;
897 struct v4l2_pix_format *pix = &f->fmt.pix;
898 struct v4l2_subdev_pad_config pad_cfg;
899 struct v4l2_subdev_format format = {
900 .which = V4L2_SUBDEV_FORMAT_TRY,
901 };
902 struct v4l2_mbus_framefmt *mf = &format.format;
903 __u32 pixfmt = pix->pixelformat;
904 int ret;
905
906 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
907 if (pixfmt && !xlate) {
908 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
909 return -EINVAL;
910 }
911
912 /* limit to MX3 hardware capabilities */
913 if (pix->height > 4096)
914 pix->height = 4096;
915 if (pix->width > 4096)
916 pix->width = 4096;
917
918 /* limit to sensor capabilities */
919 mf->width = pix->width;
920 mf->height = pix->height;
921 mf->field = pix->field;
922 mf->colorspace = pix->colorspace;
923 mf->code = xlate->code;
924
925 ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
926 if (ret < 0)
927 return ret;
928
929 pix->width = mf->width;
930 pix->height = mf->height;
931 pix->colorspace = mf->colorspace;
932
933 switch (mf->field) {
934 case V4L2_FIELD_ANY:
935 pix->field = V4L2_FIELD_NONE;
936 break;
937 case V4L2_FIELD_NONE:
938 break;
939 default:
940 dev_err(icd->parent, "Field type %d unsupported.\n",
941 mf->field);
942 ret = -EINVAL;
943 }
944
945 return ret;
946}
947
948static int mx3_camera_reqbufs(struct soc_camera_device *icd,
949 struct v4l2_requestbuffers *p)
950{
951 return 0;
952}
953
954static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
955{
956 struct soc_camera_device *icd = file->private_data;
957
958 return vb2_poll(&icd->vb2_vidq, file, pt);
959}
960
961static int mx3_camera_querycap(struct soc_camera_host *ici,
962 struct v4l2_capability *cap)
963{
964 /* cap->name is set by the firendly caller:-> */
965 strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
966 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
967 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
968
969 return 0;
970}
971
972static int mx3_camera_set_bus_param(struct soc_camera_device *icd)
973{
974 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
975 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
976 struct mx3_camera_dev *mx3_cam = ici->priv;
977 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
978 u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
979 unsigned long bus_flags, common_flags;
980 u32 dw, sens_conf;
981 const struct soc_mbus_pixelfmt *fmt;
982 int buswidth;
983 int ret;
984 const struct soc_camera_format_xlate *xlate;
985 struct device *dev = icd->parent;
986
987 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
988 if (!fmt)
989 return -EINVAL;
990
991 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
992 if (!xlate) {
993 dev_warn(dev, "Format %x not found\n", pixfmt);
994 return -EINVAL;
995 }
996
997 buswidth = fmt->bits_per_sample;
998 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
999
1000 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
1001
1002 if (ret < 0)
1003 return ret;
1004
1005 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1006 if (!ret) {
1007 common_flags = soc_mbus_config_compatible(&cfg,
1008 bus_flags);
1009 if (!common_flags) {
1010 dev_warn(icd->parent,
1011 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1012 cfg.flags, bus_flags);
1013 return -EINVAL;
1014 }
1015 } else if (ret != -ENOIOCTLCMD) {
1016 return ret;
1017 } else {
1018 common_flags = bus_flags;
1019 }
1020
1021 dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
1022 cfg.flags, bus_flags, common_flags);
1023
1024 /* Make choices, based on platform preferences */
1025 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1026 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1027 if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
1028 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1029 else
1030 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1031 }
1032
1033 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1034 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1035 if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
1036 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1037 else
1038 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1039 }
1040
1041 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
1042 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
1043 if (mx3_cam->platform_flags & MX3_CAMERA_DP)
1044 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
1045 else
1046 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
1047 }
1048
1049 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1050 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1051 if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
1052 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1053 else
1054 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1055 }
1056
1057 cfg.flags = common_flags;
1058 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1059 if (ret < 0 && ret != -ENOIOCTLCMD) {
1060 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1061 common_flags, ret);
1062 return ret;
1063 }
1064
1065 /*
1066 * So far only gated clock mode is supported. Add a line
1067 * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
1068 * below and select the required mode when supporting other
1069 * synchronisation protocols.
1070 */
1071 sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
1072 ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
1073 (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
1074 (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
1075 (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
1076 (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
1077 (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
1078
1079 /* TODO: Support RGB and YUV formats */
1080
1081 /* This has been set in mx3_camera_activate(), but we clear it above */
1082 sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
1083
1084 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1085 sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
1086 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1087 sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
1088 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1089 sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
1090 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
1091 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
1092
1093 /* Just do what we're asked to do */
1094 switch (xlate->host_fmt->bits_per_sample) {
1095 case 4:
1096 dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1097 break;
1098 case 8:
1099 dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1100 break;
1101 case 10:
1102 dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1103 break;
1104 default:
1105 /*
1106 * Actually it can only be 15 now, default is just to silence
1107 * compiler warnings
1108 */
1109 case 15:
1110 dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1111 }
1112
1113 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
1114
1115 dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
1116
1117 return 0;
1118}
1119
1120static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
1121 .owner = THIS_MODULE,
1122 .add = mx3_camera_add_device,
1123 .remove = mx3_camera_remove_device,
1124 .clock_start = mx3_camera_clock_start,
1125 .clock_stop = mx3_camera_clock_stop,
1126 .set_crop = mx3_camera_set_crop,
1127 .set_fmt = mx3_camera_set_fmt,
1128 .try_fmt = mx3_camera_try_fmt,
1129 .get_formats = mx3_camera_get_formats,
1130 .init_videobuf2 = mx3_camera_init_videobuf,
1131 .reqbufs = mx3_camera_reqbufs,
1132 .poll = mx3_camera_poll,
1133 .querycap = mx3_camera_querycap,
1134 .set_bus_param = mx3_camera_set_bus_param,
1135};
1136
1137static int mx3_camera_probe(struct platform_device *pdev)
1138{
1139 struct mx3_camera_pdata *pdata = pdev->dev.platform_data;
1140 struct mx3_camera_dev *mx3_cam;
1141 struct resource *res;
1142 void __iomem *base;
1143 int err = 0;
1144 struct soc_camera_host *soc_host;
1145
1146 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1147 base = devm_ioremap_resource(&pdev->dev, res);
1148 if (IS_ERR(base))
1149 return PTR_ERR(base);
1150
1151 if (!pdata)
1152 return -EINVAL;
1153
1154 mx3_cam = devm_kzalloc(&pdev->dev, sizeof(*mx3_cam), GFP_KERNEL);
1155 if (!mx3_cam) {
1156 dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
1157 return -ENOMEM;
1158 }
1159
1160 mx3_cam->clk = devm_clk_get(&pdev->dev, NULL);
1161 if (IS_ERR(mx3_cam->clk))
1162 return PTR_ERR(mx3_cam->clk);
1163
1164 mx3_cam->pdata = pdata;
1165 mx3_cam->platform_flags = pdata->flags;
1166 if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_MASK)) {
1167 /*
1168 * Platform hasn't set available data widths. This is bad.
1169 * Warn and use a default.
1170 */
1171 dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
1172 "data widths, using default 8 bit\n");
1173 mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
1174 }
1175 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
1176 mx3_cam->width_flags = 1 << 3;
1177 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
1178 mx3_cam->width_flags |= 1 << 7;
1179 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
1180 mx3_cam->width_flags |= 1 << 9;
1181 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
1182 mx3_cam->width_flags |= 1 << 14;
1183
1184 mx3_cam->mclk = pdata->mclk_10khz * 10000;
1185 if (!mx3_cam->mclk) {
1186 dev_warn(&pdev->dev,
1187 "mclk_10khz == 0! Please, fix your platform data. "
1188 "Using default 20MHz\n");
1189 mx3_cam->mclk = 20000000;
1190 }
1191
1192 /* list of video-buffers */
1193 INIT_LIST_HEAD(&mx3_cam->capture);
1194 spin_lock_init(&mx3_cam->lock);
1195
1196 mx3_cam->base = base;
1197
1198 soc_host = &mx3_cam->soc_host;
1199 soc_host->drv_name = MX3_CAM_DRV_NAME;
1200 soc_host->ops = &mx3_soc_camera_host_ops;
1201 soc_host->priv = mx3_cam;
1202 soc_host->v4l2_dev.dev = &pdev->dev;
1203 soc_host->nr = pdev->id;
1204
1205 mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1206 if (IS_ERR(mx3_cam->alloc_ctx))
1207 return PTR_ERR(mx3_cam->alloc_ctx);
1208
1209 if (pdata->asd_sizes) {
1210 soc_host->asd = pdata->asd;
1211 soc_host->asd_sizes = pdata->asd_sizes;
1212 }
1213
1214 err = soc_camera_host_register(soc_host);
1215 if (err)
1216 goto ecamhostreg;
1217
1218 /* IDMAC interface */
1219 dmaengine_get();
1220
1221 return 0;
1222
1223ecamhostreg:
1224 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1225 return err;
1226}
1227
1228static int mx3_camera_remove(struct platform_device *pdev)
1229{
1230 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1231 struct mx3_camera_dev *mx3_cam = container_of(soc_host,
1232 struct mx3_camera_dev, soc_host);
1233
1234 soc_camera_host_unregister(soc_host);
1235
1236 /*
1237 * The channel has either not been allocated,
1238 * or should have been released
1239 */
1240 if (WARN_ON(mx3_cam->idmac_channel[0]))
1241 dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
1242
1243 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1244
1245 dmaengine_put();
1246
1247 return 0;
1248}
1249
1250static struct platform_driver mx3_camera_driver = {
1251 .driver = {
1252 .name = MX3_CAM_DRV_NAME,
1253 },
1254 .probe = mx3_camera_probe,
1255 .remove = mx3_camera_remove,
1256};
1257
1258module_platform_driver(mx3_camera_driver);
1259
1260MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
1261MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
1262MODULE_LICENSE("GPL v2");
1263MODULE_VERSION("0.2.3");
1264MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
diff --git a/drivers/staging/media/omap1/Kconfig b/drivers/staging/media/omap1/Kconfig
deleted file mode 100644
index 6cfab3a04ae1..000000000000
--- a/drivers/staging/media/omap1/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
1config VIDEO_OMAP1
2 tristate "OMAP1 Camera Interface driver"
3 depends on VIDEO_DEV && SOC_CAMERA
4 depends on ARCH_OMAP1
5 depends on HAS_DMA
6 select VIDEOBUF_DMA_CONTIG
7 select VIDEOBUF_DMA_SG
8 ---help---
9 This is a v4l2 driver for the TI OMAP1 camera interface
10
11 This driver is deprecated and will be removed soon unless someone
12 will start the work to convert this driver to the vb2 framework
13 and remove the soc-camera dependency.
diff --git a/drivers/staging/media/omap1/Makefile b/drivers/staging/media/omap1/Makefile
deleted file mode 100644
index 2885622600f2..000000000000
--- a/drivers/staging/media/omap1/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1# Makefile for OMAP1 driver
2
3obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
diff --git a/drivers/staging/media/omap1/TODO b/drivers/staging/media/omap1/TODO
deleted file mode 100644
index 1025f9f60ff0..000000000000
--- a/drivers/staging/media/omap1/TODO
+++ /dev/null
@@ -1,8 +0,0 @@
1This driver is deprecated and will be removed soon unless someone will start
2the work to convert this driver to the vb2 framework and remove the
3soc-camera dependency.
4
5Note that trivial patches will not be accepted anymore, only a full conversion.
6
7If you want to convert this driver, please contact the linux-media mailinglist
8(see http://linuxtv.org/lists.php).
diff --git a/drivers/staging/media/omap1/omap1_camera.c b/drivers/staging/media/omap1/omap1_camera.c
deleted file mode 100644
index 54b8dd2d2bba..000000000000
--- a/drivers/staging/media/omap1/omap1_camera.c
+++ /dev/null
@@ -1,1702 +0,0 @@
1/*
2 * V4L2 SoC Camera driver for OMAP1 Camera Interface
3 *
4 * Copyright (C) 2010, Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * Based on V4L2 Driver for i.MXL/i.MXL camera (CSI) host
7 * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
8 * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
9 *
10 * Based on PXA SoC camera driver
11 * Copyright (C) 2006, Sascha Hauer, Pengutronix
12 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
13 *
14 * Hardware specific bits initialy based on former work by Matt Callow
15 * drivers/media/platform/omap/omap1510cam.c
16 * Copyright (C) 2006 Matt Callow
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23
24#include <linux/clk.h>
25#include <linux/dma-mapping.h>
26#include <linux/interrupt.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30
31#include <linux/platform_data/media/omap1_camera.h>
32#include <media/soc_camera.h>
33#include <media/drv-intf/soc_mediabus.h>
34#include <media/videobuf-dma-contig.h>
35#include <media/videobuf-dma-sg.h>
36
37#include <linux/omap-dma.h>
38
39
40#define DRIVER_NAME "omap1-camera"
41#define DRIVER_VERSION "0.0.2"
42
43#define OMAP_DMA_CAMERA_IF_RX 20
44
45/*
46 * ---------------------------------------------------------------------------
47 * OMAP1 Camera Interface registers
48 * ---------------------------------------------------------------------------
49 */
50
51#define REG_CTRLCLOCK 0x00
52#define REG_IT_STATUS 0x04
53#define REG_MODE 0x08
54#define REG_STATUS 0x0C
55#define REG_CAMDATA 0x10
56#define REG_GPIO 0x14
57#define REG_PEAK_COUNTER 0x18
58
59/* CTRLCLOCK bit shifts */
60#define LCLK_EN BIT(7)
61#define DPLL_EN BIT(6)
62#define MCLK_EN BIT(5)
63#define CAMEXCLK_EN BIT(4)
64#define POLCLK BIT(3)
65#define FOSCMOD_SHIFT 0
66#define FOSCMOD_MASK (0x7 << FOSCMOD_SHIFT)
67#define FOSCMOD_12MHz 0x0
68#define FOSCMOD_6MHz 0x2
69#define FOSCMOD_9_6MHz 0x4
70#define FOSCMOD_24MHz 0x5
71#define FOSCMOD_8MHz 0x6
72
73/* IT_STATUS bit shifts */
74#define DATA_TRANSFER BIT(5)
75#define FIFO_FULL BIT(4)
76#define H_DOWN BIT(3)
77#define H_UP BIT(2)
78#define V_DOWN BIT(1)
79#define V_UP BIT(0)
80
81/* MODE bit shifts */
82#define RAZ_FIFO BIT(18)
83#define EN_FIFO_FULL BIT(17)
84#define EN_NIRQ BIT(16)
85#define THRESHOLD_SHIFT 9
86#define THRESHOLD_MASK (0x7f << THRESHOLD_SHIFT)
87#define DMA BIT(8)
88#define EN_H_DOWN BIT(7)
89#define EN_H_UP BIT(6)
90#define EN_V_DOWN BIT(5)
91#define EN_V_UP BIT(4)
92#define ORDERCAMD BIT(3)
93
94#define IRQ_MASK (EN_V_UP | EN_V_DOWN | EN_H_UP | EN_H_DOWN | \
95 EN_NIRQ | EN_FIFO_FULL)
96
97/* STATUS bit shifts */
98#define HSTATUS BIT(1)
99#define VSTATUS BIT(0)
100
101/* GPIO bit shifts */
102#define CAM_RST BIT(0)
103
104/* end of OMAP1 Camera Interface registers */
105
106
107#define SOCAM_BUS_FLAGS (V4L2_MBUS_MASTER | \
108 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
109 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
110 V4L2_MBUS_DATA_ACTIVE_HIGH)
111
112
113#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
114#define FIFO_SHIFT __fls(FIFO_SIZE)
115
116#define DMA_BURST_SHIFT (1 + OMAP_DMA_DATA_BURST_4)
117#define DMA_BURST_SIZE (1 << DMA_BURST_SHIFT)
118
119#define DMA_ELEMENT_SHIFT OMAP_DMA_DATA_TYPE_S32
120#define DMA_ELEMENT_SIZE (1 << DMA_ELEMENT_SHIFT)
121
122#define DMA_FRAME_SHIFT_CONTIG (FIFO_SHIFT - 1)
123#define DMA_FRAME_SHIFT_SG DMA_BURST_SHIFT
124
125#define DMA_FRAME_SHIFT(x) ((x) == OMAP1_CAM_DMA_CONTIG ? \
126 DMA_FRAME_SHIFT_CONTIG : \
127 DMA_FRAME_SHIFT_SG)
128#define DMA_FRAME_SIZE(x) (1 << DMA_FRAME_SHIFT(x))
129#define DMA_SYNC OMAP_DMA_SYNC_FRAME
130#define THRESHOLD_LEVEL DMA_FRAME_SIZE
131
132
133#define MAX_VIDEO_MEM 4 /* arbitrary video memory limit in MB */
134
135
136/*
137 * Structures
138 */
139
140/* buffer for one video frame */
141struct omap1_cam_buf {
142 struct videobuf_buffer vb;
143 u32 code;
144 int inwork;
145 struct scatterlist *sgbuf;
146 int sgcount;
147 int bytes_left;
148 enum videobuf_state result;
149};
150
151struct omap1_cam_dev {
152 struct soc_camera_host soc_host;
153 struct clk *clk;
154
155 unsigned int irq;
156 void __iomem *base;
157
158 int dma_ch;
159
160 struct omap1_cam_platform_data *pdata;
161 struct resource *res;
162 unsigned long pflags;
163 unsigned long camexclk;
164
165 struct list_head capture;
166
167 /* lock used to protect videobuf */
168 spinlock_t lock;
169
170 /* Pointers to DMA buffers */
171 struct omap1_cam_buf *active;
172 struct omap1_cam_buf *ready;
173
174 enum omap1_cam_vb_mode vb_mode;
175 int (*mmap_mapper)(struct videobuf_queue *q,
176 struct videobuf_buffer *buf,
177 struct vm_area_struct *vma);
178
179 u32 reg_cache[0];
180};
181
182
183static void cam_write(struct omap1_cam_dev *pcdev, u16 reg, u32 val)
184{
185 pcdev->reg_cache[reg / sizeof(u32)] = val;
186 __raw_writel(val, pcdev->base + reg);
187}
188
189static u32 cam_read(struct omap1_cam_dev *pcdev, u16 reg, bool from_cache)
190{
191 return !from_cache ? __raw_readl(pcdev->base + reg) :
192 pcdev->reg_cache[reg / sizeof(u32)];
193}
194
195#define CAM_READ(pcdev, reg) \
196 cam_read(pcdev, REG_##reg, false)
197#define CAM_WRITE(pcdev, reg, val) \
198 cam_write(pcdev, REG_##reg, val)
199#define CAM_READ_CACHE(pcdev, reg) \
200 cam_read(pcdev, REG_##reg, true)
201
202/*
203 * Videobuf operations
204 */
205static int omap1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
206 unsigned int *size)
207{
208 struct soc_camera_device *icd = vq->priv_data;
209 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
210 struct omap1_cam_dev *pcdev = ici->priv;
211
212 *size = icd->sizeimage;
213
214 if (!*count || *count < OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode))
215 *count = OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode);
216
217 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
218 *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
219
220 dev_dbg(icd->parent,
221 "%s: count=%d, size=%d\n", __func__, *count, *size);
222
223 return 0;
224}
225
226static void free_buffer(struct videobuf_queue *vq, struct omap1_cam_buf *buf,
227 enum omap1_cam_vb_mode vb_mode)
228{
229 struct videobuf_buffer *vb = &buf->vb;
230
231 BUG_ON(in_interrupt());
232
233 videobuf_waiton(vq, vb, 0, 0);
234
235 if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
236 videobuf_dma_contig_free(vq, vb);
237 } else {
238 struct soc_camera_device *icd = vq->priv_data;
239 struct device *dev = icd->parent;
240 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
241
242 videobuf_dma_unmap(dev, dma);
243 videobuf_dma_free(dma);
244 }
245
246 vb->state = VIDEOBUF_NEEDS_INIT;
247}
248
249static int omap1_videobuf_prepare(struct videobuf_queue *vq,
250 struct videobuf_buffer *vb, enum v4l2_field field)
251{
252 struct soc_camera_device *icd = vq->priv_data;
253 struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb);
254 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
255 struct omap1_cam_dev *pcdev = ici->priv;
256 int ret;
257
258 WARN_ON(!list_empty(&vb->queue));
259
260 BUG_ON(NULL == icd->current_fmt);
261
262 buf->inwork = 1;
263
264 if (buf->code != icd->current_fmt->code || vb->field != field ||
265 vb->width != icd->user_width ||
266 vb->height != icd->user_height) {
267 buf->code = icd->current_fmt->code;
268 vb->width = icd->user_width;
269 vb->height = icd->user_height;
270 vb->field = field;
271 vb->state = VIDEOBUF_NEEDS_INIT;
272 }
273
274 vb->size = icd->sizeimage;
275
276 if (vb->baddr && vb->bsize < vb->size) {
277 ret = -EINVAL;
278 goto out;
279 }
280
281 if (vb->state == VIDEOBUF_NEEDS_INIT) {
282 ret = videobuf_iolock(vq, vb, NULL);
283 if (ret)
284 goto fail;
285
286 vb->state = VIDEOBUF_PREPARED;
287 }
288 buf->inwork = 0;
289
290 return 0;
291fail:
292 free_buffer(vq, buf, pcdev->vb_mode);
293out:
294 buf->inwork = 0;
295 return ret;
296}
297
298static void set_dma_dest_params(int dma_ch, struct omap1_cam_buf *buf,
299 enum omap1_cam_vb_mode vb_mode)
300{
301 dma_addr_t dma_addr;
302 unsigned int block_size;
303
304 if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
305 dma_addr = videobuf_to_dma_contig(&buf->vb);
306 block_size = buf->vb.size;
307 } else {
308 if (WARN_ON(!buf->sgbuf)) {
309 buf->result = VIDEOBUF_ERROR;
310 return;
311 }
312 dma_addr = sg_dma_address(buf->sgbuf);
313 if (WARN_ON(!dma_addr)) {
314 buf->sgbuf = NULL;
315 buf->result = VIDEOBUF_ERROR;
316 return;
317 }
318 block_size = sg_dma_len(buf->sgbuf);
319 if (WARN_ON(!block_size)) {
320 buf->sgbuf = NULL;
321 buf->result = VIDEOBUF_ERROR;
322 return;
323 }
324 if (unlikely(buf->bytes_left < block_size))
325 block_size = buf->bytes_left;
326 if (WARN_ON(dma_addr & (DMA_FRAME_SIZE(vb_mode) *
327 DMA_ELEMENT_SIZE - 1))) {
328 dma_addr = ALIGN(dma_addr, DMA_FRAME_SIZE(vb_mode) *
329 DMA_ELEMENT_SIZE);
330 block_size &= ~(DMA_FRAME_SIZE(vb_mode) *
331 DMA_ELEMENT_SIZE - 1);
332 }
333 buf->bytes_left -= block_size;
334 buf->sgcount++;
335 }
336
337 omap_set_dma_dest_params(dma_ch,
338 OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0);
339 omap_set_dma_transfer_params(dma_ch,
340 OMAP_DMA_DATA_TYPE_S32, DMA_FRAME_SIZE(vb_mode),
341 block_size >> (DMA_FRAME_SHIFT(vb_mode) + DMA_ELEMENT_SHIFT),
342 DMA_SYNC, 0, 0);
343}
344
345static struct omap1_cam_buf *prepare_next_vb(struct omap1_cam_dev *pcdev)
346{
347 struct omap1_cam_buf *buf;
348
349 /*
350 * If there is already a buffer pointed out by the pcdev->ready,
351 * (re)use it, otherwise try to fetch and configure a new one.
352 */
353 buf = pcdev->ready;
354 if (!buf) {
355 if (list_empty(&pcdev->capture))
356 return buf;
357 buf = list_entry(pcdev->capture.next,
358 struct omap1_cam_buf, vb.queue);
359 buf->vb.state = VIDEOBUF_ACTIVE;
360 pcdev->ready = buf;
361 list_del_init(&buf->vb.queue);
362 }
363
364 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
365 /*
366 * In CONTIG mode, we can safely enter next buffer parameters
367 * into the DMA programming register set after the DMA
368 * has already been activated on the previous buffer
369 */
370 set_dma_dest_params(pcdev->dma_ch, buf, pcdev->vb_mode);
371 } else {
372 /*
373 * In SG mode, the above is not safe since there are probably
374 * a bunch of sgbufs from previous sglist still pending.
375 * Instead, mark the sglist fresh for the upcoming
376 * try_next_sgbuf().
377 */
378 buf->sgbuf = NULL;
379 }
380
381 return buf;
382}
383
384static struct scatterlist *try_next_sgbuf(int dma_ch, struct omap1_cam_buf *buf)
385{
386 struct scatterlist *sgbuf;
387
388 if (likely(buf->sgbuf)) {
389 /* current sglist is active */
390 if (unlikely(!buf->bytes_left)) {
391 /* indicate sglist complete */
392 sgbuf = NULL;
393 } else {
394 /* process next sgbuf */
395 sgbuf = sg_next(buf->sgbuf);
396 if (WARN_ON(!sgbuf)) {
397 buf->result = VIDEOBUF_ERROR;
398 } else if (WARN_ON(!sg_dma_len(sgbuf))) {
399 sgbuf = NULL;
400 buf->result = VIDEOBUF_ERROR;
401 }
402 }
403 buf->sgbuf = sgbuf;
404 } else {
405 /* sglist is fresh, initialize it before using */
406 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
407
408 sgbuf = dma->sglist;
409 if (!(WARN_ON(!sgbuf))) {
410 buf->sgbuf = sgbuf;
411 buf->sgcount = 0;
412 buf->bytes_left = buf->vb.size;
413 buf->result = VIDEOBUF_DONE;
414 }
415 }
416 if (sgbuf)
417 /*
418 * Put our next sgbuf parameters (address, size)
419 * into the DMA programming register set.
420 */
421 set_dma_dest_params(dma_ch, buf, OMAP1_CAM_DMA_SG);
422
423 return sgbuf;
424}
425
426static void start_capture(struct omap1_cam_dev *pcdev)
427{
428 struct omap1_cam_buf *buf = pcdev->active;
429 u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
430 u32 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN;
431
432 if (WARN_ON(!buf))
433 return;
434
435 /*
436 * Enable start of frame interrupt, which we will use for activating
437 * our end of frame watchdog when capture actually starts.
438 */
439 mode |= EN_V_UP;
440
441 if (unlikely(ctrlclock & LCLK_EN))
442 /* stop pixel clock before FIFO reset */
443 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
444 /* reset FIFO */
445 CAM_WRITE(pcdev, MODE, mode | RAZ_FIFO);
446
447 omap_start_dma(pcdev->dma_ch);
448
449 if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
450 /*
451 * In SG mode, it's a good moment for fetching next sgbuf
452 * from the current sglist and, if available, already putting
453 * its parameters into the DMA programming register set.
454 */
455 try_next_sgbuf(pcdev->dma_ch, buf);
456 }
457
458 /* (re)enable pixel clock */
459 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | LCLK_EN);
460 /* release FIFO reset */
461 CAM_WRITE(pcdev, MODE, mode);
462}
463
464static void suspend_capture(struct omap1_cam_dev *pcdev)
465{
466 u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
467
468 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
469 omap_stop_dma(pcdev->dma_ch);
470}
471
472static void disable_capture(struct omap1_cam_dev *pcdev)
473{
474 u32 mode = CAM_READ_CACHE(pcdev, MODE);
475
476 CAM_WRITE(pcdev, MODE, mode & ~(IRQ_MASK | DMA));
477}
478
479static void omap1_videobuf_queue(struct videobuf_queue *vq,
480 struct videobuf_buffer *vb)
481{
482 struct soc_camera_device *icd = vq->priv_data;
483 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
484 struct omap1_cam_dev *pcdev = ici->priv;
485 struct omap1_cam_buf *buf;
486 u32 mode;
487
488 list_add_tail(&vb->queue, &pcdev->capture);
489 vb->state = VIDEOBUF_QUEUED;
490
491 if (pcdev->active) {
492 /*
493 * Capture in progress, so don't touch pcdev->ready even if
494 * empty. Since the transfer of the DMA programming register set
495 * content to the DMA working register set is done automatically
496 * by the DMA hardware, this can pretty well happen while we
497 * are keeping the lock here. Leave fetching it from the queue
498 * to be done when a next DMA interrupt occures instead.
499 */
500 return;
501 }
502
503 WARN_ON(pcdev->ready);
504
505 buf = prepare_next_vb(pcdev);
506 if (WARN_ON(!buf))
507 return;
508
509 pcdev->active = buf;
510 pcdev->ready = NULL;
511
512 dev_dbg(icd->parent,
513 "%s: capture not active, setup FIFO, start DMA\n", __func__);
514 mode = CAM_READ_CACHE(pcdev, MODE) & ~THRESHOLD_MASK;
515 mode |= THRESHOLD_LEVEL(pcdev->vb_mode) << THRESHOLD_SHIFT;
516 CAM_WRITE(pcdev, MODE, mode | EN_FIFO_FULL | DMA);
517
518 if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
519 /*
520 * In SG mode, the above prepare_next_vb() didn't actually
521 * put anything into the DMA programming register set,
522 * so we have to do it now, before activating DMA.
523 */
524 try_next_sgbuf(pcdev->dma_ch, buf);
525 }
526
527 start_capture(pcdev);
528}
529
530static void omap1_videobuf_release(struct videobuf_queue *vq,
531 struct videobuf_buffer *vb)
532{
533 struct omap1_cam_buf *buf =
534 container_of(vb, struct omap1_cam_buf, vb);
535 struct soc_camera_device *icd = vq->priv_data;
536 struct device *dev = icd->parent;
537 struct soc_camera_host *ici = to_soc_camera_host(dev);
538 struct omap1_cam_dev *pcdev = ici->priv;
539
540 switch (vb->state) {
541 case VIDEOBUF_DONE:
542 dev_dbg(dev, "%s (done)\n", __func__);
543 break;
544 case VIDEOBUF_ACTIVE:
545 dev_dbg(dev, "%s (active)\n", __func__);
546 break;
547 case VIDEOBUF_QUEUED:
548 dev_dbg(dev, "%s (queued)\n", __func__);
549 break;
550 case VIDEOBUF_PREPARED:
551 dev_dbg(dev, "%s (prepared)\n", __func__);
552 break;
553 default:
554 dev_dbg(dev, "%s (unknown %d)\n", __func__, vb->state);
555 break;
556 }
557
558 free_buffer(vq, buf, pcdev->vb_mode);
559}
560
561static void videobuf_done(struct omap1_cam_dev *pcdev,
562 enum videobuf_state result)
563{
564 struct omap1_cam_buf *buf = pcdev->active;
565 struct videobuf_buffer *vb;
566 struct device *dev = pcdev->soc_host.icd->parent;
567
568 if (WARN_ON(!buf)) {
569 suspend_capture(pcdev);
570 disable_capture(pcdev);
571 return;
572 }
573
574 if (result == VIDEOBUF_ERROR)
575 suspend_capture(pcdev);
576
577 vb = &buf->vb;
578 if (waitqueue_active(&vb->done)) {
579 if (!pcdev->ready && result != VIDEOBUF_ERROR) {
580 /*
581 * No next buffer has been entered into the DMA
582 * programming register set on time (could be done only
583 * while the previous DMA interurpt was processed, not
584 * later), so the last DMA block, be it a whole buffer
585 * if in CONTIG or its last sgbuf if in SG mode, is
586 * about to be reused by the just autoreinitialized DMA
587 * engine, and overwritten with next frame data. Best we
588 * can do is stopping the capture as soon as possible,
589 * hopefully before the next frame start.
590 */
591 suspend_capture(pcdev);
592 }
593 vb->state = result;
594 v4l2_get_timestamp(&vb->ts);
595 if (result != VIDEOBUF_ERROR)
596 vb->field_count++;
597 wake_up(&vb->done);
598
599 /* shift in next buffer */
600 buf = pcdev->ready;
601 pcdev->active = buf;
602 pcdev->ready = NULL;
603
604 if (!buf) {
605 /*
606 * No next buffer was ready on time (see above), so
607 * indicate error condition to force capture restart or
608 * stop, depending on next buffer already queued or not.
609 */
610 result = VIDEOBUF_ERROR;
611 prepare_next_vb(pcdev);
612
613 buf = pcdev->ready;
614 pcdev->active = buf;
615 pcdev->ready = NULL;
616 }
617 } else if (pcdev->ready) {
618 /*
619 * In both CONTIG and SG mode, the DMA engine has possibly
620 * been already autoreinitialized with the preprogrammed
621 * pcdev->ready buffer. We can either accept this fact
622 * and just swap the buffers, or provoke an error condition
623 * and restart capture. The former seems less intrusive.
624 */
625 dev_dbg(dev, "%s: nobody waiting on videobuf, swap with next\n",
626 __func__);
627 pcdev->active = pcdev->ready;
628
629 if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
630 /*
631 * In SG mode, we have to make sure that the buffer we
632 * are putting back into the pcdev->ready is marked
633 * fresh.
634 */
635 buf->sgbuf = NULL;
636 }
637 pcdev->ready = buf;
638
639 buf = pcdev->active;
640 } else {
641 /*
642 * No next buffer has been entered into
643 * the DMA programming register set on time.
644 */
645 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
646 /*
647 * In CONTIG mode, the DMA engine has already been
648 * reinitialized with the current buffer. Best we can do
649 * is not touching it.
650 */
651 dev_dbg(dev,
652 "%s: nobody waiting on videobuf, reuse it\n",
653 __func__);
654 } else {
655 /*
656 * In SG mode, the DMA engine has just been
657 * autoreinitialized with the last sgbuf from the
658 * current list. Restart capture in order to transfer
659 * next frame start into the first sgbuf, not the last
660 * one.
661 */
662 if (result != VIDEOBUF_ERROR) {
663 suspend_capture(pcdev);
664 result = VIDEOBUF_ERROR;
665 }
666 }
667 }
668
669 if (!buf) {
670 dev_dbg(dev, "%s: no more videobufs, stop capture\n", __func__);
671 disable_capture(pcdev);
672 return;
673 }
674
675 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
676 /*
677 * In CONTIG mode, the current buffer parameters had already
678 * been entered into the DMA programming register set while the
679 * buffer was fetched with prepare_next_vb(), they may have also
680 * been transferred into the runtime set and already active if
681 * the DMA still running.
682 */
683 } else {
684 /* In SG mode, extra steps are required */
685 if (result == VIDEOBUF_ERROR)
686 /* make sure we (re)use sglist from start on error */
687 buf->sgbuf = NULL;
688
689 /*
690 * In any case, enter the next sgbuf parameters into the DMA
691 * programming register set. They will be used either during
692 * nearest DMA autoreinitialization or, in case of an error,
693 * on DMA startup below.
694 */
695 try_next_sgbuf(pcdev->dma_ch, buf);
696 }
697
698 if (result == VIDEOBUF_ERROR) {
699 dev_dbg(dev, "%s: videobuf error; reset FIFO, restart DMA\n",
700 __func__);
701 start_capture(pcdev);
702 /*
703 * In SG mode, the above also resulted in the next sgbuf
704 * parameters being entered into the DMA programming register
705 * set, making them ready for next DMA autoreinitialization.
706 */
707 }
708
709 /*
710 * Finally, try fetching next buffer.
711 * In CONTIG mode, it will also enter it into the DMA programming
712 * register set, making it ready for next DMA autoreinitialization.
713 */
714 prepare_next_vb(pcdev);
715}
716
717static void dma_isr(int channel, unsigned short status, void *data)
718{
719 struct omap1_cam_dev *pcdev = data;
720 struct omap1_cam_buf *buf = pcdev->active;
721 unsigned long flags;
722
723 spin_lock_irqsave(&pcdev->lock, flags);
724
725 if (WARN_ON(!buf)) {
726 suspend_capture(pcdev);
727 disable_capture(pcdev);
728 goto out;
729 }
730
731 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
732 /*
733 * In CONTIG mode, assume we have just managed to collect the
734 * whole frame, hopefully before our end of frame watchdog is
735 * triggered. Then, all we have to do is disabling the watchdog
736 * for this frame, and calling videobuf_done() with success
737 * indicated.
738 */
739 CAM_WRITE(pcdev, MODE,
740 CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN);
741 videobuf_done(pcdev, VIDEOBUF_DONE);
742 } else {
743 /*
744 * In SG mode, we have to process every sgbuf from the current
745 * sglist, one after another.
746 */
747 if (buf->sgbuf) {
748 /*
749 * Current sglist not completed yet, try fetching next
750 * sgbuf, hopefully putting it into the DMA programming
751 * register set, making it ready for next DMA
752 * autoreinitialization.
753 */
754 try_next_sgbuf(pcdev->dma_ch, buf);
755 if (buf->sgbuf)
756 goto out;
757
758 /*
759 * No more sgbufs left in the current sglist. This
760 * doesn't mean that the whole videobuffer is already
761 * complete, but only that the last sgbuf from the
762 * current sglist is about to be filled. It will be
763 * ready on next DMA interrupt, signalled with the
764 * buf->sgbuf set back to NULL.
765 */
766 if (buf->result != VIDEOBUF_ERROR) {
767 /*
768 * Video frame collected without errors so far,
769 * we can prepare for collecting a next one
770 * as soon as DMA gets autoreinitialized
771 * after the current (last) sgbuf is completed.
772 */
773 buf = prepare_next_vb(pcdev);
774 if (!buf)
775 goto out;
776
777 try_next_sgbuf(pcdev->dma_ch, buf);
778 goto out;
779 }
780 }
781 /* end of videobuf */
782 videobuf_done(pcdev, buf->result);
783 }
784
785out:
786 spin_unlock_irqrestore(&pcdev->lock, flags);
787}
788
789static irqreturn_t cam_isr(int irq, void *data)
790{
791 struct omap1_cam_dev *pcdev = data;
792 struct device *dev = pcdev->soc_host.icd->parent;
793 struct omap1_cam_buf *buf = pcdev->active;
794 u32 it_status;
795 unsigned long flags;
796
797 it_status = CAM_READ(pcdev, IT_STATUS);
798 if (!it_status)
799 return IRQ_NONE;
800
801 spin_lock_irqsave(&pcdev->lock, flags);
802
803 if (WARN_ON(!buf)) {
804 dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
805 __func__, it_status);
806 suspend_capture(pcdev);
807 disable_capture(pcdev);
808 goto out;
809 }
810
811 if (unlikely(it_status & FIFO_FULL)) {
812 dev_warn(dev, "%s: FIFO overflow\n", __func__);
813
814 } else if (it_status & V_DOWN) {
815 /* end of video frame watchdog */
816 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
817 /*
818 * In CONTIG mode, the watchdog is disabled with
819 * successful DMA end of block interrupt, and reenabled
820 * on next frame start. If we get here, there is nothing
821 * to check, we must be out of sync.
822 */
823 } else {
824 if (buf->sgcount == 2) {
825 /*
826 * If exactly 2 sgbufs from the next sglist have
827 * been programmed into the DMA engine (the
828 * first one already transferred into the DMA
829 * runtime register set, the second one still
830 * in the programming set), then we are in sync.
831 */
832 goto out;
833 }
834 }
835 dev_notice(dev, "%s: unexpected end of video frame\n",
836 __func__);
837
838 } else if (it_status & V_UP) {
839 u32 mode;
840
841 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
842 /*
843 * In CONTIG mode, we need this interrupt every frame
844 * in oredr to reenable our end of frame watchdog.
845 */
846 mode = CAM_READ_CACHE(pcdev, MODE);
847 } else {
848 /*
849 * In SG mode, the below enabled end of frame watchdog
850 * is kept on permanently, so we can turn this one shot
851 * setup off.
852 */
853 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_UP;
854 }
855
856 if (!(mode & EN_V_DOWN)) {
857 /* (re)enable end of frame watchdog interrupt */
858 mode |= EN_V_DOWN;
859 }
860 CAM_WRITE(pcdev, MODE, mode);
861 goto out;
862
863 } else {
864 dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
865 __func__, it_status);
866 goto out;
867 }
868
869 videobuf_done(pcdev, VIDEOBUF_ERROR);
870out:
871 spin_unlock_irqrestore(&pcdev->lock, flags);
872 return IRQ_HANDLED;
873}
874
875static struct videobuf_queue_ops omap1_videobuf_ops = {
876 .buf_setup = omap1_videobuf_setup,
877 .buf_prepare = omap1_videobuf_prepare,
878 .buf_queue = omap1_videobuf_queue,
879 .buf_release = omap1_videobuf_release,
880};
881
882
883/*
884 * SOC Camera host operations
885 */
886
887static void sensor_reset(struct omap1_cam_dev *pcdev, bool reset)
888{
889 /* apply/release camera sensor reset if requested by platform data */
890 if (pcdev->pflags & OMAP1_CAMERA_RST_HIGH)
891 CAM_WRITE(pcdev, GPIO, reset);
892 else if (pcdev->pflags & OMAP1_CAMERA_RST_LOW)
893 CAM_WRITE(pcdev, GPIO, !reset);
894}
895
896static int omap1_cam_add_device(struct soc_camera_device *icd)
897{
898 dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
899 icd->devnum);
900
901 return 0;
902}
903
904static void omap1_cam_remove_device(struct soc_camera_device *icd)
905{
906 dev_dbg(icd->parent,
907 "OMAP1 Camera driver detached from camera %d\n", icd->devnum);
908}
909
910/*
911 * The following two functions absolutely depend on the fact, that
912 * there can be only one camera on OMAP1 camera sensor interface
913 */
914static int omap1_cam_clock_start(struct soc_camera_host *ici)
915{
916 struct omap1_cam_dev *pcdev = ici->priv;
917 u32 ctrlclock;
918
919 clk_enable(pcdev->clk);
920
921 /* setup sensor clock */
922 ctrlclock = CAM_READ(pcdev, CTRLCLOCK);
923 ctrlclock &= ~(CAMEXCLK_EN | MCLK_EN | DPLL_EN);
924 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
925
926 ctrlclock &= ~FOSCMOD_MASK;
927 switch (pcdev->camexclk) {
928 case 6000000:
929 ctrlclock |= CAMEXCLK_EN | FOSCMOD_6MHz;
930 break;
931 case 8000000:
932 ctrlclock |= CAMEXCLK_EN | FOSCMOD_8MHz | DPLL_EN;
933 break;
934 case 9600000:
935 ctrlclock |= CAMEXCLK_EN | FOSCMOD_9_6MHz | DPLL_EN;
936 break;
937 case 12000000:
938 ctrlclock |= CAMEXCLK_EN | FOSCMOD_12MHz;
939 break;
940 case 24000000:
941 ctrlclock |= CAMEXCLK_EN | FOSCMOD_24MHz | DPLL_EN;
942 default:
943 break;
944 }
945 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~DPLL_EN);
946
947 /* enable internal clock */
948 ctrlclock |= MCLK_EN;
949 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
950
951 sensor_reset(pcdev, false);
952
953 return 0;
954}
955
956static void omap1_cam_clock_stop(struct soc_camera_host *ici)
957{
958 struct omap1_cam_dev *pcdev = ici->priv;
959 u32 ctrlclock;
960
961 suspend_capture(pcdev);
962 disable_capture(pcdev);
963
964 sensor_reset(pcdev, true);
965
966 /* disable and release system clocks */
967 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
968 ctrlclock &= ~(MCLK_EN | DPLL_EN | CAMEXCLK_EN);
969 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
970
971 ctrlclock = (ctrlclock & ~FOSCMOD_MASK) | FOSCMOD_12MHz;
972 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
973 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | MCLK_EN);
974
975 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN);
976
977 clk_disable(pcdev->clk);
978}
979
980/* Duplicate standard formats based on host capability of byte swapping */
981static const struct soc_mbus_lookup omap1_cam_formats[] = {
982{
983 .code = MEDIA_BUS_FMT_UYVY8_2X8,
984 .fmt = {
985 .fourcc = V4L2_PIX_FMT_YUYV,
986 .name = "YUYV",
987 .bits_per_sample = 8,
988 .packing = SOC_MBUS_PACKING_2X8_PADHI,
989 .order = SOC_MBUS_ORDER_BE,
990 .layout = SOC_MBUS_LAYOUT_PACKED,
991 },
992}, {
993 .code = MEDIA_BUS_FMT_VYUY8_2X8,
994 .fmt = {
995 .fourcc = V4L2_PIX_FMT_YVYU,
996 .name = "YVYU",
997 .bits_per_sample = 8,
998 .packing = SOC_MBUS_PACKING_2X8_PADHI,
999 .order = SOC_MBUS_ORDER_BE,
1000 .layout = SOC_MBUS_LAYOUT_PACKED,
1001 },
1002}, {
1003 .code = MEDIA_BUS_FMT_YUYV8_2X8,
1004 .fmt = {
1005 .fourcc = V4L2_PIX_FMT_UYVY,
1006 .name = "UYVY",
1007 .bits_per_sample = 8,
1008 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1009 .order = SOC_MBUS_ORDER_BE,
1010 .layout = SOC_MBUS_LAYOUT_PACKED,
1011 },
1012}, {
1013 .code = MEDIA_BUS_FMT_YVYU8_2X8,
1014 .fmt = {
1015 .fourcc = V4L2_PIX_FMT_VYUY,
1016 .name = "VYUY",
1017 .bits_per_sample = 8,
1018 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1019 .order = SOC_MBUS_ORDER_BE,
1020 .layout = SOC_MBUS_LAYOUT_PACKED,
1021 },
1022}, {
1023 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
1024 .fmt = {
1025 .fourcc = V4L2_PIX_FMT_RGB555,
1026 .name = "RGB555",
1027 .bits_per_sample = 8,
1028 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1029 .order = SOC_MBUS_ORDER_BE,
1030 .layout = SOC_MBUS_LAYOUT_PACKED,
1031 },
1032}, {
1033 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
1034 .fmt = {
1035 .fourcc = V4L2_PIX_FMT_RGB555X,
1036 .name = "RGB555X",
1037 .bits_per_sample = 8,
1038 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1039 .order = SOC_MBUS_ORDER_BE,
1040 .layout = SOC_MBUS_LAYOUT_PACKED,
1041 },
1042}, {
1043 .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
1044 .fmt = {
1045 .fourcc = V4L2_PIX_FMT_RGB565,
1046 .name = "RGB565",
1047 .bits_per_sample = 8,
1048 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1049 .order = SOC_MBUS_ORDER_BE,
1050 .layout = SOC_MBUS_LAYOUT_PACKED,
1051 },
1052}, {
1053 .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
1054 .fmt = {
1055 .fourcc = V4L2_PIX_FMT_RGB565X,
1056 .name = "RGB565X",
1057 .bits_per_sample = 8,
1058 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1059 .order = SOC_MBUS_ORDER_BE,
1060 .layout = SOC_MBUS_LAYOUT_PACKED,
1061 },
1062},
1063};
1064
1065static int omap1_cam_get_formats(struct soc_camera_device *icd,
1066 unsigned int idx, struct soc_camera_format_xlate *xlate)
1067{
1068 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1069 struct device *dev = icd->parent;
1070 int formats = 0, ret;
1071 struct v4l2_subdev_mbus_code_enum code = {
1072 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1073 .index = idx,
1074 };
1075 const struct soc_mbus_pixelfmt *fmt;
1076
1077 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
1078 if (ret < 0)
1079 /* No more formats */
1080 return 0;
1081
1082 fmt = soc_mbus_get_fmtdesc(code.code);
1083 if (!fmt) {
1084 dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
1085 idx, code.code);
1086 return 0;
1087 }
1088
1089 /* Check support for the requested bits-per-sample */
1090 if (fmt->bits_per_sample != 8)
1091 return 0;
1092
1093 switch (code.code) {
1094 case MEDIA_BUS_FMT_YUYV8_2X8:
1095 case MEDIA_BUS_FMT_YVYU8_2X8:
1096 case MEDIA_BUS_FMT_UYVY8_2X8:
1097 case MEDIA_BUS_FMT_VYUY8_2X8:
1098 case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE:
1099 case MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE:
1100 case MEDIA_BUS_FMT_RGB565_2X8_BE:
1101 case MEDIA_BUS_FMT_RGB565_2X8_LE:
1102 formats++;
1103 if (xlate) {
1104 xlate->host_fmt = soc_mbus_find_fmtdesc(code.code,
1105 omap1_cam_formats,
1106 ARRAY_SIZE(omap1_cam_formats));
1107 xlate->code = code.code;
1108 xlate++;
1109 dev_dbg(dev,
1110 "%s: providing format %s as byte swapped code #%d\n",
1111 __func__, xlate->host_fmt->name, code.code);
1112 }
1113 default:
1114 if (xlate)
1115 dev_dbg(dev,
1116 "%s: providing format %s in pass-through mode\n",
1117 __func__, fmt->name);
1118 }
1119 formats++;
1120 if (xlate) {
1121 xlate->host_fmt = fmt;
1122 xlate->code = code.code;
1123 xlate++;
1124 }
1125
1126 return formats;
1127}
1128
1129static bool is_dma_aligned(s32 bytes_per_line, unsigned int height,
1130 enum omap1_cam_vb_mode vb_mode)
1131{
1132 int size = bytes_per_line * height;
1133
1134 return IS_ALIGNED(bytes_per_line, DMA_ELEMENT_SIZE) &&
1135 IS_ALIGNED(size, DMA_FRAME_SIZE(vb_mode) * DMA_ELEMENT_SIZE);
1136}
1137
1138static int dma_align(int *width, int *height,
1139 const struct soc_mbus_pixelfmt *fmt,
1140 enum omap1_cam_vb_mode vb_mode, bool enlarge)
1141{
1142 s32 bytes_per_line = soc_mbus_bytes_per_line(*width, fmt);
1143
1144 if (bytes_per_line < 0)
1145 return bytes_per_line;
1146
1147 if (!is_dma_aligned(bytes_per_line, *height, vb_mode)) {
1148 unsigned int pxalign = __fls(bytes_per_line / *width);
1149 unsigned int salign = DMA_FRAME_SHIFT(vb_mode) +
1150 DMA_ELEMENT_SHIFT - pxalign;
1151 unsigned int incr = enlarge << salign;
1152
1153 v4l_bound_align_image(width, 1, *width + incr, 0,
1154 height, 1, *height + incr, 0, salign);
1155 return 0;
1156 }
1157 return 1;
1158}
1159
1160#define subdev_call_with_sense(pcdev, dev, icd, sd, op, function, args...) \
1161({ \
1162 struct soc_camera_sense sense = { \
1163 .master_clock = pcdev->camexclk, \
1164 .pixel_clock_max = 0, \
1165 }; \
1166 int __ret; \
1167 \
1168 if (pcdev->pdata) \
1169 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \
1170 icd->sense = &sense; \
1171 __ret = v4l2_subdev_call(sd, op, function, ##args); \
1172 icd->sense = NULL; \
1173 \
1174 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \
1175 if (sense.pixel_clock > sense.pixel_clock_max) { \
1176 dev_err(dev, \
1177 "%s: pixel clock %lu set by the camera too high!\n", \
1178 __func__, sense.pixel_clock); \
1179 __ret = -EINVAL; \
1180 } \
1181 } \
1182 __ret; \
1183})
1184
1185static int set_format(struct omap1_cam_dev *pcdev, struct device *dev,
1186 struct soc_camera_device *icd, struct v4l2_subdev *sd,
1187 struct v4l2_subdev_format *format,
1188 const struct soc_camera_format_xlate *xlate)
1189{
1190 s32 bytes_per_line;
1191 struct v4l2_mbus_framefmt *mf = &format->format;
1192 int ret = subdev_call_with_sense(pcdev, dev, icd, sd, pad, set_fmt, NULL, format);
1193
1194 if (ret < 0) {
1195 dev_err(dev, "%s: set_fmt failed\n", __func__);
1196 return ret;
1197 }
1198
1199 if (mf->code != xlate->code) {
1200 dev_err(dev, "%s: unexpected pixel code change\n", __func__);
1201 return -EINVAL;
1202 }
1203
1204 bytes_per_line = soc_mbus_bytes_per_line(mf->width, xlate->host_fmt);
1205 if (bytes_per_line < 0) {
1206 dev_err(dev, "%s: soc_mbus_bytes_per_line() failed\n",
1207 __func__);
1208 return bytes_per_line;
1209 }
1210
1211 if (!is_dma_aligned(bytes_per_line, mf->height, pcdev->vb_mode)) {
1212 dev_err(dev, "%s: resulting geometry %ux%u not DMA aligned\n",
1213 __func__, mf->width, mf->height);
1214 return -EINVAL;
1215 }
1216 return 0;
1217}
1218
1219static int omap1_cam_set_crop(struct soc_camera_device *icd,
1220 const struct v4l2_crop *crop)
1221{
1222 const struct v4l2_rect *rect = &crop->c;
1223 const struct soc_camera_format_xlate *xlate = icd->current_fmt;
1224 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1225 struct device *dev = icd->parent;
1226 struct soc_camera_host *ici = to_soc_camera_host(dev);
1227 struct omap1_cam_dev *pcdev = ici->priv;
1228 struct v4l2_subdev_format fmt = {
1229 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1230 };
1231 struct v4l2_mbus_framefmt *mf = &fmt.format;
1232 int ret;
1233
1234 ret = subdev_call_with_sense(pcdev, dev, icd, sd, video, s_crop, crop);
1235 if (ret < 0) {
1236 dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__,
1237 rect->width, rect->height, rect->left, rect->top);
1238 return ret;
1239 }
1240
1241 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
1242 if (ret < 0) {
1243 dev_warn(dev, "%s: failed to fetch current format\n", __func__);
1244 return ret;
1245 }
1246
1247 ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode,
1248 false);
1249 if (ret < 0) {
1250 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
1251 __func__, mf->width, mf->height,
1252 xlate->host_fmt->name);
1253 return ret;
1254 }
1255
1256 if (!ret) {
1257 /* sensor returned geometry not DMA aligned, trying to fix */
1258 ret = set_format(pcdev, dev, icd, sd, &fmt, xlate);
1259 if (ret < 0) {
1260 dev_err(dev, "%s: failed to set format\n", __func__);
1261 return ret;
1262 }
1263 }
1264
1265 icd->user_width = mf->width;
1266 icd->user_height = mf->height;
1267
1268 return 0;
1269}
1270
1271static int omap1_cam_set_fmt(struct soc_camera_device *icd,
1272 struct v4l2_format *f)
1273{
1274 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1275 const struct soc_camera_format_xlate *xlate;
1276 struct device *dev = icd->parent;
1277 struct soc_camera_host *ici = to_soc_camera_host(dev);
1278 struct omap1_cam_dev *pcdev = ici->priv;
1279 struct v4l2_pix_format *pix = &f->fmt.pix;
1280 struct v4l2_subdev_format format = {
1281 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1282 };
1283 struct v4l2_mbus_framefmt *mf = &format.format;
1284 int ret;
1285
1286 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1287 if (!xlate) {
1288 dev_warn(dev, "%s: format %#x not found\n", __func__,
1289 pix->pixelformat);
1290 return -EINVAL;
1291 }
1292
1293 mf->width = pix->width;
1294 mf->height = pix->height;
1295 mf->field = pix->field;
1296 mf->colorspace = pix->colorspace;
1297 mf->code = xlate->code;
1298
1299 ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode,
1300 true);
1301 if (ret < 0) {
1302 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
1303 __func__, pix->width, pix->height,
1304 xlate->host_fmt->name);
1305 return ret;
1306 }
1307
1308 ret = set_format(pcdev, dev, icd, sd, &format, xlate);
1309 if (ret < 0) {
1310 dev_err(dev, "%s: failed to set format\n", __func__);
1311 return ret;
1312 }
1313
1314 pix->width = mf->width;
1315 pix->height = mf->height;
1316 pix->field = mf->field;
1317 pix->colorspace = mf->colorspace;
1318 icd->current_fmt = xlate;
1319
1320 return 0;
1321}
1322
1323static int omap1_cam_try_fmt(struct soc_camera_device *icd,
1324 struct v4l2_format *f)
1325{
1326 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1327 const struct soc_camera_format_xlate *xlate;
1328 struct v4l2_pix_format *pix = &f->fmt.pix;
1329 struct v4l2_subdev_pad_config pad_cfg;
1330 struct v4l2_subdev_format format = {
1331 .which = V4L2_SUBDEV_FORMAT_TRY,
1332 };
1333 struct v4l2_mbus_framefmt *mf = &format.format;
1334 int ret;
1335 /* TODO: limit to mx1 hardware capabilities */
1336
1337 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1338 if (!xlate) {
1339 dev_warn(icd->parent, "Format %#x not found\n",
1340 pix->pixelformat);
1341 return -EINVAL;
1342 }
1343
1344 mf->width = pix->width;
1345 mf->height = pix->height;
1346 mf->field = pix->field;
1347 mf->colorspace = pix->colorspace;
1348 mf->code = xlate->code;
1349
1350 /* limit to sensor capabilities */
1351 ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
1352 if (ret < 0)
1353 return ret;
1354
1355 pix->width = mf->width;
1356 pix->height = mf->height;
1357 pix->field = mf->field;
1358 pix->colorspace = mf->colorspace;
1359
1360 return 0;
1361}
1362
1363static bool sg_mode;
1364
1365/*
1366 * Local mmap_mapper wrapper,
1367 * used for detecting videobuf-dma-contig buffer allocation failures
1368 * and switching to videobuf-dma-sg automatically for future attempts.
1369 */
1370static int omap1_cam_mmap_mapper(struct videobuf_queue *q,
1371 struct videobuf_buffer *buf,
1372 struct vm_area_struct *vma)
1373{
1374 struct soc_camera_device *icd = q->priv_data;
1375 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1376 struct omap1_cam_dev *pcdev = ici->priv;
1377 int ret;
1378
1379 ret = pcdev->mmap_mapper(q, buf, vma);
1380
1381 if (ret == -ENOMEM)
1382 sg_mode = true;
1383
1384 return ret;
1385}
1386
1387static void omap1_cam_init_videobuf(struct videobuf_queue *q,
1388 struct soc_camera_device *icd)
1389{
1390 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1391 struct omap1_cam_dev *pcdev = ici->priv;
1392
1393 if (!sg_mode)
1394 videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops,
1395 icd->parent, &pcdev->lock,
1396 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
1397 sizeof(struct omap1_cam_buf), icd, &ici->host_lock);
1398 else
1399 videobuf_queue_sg_init(q, &omap1_videobuf_ops,
1400 icd->parent, &pcdev->lock,
1401 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
1402 sizeof(struct omap1_cam_buf), icd, &ici->host_lock);
1403
1404 /* use videobuf mode (auto)selected with the module parameter */
1405 pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG;
1406
1407 /*
1408 * Ensure we substitute the videobuf-dma-contig version of the
1409 * mmap_mapper() callback with our own wrapper, used for switching
1410 * automatically to videobuf-dma-sg on buffer allocation failure.
1411 */
1412 if (!sg_mode && q->int_ops->mmap_mapper != omap1_cam_mmap_mapper) {
1413 pcdev->mmap_mapper = q->int_ops->mmap_mapper;
1414 q->int_ops->mmap_mapper = omap1_cam_mmap_mapper;
1415 }
1416}
1417
1418static int omap1_cam_reqbufs(struct soc_camera_device *icd,
1419 struct v4l2_requestbuffers *p)
1420{
1421 int i;
1422
1423 /*
1424 * This is for locking debugging only. I removed spinlocks and now I
1425 * check whether .prepare is ever called on a linked buffer, or whether
1426 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1427 * it hadn't triggered
1428 */
1429 for (i = 0; i < p->count; i++) {
1430 struct omap1_cam_buf *buf = container_of(icd->vb_vidq.bufs[i],
1431 struct omap1_cam_buf, vb);
1432 buf->inwork = 0;
1433 INIT_LIST_HEAD(&buf->vb.queue);
1434 }
1435
1436 return 0;
1437}
1438
1439static int omap1_cam_querycap(struct soc_camera_host *ici,
1440 struct v4l2_capability *cap)
1441{
1442 /* cap->name is set by the friendly caller:-> */
1443 strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card));
1444 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1445 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1446
1447 return 0;
1448}
1449
1450static int omap1_cam_set_bus_param(struct soc_camera_device *icd)
1451{
1452 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1453 struct device *dev = icd->parent;
1454 struct soc_camera_host *ici = to_soc_camera_host(dev);
1455 struct omap1_cam_dev *pcdev = ici->priv;
1456 u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
1457 const struct soc_camera_format_xlate *xlate;
1458 const struct soc_mbus_pixelfmt *fmt;
1459 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1460 unsigned long common_flags;
1461 u32 ctrlclock, mode;
1462 int ret;
1463
1464 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1465 if (!ret) {
1466 common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
1467 if (!common_flags) {
1468 dev_warn(dev,
1469 "Flags incompatible: camera 0x%x, host 0x%x\n",
1470 cfg.flags, SOCAM_BUS_FLAGS);
1471 return -EINVAL;
1472 }
1473 } else if (ret != -ENOIOCTLCMD) {
1474 return ret;
1475 } else {
1476 common_flags = SOCAM_BUS_FLAGS;
1477 }
1478
1479 /* Make choices, possibly based on platform configuration */
1480 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1481 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1482 if (!pcdev->pdata ||
1483 pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
1484 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1485 else
1486 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1487 }
1488
1489 cfg.flags = common_flags;
1490 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1491 if (ret < 0 && ret != -ENOIOCTLCMD) {
1492 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1493 common_flags, ret);
1494 return ret;
1495 }
1496
1497 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
1498 if (ctrlclock & LCLK_EN)
1499 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
1500
1501 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
1502 dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
1503 ctrlclock |= POLCLK;
1504 } else {
1505 dev_dbg(dev, "CTRLCLOCK_REG &= ~POLCLK\n");
1506 ctrlclock &= ~POLCLK;
1507 }
1508 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
1509
1510 if (ctrlclock & LCLK_EN)
1511 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
1512
1513 /* select bus endianness */
1514 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1515 fmt = xlate->host_fmt;
1516
1517 mode = CAM_READ(pcdev, MODE) & ~(RAZ_FIFO | IRQ_MASK | DMA);
1518 if (fmt->order == SOC_MBUS_ORDER_LE) {
1519 dev_dbg(dev, "MODE_REG &= ~ORDERCAMD\n");
1520 CAM_WRITE(pcdev, MODE, mode & ~ORDERCAMD);
1521 } else {
1522 dev_dbg(dev, "MODE_REG |= ORDERCAMD\n");
1523 CAM_WRITE(pcdev, MODE, mode | ORDERCAMD);
1524 }
1525
1526 return 0;
1527}
1528
1529static unsigned int omap1_cam_poll(struct file *file, poll_table *pt)
1530{
1531 struct soc_camera_device *icd = file->private_data;
1532 struct omap1_cam_buf *buf;
1533
1534 buf = list_entry(icd->vb_vidq.stream.next, struct omap1_cam_buf,
1535 vb.stream);
1536
1537 poll_wait(file, &buf->vb.done, pt);
1538
1539 if (buf->vb.state == VIDEOBUF_DONE ||
1540 buf->vb.state == VIDEOBUF_ERROR)
1541 return POLLIN | POLLRDNORM;
1542
1543 return 0;
1544}
1545
1546static struct soc_camera_host_ops omap1_host_ops = {
1547 .owner = THIS_MODULE,
1548 .add = omap1_cam_add_device,
1549 .remove = omap1_cam_remove_device,
1550 .clock_start = omap1_cam_clock_start,
1551 .clock_stop = omap1_cam_clock_stop,
1552 .get_formats = omap1_cam_get_formats,
1553 .set_crop = omap1_cam_set_crop,
1554 .set_fmt = omap1_cam_set_fmt,
1555 .try_fmt = omap1_cam_try_fmt,
1556 .init_videobuf = omap1_cam_init_videobuf,
1557 .reqbufs = omap1_cam_reqbufs,
1558 .querycap = omap1_cam_querycap,
1559 .set_bus_param = omap1_cam_set_bus_param,
1560 .poll = omap1_cam_poll,
1561};
1562
1563static int omap1_cam_probe(struct platform_device *pdev)
1564{
1565 struct omap1_cam_dev *pcdev;
1566 struct resource *res;
1567 struct clk *clk;
1568 void __iomem *base;
1569 unsigned int irq;
1570 int err = 0;
1571
1572 irq = platform_get_irq(pdev, 0);
1573 if ((int)irq <= 0) {
1574 err = -ENODEV;
1575 goto exit;
1576 }
1577
1578 clk = devm_clk_get(&pdev->dev, "armper_ck");
1579 if (IS_ERR(clk))
1580 return PTR_ERR(clk);
1581
1582 pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev) + resource_size(res),
1583 GFP_KERNEL);
1584 if (!pcdev)
1585 return -ENOMEM;
1586
1587 pcdev->clk = clk;
1588
1589 pcdev->pdata = pdev->dev.platform_data;
1590 if (pcdev->pdata) {
1591 pcdev->pflags = pcdev->pdata->flags;
1592 pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
1593 }
1594
1595 switch (pcdev->camexclk) {
1596 case 6000000:
1597 case 8000000:
1598 case 9600000:
1599 case 12000000:
1600 case 24000000:
1601 break;
1602 default:
1603 /* pcdev->camexclk != 0 => pcdev->pdata != NULL */
1604 dev_warn(&pdev->dev,
1605 "Incorrect sensor clock frequency %ld kHz, "
1606 "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
1607 "please correct your platform data\n",
1608 pcdev->pdata->camexclk_khz);
1609 pcdev->camexclk = 0;
1610 case 0:
1611 dev_info(&pdev->dev, "Not providing sensor clock\n");
1612 }
1613
1614 INIT_LIST_HEAD(&pcdev->capture);
1615 spin_lock_init(&pcdev->lock);
1616
1617 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1618 base = devm_ioremap_resource(&pdev->dev, res);
1619 if (IS_ERR(base))
1620 return PTR_ERR(base);
1621
1622 pcdev->irq = irq;
1623 pcdev->base = base;
1624
1625 sensor_reset(pcdev, true);
1626
1627 err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME,
1628 dma_isr, (void *)pcdev, &pcdev->dma_ch);
1629 if (err < 0) {
1630 dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n");
1631 return -EBUSY;
1632 }
1633 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch);
1634
1635 /* preconfigure DMA */
1636 omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB,
1637 OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA,
1638 0, 0);
1639 omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4);
1640 /* setup DMA autoinitialization */
1641 omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch);
1642
1643 err = devm_request_irq(&pdev->dev, pcdev->irq, cam_isr, 0, DRIVER_NAME,
1644 pcdev);
1645 if (err) {
1646 dev_err(&pdev->dev, "Camera interrupt register failed\n");
1647 goto exit_free_dma;
1648 }
1649
1650 pcdev->soc_host.drv_name = DRIVER_NAME;
1651 pcdev->soc_host.ops = &omap1_host_ops;
1652 pcdev->soc_host.priv = pcdev;
1653 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1654 pcdev->soc_host.nr = pdev->id;
1655
1656 err = soc_camera_host_register(&pcdev->soc_host);
1657 if (err)
1658 return err;
1659
1660 dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n");
1661
1662 return 0;
1663
1664exit_free_dma:
1665 omap_free_dma(pcdev->dma_ch);
1666exit:
1667 return err;
1668}
1669
1670static int omap1_cam_remove(struct platform_device *pdev)
1671{
1672 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1673 struct omap1_cam_dev *pcdev = container_of(soc_host,
1674 struct omap1_cam_dev, soc_host);
1675
1676 omap_free_dma(pcdev->dma_ch);
1677
1678 soc_camera_host_unregister(soc_host);
1679
1680 dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n");
1681
1682 return 0;
1683}
1684
1685static struct platform_driver omap1_cam_driver = {
1686 .driver = {
1687 .name = DRIVER_NAME,
1688 },
1689 .probe = omap1_cam_probe,
1690 .remove = omap1_cam_remove,
1691};
1692
1693module_platform_driver(omap1_cam_driver);
1694
1695module_param(sg_mode, bool, 0644);
1696MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
1697
1698MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
1699MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
1700MODULE_LICENSE("GPL v2");
1701MODULE_VERSION(DRIVER_VERSION);
1702MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/staging/media/timb/Kconfig b/drivers/staging/media/timb/Kconfig
deleted file mode 100644
index e413fecc1e67..000000000000
--- a/drivers/staging/media/timb/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
1config VIDEO_TIMBERDALE
2 tristate "Support for timberdale Video In/LogiWIN"
3 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && HAS_DMA
4 depends on (MFD_TIMBERDALE && TIMB_DMA) || COMPILE_TEST
5 select VIDEO_ADV7180
6 select VIDEOBUF_DMA_CONTIG
7 ---help---
8 Add support for the Video In peripherial of the timberdale FPGA.
9
10 This driver is deprecated and will be removed soon unless someone
11 will start the work to convert this driver to the vb2 framework.
diff --git a/drivers/staging/media/timb/Makefile b/drivers/staging/media/timb/Makefile
deleted file mode 100644
index 4c989c23a0e0..000000000000
--- a/drivers/staging/media/timb/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
diff --git a/drivers/staging/media/timb/timblogiw.c b/drivers/staging/media/timb/timblogiw.c
deleted file mode 100644
index 113c9f3c0b3e..000000000000
--- a/drivers/staging/media/timb/timblogiw.c
+++ /dev/null
@@ -1,870 +0,0 @@
1/*
2 * timblogiw.c timberdale FPGA LogiWin Video In driver
3 * Copyright (c) 2009-2010 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * Timberdale FPGA LogiWin Video In
21 */
22
23#include <linux/platform_device.h>
24#include <linux/slab.h>
25#include <linux/dmaengine.h>
26#include <linux/scatterlist.h>
27#include <linux/interrupt.h>
28#include <linux/list.h>
29#include <linux/i2c.h>
30#include <linux/module.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-device.h>
33#include <media/videobuf-dma-contig.h>
34#include <linux/platform_data/media/timb_video.h>
35
36#define DRIVER_NAME "timb-video"
37
38#define TIMBLOGIWIN_NAME "Timberdale Video-In"
39#define TIMBLOGIW_VERSION_CODE 0x04
40
41#define TIMBLOGIW_LINES_PER_DESC 44
42#define TIMBLOGIW_MAX_VIDEO_MEM 16
43
44#define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name)
45
46
47struct timblogiw {
48 struct video_device video_dev;
49 struct v4l2_device v4l2_dev; /* mutual exclusion */
50 struct mutex lock;
51 struct device *dev;
52 struct timb_video_platform_data pdata;
53 struct v4l2_subdev *sd_enc; /* encoder */
54 bool opened;
55};
56
57struct timblogiw_tvnorm {
58 v4l2_std_id std;
59 u16 width;
60 u16 height;
61 u8 fps;
62};
63
64struct timblogiw_fh {
65 struct videobuf_queue vb_vidq;
66 struct timblogiw_tvnorm const *cur_norm;
67 struct list_head capture;
68 struct dma_chan *chan;
69 spinlock_t queue_lock; /* mutual exclusion */
70 unsigned int frame_count;
71};
72
73struct timblogiw_buffer {
74 /* common v4l buffer stuff -- must be first */
75 struct videobuf_buffer vb;
76 struct scatterlist sg[16];
77 dma_cookie_t cookie;
78 struct timblogiw_fh *fh;
79};
80
81static const struct timblogiw_tvnorm timblogiw_tvnorms[] = {
82 {
83 .std = V4L2_STD_PAL,
84 .width = 720,
85 .height = 576,
86 .fps = 25
87 },
88 {
89 .std = V4L2_STD_NTSC,
90 .width = 720,
91 .height = 480,
92 .fps = 30
93 }
94};
95
96static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm)
97{
98 return norm->width * 2;
99}
100
101
102static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm)
103{
104 return norm->height * timblogiw_bytes_per_line(norm);
105}
106
107static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std)
108{
109 int i;
110 for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
111 if (timblogiw_tvnorms[i].std & std)
112 return timblogiw_tvnorms + i;
113
114 /* default to first element */
115 return timblogiw_tvnorms;
116}
117
118static void timblogiw_dma_cb(void *data)
119{
120 struct timblogiw_buffer *buf = data;
121 struct timblogiw_fh *fh = buf->fh;
122 struct videobuf_buffer *vb = &buf->vb;
123
124 spin_lock(&fh->queue_lock);
125
126 /* mark the transfer done */
127 buf->cookie = -1;
128
129 fh->frame_count++;
130
131 if (vb->state != VIDEOBUF_ERROR) {
132 list_del(&vb->queue);
133 v4l2_get_timestamp(&vb->ts);
134 vb->field_count = fh->frame_count * 2;
135 vb->state = VIDEOBUF_DONE;
136
137 wake_up(&vb->done);
138 }
139
140 if (!list_empty(&fh->capture)) {
141 vb = list_entry(fh->capture.next, struct videobuf_buffer,
142 queue);
143 vb->state = VIDEOBUF_ACTIVE;
144 }
145
146 spin_unlock(&fh->queue_lock);
147}
148
149static bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param)
150{
151 return chan->chan_id == (uintptr_t)filter_param;
152}
153
154/* IOCTL functions */
155
156static int timblogiw_g_fmt(struct file *file, void *priv,
157 struct v4l2_format *format)
158{
159 struct video_device *vdev = video_devdata(file);
160 struct timblogiw *lw = video_get_drvdata(vdev);
161 struct timblogiw_fh *fh = priv;
162
163 dev_dbg(&vdev->dev, "%s entry\n", __func__);
164
165 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
166 return -EINVAL;
167
168 mutex_lock(&lw->lock);
169
170 format->fmt.pix.width = fh->cur_norm->width;
171 format->fmt.pix.height = fh->cur_norm->height;
172 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
173 format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm);
174 format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm);
175 format->fmt.pix.field = V4L2_FIELD_NONE;
176
177 mutex_unlock(&lw->lock);
178
179 return 0;
180}
181
182static int timblogiw_try_fmt(struct file *file, void *priv,
183 struct v4l2_format *format)
184{
185 struct video_device *vdev = video_devdata(file);
186 struct v4l2_pix_format *pix = &format->fmt.pix;
187
188 dev_dbg(&vdev->dev,
189 "%s - width=%d, height=%d, pixelformat=%d, field=%d\n"
190 "bytes per line %d, size image: %d, colorspace: %d\n",
191 __func__,
192 pix->width, pix->height, pix->pixelformat, pix->field,
193 pix->bytesperline, pix->sizeimage, pix->colorspace);
194
195 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
196 return -EINVAL;
197
198 if (pix->field != V4L2_FIELD_NONE)
199 return -EINVAL;
200
201 if (pix->pixelformat != V4L2_PIX_FMT_UYVY)
202 return -EINVAL;
203
204 return 0;
205}
206
207static int timblogiw_s_fmt(struct file *file, void *priv,
208 struct v4l2_format *format)
209{
210 struct video_device *vdev = video_devdata(file);
211 struct timblogiw *lw = video_get_drvdata(vdev);
212 struct timblogiw_fh *fh = priv;
213 struct v4l2_pix_format *pix = &format->fmt.pix;
214 int err;
215
216 mutex_lock(&lw->lock);
217
218 err = timblogiw_try_fmt(file, priv, format);
219 if (err)
220 goto out;
221
222 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
223 dev_err(&vdev->dev, "%s queue busy\n", __func__);
224 err = -EBUSY;
225 goto out;
226 }
227
228 pix->width = fh->cur_norm->width;
229 pix->height = fh->cur_norm->height;
230
231out:
232 mutex_unlock(&lw->lock);
233 return err;
234}
235
236static int timblogiw_querycap(struct file *file, void *priv,
237 struct v4l2_capability *cap)
238{
239 struct video_device *vdev = video_devdata(file);
240
241 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
242 strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
243 strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
244 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vdev->name);
245 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
246 V4L2_CAP_READWRITE;
247 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
248
249 return 0;
250}
251
252static int timblogiw_enum_fmt(struct file *file, void *priv,
253 struct v4l2_fmtdesc *fmt)
254{
255 struct video_device *vdev = video_devdata(file);
256
257 dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index);
258
259 if (fmt->index != 0)
260 return -EINVAL;
261 memset(fmt, 0, sizeof(*fmt));
262 fmt->index = 0;
263 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
264 strncpy(fmt->description, "4:2:2, packed, YUYV",
265 sizeof(fmt->description)-1);
266 fmt->pixelformat = V4L2_PIX_FMT_UYVY;
267
268 return 0;
269}
270
271static int timblogiw_g_parm(struct file *file, void *priv,
272 struct v4l2_streamparm *sp)
273{
274 struct timblogiw_fh *fh = priv;
275 struct v4l2_captureparm *cp = &sp->parm.capture;
276
277 cp->capability = V4L2_CAP_TIMEPERFRAME;
278 cp->timeperframe.numerator = 1;
279 cp->timeperframe.denominator = fh->cur_norm->fps;
280
281 return 0;
282}
283
284static int timblogiw_reqbufs(struct file *file, void *priv,
285 struct v4l2_requestbuffers *rb)
286{
287 struct video_device *vdev = video_devdata(file);
288 struct timblogiw_fh *fh = priv;
289
290 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
291
292 return videobuf_reqbufs(&fh->vb_vidq, rb);
293}
294
295static int timblogiw_querybuf(struct file *file, void *priv,
296 struct v4l2_buffer *b)
297{
298 struct video_device *vdev = video_devdata(file);
299 struct timblogiw_fh *fh = priv;
300
301 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
302
303 return videobuf_querybuf(&fh->vb_vidq, b);
304}
305
306static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
307{
308 struct video_device *vdev = video_devdata(file);
309 struct timblogiw_fh *fh = priv;
310
311 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
312
313 return videobuf_qbuf(&fh->vb_vidq, b);
314}
315
316static int timblogiw_dqbuf(struct file *file, void *priv,
317 struct v4l2_buffer *b)
318{
319 struct video_device *vdev = video_devdata(file);
320 struct timblogiw_fh *fh = priv;
321
322 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
323
324 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
325}
326
327static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std)
328{
329 struct video_device *vdev = video_devdata(file);
330 struct timblogiw_fh *fh = priv;
331
332 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
333
334 *std = fh->cur_norm->std;
335 return 0;
336}
337
338static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id std)
339{
340 struct video_device *vdev = video_devdata(file);
341 struct timblogiw *lw = video_get_drvdata(vdev);
342 struct timblogiw_fh *fh = priv;
343 int err = 0;
344
345 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
346
347 mutex_lock(&lw->lock);
348
349 if (TIMBLOGIW_HAS_DECODER(lw))
350 err = v4l2_subdev_call(lw->sd_enc, video, s_std, std);
351
352 if (!err)
353 fh->cur_norm = timblogiw_get_norm(std);
354
355 mutex_unlock(&lw->lock);
356
357 return err;
358}
359
360static int timblogiw_enuminput(struct file *file, void *priv,
361 struct v4l2_input *inp)
362{
363 struct video_device *vdev = video_devdata(file);
364 int i;
365
366 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
367
368 if (inp->index != 0)
369 return -EINVAL;
370
371 inp->index = 0;
372
373 strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1);
374 inp->type = V4L2_INPUT_TYPE_CAMERA;
375
376 inp->std = 0;
377 for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
378 inp->std |= timblogiw_tvnorms[i].std;
379
380 return 0;
381}
382
383static int timblogiw_g_input(struct file *file, void *priv,
384 unsigned int *input)
385{
386 struct video_device *vdev = video_devdata(file);
387
388 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
389
390 *input = 0;
391
392 return 0;
393}
394
395static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
396{
397 struct video_device *vdev = video_devdata(file);
398
399 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
400
401 if (input != 0)
402 return -EINVAL;
403 return 0;
404}
405
406static int timblogiw_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
407{
408 struct video_device *vdev = video_devdata(file);
409 struct timblogiw_fh *fh = priv;
410
411 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
412
413 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
414 dev_dbg(&vdev->dev, "%s - No capture device\n", __func__);
415 return -EINVAL;
416 }
417
418 fh->frame_count = 0;
419 return videobuf_streamon(&fh->vb_vidq);
420}
421
422static int timblogiw_streamoff(struct file *file, void *priv,
423 enum v4l2_buf_type type)
424{
425 struct video_device *vdev = video_devdata(file);
426 struct timblogiw_fh *fh = priv;
427
428 dev_dbg(&vdev->dev, "%s entry\n", __func__);
429
430 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
431 return -EINVAL;
432
433 return videobuf_streamoff(&fh->vb_vidq);
434}
435
436static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std)
437{
438 struct video_device *vdev = video_devdata(file);
439 struct timblogiw *lw = video_get_drvdata(vdev);
440 struct timblogiw_fh *fh = priv;
441
442 dev_dbg(&vdev->dev, "%s entry\n", __func__);
443
444 if (TIMBLOGIW_HAS_DECODER(lw))
445 return v4l2_subdev_call(lw->sd_enc, video, querystd, std);
446 else {
447 *std = fh->cur_norm->std;
448 return 0;
449 }
450}
451
452static int timblogiw_enum_framesizes(struct file *file, void *priv,
453 struct v4l2_frmsizeenum *fsize)
454{
455 struct video_device *vdev = video_devdata(file);
456 struct timblogiw_fh *fh = priv;
457
458 dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__,
459 fsize->index, fsize->pixel_format);
460
461 if ((fsize->index != 0) ||
462 (fsize->pixel_format != V4L2_PIX_FMT_UYVY))
463 return -EINVAL;
464
465 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
466 fsize->discrete.width = fh->cur_norm->width;
467 fsize->discrete.height = fh->cur_norm->height;
468
469 return 0;
470}
471
472/* Video buffer functions */
473
474static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
475 unsigned int *size)
476{
477 struct timblogiw_fh *fh = vq->priv_data;
478
479 *size = timblogiw_frame_size(fh->cur_norm);
480
481 if (!*count)
482 *count = 32;
483
484 while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024)
485 (*count)--;
486
487 return 0;
488}
489
490static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
491 enum v4l2_field field)
492{
493 struct timblogiw_fh *fh = vq->priv_data;
494 struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
495 vb);
496 unsigned int data_size = timblogiw_frame_size(fh->cur_norm);
497 int err = 0;
498
499 if (vb->baddr && vb->bsize < data_size)
500 /* User provided buffer, but it is too small */
501 return -ENOMEM;
502
503 vb->size = data_size;
504 vb->width = fh->cur_norm->width;
505 vb->height = fh->cur_norm->height;
506 vb->field = field;
507
508 if (vb->state == VIDEOBUF_NEEDS_INIT) {
509 int i;
510 unsigned int size;
511 unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
512 timblogiw_bytes_per_line(fh->cur_norm);
513 dma_addr_t addr;
514
515 sg_init_table(buf->sg, ARRAY_SIZE(buf->sg));
516
517 err = videobuf_iolock(vq, vb, NULL);
518 if (err)
519 goto err;
520
521 addr = videobuf_to_dma_contig(vb);
522 for (i = 0, size = 0; size < data_size; i++) {
523 sg_dma_address(buf->sg + i) = addr + size;
524 size += bytes_per_desc;
525 sg_dma_len(buf->sg + i) = (size > data_size) ?
526 (bytes_per_desc - (size - data_size)) :
527 bytes_per_desc;
528 }
529
530 vb->state = VIDEOBUF_PREPARED;
531 buf->cookie = -1;
532 buf->fh = fh;
533 }
534
535 return 0;
536
537err:
538 videobuf_dma_contig_free(vq, vb);
539 vb->state = VIDEOBUF_NEEDS_INIT;
540 return err;
541}
542
543static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
544{
545 struct timblogiw_fh *fh = vq->priv_data;
546 struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
547 vb);
548 struct dma_async_tx_descriptor *desc;
549 int sg_elems;
550 int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
551 timblogiw_bytes_per_line(fh->cur_norm);
552
553 sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc;
554 sg_elems +=
555 (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0;
556
557 if (list_empty(&fh->capture))
558 vb->state = VIDEOBUF_ACTIVE;
559 else
560 vb->state = VIDEOBUF_QUEUED;
561
562 list_add_tail(&vb->queue, &fh->capture);
563
564 spin_unlock_irq(&fh->queue_lock);
565
566 desc = dmaengine_prep_slave_sg(fh->chan,
567 buf->sg, sg_elems, DMA_DEV_TO_MEM,
568 DMA_PREP_INTERRUPT);
569 if (!desc) {
570 spin_lock_irq(&fh->queue_lock);
571 list_del_init(&vb->queue);
572 vb->state = VIDEOBUF_PREPARED;
573 return;
574 }
575
576 desc->callback_param = buf;
577 desc->callback = timblogiw_dma_cb;
578
579 buf->cookie = desc->tx_submit(desc);
580
581 spin_lock_irq(&fh->queue_lock);
582}
583
584static void buffer_release(struct videobuf_queue *vq,
585 struct videobuf_buffer *vb)
586{
587 struct timblogiw_fh *fh = vq->priv_data;
588 struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
589 vb);
590
591 videobuf_waiton(vq, vb, 0, 0);
592 if (buf->cookie >= 0)
593 dma_sync_wait(fh->chan, buf->cookie);
594
595 videobuf_dma_contig_free(vq, vb);
596 vb->state = VIDEOBUF_NEEDS_INIT;
597}
598
599static struct videobuf_queue_ops timblogiw_video_qops = {
600 .buf_setup = buffer_setup,
601 .buf_prepare = buffer_prepare,
602 .buf_queue = buffer_queue,
603 .buf_release = buffer_release,
604};
605
606/* Device Operations functions */
607
608static int timblogiw_open(struct file *file)
609{
610 struct video_device *vdev = video_devdata(file);
611 struct timblogiw *lw = video_get_drvdata(vdev);
612 struct timblogiw_fh *fh;
613 v4l2_std_id std;
614 dma_cap_mask_t mask;
615 int err = 0;
616
617 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
618
619 mutex_lock(&lw->lock);
620 if (lw->opened) {
621 err = -EBUSY;
622 goto out;
623 }
624
625 if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) {
626 struct i2c_adapter *adapt;
627
628 /* find the video decoder */
629 adapt = i2c_get_adapter(lw->pdata.i2c_adapter);
630 if (!adapt) {
631 dev_err(&vdev->dev, "No I2C bus #%d\n",
632 lw->pdata.i2c_adapter);
633 err = -ENODEV;
634 goto out;
635 }
636
637 /* now find the encoder */
638 lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt,
639 lw->pdata.encoder.info, NULL);
640
641 i2c_put_adapter(adapt);
642
643 if (!lw->sd_enc) {
644 dev_err(&vdev->dev, "Failed to get encoder: %s\n",
645 lw->pdata.encoder.module_name);
646 err = -ENODEV;
647 goto out;
648 }
649 }
650
651 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
652 if (!fh) {
653 err = -ENOMEM;
654 goto out;
655 }
656
657 fh->cur_norm = timblogiw_tvnorms;
658 timblogiw_querystd(file, fh, &std);
659 fh->cur_norm = timblogiw_get_norm(std);
660
661 INIT_LIST_HEAD(&fh->capture);
662 spin_lock_init(&fh->queue_lock);
663
664 dma_cap_zero(mask);
665 dma_cap_set(DMA_SLAVE, mask);
666 dma_cap_set(DMA_PRIVATE, mask);
667
668 /* find the DMA channel */
669 fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn,
670 (void *)(uintptr_t)lw->pdata.dma_channel);
671 if (!fh->chan) {
672 dev_err(&vdev->dev, "Failed to get DMA channel\n");
673 kfree(fh);
674 err = -ENODEV;
675 goto out;
676 }
677
678 file->private_data = fh;
679 videobuf_queue_dma_contig_init(&fh->vb_vidq,
680 &timblogiw_video_qops, lw->dev, &fh->queue_lock,
681 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
682 sizeof(struct timblogiw_buffer), fh, NULL);
683
684 lw->opened = true;
685out:
686 mutex_unlock(&lw->lock);
687
688 return err;
689}
690
691static int timblogiw_close(struct file *file)
692{
693 struct video_device *vdev = video_devdata(file);
694 struct timblogiw *lw = video_get_drvdata(vdev);
695 struct timblogiw_fh *fh = file->private_data;
696
697 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
698
699 videobuf_stop(&fh->vb_vidq);
700 videobuf_mmap_free(&fh->vb_vidq);
701
702 dma_release_channel(fh->chan);
703
704 kfree(fh);
705
706 mutex_lock(&lw->lock);
707 lw->opened = false;
708 mutex_unlock(&lw->lock);
709 return 0;
710}
711
712static ssize_t timblogiw_read(struct file *file, char __user *data,
713 size_t count, loff_t *ppos)
714{
715 struct video_device *vdev = video_devdata(file);
716 struct timblogiw_fh *fh = file->private_data;
717
718 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
719
720 return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
721 file->f_flags & O_NONBLOCK);
722}
723
724static unsigned int timblogiw_poll(struct file *file,
725 struct poll_table_struct *wait)
726{
727 struct video_device *vdev = video_devdata(file);
728 struct timblogiw_fh *fh = file->private_data;
729
730 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
731
732 return videobuf_poll_stream(file, &fh->vb_vidq, wait);
733}
734
735static int timblogiw_mmap(struct file *file, struct vm_area_struct *vma)
736{
737 struct video_device *vdev = video_devdata(file);
738 struct timblogiw_fh *fh = file->private_data;
739
740 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
741
742 return videobuf_mmap_mapper(&fh->vb_vidq, vma);
743}
744
745/* Platform device functions */
746
747static struct v4l2_ioctl_ops timblogiw_ioctl_ops = {
748 .vidioc_querycap = timblogiw_querycap,
749 .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt,
750 .vidioc_g_fmt_vid_cap = timblogiw_g_fmt,
751 .vidioc_try_fmt_vid_cap = timblogiw_try_fmt,
752 .vidioc_s_fmt_vid_cap = timblogiw_s_fmt,
753 .vidioc_g_parm = timblogiw_g_parm,
754 .vidioc_reqbufs = timblogiw_reqbufs,
755 .vidioc_querybuf = timblogiw_querybuf,
756 .vidioc_qbuf = timblogiw_qbuf,
757 .vidioc_dqbuf = timblogiw_dqbuf,
758 .vidioc_g_std = timblogiw_g_std,
759 .vidioc_s_std = timblogiw_s_std,
760 .vidioc_enum_input = timblogiw_enuminput,
761 .vidioc_g_input = timblogiw_g_input,
762 .vidioc_s_input = timblogiw_s_input,
763 .vidioc_streamon = timblogiw_streamon,
764 .vidioc_streamoff = timblogiw_streamoff,
765 .vidioc_querystd = timblogiw_querystd,
766 .vidioc_enum_framesizes = timblogiw_enum_framesizes,
767};
768
769static struct v4l2_file_operations timblogiw_fops = {
770 .owner = THIS_MODULE,
771 .open = timblogiw_open,
772 .release = timblogiw_close,
773 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
774 .mmap = timblogiw_mmap,
775 .read = timblogiw_read,
776 .poll = timblogiw_poll,
777};
778
779static struct video_device timblogiw_template = {
780 .name = TIMBLOGIWIN_NAME,
781 .fops = &timblogiw_fops,
782 .ioctl_ops = &timblogiw_ioctl_ops,
783 .release = video_device_release_empty,
784 .minor = -1,
785 .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC
786};
787
788static int timblogiw_probe(struct platform_device *pdev)
789{
790 int err;
791 struct timblogiw *lw = NULL;
792 struct timb_video_platform_data *pdata = pdev->dev.platform_data;
793
794 if (!pdata) {
795 dev_err(&pdev->dev, "No platform data\n");
796 err = -EINVAL;
797 goto err;
798 }
799
800 if (!pdata->encoder.module_name)
801 dev_info(&pdev->dev, "Running without decoder\n");
802
803 lw = devm_kzalloc(&pdev->dev, sizeof(*lw), GFP_KERNEL);
804 if (!lw) {
805 err = -ENOMEM;
806 goto err;
807 }
808
809 if (pdev->dev.parent)
810 lw->dev = pdev->dev.parent;
811 else
812 lw->dev = &pdev->dev;
813
814 memcpy(&lw->pdata, pdata, sizeof(lw->pdata));
815
816 mutex_init(&lw->lock);
817
818 lw->video_dev = timblogiw_template;
819
820 strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name));
821 err = v4l2_device_register(NULL, &lw->v4l2_dev);
822 if (err)
823 goto err;
824
825 lw->video_dev.v4l2_dev = &lw->v4l2_dev;
826
827 platform_set_drvdata(pdev, lw);
828 video_set_drvdata(&lw->video_dev, lw);
829
830 err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0);
831 if (err) {
832 dev_err(&pdev->dev, "Error reg video: %d\n", err);
833 goto err_request;
834 }
835
836 return 0;
837
838err_request:
839 v4l2_device_unregister(&lw->v4l2_dev);
840err:
841 dev_err(&pdev->dev, "Failed to register: %d\n", err);
842
843 return err;
844}
845
846static int timblogiw_remove(struct platform_device *pdev)
847{
848 struct timblogiw *lw = platform_get_drvdata(pdev);
849
850 video_unregister_device(&lw->video_dev);
851
852 v4l2_device_unregister(&lw->v4l2_dev);
853
854 return 0;
855}
856
857static struct platform_driver timblogiw_platform_driver = {
858 .driver = {
859 .name = DRIVER_NAME,
860 },
861 .probe = timblogiw_probe,
862 .remove = timblogiw_remove,
863};
864
865module_platform_driver(timblogiw_platform_driver);
866
867MODULE_DESCRIPTION(TIMBLOGIWIN_NAME);
868MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>");
869MODULE_LICENSE("GPL v2");
870MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index c201060e0c6d..f8e1992d6423 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -1,7 +1,8 @@
1#ifndef __OF_RESERVED_MEM_H 1#ifndef __OF_RESERVED_MEM_H
2#define __OF_RESERVED_MEM_H 2#define __OF_RESERVED_MEM_H
3 3
4struct device; 4#include <linux/device.h>
5
5struct of_phandle_args; 6struct of_phandle_args;
6struct reserved_mem_ops; 7struct reserved_mem_ops;
7 8
@@ -28,7 +29,9 @@ typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem);
28 _OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn) 29 _OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn)
29 30
30#ifdef CONFIG_OF_RESERVED_MEM 31#ifdef CONFIG_OF_RESERVED_MEM
31int of_reserved_mem_device_init(struct device *dev); 32
33int of_reserved_mem_device_init_by_idx(struct device *dev,
34 struct device_node *np, int idx);
32void of_reserved_mem_device_release(struct device *dev); 35void of_reserved_mem_device_release(struct device *dev);
33 36
34int early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, 37int early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
@@ -42,7 +45,8 @@ void fdt_init_reserved_mem(void);
42void fdt_reserved_mem_save_node(unsigned long node, const char *uname, 45void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
43 phys_addr_t base, phys_addr_t size); 46 phys_addr_t base, phys_addr_t size);
44#else 47#else
45static inline int of_reserved_mem_device_init(struct device *dev) 48static inline int of_reserved_mem_device_init_by_idx(struct device *dev,
49 struct device_node *np, int idx)
46{ 50{
47 return -ENOSYS; 51 return -ENOSYS;
48} 52}
@@ -53,4 +57,19 @@ static inline void fdt_reserved_mem_save_node(unsigned long node,
53 const char *uname, phys_addr_t base, phys_addr_t size) { } 57 const char *uname, phys_addr_t base, phys_addr_t size) { }
54#endif 58#endif
55 59
60/**
61 * of_reserved_mem_device_init() - assign reserved memory region to given device
62 * @dev: Pointer to the device to configure
63 *
64 * This function assigns respective DMA-mapping operations based on the first
65 * reserved memory region specified by 'memory-region' property in device tree
66 * node of the given device.
67 *
68 * Returns error code or zero on success.
69 */
70static inline int of_reserved_mem_device_init(struct device *dev)
71{
72 return of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);
73}
74
56#endif /* __OF_RESERVED_MEM_H */ 75#endif /* __OF_RESERVED_MEM_H */
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a9b33c47310d..f743ae2210ee 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -347,7 +347,7 @@ struct media_entity_notify {
347struct media_device { 347struct media_device {
348 /* dev->driver_data points to this struct. */ 348 /* dev->driver_data points to this struct. */
349 struct device *dev; 349 struct device *dev;
350 struct media_devnode devnode; 350 struct media_devnode *devnode;
351 351
352 char model[32]; 352 char model[32];
353 char driver_name[32]; 353 char driver_name[32];
@@ -393,9 +393,6 @@ struct usb_device;
393#define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0 393#define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0
394#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1 394#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1
395 395
396/* media_devnode to media_device */
397#define to_media_device(node) container_of(node, struct media_device, devnode)
398
399/** 396/**
400 * media_entity_enum_init - Initialise an entity enumeration 397 * media_entity_enum_init - Initialise an entity enumeration
401 * 398 *
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h
index fe42f08e72bd..37d494805944 100644
--- a/include/media/media-devnode.h
+++ b/include/media/media-devnode.h
@@ -33,6 +33,8 @@
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/cdev.h> 34#include <linux/cdev.h>
35 35
36struct media_device;
37
36/* 38/*
37 * Flag to mark the media_devnode struct as registered. Drivers must not touch 39 * Flag to mark the media_devnode struct as registered. Drivers must not touch
38 * this flag directly, it will be set and cleared by media_devnode_register and 40 * this flag directly, it will be set and cleared by media_devnode_register and
@@ -67,8 +69,9 @@ struct media_file_operations {
67 69
68/** 70/**
69 * struct media_devnode - Media device node 71 * struct media_devnode - Media device node
72 * @media_dev: pointer to struct &media_device
70 * @fops: pointer to struct &media_file_operations with media device ops 73 * @fops: pointer to struct &media_file_operations with media device ops
71 * @dev: struct device pointer for the media controller device 74 * @dev: pointer to struct &device containing the media controller device
72 * @cdev: struct cdev pointer character device 75 * @cdev: struct cdev pointer character device
73 * @parent: parent device 76 * @parent: parent device
74 * @minor: device node minor number 77 * @minor: device node minor number
@@ -81,6 +84,8 @@ struct media_file_operations {
81 * before registering the node. 84 * before registering the node.
82 */ 85 */
83struct media_devnode { 86struct media_devnode {
87 struct media_device *media_dev;
88
84 /* device ops */ 89 /* device ops */
85 const struct media_file_operations *fops; 90 const struct media_file_operations *fops;
86 91
@@ -94,7 +99,7 @@ struct media_devnode {
94 unsigned long flags; /* Use bitops to access flags */ 99 unsigned long flags; /* Use bitops to access flags */
95 100
96 /* callbacks */ 101 /* callbacks */
97 void (*release)(struct media_devnode *mdev); 102 void (*release)(struct media_devnode *devnode);
98}; 103};
99 104
100/* dev to media_devnode */ 105/* dev to media_devnode */
@@ -103,7 +108,8 @@ struct media_devnode {
103/** 108/**
104 * media_devnode_register - register a media device node 109 * media_devnode_register - register a media device node
105 * 110 *
106 * @mdev: media device node structure we want to register 111 * @mdev: struct media_device we want to register a device node
112 * @devnode: media device node structure we want to register
107 * @owner: should be filled with %THIS_MODULE 113 * @owner: should be filled with %THIS_MODULE
108 * 114 *
109 * The registration code assigns minor numbers and registers the new device node 115 * The registration code assigns minor numbers and registers the new device node
@@ -116,20 +122,33 @@ struct media_devnode {
116 * the media_devnode structure is *not* called, so the caller is responsible for 122 * the media_devnode structure is *not* called, so the caller is responsible for
117 * freeing any data. 123 * freeing any data.
118 */ 124 */
119int __must_check media_devnode_register(struct media_devnode *mdev, 125int __must_check media_devnode_register(struct media_device *mdev,
126 struct media_devnode *devnode,
120 struct module *owner); 127 struct module *owner);
121 128
122/** 129/**
130 * media_devnode_unregister_prepare - clear the media device node register bit
131 * @devnode: the device node to prepare for unregister
132 *
133 * This clears the passed device register bit. Future open calls will be met
134 * with errors. Should be called before media_devnode_unregister() to avoid
135 * races with unregister and device file open calls.
136 *
137 * This function can safely be called if the device node has never been
138 * registered or has already been unregistered.
139 */
140void media_devnode_unregister_prepare(struct media_devnode *devnode);
141
142/**
123 * media_devnode_unregister - unregister a media device node 143 * media_devnode_unregister - unregister a media device node
124 * @mdev: the device node to unregister 144 * @devnode: the device node to unregister
125 * 145 *
126 * This unregisters the passed device. Future open calls will be met with 146 * This unregisters the passed device. Future open calls will be met with
127 * errors. 147 * errors.
128 * 148 *
129 * This function can safely be called if the device node has never been 149 * Should be called after media_devnode_unregister_prepare()
130 * registered or has already been unregistered.
131 */ 150 */
132void media_devnode_unregister(struct media_devnode *mdev); 151void media_devnode_unregister(struct media_devnode *devnode);
133 152
134/** 153/**
135 * media_devnode_data - returns a pointer to the &media_devnode 154 * media_devnode_data - returns a pointer to the &media_devnode
@@ -145,11 +164,16 @@ static inline struct media_devnode *media_devnode_data(struct file *filp)
145 * media_devnode_is_registered - returns true if &media_devnode is registered; 164 * media_devnode_is_registered - returns true if &media_devnode is registered;
146 * false otherwise. 165 * false otherwise.
147 * 166 *
148 * @mdev: pointer to struct &media_devnode. 167 * @devnode: pointer to struct &media_devnode.
168 *
169 * Note: If mdev is NULL, it also returns false.
149 */ 170 */
150static inline int media_devnode_is_registered(struct media_devnode *mdev) 171static inline int media_devnode_is_registered(struct media_devnode *devnode)
151{ 172{
152 return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); 173 if (!devnode)
174 return false;
175
176 return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
153} 177}
154 178
155#endif /* _MEDIA_DEVNODE_H */ 179#endif /* _MEDIA_DEVNODE_H */
diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
new file mode 100644
index 000000000000..4c7fc77eaf29
--- /dev/null
+++ b/include/media/rcar-fcp.h
@@ -0,0 +1,37 @@
1/*
2 * rcar-fcp.h -- R-Car Frame Compression Processor Driver
3 *
4 * Copyright (C) 2016 Renesas Electronics Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#ifndef __MEDIA_RCAR_FCP_H__
14#define __MEDIA_RCAR_FCP_H__
15
16struct device_node;
17struct rcar_fcp_device;
18
19#if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
20struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
21void rcar_fcp_put(struct rcar_fcp_device *fcp);
22int rcar_fcp_enable(struct rcar_fcp_device *fcp);
23void rcar_fcp_disable(struct rcar_fcp_device *fcp);
24#else
25static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
26{
27 return ERR_PTR(-ENOENT);
28}
29static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
30static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
31{
32 return -ENOSYS;
33}
34static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { }
35#endif
36
37#endif /* __MEDIA_RCAR_FCP_H__ */
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
index 2087c9a68be3..f7dc8401817e 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -35,6 +35,8 @@ static inline void *vb2_dma_contig_init_ctx(struct device *dev)
35} 35}
36 36
37void vb2_dma_contig_cleanup_ctx(void *alloc_ctx); 37void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
38int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
39void vb2_dma_contig_clear_max_seg_size(struct device *dev);
38 40
39extern const struct vb2_mem_ops vb2_dma_contig_memops; 41extern const struct vb2_mem_ops vb2_dma_contig_memops;
40 42
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 3e654a0455bd..9322d9775fb7 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -14,31 +14,28 @@
14#define __MEDIA_VSP1_H__ 14#define __MEDIA_VSP1_H__
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/videodev2.h>
17 18
18struct device; 19struct device;
19struct v4l2_rect;
20 20
21int vsp1_du_init(struct device *dev); 21int vsp1_du_init(struct device *dev);
22 22
23int vsp1_du_setup_lif(struct device *dev, unsigned int width, 23int vsp1_du_setup_lif(struct device *dev, unsigned int width,
24 unsigned int height); 24 unsigned int height);
25 25
26struct vsp1_du_atomic_config {
27 u32 pixelformat;
28 unsigned int pitch;
29 dma_addr_t mem[2];
30 struct v4l2_rect src;
31 struct v4l2_rect dst;
32 unsigned int alpha;
33 unsigned int zpos;
34};
35
26void vsp1_du_atomic_begin(struct device *dev); 36void vsp1_du_atomic_begin(struct device *dev);
27int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf, 37int vsp1_du_atomic_update(struct device *dev, unsigned int rpf,
28 u32 pixelformat, unsigned int pitch, 38 const struct vsp1_du_atomic_config *cfg);
29 dma_addr_t mem[2], const struct v4l2_rect *src,
30 const struct v4l2_rect *dst, unsigned int alpha,
31 unsigned int zpos);
32void vsp1_du_atomic_flush(struct device *dev); 39void vsp1_du_atomic_flush(struct device *dev);
33 40
34static inline int vsp1_du_atomic_update(struct device *dev,
35 unsigned int rpf_index, u32 pixelformat,
36 unsigned int pitch, dma_addr_t mem[2],
37 const struct v4l2_rect *src,
38 const struct v4l2_rect *dst)
39{
40 return vsp1_du_atomic_update_ext(dev, rpf_index, pixelformat, pitch,
41 mem, src, dst, 255, 0);
42}
43
44#endif /* __MEDIA_VSP1_H__ */ 41#endif /* __MEDIA_VSP1_H__ */
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index df59edee25d1..7acf0f634f70 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -95,6 +95,16 @@ struct media_device_info {
95#define MEDIA_ENT_F_AUDIO_MIXER (MEDIA_ENT_F_BASE + 0x03003) 95#define MEDIA_ENT_F_AUDIO_MIXER (MEDIA_ENT_F_BASE + 0x03003)
96 96
97/* 97/*
98 * Processing entities
99 */
100#define MEDIA_ENT_F_PROC_VIDEO_COMPOSER (MEDIA_ENT_F_BASE + 0x4001)
101#define MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER (MEDIA_ENT_F_BASE + 0x4002)
102#define MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV (MEDIA_ENT_F_BASE + 0x4003)
103#define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004)
104#define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005)
105#define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006)
106
107/*
98 * Connectors 108 * Connectors
99 */ 109 */
100/* It is a responsibility of the entity drivers to add connectors and links */ 110/* It is a responsibility of the entity drivers to add connectors and links */
diff --git a/include/uapi/linux/vsp1.h b/include/uapi/linux/vsp1.h
deleted file mode 100644
index 9a823696d816..000000000000
--- a/include/uapi/linux/vsp1.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * vsp1.h
3 *
4 * Renesas R-Car VSP1 - User-space API
5 *
6 * Copyright (C) 2013 Renesas Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __VSP1_USER_H__
16#define __VSP1_USER_H__
17
18#include <linux/types.h>
19#include <linux/videodev2.h>
20
21/*
22 * Private IOCTLs
23 *
24 * VIDIOC_VSP1_LUT_CONFIG - Configure the lookup table
25 */
26
27#define VIDIOC_VSP1_LUT_CONFIG \
28 _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct vsp1_lut_config)
29
30struct vsp1_lut_config {
31 __u32 lut[256];
32};
33
34#endif /* __VSP1_USER_H__ */