4e5c349072f9ea0014d5d8408d08187613fc075e
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
1 From 63f4970ce038e60455a6225b317d0b259e046c94 Mon Sep 17 00:00:00 2001
2 From: Jacopo Mondi <jacopo+renesas@jmondi.org>
3 Date: Tue, 16 Jun 2020 16:12:39 +0200
4 Subject: [PATCH] media: pxa_camera: Use the new set_mbus_config op
5
6 Upstream https://patchwork.linuxtv.org/patch/64671/
7
8 Move the PXA camera driver to use the new set_mbus_config pad operation.
9 For this platform the change is not only cosmetic, as the pxa driver is
10 currently the only driver in mainline to make use of the g_mbus_config
11 and s_mbus_config video operations.
12
13 The existing driver semantic is the following:
14 - Collect all supported mbus config flags from the remote end
15 - Match them with the supported PXA mbus configuration flags
16 - If the remote subdevice allows multiple options for for VSYNC, HSYNC
17 and PCLK polarity, use platform data requested settings
18
19 The semantic of the new get_mbus_config and set_mbus_config differs from
20 the corresponding video ops, particularly in the fact get_mbus_config
21 reports the current mbus configuration and not the set of supported
22 configuration options, with set_mbus_config always reporting the actual
23 mbus configuration applied to the remote subdevice.
24
25 Adapt the driver to perform the following
26 - Set the remote subdevice mbus configuration according to the PXA
27 platform data preferences.
28 - If the applied configuration differs from the requested one (i.e. the
29 remote subdevice does not allow changing one setting) make sure that
30 - The remote end does not claim for DATA_ACTIVE_LOW, which seems not
31 supported by the platform
32 - The bus mastering roles match
33
34 While at there remove a few checks performed on the media bus
35 configuration at get_format() time as they do not belong there.
36
37 Compile-tested only.
38
39 Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
40 ---
41 drivers/media/platform/pxa_camera.c | 189 ++++++++--------------------
42 1 file changed, 51 insertions(+), 138 deletions(-)
43
44 --- a/drivers/media/platform/pxa_camera.c
45 +++ b/drivers/media/platform/pxa_camera.c
46 @@ -605,42 +605,6 @@ static const struct pxa_mbus_pixelfmt *p
47 return pxa_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
48 }
49
50 -static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
51 - unsigned int flags)
52 -{
53 - unsigned long common_flags;
54 - bool hsync = true, vsync = true, pclk, data, mode;
55 - bool mipi_lanes, mipi_clock;
56 -
57 - common_flags = cfg->flags & flags;
58 -
59 - switch (cfg->type) {
60 - case V4L2_MBUS_PARALLEL:
61 - hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
62 - V4L2_MBUS_HSYNC_ACTIVE_LOW);
63 - vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
64 - V4L2_MBUS_VSYNC_ACTIVE_LOW);
65 - /* fall through */
66 - case V4L2_MBUS_BT656:
67 - pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
68 - V4L2_MBUS_PCLK_SAMPLE_FALLING);
69 - data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
70 - V4L2_MBUS_DATA_ACTIVE_LOW);
71 - mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
72 - return (!hsync || !vsync || !pclk || !data || !mode) ?
73 - 0 : common_flags;
74 - case V4L2_MBUS_CSI2_DPHY:
75 - mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
76 - mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
77 - V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
78 - return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
79 - default:
80 - WARN_ON(1);
81 - return -EINVAL;
82 - }
83 - return 0;
84 -}
85 -
86 /**
87 * struct pxa_camera_format_xlate - match between host and sensor formats
88 * @code: code of a sensor provided format
89 @@ -1231,31 +1195,6 @@ static irqreturn_t pxa_camera_irq(int ir
90 return IRQ_HANDLED;
91 }
92
93 -static int test_platform_param(struct pxa_camera_dev *pcdev,
94 - unsigned char buswidth, unsigned long *flags)
95 -{
96 - /*
97 - * Platform specified synchronization and pixel clock polarities are
98 - * only a recommendation and are only used during probing. The PXA270
99 - * quick capture interface supports both.
100 - */
101 - *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
102 - V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
103 - V4L2_MBUS_HSYNC_ACTIVE_HIGH |
104 - V4L2_MBUS_HSYNC_ACTIVE_LOW |
105 - V4L2_MBUS_VSYNC_ACTIVE_HIGH |
106 - V4L2_MBUS_VSYNC_ACTIVE_LOW |
107 - V4L2_MBUS_DATA_ACTIVE_HIGH |
108 - V4L2_MBUS_PCLK_SAMPLE_RISING |
109 - V4L2_MBUS_PCLK_SAMPLE_FALLING;
110 -
111 - /* If requested data width is supported by the platform, use it */
112 - if ((1 << (buswidth - 1)) & pcdev->width_flags)
113 - return 0;
114 -
115 - return -EINVAL;
116 -}
117 -
118 static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev,
119 unsigned long flags, __u32 pixfmt)
120 {
121 @@ -1601,99 +1540,78 @@ static int pxa_camera_init_videobuf2(str
122 */
123 static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev)
124 {
125 + unsigned int bus_width = pcdev->current_fmt->host_fmt->bits_per_sample;
126 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
127 u32 pixfmt = pcdev->current_fmt->host_fmt->fourcc;
128 - unsigned long bus_flags, common_flags;
129 + int mbus_config;
130 int ret;
131
132 - ret = test_platform_param(pcdev,
133 - pcdev->current_fmt->host_fmt->bits_per_sample,
134 - &bus_flags);
135 - if (ret < 0)
136 - return ret;
137 -
138 - ret = sensor_call(pcdev, video, g_mbus_config, &cfg);
139 - if (!ret) {
140 - common_flags = pxa_mbus_config_compatible(&cfg,
141 - bus_flags);
142 - if (!common_flags) {
143 - dev_warn(pcdev_to_dev(pcdev),
144 - "Flags incompatible: camera 0x%x, host 0x%lx\n",
145 - cfg.flags, bus_flags);
146 - return -EINVAL;
147 - }
148 - } else if (ret != -ENOIOCTLCMD) {
149 - return ret;
150 - } else {
151 - common_flags = bus_flags;
152 + if (!((1 << (bus_width - 1)) & pcdev->width_flags)) {
153 + dev_err(pcdev_to_dev(pcdev), "Unsupported bus width %u",
154 + bus_width);
155 + return -EINVAL;
156 }
157
158 pcdev->channels = 1;
159
160 /* Make choices, based on platform preferences */
161 - if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
162 - (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
163 - if (pcdev->platform_flags & PXA_CAMERA_HSP)
164 - common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
165 - else
166 - common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
167 - }
168 -
169 - if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
170 - (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
171 - if (pcdev->platform_flags & PXA_CAMERA_VSP)
172 - common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
173 - else
174 - common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
175 - }
176 -
177 - if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
178 - (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
179 - if (pcdev->platform_flags & PXA_CAMERA_PCP)
180 - common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
181 - else
182 - common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
183 - }
184 -
185 - cfg.flags = common_flags;
186 - ret = sensor_call(pcdev, video, s_mbus_config, &cfg);
187 - if (ret < 0 && ret != -ENOIOCTLCMD) {
188 - dev_dbg(pcdev_to_dev(pcdev),
189 - "camera s_mbus_config(0x%lx) returned %d\n",
190 - common_flags, ret);
191 - return ret;
192 - }
193 + mbus_config = 0;
194 + if (pcdev->platform_flags & PXA_CAMERA_MASTER)
195 + mbus_config |= V4L2_MBUS_MASTER;
196 + else
197 + mbus_config |= V4L2_MBUS_SLAVE;
198
199 - pxa_camera_setup_cicr(pcdev, common_flags, pixfmt);
200 + if (pcdev->platform_flags & PXA_CAMERA_HSP)
201 + mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_HIGH;
202 + else
203 + mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_LOW;
204
205 - return 0;
206 -}
207 + if (pcdev->platform_flags & PXA_CAMERA_VSP)
208 + mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_HIGH;
209 + else
210 + mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_LOW;
211
212 -static int pxa_camera_try_bus_param(struct pxa_camera_dev *pcdev,
213 - unsigned char buswidth)
214 -{
215 - struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
216 - unsigned long bus_flags, common_flags;
217 - int ret = test_platform_param(pcdev, buswidth, &bus_flags);
218 + if (pcdev->platform_flags & PXA_CAMERA_PCP)
219 + mbus_config |= V4L2_MBUS_PCLK_SAMPLE_RISING;
220 + else
221 + mbus_config |= V4L2_MBUS_PCLK_SAMPLE_FALLING;
222 + mbus_config |= V4L2_MBUS_DATA_ACTIVE_HIGH;
223
224 - if (ret < 0)
225 + cfg.flags = mbus_config;
226 + ret = sensor_call(pcdev, pad, set_mbus_config, 0, &cfg);
227 + if (ret < 0 && ret != -ENOIOCTLCMD) {
228 + dev_err(pcdev_to_dev(pcdev),
229 + "Failed to call set_mbus_config: %d\n", ret);
230 return ret;
231 + }
232 +
233 + /*
234 + * If the requested media bus configuration has not been fully applied
235 + * make sure it is supported by the platform.
236 + *
237 + * PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering
238 + * roles should match.
239 + */
240 + if (cfg.flags != mbus_config) {
241 + unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER |
242 + V4L2_MBUS_SLAVE);
243 + if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER |
244 + V4L2_MBUS_SLAVE))) {
245 + dev_err(pcdev_to_dev(pcdev),
246 + "Unsupported mbus configuration: bus mastering\n");
247 + return -EINVAL;
248 + }
249
250 - ret = sensor_call(pcdev, video, g_mbus_config, &cfg);
251 - if (!ret) {
252 - common_flags = pxa_mbus_config_compatible(&cfg,
253 - bus_flags);
254 - if (!common_flags) {
255 - dev_warn(pcdev_to_dev(pcdev),
256 - "Flags incompatible: camera 0x%x, host 0x%lx\n",
257 - cfg.flags, bus_flags);
258 + if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
259 + dev_err(pcdev_to_dev(pcdev),
260 + "Unsupported mbus configuration: DATA_ACTIVE_LOW\n");
261 return -EINVAL;
262 }
263 - } else if (ret == -ENOIOCTLCMD) {
264 - ret = 0;
265 }
266
267 - return ret;
268 + pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt);
269 +
270 + return 0;
271 }
272
273 static const struct pxa_mbus_pixelfmt pxa_camera_formats[] = {
274 @@ -1741,11 +1659,6 @@ static int pxa_camera_get_formats(struct
275 return 0;
276 }
277
278 - /* This also checks support for the requested bits-per-sample */
279 - ret = pxa_camera_try_bus_param(pcdev, fmt->bits_per_sample);
280 - if (ret < 0)
281 - return 0;
282 -
283 switch (code.code) {
284 case MEDIA_BUS_FMT_UYVY8_2X8:
285 formats++;