18565a7933af47633332519fff64b462aa3be183
[openwrt/staging/ldir.git] /
1 From 30351afb528e439a48960443c028b6b9c236c55a Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Tue, 23 Jun 2020 15:14:05 +0100
4 Subject: [PATCH] media: bcm2835-unicam: Fixup review comments from
5 Hans.
6
7 Updates the driver based on the upstream review comments from
8 Hans Verkuil at https://patchwork.linuxtv.org/patch/63531/
9
10 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
11 ---
12 drivers/media/platform/bcm2835/Kconfig | 12 ++--
13 .../media/platform/bcm2835/bcm2835-unicam.c | 70 ++++++++-----------
14 2 files changed, 39 insertions(+), 43 deletions(-)
15
16 --- a/drivers/media/platform/bcm2835/Kconfig
17 +++ b/drivers/media/platform/bcm2835/Kconfig
18 @@ -1,15 +1,19 @@
19 # Broadcom VideoCore4 V4L2 camera support
20
21 config VIDEO_BCM2835_UNICAM
22 - tristate "Broadcom BCM2835 Unicam video capture driver"
23 + tristate "Broadcom BCM283x/BCM271x Unicam video capture driver"
24 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
25 depends on ARCH_BCM2835 || COMPILE_TEST
26 select VIDEOBUF2_DMA_CONTIG
27 select V4L2_FWNODE
28 help
29 - Say Y here to enable support for the BCM2835 CSI-2 receiver. This is a
30 - V4L2 driver that controls the CSI-2 receiver directly, independently
31 - from the VC4 firmware.
32 + Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver.
33 + This is a V4L2 driver that controls the CSI-2 receiver directly,
34 + independently from the VC4 firmware.
35 + This driver is mutually exclusive with the use of bcm2835-camera. The
36 + firmware will disable all access to the peripheral from within the
37 + firmware if it finds a DT node using it, and bcm2835-camera will
38 + therefore fail to probe.
39
40 To compile this driver as a module, choose M here. The module will be
41 called bcm2835-unicam.
42 --- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
43 +++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
44 @@ -1,6 +1,6 @@
45 // SPDX-License-Identifier: GPL-2.0-only
46 /*
47 - * BCM2835 Unicam Capture Driver
48 + * BCM283x / BCM271x Unicam Capture Driver
49 *
50 * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
51 *
52 @@ -554,9 +554,8 @@ static const struct unicam_fmt *find_for
53 return NULL;
54 }
55
56 -static inline unsigned int bytes_per_line(u32 width,
57 - const struct unicam_fmt *fmt,
58 - u32 v4l2_fourcc)
59 +static unsigned int bytes_per_line(u32 width, const struct unicam_fmt *fmt,
60 + u32 v4l2_fourcc)
61 {
62 if (v4l2_fourcc == fmt->repacked_fourcc)
63 /* Repacking always goes to 16bpp */
64 @@ -708,7 +707,7 @@ static void unicam_wr_dma_addr(struct un
65 }
66 }
67
68 -static inline unsigned int unicam_get_lines_done(struct unicam_device *dev)
69 +static unsigned int unicam_get_lines_done(struct unicam_device *dev)
70 {
71 dma_addr_t start_addr, cur_addr;
72 unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline;
73 @@ -722,7 +721,7 @@ static inline unsigned int unicam_get_li
74 return (unsigned int)(cur_addr - start_addr) / stride;
75 }
76
77 -static inline void unicam_schedule_next_buffer(struct unicam_node *node)
78 +static void unicam_schedule_next_buffer(struct unicam_node *node)
79 {
80 struct unicam_device *dev = node->dev;
81 struct unicam_buffer *buf;
82 @@ -741,7 +740,7 @@ static inline void unicam_schedule_next_
83 unicam_wr_dma_addr(dev, addr, size, node->pad_id);
84 }
85
86 -static inline void unicam_schedule_dummy_buffer(struct unicam_node *node)
87 +static void unicam_schedule_dummy_buffer(struct unicam_node *node)
88 {
89 struct unicam_device *dev = node->dev;
90
91 @@ -753,8 +752,8 @@ static inline void unicam_schedule_dummy
92 node->next_frm = NULL;
93 }
94
95 -static inline void unicam_process_buffer_complete(struct unicam_node *node,
96 - unsigned int sequence)
97 +static void unicam_process_buffer_complete(struct unicam_node *node,
98 + unsigned int sequence)
99 {
100 node->cur_frm->vb.field = node->m_fmt.field;
101 node->cur_frm->vb.sequence = sequence;
102 @@ -762,16 +761,6 @@ static inline void unicam_process_buffer
103 vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
104 }
105
106 -static bool unicam_all_nodes_streaming(struct unicam_device *dev)
107 -{
108 - bool ret;
109 -
110 - ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming;
111 - ret &= !dev->node[METADATA_PAD].open ||
112 - dev->node[METADATA_PAD].streaming;
113 - return ret;
114 -}
115 -
116 static void unicam_queue_event_sof(struct unicam_device *unicam)
117 {
118 struct v4l2_event event = {
119 @@ -894,8 +883,8 @@ static int unicam_querycap(struct file *
120 struct unicam_node *node = video_drvdata(file);
121 struct unicam_device *dev = node->dev;
122
123 - strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
124 - strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
125 + strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
126 + strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
127
128 snprintf(cap->bus_info, sizeof(cap->bus_info),
129 "platform:%s", dev_name(&dev->pdev->dev));
130 @@ -988,8 +977,8 @@ static int unicam_g_fmt_vid_cap(struct f
131 return 0;
132 }
133
134 -static
135 -const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev)
136 +static const struct unicam_fmt *
137 +get_first_supported_format(struct unicam_device *dev)
138 {
139 struct v4l2_subdev_mbus_code_enum mbus_code;
140 const struct unicam_fmt *fmt = NULL;
141 @@ -1579,7 +1568,8 @@ static void unicam_disable(struct unicam
142 clk_write(dev, 0);
143 }
144
145 -static void unicam_return_buffers(struct unicam_node *node)
146 +static void unicam_return_buffers(struct unicam_node *node,
147 + enum vb2_buffer_state state)
148 {
149 struct unicam_buffer *buf, *tmp;
150 unsigned long flags;
151 @@ -1587,15 +1577,15 @@ static void unicam_return_buffers(struct
152 spin_lock_irqsave(&node->dma_queue_lock, flags);
153 list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) {
154 list_del(&buf->list);
155 - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
156 + vb2_buffer_done(&buf->vb.vb2_buf, state);
157 }
158
159 if (node->cur_frm)
160 vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
161 - VB2_BUF_STATE_ERROR);
162 + state);
163 if (node->next_frm && node->cur_frm != node->next_frm)
164 vb2_buffer_done(&node->next_frm->vb.vb2_buf,
165 - VB2_BUF_STATE_ERROR);
166 + state);
167
168 node->cur_frm = NULL;
169 node->next_frm = NULL;
170 @@ -1612,7 +1602,13 @@ static int unicam_start_streaming(struct
171 int ret;
172
173 node->streaming = true;
174 - if (!unicam_all_nodes_streaming(dev)) {
175 + if (!(dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming &&
176 + (!dev->node[METADATA_PAD].open ||
177 + dev->node[METADATA_PAD].streaming))) {
178 + /*
179 + * Metadata pad must be enabled before image pad if it is
180 + * wanted.
181 + */
182 unicam_dbg(3, dev, "Not all nodes are streaming yet.");
183 return 0;
184 }
185 @@ -1699,7 +1695,7 @@ err_disable_unicam:
186 err_pm_put:
187 unicam_runtime_put(dev);
188 err_streaming:
189 - unicam_return_buffers(node);
190 + unicam_return_buffers(node, VB2_BUF_STATE_QUEUED);
191 node->streaming = false;
192
193 return ret;
194 @@ -1736,7 +1732,7 @@ static void unicam_stop_streaming(struct
195 }
196
197 /* Clear all queued buffers for the node */
198 - unicam_return_buffers(node);
199 + unicam_return_buffers(node, VB2_BUF_STATE_ERROR);
200 }
201
202 static int unicam_enum_input(struct file *file, void *priv,
203 @@ -1754,14 +1750,13 @@ static int unicam_enum_input(struct file
204 inp->std = 0;
205 } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) {
206 inp->capabilities = V4L2_IN_CAP_STD;
207 - if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std)
208 - < 0)
209 + if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) < 0)
210 inp->std = V4L2_STD_ALL;
211 } else {
212 inp->capabilities = 0;
213 inp->std = 0;
214 }
215 - sprintf(inp->name, "Camera 0");
216 + snprintf(inp->name, sizeof(inp->name), "Camera 0");
217 return 0;
218 }
219
220 @@ -1984,6 +1979,9 @@ static int unicam_s_dv_timings(struct fi
221 ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings,
222 &current_timings);
223
224 + if (ret < 0)
225 + return ret;
226 +
227 if (v4l2_match_dv_timings(timings, &current_timings, 0, false))
228 return 0;
229
230 @@ -2414,12 +2412,6 @@ static int register_node(struct unicam_d
231 unicam_err(unicam, "Unable to allocate dummy buffer.\n");
232 return -ENOMEM;
233 }
234 -
235 - if (pad_id == METADATA_PAD) {
236 - v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT);
237 - v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT);
238 - v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT);
239 - }
240 if (pad_id == METADATA_PAD ||
241 !v4l2_subdev_has_op(unicam->sensor, video, s_std)) {
242 v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD);