1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Video for Linux Two 4 * 5 * A generic video device interface for the LINUX operating system 6 * using a set of device structures/vectors for low level operations. 7 * 8 * This file replaces the videodev.c file that comes with the 9 * regular kernel distribution. 10 * 11 * Author: Bill Dirks <bill@thedirks.org> 12 * based on code by Alan Cox, <alan@cymru.net> 13 */ 14 15 /* 16 * Video capture interface for Linux 17 * 18 * A generic video device interface for the LINUX operating system 19 * using a set of device structures/vectors for low level operations. 20 * 21 * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk> 22 * 23 * Fixes: 24 */ 25 26 /* 27 * Video4linux 1/2 integration by Justin Schoeman 28 * <justin@suntiger.ee.up.ac.za> 29 * 2.4 PROCFS support ported from 2.4 kernels by 30 * Iñaki García Etxebarria <garetxe@euskalnet.net> 31 * Makefile fix by "W. Michael Petullo" <mike@flyn.org> 32 * 2.4 devfs support ported from 2.4 kernels by 33 * Dan Merillat <dan@merillat.org> 34 * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman) 35 */ 36 37 #include <linux/clk.h> 38 #include <linux/clkdev.h> 39 #include <linux/clk-provider.h> 40 #include <linux/module.h> 41 #include <linux/types.h> 42 #include <linux/kernel.h> 43 #include <linux/mm.h> 44 #include <linux/string.h> 45 #include <linux/errno.h> 46 #include <linux/uaccess.h> 47 #include <asm/io.h> 48 #include <asm/div64.h> 49 #include <media/v4l2-common.h> 50 #include <media/v4l2-device.h> 51 #include <media/v4l2-ctrls.h> 52 53 #include <linux/videodev2.h> 54 55 /* 56 * 57 * V 4 L 2 D R I V E R H E L P E R A P I 58 * 59 */ 60 61 /* 62 * Video Standard Operations (contributed by Michael Schimek) 63 */ 64 65 /* Helper functions for control handling */ 66 67 /* Fill in a struct v4l2_queryctrl */ 68 int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _step, s32 _def) 69 { 70 const char *name; 71 s64 min = _min; 72 s64 max = _max; 73 u64 step = _step; 74 s64 def = _def; 75 76 v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type, 77 &min, &max, &step, &def, &qctrl->flags); 78 79 if (name == NULL) 80 return -EINVAL; 81 82 qctrl->minimum = min; 83 qctrl->maximum = max; 84 qctrl->step = step; 85 qctrl->default_value = def; 86 qctrl->reserved[0] = qctrl->reserved[1] = 0; 87 strscpy(qctrl->name, name, sizeof(qctrl->name)); 88 return 0; 89 } 90 EXPORT_SYMBOL(v4l2_ctrl_query_fill); 91 92 /* Clamp x to be between min and max, aligned to a multiple of 2^align. min 93 * and max don't have to be aligned, but there must be at least one valid 94 * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples 95 * of 16 between 17 and 31. */ 96 static unsigned int clamp_align(unsigned int x, unsigned int min, 97 unsigned int max, unsigned int align) 98 { 99 /* Bits that must be zero to be aligned */ 100 unsigned int mask = ~((1 << align) - 1); 101 102 /* Clamp to aligned min and max */ 103 x = clamp(x, (min + ~mask) & mask, max & mask); 104 105 /* Round to nearest aligned value */ 106 if (align) 107 x = (x + (1 << (align - 1))) & mask; 108 109 return x; 110 } 111 112 static unsigned int clamp_roundup(unsigned int x, unsigned int min, 113 unsigned int max, unsigned int alignment) 114 { 115 x = clamp(x, min, max); 116 if (alignment) 117 x = round_up(x, alignment); 118 119 return x; 120 } 121 122 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax, 123 unsigned int walign, 124 u32 *h, unsigned int hmin, unsigned int hmax, 125 unsigned int halign, unsigned int salign) 126 { 127 *w = clamp_align(*w, wmin, wmax, walign); 128 *h = clamp_align(*h, hmin, hmax, halign); 129 130 /* Usually we don't need to align the size and are done now. */ 131 if (!salign) 132 return; 133 134 /* How much alignment do we have? */ 135 walign = __ffs(*w); 136 halign = __ffs(*h); 137 /* Enough to satisfy the image alignment? */ 138 if (walign + halign < salign) { 139 /* Max walign where there is still a valid width */ 140 unsigned int wmaxa = __fls(wmax ^ (wmin - 1)); 141 /* Max halign where there is still a valid height */ 142 unsigned int hmaxa = __fls(hmax ^ (hmin - 1)); 143 144 /* up the smaller alignment until we have enough */ 145 do { 146 if (halign >= hmaxa || 147 (walign <= halign && walign < wmaxa)) { 148 *w = clamp_align(*w, wmin, wmax, walign + 1); 149 walign = __ffs(*w); 150 } else { 151 *h = clamp_align(*h, hmin, hmax, halign + 1); 152 halign = __ffs(*h); 153 } 154 } while (halign + walign < salign); 155 } 156 } 157 EXPORT_SYMBOL_GPL(v4l_bound_align_image); 158 159 const void * 160 __v4l2_find_nearest_size_conditional(const void *array, size_t array_size, 161 size_t entry_size, size_t width_offset, 162 size_t height_offset, s32 width, 163 s32 height, 164 bool (*func)(const void *array, 165 size_t index, 166 const void *context), 167 const void *context) 168 { 169 u32 error, min_error = U32_MAX; 170 const void *best = NULL; 171 size_t i; 172 173 if (!array) 174 return NULL; 175 176 for (i = 0; i < array_size; i++, array += entry_size) { 177 const u32 *entry_width = array + width_offset; 178 const u32 *entry_height = array + height_offset; 179 180 if (func && !func(array, i, context)) 181 continue; 182 183 error = abs(*entry_width - width) + abs(*entry_height - height); 184 if (error > min_error) 185 continue; 186 187 min_error = error; 188 best = array; 189 if (!error) 190 break; 191 } 192 193 return best; 194 } 195 EXPORT_SYMBOL_GPL(__v4l2_find_nearest_size_conditional); 196 197 int v4l2_g_parm_cap(struct video_device *vdev, 198 struct v4l2_subdev *sd, struct v4l2_streamparm *a) 199 { 200 struct v4l2_subdev_frame_interval ival = { 0 }; 201 int ret; 202 203 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 204 a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 205 return -EINVAL; 206 207 if (vdev->device_caps & V4L2_CAP_READWRITE) 208 a->parm.capture.readbuffers = 2; 209 if (v4l2_subdev_has_op(sd, pad, get_frame_interval)) 210 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 211 ret = v4l2_subdev_call_state_active(sd, pad, get_frame_interval, &ival); 212 if (!ret) 213 a->parm.capture.timeperframe = ival.interval; 214 return ret; 215 } 216 EXPORT_SYMBOL_GPL(v4l2_g_parm_cap); 217 218 int v4l2_s_parm_cap(struct video_device *vdev, 219 struct v4l2_subdev *sd, struct v4l2_streamparm *a) 220 { 221 struct v4l2_subdev_frame_interval ival = { 222 .interval = a->parm.capture.timeperframe 223 }; 224 int ret; 225 226 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 227 a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 228 return -EINVAL; 229 230 memset(&a->parm, 0, sizeof(a->parm)); 231 if (vdev->device_caps & V4L2_CAP_READWRITE) 232 a->parm.capture.readbuffers = 2; 233 else 234 a->parm.capture.readbuffers = 0; 235 236 if (v4l2_subdev_has_op(sd, pad, get_frame_interval)) 237 a->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 238 ret = v4l2_subdev_call_state_active(sd, pad, set_frame_interval, &ival); 239 if (!ret) 240 a->parm.capture.timeperframe = ival.interval; 241 return ret; 242 } 243 EXPORT_SYMBOL_GPL(v4l2_s_parm_cap); 244 245 const struct v4l2_format_info *v4l2_format_info(u32 format) 246 { 247 static const struct v4l2_format_info formats[] = { 248 /* RGB formats */ 249 { .format = V4L2_PIX_FMT_BGR24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 250 { .format = V4L2_PIX_FMT_RGB24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 251 { .format = V4L2_PIX_FMT_HSV24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 252 { .format = V4L2_PIX_FMT_BGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 253 { .format = V4L2_PIX_FMT_XBGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 254 { .format = V4L2_PIX_FMT_BGRX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 255 { .format = V4L2_PIX_FMT_RGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 256 { .format = V4L2_PIX_FMT_XRGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 257 { .format = V4L2_PIX_FMT_RGBX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 258 { .format = V4L2_PIX_FMT_HSV32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 259 { .format = V4L2_PIX_FMT_ARGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 260 { .format = V4L2_PIX_FMT_RGBA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 261 { .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 262 { .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 263 { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 264 { .format = V4L2_PIX_FMT_RGB565X, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 265 { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 266 { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 267 { .format = V4L2_PIX_FMT_BGR48_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 268 { .format = V4L2_PIX_FMT_BGR48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 269 { .format = V4L2_PIX_FMT_RGB48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 270 { .format = V4L2_PIX_FMT_ABGR64_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 271 { .format = V4L2_PIX_FMT_RGBA1010102, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 272 { .format = V4L2_PIX_FMT_RGBX1010102, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 273 { .format = V4L2_PIX_FMT_ARGB2101010, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 274 275 /* YUV packed formats */ 276 { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 277 { .format = V4L2_PIX_FMT_YVYU, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 278 { .format = V4L2_PIX_FMT_UYVY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 279 { .format = V4L2_PIX_FMT_VYUY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 280 { .format = V4L2_PIX_FMT_Y210, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 281 { .format = V4L2_PIX_FMT_Y212, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 282 { .format = V4L2_PIX_FMT_Y216, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 283 { .format = V4L2_PIX_FMT_YUV48_12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 284 { .format = V4L2_PIX_FMT_MT2110T, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2, 285 .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }}, 286 { .format = V4L2_PIX_FMT_MT2110R, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2, 287 .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }}, 288 289 /* YUV planar formats */ 290 { .format = V4L2_PIX_FMT_NV12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 291 { .format = V4L2_PIX_FMT_NV21, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 292 { .format = V4L2_PIX_FMT_NV15, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 293 { .format = V4L2_PIX_FMT_NV16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 294 { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 295 { .format = V4L2_PIX_FMT_NV20, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 296 { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 297 { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 298 { .format = V4L2_PIX_FMT_P010, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 299 { .format = V4L2_PIX_FMT_P012, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 300 301 { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 4 }, 302 { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 4 }, 303 { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 4, .vdiv = 1 }, 304 { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 305 { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 306 { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 307 { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 308 309 /* Tiled YUV formats */ 310 { .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 311 { .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2, 312 .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 }}, 313 { .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 314 315 /* YUV planar formats, non contiguous variant */ 316 { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 317 { .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 318 { .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 319 { .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 320 { .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 321 { .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 322 323 { .format = V4L2_PIX_FMT_NV12M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 324 { .format = V4L2_PIX_FMT_NV21M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 325 { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 326 { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 }, 327 { .format = V4L2_PIX_FMT_P012M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 }, 328 329 /* Tiled YUV formats, non contiguous variant */ 330 { .format = V4L2_PIX_FMT_NV12MT, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2, 331 .block_w = { 64, 32, 0, 0 }, .block_h = { 32, 16, 0, 0 }}, 332 { .format = V4L2_PIX_FMT_NV12MT_16X16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2, 333 .block_w = { 16, 8, 0, 0 }, .block_h = { 16, 8, 0, 0 }}, 334 335 /* Bayer RGB formats */ 336 { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 337 { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 338 { .format = V4L2_PIX_FMT_SGRBG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 339 { .format = V4L2_PIX_FMT_SRGGB8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 340 { .format = V4L2_PIX_FMT_SBGGR10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 341 { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 342 { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 343 { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 344 { .format = V4L2_PIX_FMT_SBGGR10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 345 { .format = V4L2_PIX_FMT_SGBRG10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 346 { .format = V4L2_PIX_FMT_SGRBG10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 347 { .format = V4L2_PIX_FMT_SRGGB10P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 5, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 348 { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 349 { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 350 { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 351 { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 352 { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 353 { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 354 { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 355 { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 356 { .format = V4L2_PIX_FMT_SBGGR12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 357 { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 358 { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 359 { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 360 { .format = V4L2_PIX_FMT_SBGGR12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 361 { .format = V4L2_PIX_FMT_SGBRG12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 362 { .format = V4L2_PIX_FMT_SGRBG12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 363 { .format = V4L2_PIX_FMT_SRGGB12P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .bpp_div = { 2, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 364 { .format = V4L2_PIX_FMT_SBGGR14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 365 { .format = V4L2_PIX_FMT_SGBRG14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 366 { .format = V4L2_PIX_FMT_SGRBG14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 367 { .format = V4L2_PIX_FMT_SRGGB14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 368 { .format = V4L2_PIX_FMT_SBGGR14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 369 { .format = V4L2_PIX_FMT_SGBRG14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 370 { .format = V4L2_PIX_FMT_SGRBG14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 371 { .format = V4L2_PIX_FMT_SRGGB14P, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 7, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 372 { .format = V4L2_PIX_FMT_SBGGR16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 373 { .format = V4L2_PIX_FMT_SGBRG16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 374 { .format = V4L2_PIX_FMT_SGRBG16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 375 { .format = V4L2_PIX_FMT_SRGGB16, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 376 377 /* Renesas Camera Data Receiver Unit formats, bayer order agnostic */ 378 { .format = V4L2_PIX_FMT_RAW_CRU10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 6, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 379 { .format = V4L2_PIX_FMT_RAW_CRU12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 5, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 380 { .format = V4L2_PIX_FMT_RAW_CRU14, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 4, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 381 { .format = V4L2_PIX_FMT_RAW_CRU20, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 3, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 }, 382 }; 383 unsigned int i; 384 385 for (i = 0; i < ARRAY_SIZE(formats); ++i) 386 if (formats[i].format == format) 387 return &formats[i]; 388 return NULL; 389 } 390 EXPORT_SYMBOL(v4l2_format_info); 391 392 static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane) 393 { 394 if (!info->block_w[plane]) 395 return 1; 396 return info->block_w[plane]; 397 } 398 399 static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane) 400 { 401 if (!info->block_h[plane]) 402 return 1; 403 return info->block_h[plane]; 404 } 405 406 static inline unsigned int v4l2_format_plane_stride(const struct v4l2_format_info *info, int plane, 407 unsigned int width) 408 { 409 unsigned int hdiv = plane ? info->hdiv : 1; 410 unsigned int aligned_width = 411 ALIGN(width, v4l2_format_block_width(info, plane)); 412 413 return DIV_ROUND_UP(aligned_width, hdiv) * 414 info->bpp[plane] / info->bpp_div[plane]; 415 } 416 417 static inline unsigned int v4l2_format_plane_height(const struct v4l2_format_info *info, int plane, 418 unsigned int height) 419 { 420 unsigned int vdiv = plane ? info->vdiv : 1; 421 unsigned int aligned_height = 422 ALIGN(height, v4l2_format_block_height(info, plane)); 423 424 return DIV_ROUND_UP(aligned_height, vdiv); 425 } 426 427 static inline unsigned int v4l2_format_plane_size(const struct v4l2_format_info *info, int plane, 428 unsigned int width, unsigned int height) 429 { 430 return v4l2_format_plane_stride(info, plane, width) * 431 v4l2_format_plane_height(info, plane, height); 432 } 433 434 void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, 435 const struct v4l2_frmsize_stepwise *frmsize) 436 { 437 if (!frmsize) 438 return; 439 440 /* 441 * Clamp width/height to meet min/max constraints and round it up to 442 * macroblock alignment. 443 */ 444 *width = clamp_roundup(*width, frmsize->min_width, frmsize->max_width, 445 frmsize->step_width); 446 *height = clamp_roundup(*height, frmsize->min_height, frmsize->max_height, 447 frmsize->step_height); 448 } 449 EXPORT_SYMBOL_GPL(v4l2_apply_frmsize_constraints); 450 451 int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, 452 u32 pixelformat, u32 width, u32 height) 453 { 454 const struct v4l2_format_info *info; 455 struct v4l2_plane_pix_format *plane; 456 int i; 457 458 info = v4l2_format_info(pixelformat); 459 if (!info) 460 return -EINVAL; 461 462 pixfmt->width = width; 463 pixfmt->height = height; 464 pixfmt->pixelformat = pixelformat; 465 pixfmt->num_planes = info->mem_planes; 466 467 if (info->mem_planes == 1) { 468 plane = &pixfmt->plane_fmt[0]; 469 plane->bytesperline = v4l2_format_plane_stride(info, 0, width); 470 plane->sizeimage = 0; 471 472 for (i = 0; i < info->comp_planes; i++) 473 plane->sizeimage += 474 v4l2_format_plane_size(info, i, width, height); 475 } else { 476 for (i = 0; i < info->comp_planes; i++) { 477 plane = &pixfmt->plane_fmt[i]; 478 plane->bytesperline = 479 v4l2_format_plane_stride(info, i, width); 480 plane->sizeimage = plane->bytesperline * 481 v4l2_format_plane_height(info, i, height); 482 } 483 } 484 return 0; 485 } 486 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp); 487 488 int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, 489 u32 width, u32 height) 490 { 491 const struct v4l2_format_info *info; 492 int i; 493 494 info = v4l2_format_info(pixelformat); 495 if (!info) 496 return -EINVAL; 497 498 /* Single planar API cannot be used for multi plane formats. */ 499 if (info->mem_planes > 1) 500 return -EINVAL; 501 502 pixfmt->width = width; 503 pixfmt->height = height; 504 pixfmt->pixelformat = pixelformat; 505 pixfmt->bytesperline = v4l2_format_plane_stride(info, 0, width); 506 pixfmt->sizeimage = 0; 507 508 for (i = 0; i < info->comp_planes; i++) 509 pixfmt->sizeimage += 510 v4l2_format_plane_size(info, i, width, height); 511 return 0; 512 } 513 EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); 514 515 #ifdef CONFIG_MEDIA_CONTROLLER 516 static s64 v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, 517 unsigned int mul, unsigned int div) 518 { 519 struct v4l2_ctrl *ctrl; 520 s64 freq; 521 522 ctrl = v4l2_ctrl_find(handler, V4L2_CID_LINK_FREQ); 523 if (ctrl) { 524 struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ }; 525 int ret; 526 527 qm.index = v4l2_ctrl_g_ctrl(ctrl); 528 529 ret = v4l2_querymenu(handler, &qm); 530 if (ret) 531 return -ENOENT; 532 533 freq = qm.value; 534 } else { 535 if (!mul || !div) 536 return -ENOENT; 537 538 ctrl = v4l2_ctrl_find(handler, V4L2_CID_PIXEL_RATE); 539 if (!ctrl) 540 return -ENOENT; 541 542 freq = div_u64(v4l2_ctrl_g_ctrl_int64(ctrl) * mul, div); 543 544 pr_warn_once("%s: Link frequency estimated using pixel rate: result might be inaccurate\n", 545 __func__); 546 pr_warn_once("%s: Consider implementing support for V4L2_CID_LINK_FREQ in the transmitter driver\n", 547 __func__); 548 } 549 550 return freq > 0 ? freq : -EINVAL; 551 } 552 553 s64 v4l2_get_link_freq(const struct media_pad *pad, unsigned int mul, 554 unsigned int div) 555 { 556 struct v4l2_mbus_config mbus_config = {}; 557 struct v4l2_subdev *sd; 558 int ret; 559 560 sd = media_entity_to_v4l2_subdev(pad->entity); 561 ret = v4l2_subdev_call(sd, pad, get_mbus_config, pad->index, 562 &mbus_config); 563 if (ret < 0 && ret != -ENOIOCTLCMD) 564 return ret; 565 566 if (mbus_config.link_freq) 567 return mbus_config.link_freq; 568 569 /* 570 * Fall back to using the link frequency control if the media bus config 571 * doesn't provide a link frequency. 572 */ 573 return v4l2_get_link_freq_ctrl(sd->ctrl_handler, mul, div); 574 } 575 EXPORT_SYMBOL_GPL(v4l2_get_link_freq); 576 #endif 577 578 /* 579 * Simplify a fraction using a simple continued fraction decomposition. The 580 * idea here is to convert fractions such as 333333/10000000 to 1/30 using 581 * 32 bit arithmetic only. The algorithm is not perfect and relies upon two 582 * arbitrary parameters to remove non-significative terms from the simple 583 * continued fraction decomposition. Using 8 and 333 for n_terms and threshold 584 * respectively seems to give nice results. 585 */ 586 void v4l2_simplify_fraction(u32 *numerator, u32 *denominator, 587 unsigned int n_terms, unsigned int threshold) 588 { 589 u32 *an; 590 u32 x, y, r; 591 unsigned int i, n; 592 593 an = kmalloc_array(n_terms, sizeof(*an), GFP_KERNEL); 594 if (an == NULL) 595 return; 596 597 /* 598 * Convert the fraction to a simple continued fraction. See 599 * https://en.wikipedia.org/wiki/Continued_fraction 600 * Stop if the current term is bigger than or equal to the given 601 * threshold. 602 */ 603 x = *numerator; 604 y = *denominator; 605 606 for (n = 0; n < n_terms && y != 0; ++n) { 607 an[n] = x / y; 608 if (an[n] >= threshold) { 609 if (n < 2) 610 n++; 611 break; 612 } 613 614 r = x - an[n] * y; 615 x = y; 616 y = r; 617 } 618 619 /* Expand the simple continued fraction back to an integer fraction. */ 620 x = 0; 621 y = 1; 622 623 for (i = n; i > 0; --i) { 624 r = y; 625 y = an[i-1] * y + x; 626 x = r; 627 } 628 629 *numerator = y; 630 *denominator = x; 631 kfree(an); 632 } 633 EXPORT_SYMBOL_GPL(v4l2_simplify_fraction); 634 635 /* 636 * Convert a fraction to a frame interval in 100ns multiples. The idea here is 637 * to compute numerator / denominator * 10000000 using 32 bit fixed point 638 * arithmetic only. 639 */ 640 u32 v4l2_fraction_to_interval(u32 numerator, u32 denominator) 641 { 642 u32 multiplier; 643 644 /* Saturate the result if the operation would overflow. */ 645 if (denominator == 0 || 646 numerator/denominator >= ((u32)-1)/10000000) 647 return (u32)-1; 648 649 /* 650 * Divide both the denominator and the multiplier by two until 651 * numerator * multiplier doesn't overflow. If anyone knows a better 652 * algorithm please let me know. 653 */ 654 multiplier = 10000000; 655 while (numerator > ((u32)-1)/multiplier) { 656 multiplier /= 2; 657 denominator /= 2; 658 } 659 660 return denominator ? numerator * multiplier / denominator : 0; 661 } 662 EXPORT_SYMBOL_GPL(v4l2_fraction_to_interval); 663 664 int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, 665 unsigned int num_of_fw_link_freqs, 666 const s64 *driver_link_freqs, 667 unsigned int num_of_driver_link_freqs, 668 unsigned long *bitmap) 669 { 670 unsigned int i; 671 672 *bitmap = 0; 673 674 if (!num_of_fw_link_freqs) { 675 dev_err(dev, "no link frequencies in firmware\n"); 676 return -ENODATA; 677 } 678 679 for (i = 0; i < num_of_fw_link_freqs; i++) { 680 unsigned int j; 681 682 for (j = 0; j < num_of_driver_link_freqs; j++) { 683 if (fw_link_freqs[i] != driver_link_freqs[j]) 684 continue; 685 686 dev_dbg(dev, "enabling link frequency %lld Hz\n", 687 driver_link_freqs[j]); 688 *bitmap |= BIT(j); 689 break; 690 } 691 } 692 693 if (!*bitmap) { 694 dev_err(dev, "no matching link frequencies found\n"); 695 696 dev_dbg(dev, "specified in firmware:\n"); 697 for (i = 0; i < num_of_fw_link_freqs; i++) 698 dev_dbg(dev, "\t%llu Hz\n", fw_link_freqs[i]); 699 700 dev_dbg(dev, "driver supported:\n"); 701 for (i = 0; i < num_of_driver_link_freqs; i++) 702 dev_dbg(dev, "\t%lld Hz\n", driver_link_freqs[i]); 703 704 return -ENOENT; 705 } 706 707 return 0; 708 } 709 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap); 710 711 struct clk *__devm_v4l2_sensor_clk_get(struct device *dev, const char *id, 712 bool legacy, bool fixed_rate, 713 unsigned long clk_rate) 714 { 715 bool of_node = is_of_node(dev_fwnode(dev)); 716 const char *clk_id __free(kfree) = NULL; 717 struct clk_hw *clk_hw; 718 struct clk *clk; 719 u32 rate = clk_rate; 720 int ret = 0; 721 722 clk = devm_clk_get_optional(dev, id); 723 if (IS_ERR(clk)) 724 return clk; 725 726 /* 727 * If the caller didn't request a fixed rate, retrieve it from the 728 * clock-frequency property. -EINVAL indicates the property is absent, 729 * and is not a failure. Other errors, or success with a clock-frequency 730 * value of 0, are hard failures. 731 */ 732 if (!fixed_rate || !clk_rate) { 733 ret = device_property_read_u32(dev, "clock-frequency", &rate); 734 if ((ret && ret != -EINVAL) || (!ret && !rate)) 735 return ERR_PTR(-EINVAL); 736 } 737 738 if (clk) { 739 /* 740 * On non-OF platforms, or when legacy behaviour is requested, 741 * set the clock rate if a rate has been specified by the caller 742 * or by the clock-frequency property. 743 */ 744 if (rate && (!of_node || legacy)) { 745 ret = clk_set_rate(clk, rate); 746 if (ret) { 747 dev_err(dev, "Failed to set clock rate: %u\n", 748 rate); 749 return ERR_PTR(ret); 750 } 751 } 752 return clk; 753 } 754 755 /* 756 * Register a dummy fixed clock on non-OF platforms or when legacy 757 * behaviour is requested. This required the common clock framework. 758 */ 759 if (!IS_ENABLED(CONFIG_COMMON_CLK) || (of_node && !legacy)) 760 return ERR_PTR(-ENOENT); 761 762 /* We need a rate to create a clock. */ 763 if (ret) 764 return ERR_PTR(ret == -EINVAL ? -EPROBE_DEFER : ret); 765 766 if (!id) { 767 clk_id = kasprintf(GFP_KERNEL, "clk-%s", dev_name(dev)); 768 if (!clk_id) 769 return ERR_PTR(-ENOMEM); 770 id = clk_id; 771 } 772 773 clk_hw = devm_clk_hw_register_fixed_rate(dev, id, NULL, 0, rate); 774 if (IS_ERR(clk_hw)) 775 return ERR_CAST(clk_hw); 776 777 return clk_hw->clk; 778 } 779 EXPORT_SYMBOL_GPL(__devm_v4l2_sensor_clk_get); 780