2 * SoC-camera host driver for Renesas R-Car VIN unit
4 * Copyright (C) 2011-2013 Renesas Solutions Corp.
5 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7 * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
9 * Copyright (C) 2008 Magnus Damm
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.
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
23 #include <linux/of_device.h>
24 #include <linux/platform_data/camera-rcar.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/slab.h>
28 #include <linux/videodev2.h>
30 #include <media/soc_camera.h>
31 #include <media/soc_mediabus.h>
32 #include <media/v4l2-common.h>
33 #include <media/v4l2-dev.h>
34 #include <media/v4l2-device.h>
35 #include <media/v4l2-mediabus.h>
36 #include <media/v4l2-of.h>
37 #include <media/v4l2-subdev.h>
38 #include <media/videobuf2-dma-contig.h>
40 #include "soc_scale_crop.h"
42 #define DRV_NAME "rcar_vin"
44 /* Register offsets for R-Car VIN */
45 #define VNMC_REG 0x00 /* Video n Main Control Register */
46 #define VNMS_REG 0x04 /* Video n Module Status Register */
47 #define VNFC_REG 0x08 /* Video n Frame Capture Register */
48 #define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */
49 #define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */
50 #define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */
51 #define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */
52 #define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */
53 #define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */
54 #define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */
55 #define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */
56 #define VNIS_REG 0x2C /* Video n Image Stride Register */
57 #define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
58 #define VNIE_REG 0x40 /* Video n Interrupt Enable Register */
59 #define VNINTS_REG 0x44 /* Video n Interrupt Status Register */
60 #define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */
61 #define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */
62 #define VNYS_REG 0x50 /* Video n Y Scale Register */
63 #define VNXS_REG 0x54 /* Video n X Scale Register */
64 #define VNDMR_REG 0x58 /* Video n Data Mode Register */
65 #define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */
66 #define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */
67 #define VNC1A_REG 0x80 /* Video n Coefficient Set C1A Register */
68 #define VNC1B_REG 0x84 /* Video n Coefficient Set C1B Register */
69 #define VNC1C_REG 0x88 /* Video n Coefficient Set C1C Register */
70 #define VNC2A_REG 0x90 /* Video n Coefficient Set C2A Register */
71 #define VNC2B_REG 0x94 /* Video n Coefficient Set C2B Register */
72 #define VNC2C_REG 0x98 /* Video n Coefficient Set C2C Register */
73 #define VNC3A_REG 0xA0 /* Video n Coefficient Set C3A Register */
74 #define VNC3B_REG 0xA4 /* Video n Coefficient Set C3B Register */
75 #define VNC3C_REG 0xA8 /* Video n Coefficient Set C3C Register */
76 #define VNC4A_REG 0xB0 /* Video n Coefficient Set C4A Register */
77 #define VNC4B_REG 0xB4 /* Video n Coefficient Set C4B Register */
78 #define VNC4C_REG 0xB8 /* Video n Coefficient Set C4C Register */
79 #define VNC5A_REG 0xC0 /* Video n Coefficient Set C5A Register */
80 #define VNC5B_REG 0xC4 /* Video n Coefficient Set C5B Register */
81 #define VNC5C_REG 0xC8 /* Video n Coefficient Set C5C Register */
82 #define VNC6A_REG 0xD0 /* Video n Coefficient Set C6A Register */
83 #define VNC6B_REG 0xD4 /* Video n Coefficient Set C6B Register */
84 #define VNC6C_REG 0xD8 /* Video n Coefficient Set C6C Register */
85 #define VNC7A_REG 0xE0 /* Video n Coefficient Set C7A Register */
86 #define VNC7B_REG 0xE4 /* Video n Coefficient Set C7B Register */
87 #define VNC7C_REG 0xE8 /* Video n Coefficient Set C7C Register */
88 #define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */
89 #define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */
90 #define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */
92 /* Register bit fields for R-Car VIN */
93 /* Video n Main Control Register bits */
94 #define VNMC_FOC (1 << 21)
95 #define VNMC_YCAL (1 << 19)
96 #define VNMC_INF_YUV8_BT656 (0 << 16)
97 #define VNMC_INF_YUV8_BT601 (1 << 16)
98 #define VNMC_INF_YUV10_BT656 (2 << 16)
99 #define VNMC_INF_YUV10_BT601 (3 << 16)
100 #define VNMC_INF_YUV16 (5 << 16)
101 #define VNMC_VUP (1 << 10)
102 #define VNMC_IM_ODD (0 << 3)
103 #define VNMC_IM_ODD_EVEN (1 << 3)
104 #define VNMC_IM_EVEN (2 << 3)
105 #define VNMC_IM_FULL (3 << 3)
106 #define VNMC_BPS (1 << 1)
107 #define VNMC_ME (1 << 0)
109 /* Video n Module Status Register bits */
110 #define VNMS_FBS_MASK (3 << 3)
111 #define VNMS_FBS_SHIFT 3
112 #define VNMS_AV (1 << 1)
113 #define VNMS_CA (1 << 0)
115 /* Video n Frame Capture Register bits */
116 #define VNFC_C_FRAME (1 << 1)
117 #define VNFC_S_FRAME (1 << 0)
119 /* Video n Interrupt Enable Register bits */
120 #define VNIE_FIE (1 << 4)
121 #define VNIE_EFE (1 << 1)
123 /* Video n Data Mode Register bits */
124 #define VNDMR_EXRGB (1 << 8)
125 #define VNDMR_BPSM (1 << 4)
126 #define VNDMR_DTMD_YCSEP (1 << 1)
127 #define VNDMR_DTMD_ARGB1555 (1 << 0)
129 /* Video n Data Mode Register 2 bits */
130 #define VNDMR2_VPS (1 << 30)
131 #define VNDMR2_HPS (1 << 29)
132 #define VNDMR2_FTEV (1 << 17)
133 #define VNDMR2_VLV(n) ((n & 0xf) << 12)
135 #define VIN_MAX_WIDTH 2048
136 #define VIN_MAX_HEIGHT 2048
138 #define TIMEOUT_MS 100
148 unsigned short xs_value;
152 static const struct vin_coeff vin_coeff_set[] = {
154 0x00000000, 0x00000000, 0x00000000,
155 0x00000000, 0x00000000, 0x00000000,
156 0x00000000, 0x00000000, 0x00000000,
157 0x00000000, 0x00000000, 0x00000000,
158 0x00000000, 0x00000000, 0x00000000,
159 0x00000000, 0x00000000, 0x00000000,
160 0x00000000, 0x00000000, 0x00000000,
161 0x00000000, 0x00000000, 0x00000000 },
164 0x000fa400, 0x000fa400, 0x09625902,
165 0x000003f8, 0x00000403, 0x3de0d9f0,
166 0x001fffed, 0x00000804, 0x3cc1f9c3,
167 0x001003de, 0x00000c01, 0x3cb34d7f,
168 0x002003d2, 0x00000c00, 0x3d24a92d,
169 0x00200bca, 0x00000bff, 0x3df600d2,
170 0x002013cc, 0x000007ff, 0x3ed70c7e,
171 0x00100fde, 0x00000000, 0x3f87c036 },
174 0x002ffff1, 0x002ffff1, 0x02a0a9c8,
175 0x002003e7, 0x001ffffa, 0x000185bc,
176 0x002007dc, 0x000003ff, 0x3e52859c,
177 0x00200bd4, 0x00000002, 0x3d53996b,
178 0x00100fd0, 0x00000403, 0x3d04ad2d,
179 0x00000bd5, 0x00000403, 0x3d35ace7,
180 0x3ff003e4, 0x00000801, 0x3dc674a1,
181 0x3fffe800, 0x00000800, 0x3e76f461 },
184 0x00100be3, 0x00100be3, 0x04d1359a,
185 0x00000fdb, 0x002003ed, 0x0211fd93,
186 0x00000fd6, 0x002003f4, 0x0002d97b,
187 0x000007d6, 0x002ffffb, 0x3e93b956,
188 0x3ff003da, 0x001003ff, 0x3db49926,
189 0x3fffefe9, 0x00100001, 0x3d655cee,
190 0x3fffd400, 0x00000003, 0x3d65f4b6,
191 0x000fb421, 0x00000402, 0x3dc6547e },
194 0x00000bdd, 0x00000bdd, 0x06519578,
195 0x3ff007da, 0x00000be3, 0x03c24973,
196 0x3ff003d9, 0x00000be9, 0x01b30d5f,
197 0x3ffff7df, 0x001003f1, 0x0003c542,
198 0x000fdfec, 0x001003f7, 0x3ec4711d,
199 0x000fc400, 0x002ffffd, 0x3df504f1,
200 0x001fa81a, 0x002ffc00, 0x3d957cc2,
201 0x002f8c3c, 0x00100000, 0x3db5c891 },
204 0x3ff003dc, 0x3ff003dc, 0x0791e558,
205 0x000ff7dd, 0x3ff007de, 0x05328554,
206 0x000fe7e3, 0x3ff00be2, 0x03232546,
207 0x000fd7ee, 0x000007e9, 0x0143bd30,
208 0x001fb800, 0x000007ee, 0x00044511,
209 0x002fa015, 0x000007f4, 0x3ef4bcee,
210 0x002f8832, 0x001003f9, 0x3e4514c7,
211 0x001f7853, 0x001003fd, 0x3de54c9f },
214 0x000fefe0, 0x000fefe0, 0x08721d3c,
215 0x001fdbe7, 0x000ffbde, 0x0652a139,
216 0x001fcbf0, 0x000003df, 0x0463292e,
217 0x002fb3ff, 0x3ff007e3, 0x0293a91d,
218 0x002f9c12, 0x3ff00be7, 0x01241905,
219 0x001f8c29, 0x000007ed, 0x3fe470eb,
220 0x000f7c46, 0x000007f2, 0x3f04b8ca,
221 0x3fef7865, 0x000007f6, 0x3e74e4a8 },
224 0x001fd3e9, 0x001fd3e9, 0x08f23d26,
225 0x002fbff3, 0x001fe3e4, 0x0712ad23,
226 0x002fa800, 0x000ff3e0, 0x05631d1b,
227 0x001f9810, 0x000ffbe1, 0x03b3890d,
228 0x000f8c23, 0x000003e3, 0x0233e8fa,
229 0x3fef843b, 0x000003e7, 0x00f430e4,
230 0x3fbf8456, 0x3ff00bea, 0x00046cc8,
231 0x3f8f8c72, 0x3ff00bef, 0x3f3490ac },
234 0x001fbbf4, 0x001fbbf4, 0x09425112,
235 0x001fa800, 0x002fc7ed, 0x0792b110,
236 0x000f980e, 0x001fdbe6, 0x0613110a,
237 0x3fff8c20, 0x001fe7e3, 0x04a368fd,
238 0x3fcf8c33, 0x000ff7e2, 0x0343b8ed,
239 0x3f9f8c4a, 0x000fffe3, 0x0203f8da,
240 0x3f5f9c61, 0x000003e6, 0x00e428c5,
241 0x3f1fb07b, 0x000003eb, 0x3fe440af },
244 0x000fa400, 0x000fa400, 0x09625902,
245 0x3fff980c, 0x001fb7f5, 0x0812b0ff,
246 0x3fdf901c, 0x001fc7ed, 0x06b2fcfa,
247 0x3faf902d, 0x001fd3e8, 0x055348f1,
248 0x3f7f983f, 0x001fe3e5, 0x04038ce3,
249 0x3f3fa454, 0x001fefe3, 0x02e3c8d1,
250 0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0,
251 0x3ecfd880, 0x000fffe6, 0x00c404ac },
254 0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4,
255 0x3fbf9818, 0x3fffa400, 0x0842a8f1,
256 0x3f8f9827, 0x000fb3f7, 0x0702f0ec,
257 0x3f5fa037, 0x000fc3ef, 0x05d330e4,
258 0x3f2fac49, 0x001fcfea, 0x04a364d9,
259 0x3effc05c, 0x001fdbe7, 0x038394ca,
260 0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb,
261 0x3ea00083, 0x001fefe6, 0x0183c0a9 },
264 0x3f9fa014, 0x3f9fa014, 0x098260e6,
265 0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5,
266 0x3f4fa431, 0x3fefa400, 0x0742d8e1,
267 0x3f1fb440, 0x3fffb3f8, 0x062310d9,
268 0x3eefc850, 0x000fbbf2, 0x050340d0,
269 0x3ecfe062, 0x000fcbec, 0x041364c2,
270 0x3ea00073, 0x001fd3ea, 0x03037cb5,
271 0x3e902086, 0x001fdfe8, 0x022388a5 },
274 0x3f5fa81e, 0x3f5fa81e, 0x096258da,
275 0x3f3fac2b, 0x3f8fa412, 0x088290d8,
276 0x3f0fbc38, 0x3fafa408, 0x0772c8d5,
277 0x3eefcc47, 0x3fcfa800, 0x0672f4ce,
278 0x3ecfe456, 0x3fefaffa, 0x05531cc6,
279 0x3eb00066, 0x3fffbbf3, 0x047334bb,
280 0x3ea01c77, 0x000fc7ee, 0x039348ae,
281 0x3ea04486, 0x000fd3eb, 0x02b350a1 },
284 0x3f2fb426, 0x3f2fb426, 0x094250ce,
285 0x3f0fc032, 0x3f4fac1b, 0x086284cd,
286 0x3eefd040, 0x3f7fa811, 0x0782acc9,
287 0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4,
288 0x3eb0005b, 0x3fbfac00, 0x05b2f4bc,
289 0x3eb0186a, 0x3fdfb3fa, 0x04c308b4,
290 0x3eb04077, 0x3fefbbf4, 0x03f31ca8,
291 0x3ec06884, 0x000fbff2, 0x03031c9e },
294 0x3f0fc42d, 0x3f0fc42d, 0x090240c4,
295 0x3eefd439, 0x3f2fb822, 0x08526cc2,
296 0x3edfe845, 0x3f4fb018, 0x078294bf,
297 0x3ec00051, 0x3f6fac0f, 0x06b2b4bb,
298 0x3ec0185f, 0x3f8fac07, 0x05e2ccb4,
299 0x3ec0386b, 0x3fafac00, 0x0502e8ac,
300 0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3,
301 0x3ef08482, 0x3fdfbbf6, 0x0372f898 },
304 0x3eefdc31, 0x3eefdc31, 0x08e238b8,
305 0x3edfec3d, 0x3f0fc828, 0x082258b9,
306 0x3ed00049, 0x3f1fc01e, 0x077278b6,
307 0x3ed01455, 0x3f3fb815, 0x06c294b2,
308 0x3ed03460, 0x3f5fb40d, 0x0602acac,
309 0x3ef0506c, 0x3f7fb006, 0x0542c0a4,
310 0x3f107476, 0x3f9fb400, 0x0472c89d,
311 0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 },
314 0x3eefec37, 0x3eefec37, 0x088220b0,
315 0x3ee00041, 0x3effdc2d, 0x07f244ae,
316 0x3ee0144c, 0x3f0fd023, 0x07625cad,
317 0x3ef02c57, 0x3f1fc81a, 0x06c274a9,
318 0x3f004861, 0x3f3fbc13, 0x060288a6,
319 0x3f20686b, 0x3f5fb80c, 0x05529c9e,
320 0x3f408c74, 0x3f6fb805, 0x04b2ac96,
321 0x3f80ac7e, 0x3f8fb800, 0x0402ac8e },
324 0x3ef0003a, 0x3ef0003a, 0x084210a6,
325 0x3ef01045, 0x3effec32, 0x07b228a7,
326 0x3f00284e, 0x3f0fdc29, 0x073244a4,
327 0x3f104058, 0x3f0fd420, 0x06a258a2,
328 0x3f305c62, 0x3f2fc818, 0x0612689d,
329 0x3f508069, 0x3f3fc011, 0x05728496,
330 0x3f80a072, 0x3f4fc00a, 0x04d28c90,
331 0x3fc0c07b, 0x3f6fbc04, 0x04429088 },
334 0x3f00103e, 0x3f00103e, 0x07f1fc9e,
335 0x3f102447, 0x3f000035, 0x0782149d,
336 0x3f203c4f, 0x3f0ff02c, 0x07122c9c,
337 0x3f405458, 0x3f0fe424, 0x06924099,
338 0x3f607061, 0x3f1fd41d, 0x06024c97,
339 0x3f909068, 0x3f2fcc16, 0x05726490,
340 0x3fc0b070, 0x3f3fc80f, 0x04f26c8a,
341 0x0000d077, 0x3f4fc409, 0x04627484 },
344 0x3f202040, 0x3f202040, 0x07a1e898,
345 0x3f303449, 0x3f100c38, 0x0741fc98,
346 0x3f504c50, 0x3f10002f, 0x06e21495,
347 0x3f706459, 0x3f1ff028, 0x06722492,
348 0x3fa08060, 0x3f1fe421, 0x05f2348f,
349 0x3fd09c67, 0x3f1fdc19, 0x05824c89,
350 0x0000bc6e, 0x3f2fd014, 0x04f25086,
351 0x0040dc74, 0x3f3fcc0d, 0x04825c7f },
354 0x3f403042, 0x3f403042, 0x0761d890,
355 0x3f504848, 0x3f301c3b, 0x0701f090,
356 0x3f805c50, 0x3f200c33, 0x06a2008f,
357 0x3fa07458, 0x3f10002b, 0x06520c8d,
358 0x3fd0905e, 0x3f1ff424, 0x05e22089,
359 0x0000ac65, 0x3f1fe81d, 0x05823483,
360 0x0030cc6a, 0x3f2fdc18, 0x04f23c81,
361 0x0080e871, 0x3f2fd412, 0x0482407c },
364 0x3f604043, 0x3f604043, 0x0721c88a,
365 0x3f80544a, 0x3f502c3c, 0x06d1d88a,
366 0x3fb06851, 0x3f301c35, 0x0681e889,
367 0x3fd08456, 0x3f30082f, 0x0611fc88,
368 0x00009c5d, 0x3f200027, 0x05d20884,
369 0x0030b863, 0x3f2ff421, 0x05621880,
370 0x0070d468, 0x3f2fe81b, 0x0502247c,
371 0x00c0ec6f, 0x3f2fe015, 0x04a22877 },
374 0x3f904c44, 0x3f904c44, 0x06e1b884,
375 0x3fb0604a, 0x3f70383e, 0x0691c885,
376 0x3fe07451, 0x3f502c36, 0x0661d483,
377 0x00009055, 0x3f401831, 0x0601ec81,
378 0x0030a85b, 0x3f300c2a, 0x05b1f480,
379 0x0070c061, 0x3f300024, 0x0562047a,
380 0x00b0d867, 0x3f3ff41e, 0x05020c77,
381 0x00f0f46b, 0x3f2fec19, 0x04a21474 },
384 0x3fb05c43, 0x3fb05c43, 0x06c1b07e,
385 0x3fe06c4b, 0x3f902c3f, 0x0681c081,
386 0x0000844f, 0x3f703838, 0x0631cc7d,
387 0x00309855, 0x3f602433, 0x05d1d47e,
388 0x0060b459, 0x3f50142e, 0x0581e47b,
389 0x00a0c85f, 0x3f400828, 0x0531f078,
390 0x00e0e064, 0x3f300021, 0x0501fc73,
391 0x00b0fc6a, 0x3f3ff41d, 0x04a20873 },
394 0x3fe06444, 0x3fe06444, 0x0681a07a,
395 0x00007849, 0x3fc0503f, 0x0641b07a,
396 0x0020904d, 0x3fa0403a, 0x05f1c07a,
397 0x0060a453, 0x3f803034, 0x05c1c878,
398 0x0090b858, 0x3f70202f, 0x0571d477,
399 0x00d0d05d, 0x3f501829, 0x0531e073,
400 0x0110e462, 0x3f500825, 0x04e1e471,
401 0x01510065, 0x3f40001f, 0x04a1f06d },
404 0x00007044, 0x00007044, 0x06519476,
405 0x00208448, 0x3fe05c3f, 0x0621a476,
406 0x0050984d, 0x3fc04c3a, 0x05e1b075,
407 0x0080ac52, 0x3fa03c35, 0x05a1b875,
408 0x00c0c056, 0x3f803030, 0x0561c473,
409 0x0100d45b, 0x3f70202b, 0x0521d46f,
410 0x0140e860, 0x3f601427, 0x04d1d46e,
411 0x01810064, 0x3f500822, 0x0491dc6b },
414 0x0110a442, 0x0110a442, 0x0551545e,
415 0x0140b045, 0x00e0983f, 0x0531585f,
416 0x0160c047, 0x00c08c3c, 0x0511645e,
417 0x0190cc4a, 0x00908039, 0x04f1685f,
418 0x01c0dc4c, 0x00707436, 0x04d1705e,
419 0x0200e850, 0x00506833, 0x04b1785b,
420 0x0230f453, 0x00305c30, 0x0491805a,
421 0x02710056, 0x0010542d, 0x04718059 },
424 0x01c0bc40, 0x01c0bc40, 0x04c13052,
425 0x01e0c841, 0x01a0b43d, 0x04c13851,
426 0x0210cc44, 0x0180a83c, 0x04a13453,
427 0x0230d845, 0x0160a03a, 0x04913c52,
428 0x0260e047, 0x01409838, 0x04714052,
429 0x0280ec49, 0x01208c37, 0x04514c50,
430 0x02b0f44b, 0x01008435, 0x04414c50,
431 0x02d1004c, 0x00e07c33, 0x0431544f },
434 0x0230c83e, 0x0230c83e, 0x04711c4c,
435 0x0250d03f, 0x0210c43c, 0x0471204b,
436 0x0270d840, 0x0200b83c, 0x0451244b,
437 0x0290dc42, 0x01e0b43a, 0x0441244c,
438 0x02b0e443, 0x01c0b038, 0x0441284b,
439 0x02d0ec44, 0x01b0a438, 0x0421304a,
440 0x02f0f445, 0x0190a036, 0x04213449,
441 0x0310f847, 0x01709c34, 0x04213848 },
444 0x0280d03d, 0x0280d03d, 0x04310c48,
445 0x02a0d43e, 0x0270c83c, 0x04311047,
446 0x02b0dc3e, 0x0250c83a, 0x04311447,
447 0x02d0e040, 0x0240c03a, 0x04211446,
448 0x02e0e840, 0x0220bc39, 0x04111847,
449 0x0300e842, 0x0210b438, 0x04012445,
450 0x0310f043, 0x0200b037, 0x04012045,
451 0x0330f444, 0x01e0ac36, 0x03f12445 },
454 0x0340dc3a, 0x0340dc3a, 0x03b0ec40,
455 0x0340e03a, 0x0330e039, 0x03c0f03e,
456 0x0350e03b, 0x0330dc39, 0x03c0ec3e,
457 0x0350e43a, 0x0320dc38, 0x03c0f43e,
458 0x0360e43b, 0x0320d839, 0x03b0f03e,
459 0x0360e83b, 0x0310d838, 0x03c0fc3b,
460 0x0370e83b, 0x0310d439, 0x03a0f83d,
461 0x0370e83c, 0x0300d438, 0x03b0fc3c },
465 enum rcar_vin_state {
471 struct rcar_vin_priv {
475 /* State of the VIN module in capturing mode */
476 enum rcar_vin_state state;
477 struct soc_camera_host ici;
478 struct list_head capture;
479 #define MAX_BUFFER_NUM 3
480 struct vb2_buffer *queue_buf[MAX_BUFFER_NUM];
481 struct vb2_alloc_ctx *alloc_ctx;
482 enum v4l2_field field;
483 unsigned int pdata_flags;
484 unsigned int vb_count;
485 unsigned int nr_hw_slots;
486 bool request_to_stop;
487 struct completion capture_stop;
491 #define is_continuous_transfer(priv) (priv->vb_count > MAX_BUFFER_NUM)
493 struct rcar_vin_buffer {
494 struct vb2_buffer vb;
495 struct list_head list;
498 #define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
499 struct rcar_vin_buffer, \
502 struct rcar_vin_cam {
503 /* VIN offsets within the camera output, before the VIN scaler */
504 unsigned int vin_left;
505 unsigned int vin_top;
506 /* Client output, as seen by the VIN */
509 /* User window from S_FMT */
510 unsigned int out_width;
511 unsigned int out_height;
513 * User window from S_CROP / G_CROP, produced by client cropping and
514 * scaling, VIN scaling and VIN cropping, mapped back onto the client
517 struct v4l2_rect subrect;
518 /* Camera cropping rectangle */
519 struct v4l2_rect rect;
520 const struct soc_mbus_pixelfmt *extra_fmt;
524 * .queue_setup() is called to check whether the driver can accept the requested
525 * number of buffers and to fill in plane sizes for the current frame format if
528 static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
529 const struct v4l2_format *fmt,
531 unsigned int *num_planes,
532 unsigned int sizes[], void *alloc_ctxs[])
534 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
535 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
536 struct rcar_vin_priv *priv = ici->priv;
539 const struct soc_camera_format_xlate *xlate;
540 unsigned int bytes_per_line;
543 xlate = soc_camera_xlate_by_fourcc(icd,
544 fmt->fmt.pix.pixelformat);
547 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
552 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
554 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
555 fmt->fmt.pix.height);
559 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
561 /* Called from VIDIOC_REQBUFS or in compatibility mode */
562 sizes[0] = icd->sizeimage;
565 alloc_ctxs[0] = priv->alloc_ctx;
567 if (!vq->num_buffers)
572 priv->vb_count = *count;
576 /* Number of hardware slots */
577 if (is_continuous_transfer(priv))
578 priv->nr_hw_slots = MAX_BUFFER_NUM;
580 priv->nr_hw_slots = 1;
582 dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
587 static int rcar_vin_setup(struct rcar_vin_priv *priv)
589 struct soc_camera_device *icd = priv->ici.icd;
590 struct rcar_vin_cam *cam = icd->host_priv;
591 u32 vnmc, dmr, interrupts;
592 bool progressive = false, output_is_yuv = false;
594 switch (priv->field) {
598 case V4L2_FIELD_BOTTOM:
601 case V4L2_FIELD_INTERLACED:
602 case V4L2_FIELD_INTERLACED_TB:
605 case V4L2_FIELD_INTERLACED_BT:
606 vnmc = VNMC_IM_FULL | VNMC_FOC;
608 case V4L2_FIELD_NONE:
609 if (is_continuous_transfer(priv)) {
610 vnmc = VNMC_IM_ODD_EVEN;
621 /* input interface */
622 switch (icd->current_fmt->code) {
623 case MEDIA_BUS_FMT_YUYV8_1X16:
624 /* BT.601/BT.1358 16bit YCbCr422 */
625 vnmc |= VNMC_INF_YUV16;
627 case MEDIA_BUS_FMT_YUYV8_2X8:
628 /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
629 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
630 VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
632 case MEDIA_BUS_FMT_YUYV10_2X10:
633 /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
634 vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
635 VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
642 switch (icd->current_fmt->host_fmt->fourcc) {
643 case V4L2_PIX_FMT_NV16:
644 iowrite32(ALIGN(cam->width * cam->height, 0x80),
645 priv->base + VNUVAOF_REG);
646 dmr = VNDMR_DTMD_YCSEP;
647 output_is_yuv = true;
649 case V4L2_PIX_FMT_YUYV:
651 output_is_yuv = true;
653 case V4L2_PIX_FMT_UYVY:
655 output_is_yuv = true;
657 case V4L2_PIX_FMT_RGB555X:
658 dmr = VNDMR_DTMD_ARGB1555;
660 case V4L2_PIX_FMT_RGB565:
663 case V4L2_PIX_FMT_RGB32:
664 if (priv->chip == RCAR_GEN2 || priv->chip == RCAR_H1 ||
665 priv->chip == RCAR_E1) {
670 dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
671 icd->current_fmt->host_fmt->fourcc);
675 /* Always update on field change */
678 /* If input and output use the same colorspace, use bypass mode */
682 /* progressive or interlaced mode */
683 interrupts = progressive ? VNIE_FIE : VNIE_EFE;
686 iowrite32(interrupts, priv->base + VNINTS_REG);
687 /* enable interrupts */
688 iowrite32(interrupts, priv->base + VNIE_REG);
689 /* start capturing */
690 iowrite32(dmr, priv->base + VNDMR_REG);
691 iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
696 static void rcar_vin_capture(struct rcar_vin_priv *priv)
698 if (is_continuous_transfer(priv))
699 /* Continuous Frame Capture Mode */
700 iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
702 /* Single Frame Capture Mode */
703 iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
706 static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
708 priv->state = STOPPING;
710 /* set continuous & single transfer off */
711 iowrite32(0, priv->base + VNFC_REG);
712 /* disable capture (release DMA buffer), reset */
713 iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
714 priv->base + VNMC_REG);
716 /* update the status if stopped already */
717 if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
718 priv->state = STOPPED;
721 static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
725 for (slot = 0; slot < priv->nr_hw_slots; slot++)
726 if (priv->queue_buf[slot] == NULL)
732 static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
734 /* Ensure all HW slots are filled */
735 return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
738 /* Moves a buffer from the queue to the HW slots */
739 static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
741 struct vb2_buffer *vb;
742 dma_addr_t phys_addr_top;
745 if (list_empty(&priv->capture))
748 /* Find a free HW slot */
749 slot = rcar_vin_get_free_hw_slot(priv);
753 vb = &list_entry(priv->capture.next, struct rcar_vin_buffer, list)->vb;
754 list_del_init(to_buf_list(vb));
755 priv->queue_buf[slot] = vb;
756 phys_addr_top = vb2_dma_contig_plane_dma_addr(vb, 0);
757 iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
762 static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
764 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
765 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
766 struct rcar_vin_priv *priv = ici->priv;
769 size = icd->sizeimage;
771 if (vb2_plane_size(vb, 0) < size) {
772 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
773 vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
777 vb2_set_plane_payload(vb, 0, size);
779 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
780 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
782 spin_lock_irq(&priv->lock);
784 list_add_tail(to_buf_list(vb), &priv->capture);
785 rcar_vin_fill_hw_slot(priv);
787 /* If we weren't running, and have enough buffers, start capturing! */
788 if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
789 if (rcar_vin_setup(priv)) {
791 list_del_init(to_buf_list(vb));
792 spin_unlock_irq(&priv->lock);
795 priv->request_to_stop = false;
796 init_completion(&priv->capture_stop);
797 priv->state = RUNNING;
798 rcar_vin_capture(priv);
801 spin_unlock_irq(&priv->lock);
806 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
810 * Wait for capture to stop and all in-flight buffers to be finished with by
811 * the video hardware. This must be called under &priv->lock
814 static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
816 while (priv->state != STOPPED) {
817 /* issue stop if running */
818 if (priv->state == RUNNING)
819 rcar_vin_request_capture_stop(priv);
821 /* wait until capturing has been stopped */
822 if (priv->state == STOPPING) {
823 priv->request_to_stop = true;
824 spin_unlock_irq(&priv->lock);
825 if (!wait_for_completion_timeout(
827 msecs_to_jiffies(TIMEOUT_MS)))
828 priv->state = STOPPED;
829 spin_lock_irq(&priv->lock);
834 static void rcar_vin_stop_streaming(struct vb2_queue *vq)
836 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
837 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
838 struct rcar_vin_priv *priv = ici->priv;
839 struct list_head *buf_head, *tmp;
842 spin_lock_irq(&priv->lock);
843 rcar_vin_wait_stop_streaming(priv);
845 for (i = 0; i < MAX_BUFFER_NUM; i++) {
846 if (priv->queue_buf[i]) {
847 vb2_buffer_done(priv->queue_buf[i],
848 VB2_BUF_STATE_ERROR);
849 priv->queue_buf[i] = NULL;
853 list_for_each_safe(buf_head, tmp, &priv->capture) {
854 vb2_buffer_done(&list_entry(buf_head,
855 struct rcar_vin_buffer, list)->vb,
856 VB2_BUF_STATE_ERROR);
857 list_del_init(buf_head);
859 spin_unlock_irq(&priv->lock);
862 static struct vb2_ops rcar_vin_vb2_ops = {
863 .queue_setup = rcar_vin_videobuf_setup,
864 .buf_queue = rcar_vin_videobuf_queue,
865 .stop_streaming = rcar_vin_stop_streaming,
866 .wait_prepare = vb2_ops_wait_prepare,
867 .wait_finish = vb2_ops_wait_finish,
870 static irqreturn_t rcar_vin_irq(int irq, void *data)
872 struct rcar_vin_priv *priv = data;
874 bool can_run = false, hw_stopped;
876 unsigned int handled = 0;
878 spin_lock(&priv->lock);
880 int_status = ioread32(priv->base + VNINTS_REG);
884 iowrite32(int_status, priv->base + VNINTS_REG);
887 /* nothing to do if capture status is 'STOPPED' */
888 if (priv->state == STOPPED)
891 hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
893 if (!priv->request_to_stop) {
894 if (is_continuous_transfer(priv))
895 slot = (ioread32(priv->base + VNMS_REG) &
896 VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
900 priv->queue_buf[slot]->v4l2_buf.field = priv->field;
901 priv->queue_buf[slot]->v4l2_buf.sequence = priv->sequence++;
902 v4l2_get_timestamp(&priv->queue_buf[slot]->v4l2_buf.timestamp);
903 vb2_buffer_done(priv->queue_buf[slot], VB2_BUF_STATE_DONE);
904 priv->queue_buf[slot] = NULL;
906 if (priv->state != STOPPING)
907 can_run = rcar_vin_fill_hw_slot(priv);
909 if (hw_stopped || !can_run) {
910 priv->state = STOPPED;
911 } else if (is_continuous_transfer(priv) &&
912 list_empty(&priv->capture) &&
913 priv->state == RUNNING) {
915 * The continuous capturing requires an explicit stop
916 * operation when there is no buffer to be set into
917 * the VnMBm registers.
919 rcar_vin_request_capture_stop(priv);
921 rcar_vin_capture(priv);
924 } else if (hw_stopped) {
925 priv->state = STOPPED;
926 priv->request_to_stop = false;
927 complete(&priv->capture_stop);
931 spin_unlock(&priv->lock);
933 return IRQ_RETVAL(handled);
936 static int rcar_vin_add_device(struct soc_camera_device *icd)
938 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
939 struct rcar_vin_priv *priv = ici->priv;
942 for (i = 0; i < MAX_BUFFER_NUM; i++)
943 priv->queue_buf[i] = NULL;
945 pm_runtime_get_sync(ici->v4l2_dev.dev);
947 dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
953 static void rcar_vin_remove_device(struct soc_camera_device *icd)
955 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
956 struct rcar_vin_priv *priv = ici->priv;
957 struct vb2_buffer *vb;
960 /* disable capture, disable interrupts */
961 iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
962 priv->base + VNMC_REG);
963 iowrite32(0, priv->base + VNIE_REG);
965 priv->state = STOPPED;
966 priv->request_to_stop = false;
968 /* make sure active buffer is cancelled */
969 spin_lock_irq(&priv->lock);
970 for (i = 0; i < MAX_BUFFER_NUM; i++) {
971 vb = priv->queue_buf[i];
973 list_del_init(to_buf_list(vb));
974 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
977 spin_unlock_irq(&priv->lock);
979 pm_runtime_put(ici->v4l2_dev.dev);
981 dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
985 static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
988 const struct vin_coeff *p_prev_set = NULL;
989 const struct vin_coeff *p_set = NULL;
991 /* Look for suitable coefficient values */
992 for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
994 p_set = &vin_coeff_set[i];
996 if (xs < p_set->xs_value)
1000 /* Use previous value if its XS value is closer */
1001 if (p_prev_set && p_set &&
1002 xs - p_prev_set->xs_value < p_set->xs_value - xs)
1005 /* Set coefficient registers */
1006 iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG);
1007 iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG);
1008 iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG);
1010 iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG);
1011 iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG);
1012 iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG);
1014 iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG);
1015 iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG);
1016 iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG);
1018 iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG);
1019 iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG);
1020 iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG);
1022 iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG);
1023 iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG);
1024 iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG);
1026 iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG);
1027 iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG);
1028 iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG);
1030 iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG);
1031 iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG);
1032 iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG);
1034 iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG);
1035 iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG);
1036 iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG);
1039 /* rect is guaranteed to not exceed the scaled camera rectangle */
1040 static int rcar_vin_set_rect(struct soc_camera_device *icd)
1042 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1043 struct rcar_vin_cam *cam = icd->host_priv;
1044 struct rcar_vin_priv *priv = ici->priv;
1045 unsigned int left_offset, top_offset;
1046 unsigned char dsize = 0;
1047 struct v4l2_rect *cam_subrect = &cam->subrect;
1050 dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
1051 icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
1053 left_offset = cam->vin_left;
1054 top_offset = cam->vin_top;
1056 if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_RGB32 &&
1057 priv->chip == RCAR_E1)
1060 dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
1061 cam->width, cam->height, cam->vin_left, cam->vin_top);
1062 dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
1063 cam_subrect->width, cam_subrect->height,
1064 cam_subrect->left, cam_subrect->top);
1066 /* Set Start/End Pixel/Line Pre-Clip */
1067 iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
1068 iowrite32((left_offset + cam_subrect->width - 1) << dsize,
1069 priv->base + VNEPPRC_REG);
1070 switch (priv->field) {
1071 case V4L2_FIELD_INTERLACED:
1072 case V4L2_FIELD_INTERLACED_TB:
1073 case V4L2_FIELD_INTERLACED_BT:
1074 iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
1075 iowrite32((top_offset + cam_subrect->height) / 2 - 1,
1076 priv->base + VNELPRC_REG);
1079 iowrite32(top_offset, priv->base + VNSLPRC_REG);
1080 iowrite32(top_offset + cam_subrect->height - 1,
1081 priv->base + VNELPRC_REG);
1085 /* Set scaling coefficient */
1087 if (cam_subrect->height != cam->out_height)
1088 value = (4096 * cam_subrect->height) / cam->out_height;
1089 dev_dbg(icd->parent, "YS Value: %x\n", value);
1090 iowrite32(value, priv->base + VNYS_REG);
1093 if (cam_subrect->width != cam->out_width)
1094 value = (4096 * cam_subrect->width) / cam->out_width;
1096 /* Horizontal upscaling is up to double size */
1097 if (0 < value && value < 2048)
1100 dev_dbg(icd->parent, "XS Value: %x\n", value);
1101 iowrite32(value, priv->base + VNXS_REG);
1103 /* Horizontal upscaling is carried out by scaling down from double size */
1107 set_coeff(priv, value);
1109 /* Set Start/End Pixel/Line Post-Clip */
1110 iowrite32(0, priv->base + VNSPPOC_REG);
1111 iowrite32(0, priv->base + VNSLPOC_REG);
1112 iowrite32((cam->out_width - 1) << dsize, priv->base + VNEPPOC_REG);
1113 switch (priv->field) {
1114 case V4L2_FIELD_INTERLACED:
1115 case V4L2_FIELD_INTERLACED_TB:
1116 case V4L2_FIELD_INTERLACED_BT:
1117 iowrite32(cam->out_height / 2 - 1,
1118 priv->base + VNELPOC_REG);
1121 iowrite32(cam->out_height - 1, priv->base + VNELPOC_REG);
1125 iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
1130 static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
1132 *vnmc = ioread32(priv->base + VNMC_REG);
1133 /* module disable */
1134 iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
1137 static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
1139 unsigned long timeout = jiffies + 10 * HZ;
1142 * Wait until the end of the current frame. It can take a long time,
1143 * but if it has been aborted by a MRST1 reset, it should exit sooner.
1145 while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
1146 time_before(jiffies, timeout))
1149 if (time_after(jiffies, timeout)) {
1150 dev_err(priv->ici.v4l2_dev.dev,
1151 "Timeout waiting for frame end! Interface problem?\n");
1155 iowrite32(vnmc, priv->base + VNMC_REG);
1158 #define VIN_MBUS_FLAGS (V4L2_MBUS_MASTER | \
1159 V4L2_MBUS_PCLK_SAMPLE_RISING | \
1160 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
1161 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
1162 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
1163 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
1164 V4L2_MBUS_DATA_ACTIVE_HIGH)
1166 static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
1168 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1169 struct rcar_vin_priv *priv = ici->priv;
1170 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1171 struct v4l2_mbus_config cfg;
1172 unsigned long common_flags;
1177 capture_stop_preserve(priv, &vnmc);
1179 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1181 common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1182 if (!common_flags) {
1183 dev_warn(icd->parent,
1184 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1185 cfg.flags, VIN_MBUS_FLAGS);
1188 } else if (ret != -ENOIOCTLCMD) {
1191 common_flags = VIN_MBUS_FLAGS;
1194 /* Make choises, based on platform preferences */
1195 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1196 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1197 if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
1198 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1200 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1203 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1204 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1205 if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
1206 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1208 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1211 cfg.flags = common_flags;
1212 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1213 if (ret < 0 && ret != -ENOIOCTLCMD)
1216 val = VNDMR2_FTEV | VNDMR2_VLV(1);
1217 if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
1219 if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
1221 iowrite32(val, priv->base + VNDMR2_REG);
1223 ret = rcar_vin_set_rect(icd);
1227 capture_restore(priv, vnmc);
1232 static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
1233 unsigned char buswidth)
1235 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1236 struct v4l2_mbus_config cfg;
1239 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1240 if (ret == -ENOIOCTLCMD)
1248 /* check is there common mbus flags */
1249 ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
1253 dev_warn(icd->parent,
1254 "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
1255 cfg.flags, VIN_MBUS_FLAGS);
1260 static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1262 return fmt->packing == SOC_MBUS_PACKING_NONE ||
1263 (fmt->bits_per_sample > 8 &&
1264 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1267 static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
1269 .fourcc = V4L2_PIX_FMT_NV16,
1271 .bits_per_sample = 8,
1272 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1273 .order = SOC_MBUS_ORDER_LE,
1274 .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
1277 .fourcc = V4L2_PIX_FMT_YUYV,
1279 .bits_per_sample = 16,
1280 .packing = SOC_MBUS_PACKING_NONE,
1281 .order = SOC_MBUS_ORDER_LE,
1282 .layout = SOC_MBUS_LAYOUT_PACKED,
1285 .fourcc = V4L2_PIX_FMT_UYVY,
1287 .bits_per_sample = 16,
1288 .packing = SOC_MBUS_PACKING_NONE,
1289 .order = SOC_MBUS_ORDER_LE,
1290 .layout = SOC_MBUS_LAYOUT_PACKED,
1293 .fourcc = V4L2_PIX_FMT_RGB565,
1295 .bits_per_sample = 16,
1296 .packing = SOC_MBUS_PACKING_NONE,
1297 .order = SOC_MBUS_ORDER_LE,
1298 .layout = SOC_MBUS_LAYOUT_PACKED,
1301 .fourcc = V4L2_PIX_FMT_RGB555X,
1303 .bits_per_sample = 16,
1304 .packing = SOC_MBUS_PACKING_NONE,
1305 .order = SOC_MBUS_ORDER_LE,
1306 .layout = SOC_MBUS_LAYOUT_PACKED,
1309 .fourcc = V4L2_PIX_FMT_RGB32,
1311 .bits_per_sample = 32,
1312 .packing = SOC_MBUS_PACKING_NONE,
1313 .order = SOC_MBUS_ORDER_LE,
1314 .layout = SOC_MBUS_LAYOUT_PACKED,
1318 static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
1319 struct soc_camera_format_xlate *xlate)
1321 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1322 struct device *dev = icd->parent;
1325 struct rcar_vin_cam *cam;
1326 struct v4l2_subdev_mbus_code_enum code = {
1327 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1330 const struct soc_mbus_pixelfmt *fmt;
1332 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
1336 fmt = soc_mbus_get_fmtdesc(code.code);
1338 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code);
1342 ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
1346 if (!icd->host_priv) {
1347 struct v4l2_subdev_format fmt = {
1348 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1350 struct v4l2_mbus_framefmt *mf = &fmt.format;
1351 struct v4l2_rect rect;
1352 struct device *dev = icd->parent;
1355 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
1359 /* Cache current client geometry */
1360 ret = soc_camera_client_g_rect(sd, &rect);
1361 if (ret == -ENOIOCTLCMD) {
1362 /* Sensor driver doesn't support cropping */
1365 rect.width = mf->width;
1366 rect.height = mf->height;
1367 } else if (ret < 0) {
1372 * If sensor proposes too large format then try smaller ones:
1373 * 1280x960, 640x480, 320x240
1375 for (shift = 0; shift < 3; shift++) {
1376 if (mf->width <= VIN_MAX_WIDTH &&
1377 mf->height <= VIN_MAX_HEIGHT)
1380 mf->width = 1280 >> shift;
1381 mf->height = 960 >> shift;
1382 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1383 soc_camera_grp_id(icd),
1392 "Failed to configure the client below %ux%u\n",
1393 mf->width, mf->height);
1397 dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height);
1399 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1403 * We are called with current camera crop,
1404 * initialise subrect with it
1407 cam->subrect = rect;
1408 cam->width = mf->width;
1409 cam->height = mf->height;
1410 cam->out_width = mf->width;
1411 cam->out_height = mf->height;
1413 icd->host_priv = cam;
1415 cam = icd->host_priv;
1418 /* Beginning of a pass */
1420 cam->extra_fmt = NULL;
1422 switch (code.code) {
1423 case MEDIA_BUS_FMT_YUYV8_1X16:
1424 case MEDIA_BUS_FMT_YUYV8_2X8:
1425 case MEDIA_BUS_FMT_YUYV10_2X10:
1429 /* Add all our formats that can be generated by VIN */
1430 cam->extra_fmt = rcar_vin_formats;
1432 n = ARRAY_SIZE(rcar_vin_formats);
1434 for (k = 0; xlate && k < n; k++, xlate++) {
1435 xlate->host_fmt = &rcar_vin_formats[k];
1436 xlate->code = code.code;
1437 dev_dbg(dev, "Providing format %s using code %d\n",
1438 rcar_vin_formats[k].name, code.code);
1442 if (!rcar_vin_packing_supported(fmt))
1445 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1450 /* Generic pass-through */
1453 xlate->host_fmt = fmt;
1454 xlate->code = code.code;
1461 static void rcar_vin_put_formats(struct soc_camera_device *icd)
1463 kfree(icd->host_priv);
1464 icd->host_priv = NULL;
1467 static int rcar_vin_set_crop(struct soc_camera_device *icd,
1468 const struct v4l2_crop *a)
1470 struct v4l2_crop a_writable = *a;
1471 const struct v4l2_rect *rect = &a_writable.c;
1472 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1473 struct rcar_vin_priv *priv = ici->priv;
1474 struct v4l2_crop cam_crop;
1475 struct rcar_vin_cam *cam = icd->host_priv;
1476 struct v4l2_rect *cam_rect = &cam_crop.c;
1477 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1478 struct device *dev = icd->parent;
1479 struct v4l2_subdev_format fmt = {
1480 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1482 struct v4l2_mbus_framefmt *mf = &fmt.format;
1486 dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1487 rect->left, rect->top);
1489 /* During camera cropping its output window can change too, stop VIN */
1490 capture_stop_preserve(priv, &vnmc);
1491 dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
1493 /* Apply iterative camera S_CROP for new input window. */
1494 ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
1495 &cam->rect, &cam->subrect);
1499 dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
1500 cam_rect->width, cam_rect->height,
1501 cam_rect->left, cam_rect->top);
1503 /* On success cam_crop contains current camera crop */
1505 /* Retrieve camera output window */
1506 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
1510 if (mf->width > VIN_MAX_WIDTH || mf->height > VIN_MAX_HEIGHT)
1513 /* Cache camera output window */
1514 cam->width = mf->width;
1515 cam->height = mf->height;
1517 icd->user_width = cam->width;
1518 icd->user_height = cam->height;
1520 cam->vin_left = rect->left & ~1;
1521 cam->vin_top = rect->top & ~1;
1523 /* Use VIN cropping to crop to the new window. */
1524 ret = rcar_vin_set_rect(icd);
1528 cam->subrect = *rect;
1530 dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
1531 icd->user_width, icd->user_height,
1532 cam->vin_left, cam->vin_top);
1534 /* Restore capture */
1535 for (i = 0; i < MAX_BUFFER_NUM; i++) {
1536 if (priv->queue_buf[i] && priv->state == STOPPED) {
1541 capture_restore(priv, vnmc);
1543 /* Even if only camera cropping succeeded */
1547 static int rcar_vin_get_crop(struct soc_camera_device *icd,
1548 struct v4l2_crop *a)
1550 struct rcar_vin_cam *cam = icd->host_priv;
1552 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1553 a->c = cam->subrect;
1558 /* Similar to set_crop multistage iterative algorithm */
1559 static int rcar_vin_set_fmt(struct soc_camera_device *icd,
1560 struct v4l2_format *f)
1562 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1563 struct rcar_vin_priv *priv = ici->priv;
1564 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1565 struct rcar_vin_cam *cam = icd->host_priv;
1566 struct v4l2_pix_format *pix = &f->fmt.pix;
1567 struct v4l2_mbus_framefmt mf;
1568 struct device *dev = icd->parent;
1569 __u32 pixfmt = pix->pixelformat;
1570 const struct soc_camera_format_xlate *xlate;
1571 unsigned int vin_sub_width = 0, vin_sub_height = 0;
1574 enum v4l2_field field;
1577 dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
1578 pixfmt, pix->width, pix->height);
1580 switch (pix->field) {
1582 pix->field = V4L2_FIELD_NONE;
1584 case V4L2_FIELD_NONE:
1585 case V4L2_FIELD_TOP:
1586 case V4L2_FIELD_BOTTOM:
1587 case V4L2_FIELD_INTERLACED_TB:
1588 case V4L2_FIELD_INTERLACED_BT:
1591 case V4L2_FIELD_INTERLACED:
1592 /* Query for standard if not explicitly mentioned _TB/_BT */
1593 ret = v4l2_subdev_call(sd, video, querystd, &std);
1595 std = V4L2_STD_625_50;
1597 field = std & V4L2_STD_625_50 ? V4L2_FIELD_INTERLACED_TB :
1598 V4L2_FIELD_INTERLACED_BT;
1602 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1604 dev_warn(dev, "Format %x not found\n", pixfmt);
1607 /* Calculate client output geometry */
1608 soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
1610 mf.field = pix->field;
1611 mf.colorspace = pix->colorspace;
1612 mf.code = xlate->code;
1615 case V4L2_PIX_FMT_RGB32:
1616 can_scale = priv->chip != RCAR_E1;
1618 case V4L2_PIX_FMT_UYVY:
1619 case V4L2_PIX_FMT_YUYV:
1620 case V4L2_PIX_FMT_RGB565:
1621 case V4L2_PIX_FMT_RGB555X:
1629 dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
1631 ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
1632 &mf, &vin_sub_width, &vin_sub_height,
1635 /* Done with the camera. Now see if we can improve the result */
1636 dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1637 ret, mf.width, mf.height, pix->width, pix->height);
1639 if (ret == -ENOIOCTLCMD)
1640 dev_dbg(dev, "Sensor doesn't support scaling\n");
1644 if (mf.code != xlate->code)
1647 /* Prepare VIN crop */
1648 cam->width = mf.width;
1649 cam->height = mf.height;
1651 /* Use VIN scaling to scale to the requested user window. */
1653 /* We cannot scale up */
1654 if (pix->width > vin_sub_width)
1655 vin_sub_width = pix->width;
1657 if (pix->height > vin_sub_height)
1658 vin_sub_height = pix->height;
1660 pix->colorspace = mf.colorspace;
1663 pix->width = vin_sub_width;
1664 pix->height = vin_sub_height;
1668 * We have calculated CFLCR, the actual configuration will be performed
1669 * in rcar_vin_set_bus_param()
1672 dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
1673 vin_sub_width, pix->width, vin_sub_height, pix->height);
1675 cam->out_width = pix->width;
1676 cam->out_height = pix->height;
1678 icd->current_fmt = xlate;
1680 priv->field = field;
1685 static int rcar_vin_try_fmt(struct soc_camera_device *icd,
1686 struct v4l2_format *f)
1688 const struct soc_camera_format_xlate *xlate;
1689 struct v4l2_pix_format *pix = &f->fmt.pix;
1690 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1691 struct v4l2_subdev_pad_config pad_cfg;
1692 struct v4l2_subdev_format format = {
1693 .which = V4L2_SUBDEV_FORMAT_TRY,
1695 struct v4l2_mbus_framefmt *mf = &format.format;
1696 __u32 pixfmt = pix->pixelformat;
1700 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1702 xlate = icd->current_fmt;
1703 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1704 pixfmt, xlate->host_fmt->fourcc);
1705 pixfmt = xlate->host_fmt->fourcc;
1706 pix->pixelformat = pixfmt;
1707 pix->colorspace = icd->colorspace;
1710 /* FIXME: calculate using depth and bus width */
1711 v4l_bound_align_image(&pix->width, 2, VIN_MAX_WIDTH, 1,
1712 &pix->height, 4, VIN_MAX_HEIGHT, 2, 0);
1715 height = pix->height;
1717 /* let soc-camera calculate these values */
1718 pix->bytesperline = 0;
1721 /* limit to sensor capabilities */
1722 mf->width = pix->width;
1723 mf->height = pix->height;
1724 mf->field = pix->field;
1725 mf->code = xlate->code;
1726 mf->colorspace = pix->colorspace;
1728 ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1729 pad, set_fmt, &pad_cfg, &format);
1733 /* Adjust only if VIN cannot scale */
1734 if (pix->width > mf->width * 2)
1735 pix->width = mf->width * 2;
1736 if (pix->height > mf->height * 3)
1737 pix->height = mf->height * 3;
1739 pix->field = mf->field;
1740 pix->colorspace = mf->colorspace;
1742 if (pixfmt == V4L2_PIX_FMT_NV16) {
1743 /* FIXME: check against rect_max after converting soc-camera */
1744 /* We can scale precisely, need a bigger image from camera */
1745 if (pix->width < width || pix->height < height) {
1747 * We presume, the sensor behaves sanely, i.e. if
1748 * requested a bigger rectangle, it will not return a
1751 mf->width = VIN_MAX_WIDTH;
1752 mf->height = VIN_MAX_HEIGHT;
1753 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1754 soc_camera_grp_id(icd),
1755 pad, set_fmt, &pad_cfg,
1758 dev_err(icd->parent,
1759 "client try_fmt() = %d\n", ret);
1763 /* We will scale exactly */
1764 if (mf->width > width)
1766 if (mf->height > height)
1767 pix->height = height;
1773 static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
1775 struct soc_camera_device *icd = file->private_data;
1777 return vb2_poll(&icd->vb2_vidq, file, pt);
1780 static int rcar_vin_querycap(struct soc_camera_host *ici,
1781 struct v4l2_capability *cap)
1783 strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
1784 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1785 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1790 static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
1791 struct soc_camera_device *icd)
1793 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1795 vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1796 vq->io_modes = VB2_MMAP | VB2_USERPTR;
1798 vq->ops = &rcar_vin_vb2_ops;
1799 vq->mem_ops = &vb2_dma_contig_memops;
1800 vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
1801 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1802 vq->lock = &ici->host_lock;
1804 return vb2_queue_init(vq);
1807 static struct soc_camera_host_ops rcar_vin_host_ops = {
1808 .owner = THIS_MODULE,
1809 .add = rcar_vin_add_device,
1810 .remove = rcar_vin_remove_device,
1811 .get_formats = rcar_vin_get_formats,
1812 .put_formats = rcar_vin_put_formats,
1813 .get_crop = rcar_vin_get_crop,
1814 .set_crop = rcar_vin_set_crop,
1815 .try_fmt = rcar_vin_try_fmt,
1816 .set_fmt = rcar_vin_set_fmt,
1817 .poll = rcar_vin_poll,
1818 .querycap = rcar_vin_querycap,
1819 .set_bus_param = rcar_vin_set_bus_param,
1820 .init_videobuf2 = rcar_vin_init_videobuf2,
1824 static const struct of_device_id rcar_vin_of_table[] = {
1825 { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
1826 { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
1827 { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
1828 { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
1829 { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
1830 { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
1833 MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
1836 static struct platform_device_id rcar_vin_id_table[] = {
1837 { "r8a7791-vin", RCAR_GEN2 },
1838 { "r8a7790-vin", RCAR_GEN2 },
1839 { "r8a7779-vin", RCAR_H1 },
1840 { "r8a7778-vin", RCAR_M1 },
1841 { "uPD35004-vin", RCAR_E1 },
1844 MODULE_DEVICE_TABLE(platform, rcar_vin_id_table);
1846 static int rcar_vin_probe(struct platform_device *pdev)
1848 const struct of_device_id *match = NULL;
1849 struct rcar_vin_priv *priv;
1850 struct resource *mem;
1851 struct rcar_vin_platform_data *pdata;
1852 unsigned int pdata_flags;
1855 if (pdev->dev.of_node) {
1856 struct v4l2_of_endpoint ep;
1857 struct device_node *np;
1859 match = of_match_device(of_match_ptr(rcar_vin_of_table),
1862 np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
1864 dev_err(&pdev->dev, "could not find endpoint\n");
1868 ret = v4l2_of_parse_endpoint(np, &ep);
1870 dev_err(&pdev->dev, "could not parse endpoint\n");
1874 if (ep.bus_type == V4L2_MBUS_BT656)
1875 pdata_flags = RCAR_VIN_BT656;
1878 if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1879 pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
1880 if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1881 pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
1886 dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
1888 pdata = pdev->dev.platform_data;
1889 if (!pdata || !pdata->flags) {
1890 dev_err(&pdev->dev, "platform data not set\n");
1893 pdata_flags = pdata->flags;
1896 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1900 irq = platform_get_irq(pdev, 0);
1904 priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
1909 priv->base = devm_ioremap_resource(&pdev->dev, mem);
1910 if (IS_ERR(priv->base))
1911 return PTR_ERR(priv->base);
1913 ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
1914 dev_name(&pdev->dev), priv);
1918 priv->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1919 if (IS_ERR(priv->alloc_ctx))
1920 return PTR_ERR(priv->alloc_ctx);
1922 priv->ici.priv = priv;
1923 priv->ici.v4l2_dev.dev = &pdev->dev;
1924 priv->ici.drv_name = dev_name(&pdev->dev);
1925 priv->ici.ops = &rcar_vin_host_ops;
1927 priv->pdata_flags = pdata_flags;
1929 priv->ici.nr = pdev->id;
1930 priv->chip = pdev->id_entry->driver_data;
1932 priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
1933 priv->chip = (enum chip_id)match->data;
1936 spin_lock_init(&priv->lock);
1937 INIT_LIST_HEAD(&priv->capture);
1939 priv->state = STOPPED;
1941 pm_suspend_ignore_children(&pdev->dev, true);
1942 pm_runtime_enable(&pdev->dev);
1944 ret = soc_camera_host_register(&priv->ici);
1951 pm_runtime_disable(&pdev->dev);
1952 vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1957 static int rcar_vin_remove(struct platform_device *pdev)
1959 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1960 struct rcar_vin_priv *priv = container_of(soc_host,
1961 struct rcar_vin_priv, ici);
1963 soc_camera_host_unregister(soc_host);
1964 pm_runtime_disable(&pdev->dev);
1965 vb2_dma_contig_cleanup_ctx(priv->alloc_ctx);
1970 static struct platform_driver rcar_vin_driver = {
1971 .probe = rcar_vin_probe,
1972 .remove = rcar_vin_remove,
1975 .of_match_table = of_match_ptr(rcar_vin_of_table),
1977 .id_table = rcar_vin_id_table,
1980 module_platform_driver(rcar_vin_driver);
1982 MODULE_LICENSE("GPL");
1983 MODULE_ALIAS("platform:rcar_vin");
1984 MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");